diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 7adb51455..8601e1aaa 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -1119,35 +1119,55 @@ class Installer { warn: (msg) => console.warn(msg), // Always show warnings }; - // Create directories for core module if core was installed - if (config.installCore || resolution.byModule.core) { - spinner.message('Creating core module directories...'); + // Create directories for all modules + spinner.message('Creating module directories...'); + const allCreatedDirs = []; + const allCreatedWdsFolders = []; - await this.moduleManager.createModuleDirectories('core', bmadDir, { + // Core module directories + if (config.installCore || resolution.byModule.core) { + const result = await this.moduleManager.createModuleDirectories('core', bmadDir, { installedIDEs: config.ides || [], moduleConfig: moduleConfigs.core || {}, coreConfig: moduleConfigs.core || {}, logger: moduleLogger, silent: true, }); + if (result) { + allCreatedDirs.push(...result.createdDirs); + allCreatedWdsFolders.push(...result.createdWdsFolders); + } } - // Create directories for user-selected modules + // User-selected module directories if (config.modules && config.modules.length > 0) { for (const moduleName of config.modules) { - spinner.message(`Creating ${moduleName} module directories...`); - - // Pass installed IDEs and module config to directory creator - await this.moduleManager.createModuleDirectories(moduleName, bmadDir, { + const result = await this.moduleManager.createModuleDirectories(moduleName, bmadDir, { installedIDEs: config.ides || [], moduleConfig: moduleConfigs[moduleName] || {}, coreConfig: moduleConfigs.core || {}, logger: moduleLogger, silent: true, }); + if (result) { + allCreatedDirs.push(...result.createdDirs); + allCreatedWdsFolders.push(...result.createdWdsFolders); + } } } + // Batch output: single log message for all created directories across all modules + if (allCreatedDirs.length > 0) { + const color = await prompts.getColor(); + const lines = allCreatedDirs.map((d) => ` ${d}`).join('\n'); + await prompts.log.message(color.yellow(`Created directories:\n${lines}`)); + } + if (allCreatedWdsFolders.length > 0) { + const color = await prompts.getColor(); + const lines = allCreatedWdsFolders.map((f) => color.dim(` ✓ ${f}/`)).join('\n'); + await prompts.log.message(color.cyan(`Created WDS folder structure:\n${lines}`)); + } + addResult('Module installers', 'ok'); // Note: Manifest files are already created by ManifestGenerator above @@ -1202,6 +1222,9 @@ class Installer { } } + // Blank line for spacing before final status + console.log(); + // Stop the single installation spinner spinner.stop('Installation complete'); diff --git a/tools/cli/installers/lib/modules/manager.js b/tools/cli/installers/lib/modules/manager.js index c7611a128..72f72c56e 100644 --- a/tools/cli/installers/lib/modules/manager.js +++ b/tools/cli/installers/lib/modules/manager.js @@ -1252,6 +1252,7 @@ class ModuleManager { * @param {Object} options - Installation options * @param {Object} options.moduleConfig - Module configuration from config collector * @param {Object} options.coreConfig - Core configuration + * @returns {Promise<{createdDirs: string[], createdWdsFolders: string[]} | undefined>} Created directories info */ async createModuleDirectories(moduleName, bmadDir, options = {}) { const moduleConfig = options.moduleConfig || {}; @@ -1286,8 +1287,6 @@ class ModuleManager { return; // No directories declared, skip } - // Get color utility for styled output - const color = await prompts.getColor(); const directories = moduleYaml.directories; const wdsFolders = moduleYaml.wds_folders || []; const createdDirs = []; @@ -1320,6 +1319,7 @@ class ModuleManager { const normalizedPath = path.normalize(fullPath); const normalizedRoot = path.normalize(projectRoot); if (!normalizedPath.startsWith(normalizedRoot + path.sep) && normalizedPath !== normalizedRoot) { + const color = await prompts.getColor(); await prompts.log.warn(color.yellow(`Warning: ${configKey} path escapes project root, skipping: ${dirPath}`)); continue; } @@ -1343,15 +1343,7 @@ class ModuleManager { } } - // Batch output: single log message for all created directories - if (createdDirs.length > 0) { - const lines = createdDirs.map((d) => ` ${d}`).join('\n'); - await prompts.log.message(color.yellow(`Created directories:\n${lines}`)); - } - if (createdWdsFolders.length > 0) { - const lines = createdWdsFolders.map((f) => color.dim(` ✓ ${f}/`)).join('\n'); - await prompts.log.message(color.cyan(`Created WDS folder structure:\n${lines}`)); - } + return { createdDirs, createdWdsFolders }; } /**