installer update to quick install and agent rebuild

This commit is contained in:
Brian Madison 2025-11-12 22:40:45 -06:00
parent 8f57effda4
commit b63bf9d067
3 changed files with 51 additions and 16 deletions

View File

@ -1627,26 +1627,33 @@ class Installer {
});
spinner.succeed('Manifests regenerated');
// Ask for IDE to update
spinner.stop();
// Note: UI lives in tools/cli/lib/ui.js; from installers/lib/core use '../../../lib/ui'
const { UI } = require('../../../lib/ui');
const ui = new UI();
const toolConfig = await ui.promptToolSelection(projectDir, []);
if (!toolConfig.skipIde && toolConfig.ides && toolConfig.ides.length > 0) {
// Update IDE configurations using the existing IDE list from manifest
if (existingIdes && existingIdes.length > 0) {
spinner.start('Updating IDE configurations...');
for (const ide of toolConfig.ides) {
for (const ide of existingIdes) {
spinner.text = `Updating ${ide}...`;
// Stop spinner before IDE setup to prevent blocking any potential prompts
// However, we pass _alreadyConfigured to skip all prompts during compile
spinner.stop();
await this.ideManager.setup(ide, projectDir, bmadDir, {
selectedModules: installedModules,
skipModuleInstall: true, // Skip module installation, just update IDE files
verbose: config.verbose,
preCollectedConfig: { _alreadyConfigured: true }, // Skip all interactive prompts during compile
});
// Restart spinner for next IDE
if (existingIdes.indexOf(ide) < existingIdes.length - 1) {
spinner.start('Updating IDE configurations...');
}
}
spinner.succeed('IDE configurations updated');
console.log(chalk.green('✓ IDE configurations updated'));
} else {
console.log(chalk.yellow('⚠️ No IDEs configured. Skipping IDE update.'));
}
return { agentCount, taskCount };

View File

@ -124,10 +124,12 @@ class UI {
* @returns {Object} Tool configuration
*/
async promptToolSelection(projectDir, selectedModules) {
// Check for existing configured IDEs
// Check for existing configured IDEs - use findBmadDir to detect custom folder names
const { Detector } = require('../installers/lib/core/detector');
const { Installer } = require('../installers/lib/core/installer');
const detector = new Detector();
const bmadDir = path.join(projectDir || process.cwd(), 'bmad');
const installer = new Installer();
const bmadDir = await installer.findBmadDir(projectDir || process.cwd());
const existingInstall = await detector.detect(bmadDir);
const configuredIdes = existingInstall.ides || [];
@ -332,8 +334,10 @@ class UI {
*/
async getExistingInstallation(directory) {
const { Detector } = require('../installers/lib/core/detector');
const { Installer } = require('../installers/lib/core/installer');
const detector = new Detector();
const bmadDir = path.join(directory, 'bmad');
const installer = new Installer();
const bmadDir = await installer.findBmadDir(directory);
const existingInstall = await detector.detect(bmadDir);
const installedModuleIds = new Set(existingInstall.modules.map((mod) => mod.id));
@ -431,9 +435,15 @@ class UI {
if (stats.isDirectory()) {
const files = await fs.readdir(directory);
if (files.length > 0) {
// Check for any bmad installation (any folder with _cfg/manifest.yaml)
const { Installer } = require('../installers/lib/core/installer');
const installer = new Installer();
const bmadDir = await installer.findBmadDir(directory);
const hasBmadInstall = (await fs.pathExists(bmadDir)) && (await fs.pathExists(path.join(bmadDir, '_cfg', 'manifest.yaml')));
console.log(
chalk.gray(`Directory exists and contains ${files.length} item(s)`) +
(files.includes('bmad') ? chalk.yellow(' including existing bmad installation') : ''),
(hasBmadInstall ? chalk.yellow(` including existing BMAD installation (${path.basename(bmadDir)})`) : ''),
);
} else {
console.log(chalk.gray('Directory exists and is empty'));

View File

@ -270,13 +270,31 @@ class YamlXmlBuilder {
/**
* Build prompts XML section
* Handles both array format and object/dictionary format
*/
buildPromptsXml(prompts) {
if (!prompts || prompts.length === 0) return '';
if (!prompts) return '';
// Handle object/dictionary format: { promptId: 'content', ... }
// Convert to array format for processing
let promptsArray = prompts;
if (!Array.isArray(prompts)) {
// Check if it's an object with no length property (dictionary format)
if (typeof prompts === 'object' && prompts.length === undefined) {
promptsArray = Object.entries(prompts).map(([id, content]) => ({
id: id,
content: content,
}));
} else {
return ''; // Not a valid prompts format
}
}
if (promptsArray.length === 0) return '';
let xml = ' <prompts>\n';
for (const prompt of prompts) {
for (const prompt of promptsArray) {
xml += ` <prompt id="${prompt.id || ''}">\n`;
xml += ` <![CDATA[\n`;
xml += ` ${prompt.content || ''}\n`;