mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-29 16:14:59 +00:00
installer updates working with basic flow
This commit is contained in:
@@ -396,9 +396,26 @@ class ConfigCollector {
|
||||
if (!this.allAnswers) {
|
||||
this.allAnswers = {};
|
||||
}
|
||||
// Load module's config.yaml (check new location first, then fallback)
|
||||
const installerConfigPath = path.join(getModulePath(moduleName), '_module-installer', 'install-config.yaml');
|
||||
const legacyConfigPath = path.join(getModulePath(moduleName), 'config.yaml');
|
||||
// Load module's config.yaml (check custom modules first, then regular modules)
|
||||
let installerConfigPath;
|
||||
let legacyConfigPath;
|
||||
|
||||
if (moduleName.startsWith('custom-')) {
|
||||
// Handle custom modules
|
||||
const actualModuleName = moduleName.replace('custom-', '');
|
||||
|
||||
// Custom modules are in the BMAD-METHOD source directory, not the installation directory
|
||||
const bmadMethodRoot = getProjectRoot(); // This gets the BMAD-METHOD root
|
||||
const customSrcPath = path.join(bmadMethodRoot, 'bmad-custom-src', 'modules', actualModuleName);
|
||||
installerConfigPath = path.join(customSrcPath, '_module-installer', 'install-config.yaml');
|
||||
legacyConfigPath = path.join(customSrcPath, 'config.yaml');
|
||||
|
||||
console.log(chalk.dim(`[DEBUG] Looking for custom module config in: ${installerConfigPath}`));
|
||||
} else {
|
||||
// Regular modules
|
||||
installerConfigPath = path.join(getModulePath(moduleName), '_module-installer', 'install-config.yaml');
|
||||
legacyConfigPath = path.join(getModulePath(moduleName), 'config.yaml');
|
||||
}
|
||||
|
||||
let configPath = null;
|
||||
if (await fs.pathExists(installerConfigPath)) {
|
||||
|
||||
@@ -418,7 +418,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 && !this.configCollector.collectedConfig.core) {
|
||||
this.configCollector.collectedConfig.core = config.coreConfig;
|
||||
// Also store in allAnswers for cross-referencing
|
||||
this.configCollector.allAnswers = {};
|
||||
@@ -427,11 +427,16 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
}
|
||||
}
|
||||
|
||||
// Collect configurations for modules (skip if quick update already collected them)
|
||||
// Collect configurations for modules (skip if quick update already collected them or if pre-collected)
|
||||
let moduleConfigs;
|
||||
if (config._quickUpdate) {
|
||||
// Quick update already collected all configs, use them directly
|
||||
moduleConfigs = this.configCollector.collectedConfig;
|
||||
} else if (config.moduleConfig) {
|
||||
// Use pre-collected configs from UI (includes custom modules)
|
||||
moduleConfigs = config.moduleConfig;
|
||||
// Also need to load them into configCollector for later use
|
||||
this.configCollector.collectedConfig = moduleConfigs;
|
||||
} else {
|
||||
// Regular install - collect configurations (core was already collected in UI.promptInstall if interactive)
|
||||
moduleConfigs = await this.configCollector.collectAllConfigurations(config.modules || [], path.resolve(config.directory));
|
||||
@@ -748,13 +753,14 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
spinner.text = 'Creating directory structure...';
|
||||
await this.createDirectoryStructure(bmadDir);
|
||||
|
||||
// Resolve dependencies for selected modules
|
||||
// Resolve dependencies for selected modules (skip custom modules)
|
||||
spinner.text = 'Resolving dependencies...';
|
||||
const projectRoot = getProjectRoot();
|
||||
const modulesToInstall = config.installCore ? ['core', ...config.modules] : config.modules;
|
||||
const regularModules = (config.modules || []).filter((m) => !m.startsWith('custom-'));
|
||||
const modulesToInstall = config.installCore ? ['core', ...regularModules] : regularModules;
|
||||
|
||||
// For dependency resolution, we need to pass the project root
|
||||
const resolution = await this.dependencyResolver.resolve(projectRoot, config.modules || [], { verbose: config.verbose });
|
||||
const resolution = await this.dependencyResolver.resolve(projectRoot, regularModules, { verbose: config.verbose });
|
||||
|
||||
if (config.verbose) {
|
||||
spinner.succeed('Dependencies resolved');
|
||||
@@ -769,17 +775,17 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
spinner.succeed('Core installed');
|
||||
}
|
||||
|
||||
// Install modules with their dependencies
|
||||
if (config.modules && config.modules.length > 0) {
|
||||
for (const moduleName of config.modules) {
|
||||
// Install modules with their dependencies (skip custom modules - they're handled by install.js)
|
||||
if (regularModules.length > 0) {
|
||||
for (const moduleName of regularModules) {
|
||||
spinner.start(`Installing module: ${moduleName}...`);
|
||||
await this.installModuleWithDependencies(moduleName, bmadDir, resolution.byModule[moduleName]);
|
||||
spinner.succeed(`Module installed: ${moduleName}`);
|
||||
}
|
||||
|
||||
// Install partial modules (only dependencies)
|
||||
// Install partial modules (only dependencies) - skip custom modules
|
||||
for (const [module, files] of Object.entries(resolution.byModule)) {
|
||||
if (!config.modules.includes(module) && module !== 'core') {
|
||||
if (!regularModules.includes(module) && module !== 'core') {
|
||||
const totalFiles =
|
||||
files.agents.length +
|
||||
files.tasks.length +
|
||||
|
||||
@@ -24,6 +24,51 @@ async function getAgentsFromBmad(bmadDir, selectedModules = []) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get custom module agents (from bmad/custom/modules/*/agents/)
|
||||
const customModulesDir = path.join(bmadDir, 'custom', 'modules');
|
||||
if (await fs.pathExists(customModulesDir)) {
|
||||
const moduleDirs = await fs.readdir(customModulesDir, { withFileTypes: true });
|
||||
|
||||
for (const moduleDir of moduleDirs) {
|
||||
if (!moduleDir.isDirectory()) continue;
|
||||
|
||||
const moduleAgentsPath = path.join(customModulesDir, moduleDir.name, 'agents');
|
||||
if (await fs.pathExists(moduleAgentsPath)) {
|
||||
const moduleAgents = await getAgentsFromDir(moduleAgentsPath, moduleDir.name);
|
||||
agents.push(...moduleAgents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get custom agents from bmad/custom/agents/ directory
|
||||
const customAgentsDir = path.join(bmadDir, 'custom', 'agents');
|
||||
if (await fs.pathExists(customAgentsDir)) {
|
||||
const agentDirs = await fs.readdir(customAgentsDir, { withFileTypes: true });
|
||||
|
||||
for (const agentDir of agentDirs) {
|
||||
if (!agentDir.isDirectory()) continue;
|
||||
|
||||
const agentDirPath = path.join(customAgentsDir, agentDir.name);
|
||||
const agentFiles = await fs.readdir(agentDirPath);
|
||||
|
||||
for (const file of agentFiles) {
|
||||
if (!file.endsWith('.md')) continue;
|
||||
if (file.includes('.customize.')) continue;
|
||||
|
||||
const filePath = path.join(agentDirPath, file);
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
if (content.includes('localskip="true"')) continue;
|
||||
|
||||
agents.push({
|
||||
path: filePath,
|
||||
name: file.replace('.md', ''),
|
||||
module: 'custom', // Mark as custom agent
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get standalone agents from bmad/agents/ directory
|
||||
const standaloneAgentsDir = path.join(bmadDir, 'agents');
|
||||
if (await fs.pathExists(standaloneAgentsDir)) {
|
||||
|
||||
Reference in New Issue
Block a user