mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-17 09:45:25 +00:00
default accepted for installer quesitons
This commit is contained in:
parent
6513c77d1b
commit
60238d2854
@ -13,5 +13,4 @@ default_selected: false # This module will not be selected by default for new in
|
||||
|
||||
creativity_self_assessment:
|
||||
prompt: "On a scale of 1 to 10, how would you rate your current level of creativity?"
|
||||
default: 7
|
||||
result: "{value}"
|
||||
|
||||
@ -303,7 +303,7 @@ class ConfigCollector {
|
||||
}
|
||||
}
|
||||
// Show "no config" message for modules with no new questions
|
||||
CLIUtils.displayModuleNoConfig(moduleName, moduleConfig.header, moduleConfig.subheader);
|
||||
console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module already up to date`));
|
||||
return false; // No new fields
|
||||
}
|
||||
|
||||
@ -339,7 +339,7 @@ class ConfigCollector {
|
||||
Object.assign(allAnswers, promptedAnswers);
|
||||
} else if (newStaticKeys.length > 0) {
|
||||
// Only static fields, no questions - show no config message
|
||||
CLIUtils.displayModuleNoConfig(moduleName, moduleConfig.header, moduleConfig.subheader);
|
||||
console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module configuration updated`));
|
||||
}
|
||||
|
||||
// Store all answers for cross-referencing
|
||||
@ -558,21 +558,57 @@ class ConfigCollector {
|
||||
// Collect all answers (static + prompted)
|
||||
let allAnswers = { ...staticAnswers };
|
||||
|
||||
// Display appropriate header based on whether there are questions
|
||||
// If there are questions to ask, prompt for accepting defaults vs customizing
|
||||
if (questions.length > 0) {
|
||||
CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader);
|
||||
console.log(); // Line break before questions
|
||||
const promptedAnswers = await inquirer.prompt(questions);
|
||||
// Get friendly module name from config or use uppercase module name
|
||||
const moduleDisplayName = moduleConfig.header || `${moduleName.toUpperCase()} Module`;
|
||||
|
||||
// Merge prompted answers with static answers
|
||||
Object.assign(allAnswers, promptedAnswers);
|
||||
// Display the module name in color first
|
||||
console.log(chalk.cyan('?') + ' ' + chalk.magenta(moduleDisplayName));
|
||||
|
||||
// Ask user if they want to accept defaults or customize on the next line
|
||||
const { customize } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'customize',
|
||||
message: 'Accept Defaults (no to customize)?',
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
|
||||
if (customize) {
|
||||
// Accept defaults - only ask questions that have NO default value
|
||||
const questionsWithoutDefaults = questions.filter((q) => q.default === undefined || q.default === null || q.default === '');
|
||||
|
||||
if (questionsWithoutDefaults.length > 0) {
|
||||
console.log(chalk.dim(`\n Asking required questions for ${moduleName.toUpperCase()}...`));
|
||||
const promptedAnswers = await inquirer.prompt(questionsWithoutDefaults);
|
||||
Object.assign(allAnswers, promptedAnswers);
|
||||
}
|
||||
|
||||
// For questions with defaults that weren't asked, we need to process them with their default values
|
||||
const questionsWithDefaults = questions.filter((q) => q.default !== undefined && q.default !== null && q.default !== '');
|
||||
for (const question of questionsWithDefaults) {
|
||||
// Skip function defaults - these are dynamic and will be evaluated later
|
||||
if (typeof question.default === 'function') {
|
||||
continue;
|
||||
}
|
||||
allAnswers[question.name] = question.default;
|
||||
}
|
||||
} else {
|
||||
// Customize - ask all questions
|
||||
console.log(chalk.dim(`\n Configuring ${moduleName.toUpperCase()}...`));
|
||||
const promptedAnswers = await inquirer.prompt(questions);
|
||||
Object.assign(allAnswers, promptedAnswers);
|
||||
}
|
||||
}
|
||||
|
||||
// Store all answers for cross-referencing
|
||||
Object.assign(this.allAnswers, allAnswers);
|
||||
|
||||
// Process all answers (both static and prompted)
|
||||
if (Object.keys(allAnswers).length > 0) {
|
||||
// Always process if we have any answers or static answers
|
||||
if (Object.keys(allAnswers).length > 0 || Object.keys(staticAnswers).length > 0) {
|
||||
const answers = allAnswers;
|
||||
|
||||
// Process answers and build result values
|
||||
@ -672,7 +708,32 @@ class ConfigCollector {
|
||||
// No longer display completion boxes - keep output clean
|
||||
} else {
|
||||
// No questions for this module - show completion message
|
||||
CLIUtils.displayModuleNoConfig(moduleName, moduleConfig.header, moduleConfig.subheader);
|
||||
console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module configured`));
|
||||
}
|
||||
|
||||
// If we have no collected config for this module, but we have a module schema,
|
||||
// ensure we have at least an empty object
|
||||
if (!this.collectedConfig[moduleName]) {
|
||||
this.collectedConfig[moduleName] = {};
|
||||
|
||||
// If we accepted defaults and have no answers, we still need to check
|
||||
// if there are any static values in the schema that should be applied
|
||||
if (moduleConfig) {
|
||||
for (const key of Object.keys(moduleConfig)) {
|
||||
if (key !== 'prompt' && moduleConfig[key] && typeof moduleConfig[key] === 'object') {
|
||||
const item = moduleConfig[key];
|
||||
// For static items (no prompt, just result), apply the result
|
||||
if (!item.prompt && item.result) {
|
||||
// Apply any placeholder replacements to the result
|
||||
let result = item.result;
|
||||
if (typeof result === 'string') {
|
||||
result = this.replacePlaceholders(result, moduleName, moduleConfig);
|
||||
}
|
||||
this.collectedConfig[moduleName][key] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,10 @@ class CustomModuleCache {
|
||||
*/
|
||||
async updateCacheManifest(manifest) {
|
||||
const yaml = require('yaml');
|
||||
const content = yaml.stringify(manifest, {
|
||||
// Clean the manifest to remove any non-serializable values
|
||||
const cleanManifest = structuredClone(manifest);
|
||||
|
||||
const content = yaml.stringify(cleanManifest, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
sortKeys: false,
|
||||
|
||||
@ -61,7 +61,10 @@ class IdeConfigManager {
|
||||
configuration: configuration || {},
|
||||
};
|
||||
|
||||
const yamlContent = yaml.stringify(configData, {
|
||||
// Clean the config to remove any non-serializable values (like functions)
|
||||
const cleanConfig = structuredClone(configData);
|
||||
|
||||
const yamlContent = yaml.stringify(cleanConfig, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
sortKeys: false,
|
||||
|
||||
@ -394,8 +394,14 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
// Clone config to avoid mutating the caller's object
|
||||
const config = { ...originalConfig };
|
||||
|
||||
// Check if core config was already collected in UI
|
||||
const hasCoreConfig = config.coreConfig && Object.keys(config.coreConfig).length > 0;
|
||||
|
||||
// Only display logo if core config wasn't already collected (meaning we're not continuing from UI)
|
||||
if (!config.coreConfig) {
|
||||
if (hasCoreConfig) {
|
||||
// Core config was already collected in UI, show smooth continuation
|
||||
// Don't clear screen, just continue flow
|
||||
} else {
|
||||
// Display BMAD logo
|
||||
CLIUtils.displayLogo();
|
||||
|
||||
@ -409,7 +415,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
const projectDir = path.resolve(config.directory);
|
||||
|
||||
// If core config was pre-collected (from interactive mode), use it
|
||||
if (config.coreConfig) {
|
||||
if (config.coreConfig && Object.keys(config.coreConfig).length > 0) {
|
||||
this.configCollector.collectedConfig.core = config.coreConfig;
|
||||
// Also store in allAnswers for cross-referencing
|
||||
this.configCollector.allAnswers = {};
|
||||
@ -1583,8 +1589,11 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
coreSection = '\n# Core Configuration Values\n';
|
||||
}
|
||||
|
||||
// Clean the config to remove any non-serializable values (like functions)
|
||||
const cleanConfig = structuredClone(finalConfig);
|
||||
|
||||
// Convert config to YAML
|
||||
let yamlContent = yaml.stringify(finalConfig, {
|
||||
let yamlContent = yaml.stringify(cleanConfig, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
minContentWidth: 0,
|
||||
|
||||
@ -486,7 +486,10 @@ class ManifestGenerator {
|
||||
ides: this.selectedIdes,
|
||||
};
|
||||
|
||||
const yamlStr = yaml.stringify(manifest, {
|
||||
// Clean the manifest to remove any non-serializable values
|
||||
const cleanManifest = structuredClone(manifest);
|
||||
|
||||
const yamlStr = yaml.stringify(cleanManifest, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
sortKeys: false,
|
||||
|
||||
@ -28,7 +28,10 @@ class Manifest {
|
||||
};
|
||||
|
||||
// Write YAML manifest
|
||||
const yamlContent = yaml.stringify(manifestData, {
|
||||
// Clean the manifest data to remove any non-serializable values
|
||||
const cleanManifestData = structuredClone(manifestData);
|
||||
|
||||
const yamlContent = yaml.stringify(cleanManifestData, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
sortKeys: false,
|
||||
@ -100,7 +103,10 @@ class Manifest {
|
||||
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
||||
await fs.ensureDir(path.dirname(manifestPath));
|
||||
|
||||
const yamlContent = yaml.stringify(manifestData, {
|
||||
// Clean the manifest data to remove any non-serializable values
|
||||
const cleanManifestData = structuredClone(manifestData);
|
||||
|
||||
const yamlContent = yaml.stringify(cleanManifestData, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
sortKeys: false,
|
||||
|
||||
@ -859,7 +859,10 @@ class ModuleManager {
|
||||
|
||||
// Write back to manifest
|
||||
const yaml = require('yaml');
|
||||
const updatedContent = yaml.stringify(manifestData, {
|
||||
// Clean the manifest data to remove any non-serializable values
|
||||
const cleanManifestData = structuredClone(manifestData);
|
||||
|
||||
const updatedContent = yaml.stringify(cleanManifestData, {
|
||||
indent: 2,
|
||||
lineWidth: 0,
|
||||
});
|
||||
|
||||
@ -703,7 +703,9 @@ class UI {
|
||||
// Now collect with existing values as defaults (false = don't skip loading, true = skip completion message)
|
||||
await configCollector.collectModuleConfig('core', directory, false, true);
|
||||
|
||||
return configCollector.collectedConfig.core;
|
||||
const coreConfig = configCollector.collectedConfig.core;
|
||||
// Ensure we always have a core config object, even if empty
|
||||
return coreConfig || {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user