Skip to content

Commit a04635e

Browse files
authored
fix: agent-manifest.csv empty after install — type mismatch + scan path bug (#2115)
Two bugs combined to produce an empty agent-manifest.csv: 1. collectAgents() only scanned {module}/agents/ directories, but agents live at various paths (bmm/1-analysis/bmad-agent-analyst/, cis/skills/bmad-cis-agent-*, etc.). Now walks the full module tree. 2. All 9 BMM agent manifests declared type: skill instead of type: agent. The manifest generator requires type: agent to include a directory in agent-manifest.csv. CIS, GDS, TEA, and WDS already had the correct type. Changes: - Fix 9 BMM bmad-skill-manifest.yaml files: type: skill → type: agent - Replace collectAgents/getAgentsFromDir with full-tree recursive scan - Module field from manifest file always takes precedence over directory - Remove dead skillManifest load (legacy .md agent support removed) - Add TODO in bmad-artifacts.js documenting legacy agent pipeline as dead code - Add 10 regression tests covering BMM, CIS, and GDS directory layouts
1 parent 94831cb commit a04635e

12 files changed

Lines changed: 188 additions & 124 deletions

File tree

src/bmm-skills/1-analysis/bmad-agent-analyst/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-analyst
33
displayName: Mary
44
title: Business Analyst

src/bmm-skills/1-analysis/bmad-agent-tech-writer/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-tech-writer
33
displayName: Paige
44
title: Technical Writer

src/bmm-skills/2-plan-workflows/bmad-agent-pm/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-pm
33
displayName: John
44
title: Product Manager

src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-ux-designer
33
displayName: Sally
44
title: UX Designer

src/bmm-skills/3-solutioning/bmad-agent-architect/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-architect
33
displayName: Winston
44
title: Architect

src/bmm-skills/4-implementation/bmad-agent-dev/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-dev
33
displayName: Amelia
44
title: Developer Agent

src/bmm-skills/4-implementation/bmad-agent-qa/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-qa
33
displayName: Quinn
44
title: QA Engineer

src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-quick-flow-solo-dev
33
displayName: Barry
44
title: Quick Flow Solo Dev

src/bmm-skills/4-implementation/bmad-agent-sm/bmad-skill-manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type: skill
1+
type: agent
22
name: bmad-agent-sm
33
displayName: Bob
44
title: Scrum Master

test/test-installation-components.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,93 @@ async function runTests() {
16481648
// skill-manifest.csv should include the native agent entrypoint
16491649
const skillManifestCsv29 = await fs.readFile(path.join(tempFixture29, '_config', 'skill-manifest.csv'), 'utf8');
16501650
assert(skillManifestCsv29.includes('bmad-tea'), 'skill-manifest.csv includes native type:agent SKILL.md entrypoint');
1651+
1652+
// --- Agents at non-agents/ paths (regression test for BMM/CIS layouts) ---
1653+
// Create a second fixture with agents at paths like bmm/1-analysis/bmad-agent-analyst/
1654+
const tempFixture29b = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-agent-paths-'));
1655+
await fs.ensureDir(path.join(tempFixture29b, '_config'));
1656+
1657+
// Agent at bmm-style path: bmm/1-analysis/bmad-agent-analyst/
1658+
const bmmAgentDir = path.join(tempFixture29b, 'bmm', '1-analysis', 'bmad-agent-analyst');
1659+
await fs.ensureDir(bmmAgentDir);
1660+
await fs.writeFile(
1661+
path.join(bmmAgentDir, 'bmad-skill-manifest.yaml'),
1662+
[
1663+
'type: agent',
1664+
'name: bmad-agent-analyst',
1665+
'displayName: Mary',
1666+
'title: Business Analyst',
1667+
'role: Strategic Business Analyst',
1668+
'module: bmm',
1669+
].join('\n') + '\n',
1670+
);
1671+
await fs.writeFile(
1672+
path.join(bmmAgentDir, 'SKILL.md'),
1673+
'---\nname: bmad-agent-analyst\ndescription: Business Analyst agent\n---\n\nAnalyst agent.\n',
1674+
);
1675+
1676+
// Agent at cis-style path: cis/skills/bmad-cis-agent-brainstorming-coach/
1677+
const cisAgentDir = path.join(tempFixture29b, 'cis', 'skills', 'bmad-cis-agent-brainstorming-coach');
1678+
await fs.ensureDir(cisAgentDir);
1679+
await fs.writeFile(
1680+
path.join(cisAgentDir, 'bmad-skill-manifest.yaml'),
1681+
[
1682+
'type: agent',
1683+
'name: bmad-cis-agent-brainstorming-coach',
1684+
'displayName: Carson',
1685+
'title: Brainstorming Specialist',
1686+
'role: Master Facilitator',
1687+
'module: cis',
1688+
].join('\n') + '\n',
1689+
);
1690+
await fs.writeFile(
1691+
path.join(cisAgentDir, 'SKILL.md'),
1692+
'---\nname: bmad-cis-agent-brainstorming-coach\ndescription: Brainstorming coach\n---\n\nCoach.\n',
1693+
);
1694+
1695+
// Agent at standard agents/ path (GDS-style): gds/agents/gds-agent-game-dev/
1696+
const gdsAgentDir = path.join(tempFixture29b, 'gds', 'agents', 'gds-agent-game-dev');
1697+
await fs.ensureDir(gdsAgentDir);
1698+
await fs.writeFile(
1699+
path.join(gdsAgentDir, 'bmad-skill-manifest.yaml'),
1700+
[
1701+
'type: agent',
1702+
'name: gds-agent-game-dev',
1703+
'displayName: Link',
1704+
'title: Game Developer',
1705+
'role: Senior Game Dev',
1706+
'module: gds',
1707+
].join('\n') + '\n',
1708+
);
1709+
await fs.writeFile(
1710+
path.join(gdsAgentDir, 'SKILL.md'),
1711+
'---\nname: gds-agent-game-dev\ndescription: Game developer agent\n---\n\nGame dev.\n',
1712+
);
1713+
1714+
const generator29b = new ManifestGenerator();
1715+
await generator29b.generateManifests(tempFixture29b, ['bmm', 'cis', 'gds'], [], { ides: [] });
1716+
1717+
// All three agents should appear in agents[] regardless of directory layout
1718+
const bmmAgent = generator29b.agents.find((a) => a.name === 'bmad-agent-analyst');
1719+
assert(bmmAgent !== undefined, 'Agent at bmm/1-analysis/ path appears in agents[]');
1720+
assert(bmmAgent && bmmAgent.module === 'bmm', 'BMM agent module field comes from manifest file');
1721+
assert(bmmAgent && bmmAgent.path.includes('bmm/1-analysis/bmad-agent-analyst'), 'BMM agent path reflects actual directory layout');
1722+
1723+
const cisAgent = generator29b.agents.find((a) => a.name === 'bmad-cis-agent-brainstorming-coach');
1724+
assert(cisAgent !== undefined, 'Agent at cis/skills/ path appears in agents[]');
1725+
assert(cisAgent && cisAgent.module === 'cis', 'CIS agent module field comes from manifest file');
1726+
1727+
const gdsAgent = generator29b.agents.find((a) => a.name === 'gds-agent-game-dev');
1728+
assert(gdsAgent !== undefined, 'Agent at gds/agents/ path appears in agents[]');
1729+
assert(gdsAgent && gdsAgent.module === 'gds', 'GDS agent module field comes from manifest file');
1730+
1731+
// agent-manifest.csv should contain all three
1732+
const agentCsv29b = await fs.readFile(path.join(tempFixture29b, '_config', 'agent-manifest.csv'), 'utf8');
1733+
assert(agentCsv29b.includes('bmad-agent-analyst'), 'agent-manifest.csv includes BMM-layout agent');
1734+
assert(agentCsv29b.includes('bmad-cis-agent-brainstorming-coach'), 'agent-manifest.csv includes CIS-layout agent');
1735+
assert(agentCsv29b.includes('gds-agent-game-dev'), 'agent-manifest.csv includes GDS-layout agent');
1736+
1737+
await fs.remove(tempFixture29b).catch(() => {});
16511738
} catch (error) {
16521739
assert(false, 'Unified skill scanner test succeeds', error.message);
16531740
} finally {

0 commit comments

Comments
 (0)