diff --git a/tools/cli/installers/lib/core/manifest-generator.js b/tools/cli/installers/lib/core/manifest-generator.js index a3930468..683e1438 100644 --- a/tools/cli/installers/lib/core/manifest-generator.js +++ b/tools/cli/installers/lib/core/manifest-generator.js @@ -260,13 +260,13 @@ class ManifestGenerator { const principlesMatch = content.match(/([\s\S]*?)<\/principles>/); // Build relative path for installation - const fileRelativePath = relativePath ? `${relativePath}/${file}` : file; + const fileRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name; const installPath = moduleName === 'core' ? `${this.bmadFolderName}/core/agents/${fileRelativePath}` : `${this.bmadFolderName}/${moduleName}/agents/${fileRelativePath}`; - const agentName = file.replace('.md', ''); + const agentName = entry.name.replace('.md', ''); // Helper function to clean and escape CSV content const cleanForCSV = (text) => { diff --git a/tools/cli/installers/lib/ide/shared/bmad-artifacts.js b/tools/cli/installers/lib/ide/shared/bmad-artifacts.js index d05b985e..7db470f9 100644 --- a/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +++ b/tools/cli/installers/lib/ide/shared/bmad-artifacts.js @@ -83,39 +83,42 @@ async function getAgentsFromDir(dirPath, moduleName) { return agents; } - const files = await fs.readdir(dirPath); + const entries = await fs.readdir(dirPath, { withFileTypes: true }); - for (const file of files) { - if (!file.endsWith('.md')) { - continue; + for (const entry of entries) { + const fullPath = path.join(dirPath, entry.name); + + if (entry.isDirectory()) { + // Recurse into subdirectories + const subDirAgents = await getAgentsFromDir(fullPath, moduleName); + agents.push(...subDirAgents); + } else if (entry.name.endsWith('.md')) { + // Skip README files and other non-agent files + if (entry.name.toLowerCase() === 'readme.md' || entry.name.toLowerCase().startsWith('readme-')) { + continue; + } + + if (entry.name.includes('.customize.')) { + continue; + } + + const content = await fs.readFile(fullPath, 'utf8'); + + if (content.includes('localskip="true"')) { + continue; + } + + // Only include files that have agent-specific content (compiled agents have tag) + if (!content.includes(' tag) - if (!content.includes('