fix: consolidate directory creation output across all modules

Move directory creation logging from ModuleManager.createModuleDirectories
into the installer caller. The method now returns created directory info
instead of logging directly, allowing the installer to batch all module
directories into a single log message under one spinner. Also adds spacing
before the final "Installation complete" status line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Davor Racić 2026-02-09 08:16:14 +01:00
parent c83b4f6391
commit 58f34c2c92
2 changed files with 35 additions and 20 deletions

View File

@ -1119,34 +1119,54 @@ class Installer {
warn: (msg) => console.warn(msg), // Always show warnings warn: (msg) => console.warn(msg), // Always show warnings
}; };
// Create directories for core module if core was installed // Create directories for all modules
if (config.installCore || resolution.byModule.core) { spinner.message('Creating module directories...');
spinner.message('Creating core 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 || [], installedIDEs: config.ides || [],
moduleConfig: moduleConfigs.core || {}, moduleConfig: moduleConfigs.core || {},
coreConfig: moduleConfigs.core || {}, coreConfig: moduleConfigs.core || {},
logger: moduleLogger, logger: moduleLogger,
silent: true, 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) { if (config.modules && config.modules.length > 0) {
for (const moduleName of config.modules) { for (const moduleName of config.modules) {
spinner.message(`Creating ${moduleName} module directories...`); const result = await this.moduleManager.createModuleDirectories(moduleName, bmadDir, {
// Pass installed IDEs and module config to directory creator
await this.moduleManager.createModuleDirectories(moduleName, bmadDir, {
installedIDEs: config.ides || [], installedIDEs: config.ides || [],
moduleConfig: moduleConfigs[moduleName] || {}, moduleConfig: moduleConfigs[moduleName] || {},
coreConfig: moduleConfigs.core || {}, coreConfig: moduleConfigs.core || {},
logger: moduleLogger, logger: moduleLogger,
silent: true, 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'); addResult('Module installers', 'ok');
@ -1202,6 +1222,9 @@ class Installer {
} }
} }
// Blank line for spacing before final status
console.log();
// Stop the single installation spinner // Stop the single installation spinner
spinner.stop('Installation complete'); spinner.stop('Installation complete');

View File

@ -1252,6 +1252,7 @@ class ModuleManager {
* @param {Object} options - Installation options * @param {Object} options - Installation options
* @param {Object} options.moduleConfig - Module configuration from config collector * @param {Object} options.moduleConfig - Module configuration from config collector
* @param {Object} options.coreConfig - Core configuration * @param {Object} options.coreConfig - Core configuration
* @returns {Promise<{createdDirs: string[], createdWdsFolders: string[]} | undefined>} Created directories info
*/ */
async createModuleDirectories(moduleName, bmadDir, options = {}) { async createModuleDirectories(moduleName, bmadDir, options = {}) {
const moduleConfig = options.moduleConfig || {}; const moduleConfig = options.moduleConfig || {};
@ -1286,8 +1287,6 @@ class ModuleManager {
return; // No directories declared, skip return; // No directories declared, skip
} }
// Get color utility for styled output
const color = await prompts.getColor();
const directories = moduleYaml.directories; const directories = moduleYaml.directories;
const wdsFolders = moduleYaml.wds_folders || []; const wdsFolders = moduleYaml.wds_folders || [];
const createdDirs = []; const createdDirs = [];
@ -1320,6 +1319,7 @@ class ModuleManager {
const normalizedPath = path.normalize(fullPath); const normalizedPath = path.normalize(fullPath);
const normalizedRoot = path.normalize(projectRoot); const normalizedRoot = path.normalize(projectRoot);
if (!normalizedPath.startsWith(normalizedRoot + path.sep) && normalizedPath !== normalizedRoot) { 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}`)); await prompts.log.warn(color.yellow(`Warning: ${configKey} path escapes project root, skipping: ${dirPath}`));
continue; continue;
} }
@ -1343,15 +1343,7 @@ class ModuleManager {
} }
} }
// Batch output: single log message for all created directories return { createdDirs, createdWdsFolders };
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}`));
}
} }
/** /**