installer improvements

This commit is contained in:
Brian Madison
2025-10-28 12:47:45 -05:00
parent ed3603f7b2
commit ee58586f39
99 changed files with 8143 additions and 1286 deletions

View File

@@ -14,6 +14,13 @@ module.exports = {
try {
const config = await ui.promptInstall();
// Handle cancel
if (config.actionType === 'cancel') {
console.log(chalk.yellow('Installation cancelled.'));
process.exit(0);
return;
}
// Handle agent compilation separately
if (config.actionType === 'compile') {
const result = await installer.compileAgents(config);
@@ -32,6 +39,11 @@ module.exports = {
return;
}
// Handle reinstall by setting force flag
if (config.actionType === 'reinstall') {
config._requestedReinstall = true;
}
// Regular install/update flow
const result = await installer.install(config);

View File

@@ -37,13 +37,26 @@ class Installer {
* Collect Tool/IDE configurations after module configuration
* @param {string} projectDir - Project directory
* @param {Array} selectedModules - Selected modules from configuration
* @param {boolean} isFullReinstall - Whether this is a full reinstall
* @param {Array} previousIdes - Previously configured IDEs (for reinstalls)
* @param {Array} preSelectedIdes - Pre-selected IDEs from early prompt (optional)
* @returns {Object} Tool/IDE selection and configurations
*/
async collectToolConfigurations(projectDir, selectedModules, isFullReinstall = false, previousIdes = []) {
// Prompt for tool selection
const { UI } = require('../../../lib/ui');
const ui = new UI();
const toolConfig = await ui.promptToolSelection(projectDir, selectedModules);
async collectToolConfigurations(projectDir, selectedModules, isFullReinstall = false, previousIdes = [], preSelectedIdes = null) {
// Use pre-selected IDEs if provided, otherwise prompt
let toolConfig;
if (preSelectedIdes === null) {
// Fallback: prompt for tool selection (backwards compatibility)
const { UI } = require('../../../lib/ui');
const ui = new UI();
toolConfig = await ui.promptToolSelection(projectDir, selectedModules);
} else {
// IDEs were already selected during initial prompts
toolConfig = {
ides: preSelectedIdes,
skipIde: !preSelectedIdes || preSelectedIdes.length === 0,
};
}
// Check for already configured IDEs
const { Detector } = require('./detector');
@@ -221,11 +234,22 @@ class Installer {
if (existingInstall.installed && !config.force && !config._quickUpdate) {
spinner.stop();
console.log(chalk.yellow('\n⚠ Existing BMAD installation detected'));
console.log(chalk.dim(` Location: ${bmadDir}`));
console.log(chalk.dim(` Version: ${existingInstall.version}`));
// Check if user already decided what to do (from early menu in ui.js)
let action = null;
if (config._requestedReinstall) {
action = 'reinstall';
} else if (config.actionType === 'update') {
action = 'update';
} else {
// Fallback: Ask the user (backwards compatibility for other code paths)
console.log(chalk.yellow('\n⚠ Existing BMAD installation detected'));
console.log(chalk.dim(` Location: ${bmadDir}`));
console.log(chalk.dim(` Version: ${existingInstall.version}`));
const promptResult = await this.promptUpdateAction();
action = promptResult.action;
}
const { action } = await this.promptUpdateAction();
if (action === 'cancel') {
console.log('Installation cancelled.');
return { success: false, cancelled: true };
@@ -388,11 +412,15 @@ class Installer {
configurations: preConfiguredIdes,
};
} else {
// Pass pre-selected IDEs from early prompt (if available)
// This allows IDE selection to happen before file copying, improving UX
const preSelectedIdes = config.ides && config.ides.length > 0 ? config.ides : null;
toolSelection = await this.collectToolConfigurations(
path.resolve(config.directory),
config.modules,
config._isFullReinstall || false,
config._previouslyConfiguredIdes || [],
preSelectedIdes,
);
}

View File

@@ -36,8 +36,10 @@ class UI {
message: 'What would you like to do?',
choices: [
{ name: 'Quick Update (Settings Preserved)', value: 'quick-update' },
{ name: 'Modify BMAD Installation (Confirm or change each setting)', value: 'install' },
{ name: 'Modify BMAD Installation (Confirm or change each setting)', value: 'update' },
{ name: 'Remove BMad Folder and Reinstall (Full clean install - BMad Customization Will Be Lost)', value: 'reinstall' },
{ name: 'Compile Agents (Quick rebuild of all agent .md files)', value: 'compile' },
{ name: 'Cancel', value: 'cancel' },
],
default: 'quick-update',
},
@@ -58,7 +60,30 @@ class UI {
directory: confirmedDirectory,
};
}
// Handle cancel
if (actionType === 'cancel') {
return {
actionType: 'cancel',
directory: confirmedDirectory,
};
}
// Handle reinstall
if (actionType === 'reinstall') {
return {
actionType: 'reinstall',
directory: confirmedDirectory,
};
}
// If actionType === 'update', continue with normal flow below
}
// Collect IDE tool selection EARLY (before module configuration)
// This allows users to make all decisions upfront before file copying begins
const toolSelection = await this.promptToolSelection(confirmedDirectory, []);
const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
const coreConfig = await this.collectCoreConfig(confirmedDirectory);
const moduleChoices = await this.getModuleChoices(installedModuleIds);
@@ -69,13 +94,13 @@ class UI {
CLIUtils.displayModuleComplete('core', false); // false = don't clear the screen again
return {
actionType: 'install', // Explicitly set action type
actionType: 'update', // User chose to update/modify existing installation
directory: confirmedDirectory,
installCore: true, // Always install core
modules: selectedModules,
// IDE selection moved to after module configuration
ides: [],
skipIde: true, // Will be handled later
// IDE selection collected early, will be configured later
ides: toolSelection.ides,
skipIde: toolSelection.skipIde,
coreConfig: coreConfig, // Pass collected core config to installer
};
}