refactor: simplify module discovery to scan entire project

- Module discovery now scans entire project recursively for install-config.yaml
- Removed hardcoded module locations (bmad-custom-src, etc.)
- Modules can exist anywhere with _module-installer/install-config.yaml
- All modules treated equally regardless of location
- No special UI handling for 'custom' modules
- Core module excluded from selection list (always installed first)
- Only install-config.yaml is valid (removed support for legacy config.yaml)

Modules are now discovered by structure, not location.
This commit is contained in:
Brian Madison
2025-12-06 15:28:37 -06:00
parent 7c5c97a914
commit 0d83799ecf
7 changed files with 243 additions and 1285 deletions

View File

@@ -24,51 +24,6 @@ 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)) {