From d81ad38aceb3b98ffb97dc4a68fe681b88ba2a62 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Sun, 15 Mar 2026 23:45:35 -0500 Subject: [PATCH] feat(installer): support new SKILL.md agent format in manifest generation Update getAgentsFromDir to detect directories with bmad-skill-manifest.yaml where type=agent and extract metadata directly from the YAML fields. This allows the agent-manifest.csv to be populated from both old-format compiled .md agents (XML parsing) and new-format SKILL.md agents (YAML manifest). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../installers/lib/core/manifest-generator.js | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tools/cli/installers/lib/core/manifest-generator.js b/tools/cli/installers/lib/core/manifest-generator.js index 5dc4ff078..515e991f8 100644 --- a/tools/cli/installers/lib/core/manifest-generator.js +++ b/tools/cli/installers/lib/core/manifest-generator.js @@ -505,6 +505,41 @@ class ManifestGenerator { if (entry.isDirectory()) { // Skip directories claimed by collectSkills if (this.skillClaimedDirs && this.skillClaimedDirs.has(fullPath)) continue; + + // Check for new-format agent: bmad-skill-manifest.yaml with type: agent + const dirManifest = await this.loadSkillManifest(fullPath); + if (dirManifest && dirManifest.__single && dirManifest.__single.type === 'agent') { + const m = dirManifest.__single; + const dirRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name; + const installPath = + moduleName === 'core' + ? `${this.bmadFolderName}/core/agents/${dirRelativePath}` + : `${this.bmadFolderName}/${moduleName}/agents/${dirRelativePath}`; + + agents.push({ + name: m.name || entry.name, + displayName: m.displayName || m.name || entry.name, + title: m.title || '', + icon: m.icon || '', + capabilities: m.capabilities ? this.cleanForCSV(m.capabilities) : '', + role: m.role ? this.cleanForCSV(m.role) : '', + identity: m.identity ? this.cleanForCSV(m.identity) : '', + communicationStyle: m.communicationStyle ? this.cleanForCSV(m.communicationStyle) : '', + principles: m.principles ? this.cleanForCSV(m.principles) : '', + module: m.module || moduleName, + path: installPath, + canonicalId: m.canonicalId || '', + }); + + this.files.push({ + type: 'agent', + name: m.name || entry.name, + module: moduleName, + path: installPath, + }); + continue; + } + // Recurse into subdirectories const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name; const subDirAgents = await this.getAgentsFromDir(fullPath, moduleName, newRelativePath);