diff --git a/tools/cli/installers/lib/core/custom-module-cache.js b/tools/cli/installers/lib/core/custom-module-cache.js index 4486e5fe5..b1cc3d0f7 100644 --- a/tools/cli/installers/lib/core/custom-module-cache.js +++ b/tools/cli/installers/lib/core/custom-module-cache.js @@ -7,6 +7,7 @@ const fs = require('fs-extra'); const path = require('node:path'); const crypto = require('node:crypto'); +const prompts = require('../../../lib/prompts'); class CustomModuleCache { constructor(bmadDir) { @@ -195,7 +196,7 @@ class CustomModuleCache { // Verify cache integrity const currentCacheHash = await this.calculateHash(cacheDir); if (currentCacheHash !== cached.cacheHash) { - console.warn(`Warning: Cache integrity check failed for ${moduleId}`); + await prompts.log.warn(`Cache integrity check failed for ${moduleId}`); } return { diff --git a/tools/cli/installers/lib/core/ide-config-manager.js b/tools/cli/installers/lib/core/ide-config-manager.js index f871e4b5d..c00c00d48 100644 --- a/tools/cli/installers/lib/core/ide-config-manager.js +++ b/tools/cli/installers/lib/core/ide-config-manager.js @@ -1,6 +1,7 @@ const path = require('node:path'); const fs = require('fs-extra'); const yaml = require('yaml'); +const prompts = require('../../../lib/prompts'); /** * Manages IDE configuration persistence @@ -93,7 +94,7 @@ class IdeConfigManager { const config = yaml.parse(content); return config; } catch (error) { - console.warn(`Warning: Failed to load IDE config for ${ideName}:`, error.message); + await prompts.log.warn(`Failed to load IDE config for ${ideName}: ${error.message}`); return null; } } @@ -123,7 +124,7 @@ class IdeConfigManager { } } } catch (error) { - console.warn('Warning: Failed to load IDE configs:', error.message); + await prompts.log.warn(`Failed to load IDE configs: ${error.message}`); } return configs; diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 7105b7a6f..8beeb4118 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -451,7 +451,6 @@ class Installer { } spinner.start('Preparing update...'); } else { - const prompts = require('../../../lib/prompts'); if (spinner.isSpinning) { spinner.stop('Reviewing module changes'); } @@ -1153,9 +1152,9 @@ class Installer { // Create a conditional logger based on verbose mode const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose; const moduleLogger = { - log: (msg) => (verboseMode ? console.log(msg) : {}), // Only log in verbose mode - error: (msg) => console.error(msg), // Always show errors - warn: (msg) => console.warn(msg), // Always show warnings + log: async (msg) => (verboseMode ? await prompts.log.message(msg) : undefined), + error: async (msg) => await prompts.log.error(msg), + warn: async (msg) => await prompts.log.warn(msg), }; // Create directories for all modules @@ -1262,7 +1261,7 @@ class Installer { } // Blank line for spacing before final status - console.log(); + await prompts.log.message(''); // Stop the single installation spinner spinner.stop('Installation complete'); diff --git a/tools/cli/installers/lib/core/manifest-generator.js b/tools/cli/installers/lib/core/manifest-generator.js index caea790eb..dd934a3c5 100644 --- a/tools/cli/installers/lib/core/manifest-generator.js +++ b/tools/cli/installers/lib/core/manifest-generator.js @@ -4,6 +4,7 @@ const yaml = require('yaml'); const crypto = require('node:crypto'); const csv = require('csv-parse/sync'); const { getSourcePath, getModulePath } = require('../../../lib/project-root'); +const prompts = require('../../../lib/prompts'); // Load package.json for version info const packageJson = require('../../../../../package.json'); @@ -241,7 +242,7 @@ class ManifestGenerator { } } } catch (error) { - console.warn(`Warning: Failed to parse workflow at ${fullPath}: ${error.message}`); + await prompts.log.warn(`Failed to parse workflow at ${fullPath}: ${error.message}`); } } } @@ -691,7 +692,7 @@ class ManifestGenerator { return preservedRows; } catch (error) { - console.warn(`Warning: Failed to read existing CSV ${csvPath}:`, error.message); + await prompts.log.warn(`Failed to read existing CSV ${csvPath}: ${error.message}`); return []; } } @@ -1068,7 +1069,7 @@ class ManifestGenerator { } } } catch (error) { - console.warn(`Warning: Could not scan for installed modules: ${error.message}`); + await prompts.log.warn(`Could not scan for installed modules: ${error.message}`); } return modules; diff --git a/tools/cli/installers/lib/core/manifest.js b/tools/cli/installers/lib/core/manifest.js index 865b75f96..5fa1229e1 100644 --- a/tools/cli/installers/lib/core/manifest.js +++ b/tools/cli/installers/lib/core/manifest.js @@ -2,6 +2,7 @@ const path = require('node:path'); const fs = require('fs-extra'); const crypto = require('node:crypto'); const { getProjectRoot } = require('../../../lib/project-root'); +const prompts = require('../../../lib/prompts'); class Manifest { /** @@ -100,7 +101,7 @@ class Manifest { ides: manifestData.ides || [], }; } catch (error) { - console.error('Failed to read YAML manifest:', error.message); + await prompts.log.error(`Failed to read YAML manifest: ${error.message}`); } } @@ -230,7 +231,7 @@ class Manifest { const content = await fs.readFile(yamlPath, 'utf8'); return yaml.parse(content); } catch (error) { - console.error('Failed to read YAML manifest:', error.message); + await prompts.log.error(`Failed to read YAML manifest: ${error.message}`); } } @@ -472,7 +473,7 @@ class Manifest { } } } catch (error) { - console.warn(`Warning: Could not parse ${filePath}:`, error.message); + await prompts.log.warn(`Could not parse ${filePath}: ${error.message}`); } } // Handle other file types (CSV, JSON, YAML, etc.) @@ -774,7 +775,7 @@ class Manifest { configs[moduleName] = yaml.parse(content); } } catch (error) { - console.warn(`Could not load config for module ${moduleName}:`, error.message); + await prompts.log.warn(`Could not load config for module ${moduleName}: ${error.message}`); } } @@ -876,7 +877,7 @@ class Manifest { const pkg = require(packageJsonPath); version = pkg.version; } catch (error) { - console.warn(`Failed to read package.json for ${moduleName}: ${error.message}`); + await prompts.log.warn(`Failed to read package.json for ${moduleName}: ${error.message}`); } } } @@ -904,7 +905,7 @@ class Manifest { repoUrl: moduleConfig.repoUrl || null, }; } catch (error) { - console.warn(`Failed to read module.yaml for ${moduleName}: ${error.message}`); + await prompts.log.warn(`Failed to read module.yaml for ${moduleName}: ${error.message}`); } } diff --git a/tools/cli/installers/lib/modules/external-manager.js b/tools/cli/installers/lib/modules/external-manager.js index a68a2ba1e..f1ea2206e 100644 --- a/tools/cli/installers/lib/modules/external-manager.js +++ b/tools/cli/installers/lib/modules/external-manager.js @@ -1,6 +1,7 @@ const fs = require('fs-extra'); const path = require('node:path'); const yaml = require('yaml'); +const prompts = require('../../../lib/prompts'); /** * Manages external official modules defined in external-official-modules.yaml @@ -29,7 +30,7 @@ class ExternalModuleManager { this.cachedModules = config; return config; } catch (error) { - console.warn(`Failed to load external modules config: ${error.message}`); + await prompts.log.warn(`Failed to load external modules config: ${error.message}`); return { modules: {} }; } } diff --git a/tools/cli/installers/lib/modules/manager.js b/tools/cli/installers/lib/modules/manager.js index 6e5526fbd..97ed34f08 100644 --- a/tools/cli/installers/lib/modules/manager.js +++ b/tools/cli/installers/lib/modules/manager.js @@ -452,7 +452,7 @@ class ModuleManager { installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`); } catch (error) { installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`); - if (!silent) await prompts.log.warn(` Warning: ${error.message}`); + if (!silent) await prompts.log.warn(` ${error.message}`); } } else { // Check if package.json is newer than node_modules @@ -478,7 +478,7 @@ class ModuleManager { installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`); } catch (error) { installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`); - if (!silent) await prompts.log.warn(` Warning: ${error.message}`); + if (!silent) await prompts.log.warn(` ${error.message}`); } } } @@ -541,7 +541,7 @@ class ModuleManager { const customContent = await fs.readFile(rootCustomConfigPath, 'utf8'); customConfig = yaml.parse(customContent); } catch (error) { - await prompts.log.warn(`Warning: Failed to read custom.yaml for ${moduleName}: ${error.message}`); + await prompts.log.warn(`Failed to read custom.yaml for ${moduleName}: ${error.message}`); } } @@ -549,7 +549,7 @@ class ModuleManager { if (customConfig) { options.moduleConfig = { ...options.moduleConfig, ...customConfig }; if (options.logger) { - options.logger.log(` Merged custom configuration for ${moduleName}`); + await options.logger.log(` Merged custom configuration for ${moduleName}`); } } @@ -857,7 +857,7 @@ class ModuleManager { await fs.writeFile(targetFile, strippedYaml, 'utf8'); } catch { // If anything fails, just copy the file as-is - await prompts.log.warn(` Warning: Could not process ${path.basename(sourceFile)}, copying as-is`); + await prompts.log.warn(` Could not process ${path.basename(sourceFile)}, copying as-is`); await fs.copy(sourceFile, targetFile, { overwrite: true }); } } @@ -1012,7 +1012,7 @@ class ModuleManager { await prompts.log.message(` Sidecar files processed: ${copiedFiles.length} files`); } } else if (process.env.BMAD_VERBOSE_INSTALL === 'true') { - await prompts.log.warn(` Warning: Agent marked as having sidecar but ${sidecarDirName} directory not found`); + await prompts.log.warn(` Agent marked as having sidecar but ${sidecarDirName} directory not found`); } } @@ -1321,7 +1321,7 @@ class ModuleManager { 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}`)); + await prompts.log.warn(color.yellow(`${configKey} path escapes project root, skipping: ${dirPath}`)); continue; }