fix: migrate installer console.warn/error calls to prompts.log API

Replace all user-facing console.warn(), console.error(), and console.log()
calls with their prompts.log.* equivalents for consistent @clack/prompts
styled output across the installer codebase.

- Migrate 13 console.warn/error calls across 5 files to prompts.log.*
- Convert moduleLogger callbacks to async prompts.log.* in installer.js
- Replace blank-line console.log() with prompts.log.message('')
- Add prompts import to 5 files that lacked it
- Remove redundant "Warning:" prefixes (prompts.log.warn adds styling)
- Remove redundant local prompts require in installer.js L454
- Add missing await on logger.log call in manager.js
- Debug-gated console.log calls in manifest-generator.js left as-is

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Davor Racić 2026-02-09 11:10:49 +01:00
parent 17017881fd
commit da37069538
7 changed files with 29 additions and 25 deletions

View File

@ -7,6 +7,7 @@
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('node:path'); const path = require('node:path');
const crypto = require('node:crypto'); const crypto = require('node:crypto');
const prompts = require('../../../lib/prompts');
class CustomModuleCache { class CustomModuleCache {
constructor(bmadDir) { constructor(bmadDir) {
@ -195,7 +196,7 @@ class CustomModuleCache {
// Verify cache integrity // Verify cache integrity
const currentCacheHash = await this.calculateHash(cacheDir); const currentCacheHash = await this.calculateHash(cacheDir);
if (currentCacheHash !== cached.cacheHash) { if (currentCacheHash !== cached.cacheHash) {
console.warn(`Warning: Cache integrity check failed for ${moduleId}`); await prompts.log.warn(`Cache integrity check failed for ${moduleId}`);
} }
return { return {

View File

@ -1,6 +1,7 @@
const path = require('node:path'); const path = require('node:path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const yaml = require('yaml'); const yaml = require('yaml');
const prompts = require('../../../lib/prompts');
/** /**
* Manages IDE configuration persistence * Manages IDE configuration persistence
@ -93,7 +94,7 @@ class IdeConfigManager {
const config = yaml.parse(content); const config = yaml.parse(content);
return config; return config;
} catch (error) { } 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; return null;
} }
} }
@ -123,7 +124,7 @@ class IdeConfigManager {
} }
} }
} catch (error) { } 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; return configs;

View File

@ -451,7 +451,6 @@ class Installer {
} }
spinner.start('Preparing update...'); spinner.start('Preparing update...');
} else { } else {
const prompts = require('../../../lib/prompts');
if (spinner.isSpinning) { if (spinner.isSpinning) {
spinner.stop('Reviewing module changes'); spinner.stop('Reviewing module changes');
} }
@ -1153,9 +1152,9 @@ class Installer {
// Create a conditional logger based on verbose mode // Create a conditional logger based on verbose mode
const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose; const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose;
const moduleLogger = { const moduleLogger = {
log: (msg) => (verboseMode ? console.log(msg) : {}), // Only log in verbose mode log: async (msg) => (verboseMode ? await prompts.log.message(msg) : undefined),
error: (msg) => console.error(msg), // Always show errors error: async (msg) => await prompts.log.error(msg),
warn: (msg) => console.warn(msg), // Always show warnings warn: async (msg) => await prompts.log.warn(msg),
}; };
// Create directories for all modules // Create directories for all modules
@ -1262,7 +1261,7 @@ class Installer {
} }
// Blank line for spacing before final status // Blank line for spacing before final status
console.log(); await prompts.log.message('');
// Stop the single installation spinner // Stop the single installation spinner
spinner.stop('Installation complete'); spinner.stop('Installation complete');

View File

@ -4,6 +4,7 @@ const yaml = require('yaml');
const crypto = require('node:crypto'); const crypto = require('node:crypto');
const csv = require('csv-parse/sync'); const csv = require('csv-parse/sync');
const { getSourcePath, getModulePath } = require('../../../lib/project-root'); const { getSourcePath, getModulePath } = require('../../../lib/project-root');
const prompts = require('../../../lib/prompts');
// Load package.json for version info // Load package.json for version info
const packageJson = require('../../../../../package.json'); const packageJson = require('../../../../../package.json');
@ -241,7 +242,7 @@ class ManifestGenerator {
} }
} }
} catch (error) { } 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; return preservedRows;
} catch (error) { } 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 []; return [];
} }
} }
@ -1068,7 +1069,7 @@ class ManifestGenerator {
} }
} }
} catch (error) { } 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; return modules;

View File

@ -2,6 +2,7 @@ const path = require('node:path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const crypto = require('node:crypto'); const crypto = require('node:crypto');
const { getProjectRoot } = require('../../../lib/project-root'); const { getProjectRoot } = require('../../../lib/project-root');
const prompts = require('../../../lib/prompts');
class Manifest { class Manifest {
/** /**
@ -100,7 +101,7 @@ class Manifest {
ides: manifestData.ides || [], ides: manifestData.ides || [],
}; };
} catch (error) { } 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'); const content = await fs.readFile(yamlPath, 'utf8');
return yaml.parse(content); return yaml.parse(content);
} catch (error) { } 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) { } 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.) // Handle other file types (CSV, JSON, YAML, etc.)
@ -774,7 +775,7 @@ class Manifest {
configs[moduleName] = yaml.parse(content); configs[moduleName] = yaml.parse(content);
} }
} catch (error) { } 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); const pkg = require(packageJsonPath);
version = pkg.version; version = pkg.version;
} catch (error) { } 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, repoUrl: moduleConfig.repoUrl || null,
}; };
} catch (error) { } 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}`);
} }
} }

View File

@ -1,6 +1,7 @@
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('node:path'); const path = require('node:path');
const yaml = require('yaml'); const yaml = require('yaml');
const prompts = require('../../../lib/prompts');
/** /**
* Manages external official modules defined in external-official-modules.yaml * Manages external official modules defined in external-official-modules.yaml
@ -29,7 +30,7 @@ class ExternalModuleManager {
this.cachedModules = config; this.cachedModules = config;
return config; return config;
} catch (error) { } 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: {} }; return { modules: {} };
} }
} }

View File

@ -452,7 +452,7 @@ class ModuleManager {
installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`); installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`);
} catch (error) { } catch (error) {
installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`); 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 { } else {
// Check if package.json is newer than node_modules // Check if package.json is newer than node_modules
@ -478,7 +478,7 @@ class ModuleManager {
installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`); installSpinner.stop(`Installed dependencies for ${moduleInfo.name}`);
} catch (error) { } catch (error) {
installSpinner.error(`Failed to install dependencies for ${moduleInfo.name}`); 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'); const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
customConfig = yaml.parse(customContent); customConfig = yaml.parse(customContent);
} catch (error) { } 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) { if (customConfig) {
options.moduleConfig = { ...options.moduleConfig, ...customConfig }; options.moduleConfig = { ...options.moduleConfig, ...customConfig };
if (options.logger) { 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'); await fs.writeFile(targetFile, strippedYaml, 'utf8');
} catch { } catch {
// If anything fails, just copy the file as-is // 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 }); await fs.copy(sourceFile, targetFile, { overwrite: true });
} }
} }
@ -1012,7 +1012,7 @@ class ModuleManager {
await prompts.log.message(` Sidecar files processed: ${copiedFiles.length} files`); await prompts.log.message(` Sidecar files processed: ${copiedFiles.length} files`);
} }
} else if (process.env.BMAD_VERBOSE_INSTALL === 'true') { } 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); 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(); 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; continue;
} }