bmad-method 4.2.0 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.claude/commands/analyst.md +14 -20
  2. package/.claude/commands/architect.md +15 -20
  3. package/.claude/commands/bmad-master.md +18 -26
  4. package/.claude/commands/bmad-orchestrator.md +80 -33
  5. package/.claude/commands/dev.md +5 -4
  6. package/.claude/commands/pm.md +11 -16
  7. package/.claude/commands/sm.md +20 -25
  8. package/.cursor/rules/analyst.mdc +13 -19
  9. package/.cursor/rules/architect.mdc +14 -19
  10. package/.cursor/rules/bmad-master.mdc +18 -26
  11. package/.cursor/rules/bmad-orchestrator.mdc +80 -33
  12. package/.cursor/rules/dev.mdc +5 -4
  13. package/.cursor/rules/pm.mdc +11 -16
  14. package/.cursor/rules/sm.mdc +19 -24
  15. package/.releaserc.json +2 -1
  16. package/.roo/README.md +0 -11
  17. package/.vscode/settings.json +4 -0
  18. package/.windsurf/rules/analyst.md +13 -19
  19. package/.windsurf/rules/architect.md +14 -19
  20. package/.windsurf/rules/bmad-master.md +18 -26
  21. package/.windsurf/rules/bmad-orchestrator.md +80 -33
  22. package/.windsurf/rules/dev.md +5 -4
  23. package/.windsurf/rules/pm.md +11 -16
  24. package/.windsurf/rules/sm.md +19 -24
  25. package/CHANGELOG.md +126 -2
  26. package/CONTRIBUTING.md +2 -0
  27. package/README.md +20 -2
  28. package/{.bmad-core → bmad-core}/agent-teams/team-all.yml +1 -3
  29. package/bmad-core/agent-teams/team-fullstack.yml +18 -0
  30. package/{.bmad-core → bmad-core}/agent-teams/team-no-ui.yml +0 -2
  31. package/{.bmad-core → bmad-core}/agents/analyst.md +14 -20
  32. package/{.bmad-core → bmad-core}/agents/architect.md +15 -20
  33. package/{.bmad-core → bmad-core}/agents/bmad-master.md +18 -26
  34. package/bmad-core/agents/bmad-orchestrator.md +128 -0
  35. package/{.bmad-core → bmad-core}/agents/dev.md +5 -4
  36. package/{.bmad-core → bmad-core}/agents/pm.md +11 -16
  37. package/{.bmad-core → bmad-core}/agents/qa.md +11 -17
  38. package/bmad-core/agents/sm.md +55 -0
  39. package/{.bmad-core → bmad-core}/agents/ux-expert.md +14 -20
  40. package/bmad-core/bmad-core-config.yml +60 -0
  41. package/bmad-core/data/bmad-kb.md +47 -0
  42. package/bmad-core/tasks/doc-migration-task.md +143 -0
  43. package/bmad-core/tasks/document-project.md +389 -0
  44. package/bmad-core/tasks/generate-ai-frontend-prompt.md +51 -0
  45. package/{.bmad-core → bmad-core}/tasks/index-docs.md +8 -3
  46. package/{.bmad-core → bmad-core}/tasks/shard-doc.md +5 -3
  47. package/{.bmad-core → bmad-core}/templates/architecture-tmpl.md +16 -13
  48. package/{.bmad-core → bmad-core}/templates/brownfield-architecture-tmpl.md +6 -6
  49. package/{.bmad-core → bmad-core}/templates/front-end-spec-tmpl.md +6 -6
  50. package/{.bmad-core → bmad-core}/templates/fullstack-architecture-tmpl.md +85 -103
  51. package/{.bmad-core → bmad-core}/templates/prd-tmpl.md +1 -1
  52. package/bmad-core/templates/simple-project-prd-tmpl.md +461 -0
  53. package/{.bmad-core → bmad-core}/templates/story-tmpl.md +2 -2
  54. package/{.bmad-core → bmad-core}/utils/agent-switcher.ide.md +6 -6
  55. package/{.bmad-core → bmad-core}/utils/workflow-management.md +14 -15
  56. package/{.bmad-core → bmad-core}/web-bundles/agents/analyst.txt +26 -21
  57. package/{.bmad-core → bmad-core}/web-bundles/agents/architect.txt +608 -236
  58. package/{.bmad-core → bmad-core}/web-bundles/agents/bmad-master.txt +467 -1049
  59. package/bmad-core/web-bundles/agents/bmad-orchestrator.txt +647 -0
  60. package/{.bmad-core → bmad-core}/web-bundles/agents/dev.txt +5 -4
  61. package/{.bmad-core → bmad-core}/web-bundles/agents/pm.txt +477 -18
  62. package/{.bmad-core → bmad-core}/web-bundles/agents/po.txt +3 -3
  63. package/{.bmad-core → bmad-core}/web-bundles/agents/qa.txt +11 -17
  64. package/{.bmad-core → bmad-core}/web-bundles/agents/sm.txt +22 -27
  65. package/{.bmad-core → bmad-core}/web-bundles/agents/ux-expert.txt +57 -70
  66. package/{.bmad-core → bmad-core}/workflows/greenfield-fullstack.yml +3 -3
  67. package/{.bmad-core → creator-tools}/tasks/create-agent.md +10 -12
  68. package/{.bmad-core/tasks/create-expansion-pack.md → creator-tools/tasks/generate-expansion-pack.md} +8 -6
  69. package/docs/bmad-workflow-guide.md +161 -0
  70. package/docs/claude-code-guide.md +119 -0
  71. package/docs/core-architecture.md +213 -0
  72. package/docs/cursor-guide.md +127 -0
  73. package/docs/how-to-contribute-with-pull-requests.md +141 -0
  74. package/docs/roo-code-guide.md +140 -0
  75. package/docs/user-guide.md +1044 -0
  76. package/docs/versioning-and-releases.md +4 -4
  77. package/docs/windsurf-guide.md +127 -0
  78. package/expansion-packs/README.md +1 -111
  79. package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/team-game-dev.yml +12 -0
  80. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +58 -0
  81. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +66 -0
  82. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +51 -0
  83. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +201 -0
  84. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +160 -0
  85. package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +254 -0
  86. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +631 -0
  87. package/expansion-packs/bmad-2d-phaser-game-dev/manifest.yml +45 -0
  88. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +111 -0
  89. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +216 -0
  90. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +308 -0
  91. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.md +560 -0
  92. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.md +345 -0
  93. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.md +331 -0
  94. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.md +235 -0
  95. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.md +451 -0
  96. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-designer.txt +1758 -0
  97. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-developer.txt +1444 -0
  98. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-sm.txt +674 -0
  99. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/team-game-dev.txt +4395 -0
  100. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/teams/team-game-dev.txt +4395 -0
  101. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yml +183 -0
  102. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yml +175 -0
  103. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/README.md +5 -5
  104. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/agents/infra-devops-platform.md +3 -3
  105. package/expansion-packs/bmad-infrastructure-devops/manifest.yml +23 -0
  106. package/expansion-packs/bmad-infrastructure-devops/tasks/create-doc.md +74 -0
  107. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/templates/infrastructure-platform-from-arch-tmpl.md +0 -0
  108. package/expansion-packs/bmad-infrastructure-devops/web-bundles/agents/infra-devops-platform.txt +2021 -0
  109. package/package.json +20 -14
  110. package/tools/builders/web-builder.js +207 -17
  111. package/tools/cli.js +55 -7
  112. package/tools/installer/README.md +2 -2
  113. package/tools/installer/bin/bmad.js +107 -28
  114. package/tools/installer/config/install.config.yml +43 -43
  115. package/tools/installer/lib/config-loader.js +39 -2
  116. package/tools/installer/lib/file-manager.js +20 -3
  117. package/tools/installer/lib/ide-setup.js +11 -1
  118. package/tools/installer/lib/installer.js +275 -29
  119. package/tools/installer/package-lock.json +538 -336
  120. package/tools/installer/package.json +8 -8
  121. package/tools/lib/dependency-resolver.js +2 -2
  122. package/tools/semantic-release-sync-installer.js +31 -0
  123. package/tools/sync-installer-version.js +34 -0
  124. package/tools/upgraders/v3-to-v4-upgrader.js +18 -13
  125. package/tools/version-bump.js +33 -26
  126. package/tools/yaml-format.js +54 -25
  127. package/.bmad-core/agent-teams/team-fullstack.yml +0 -26
  128. package/.bmad-core/agents/bmad-orchestrator.md +0 -81
  129. package/.bmad-core/agents/sm.md +0 -60
  130. package/.bmad-core/data/bmad-kb.md +0 -36
  131. package/.bmad-core/schemas/agent-team-schema.yml +0 -153
  132. package/.bmad-core/tasks/create-team.md +0 -229
  133. package/.bmad-core/tasks/doc-migration-task.md +0 -198
  134. package/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -58
  135. package/.bmad-core/web-bundles/agents/bmad-orchestrator.txt +0 -1455
  136. package/.bmad-core/web-bundles/teams/team-all.txt +0 -10315
  137. package/.bmad-core/web-bundles/teams/team-fullstack.txt +0 -9663
  138. package/.bmad-core/web-bundles/teams/team-no-ui.txt +0 -8504
  139. package/.claude/settings.local.json +0 -22
  140. package/expansion-packs/infrastructure-devops/manifest.yml +0 -38
  141. /package/{.bmad-core → bmad-core}/agents/po.md +0 -0
  142. /package/{.bmad-core → bmad-core}/checklists/architect-checklist.md +0 -0
  143. /package/{.bmad-core → bmad-core}/checklists/change-checklist.md +0 -0
  144. /package/{.bmad-core → bmad-core}/checklists/pm-checklist.md +0 -0
  145. /package/{.bmad-core → bmad-core}/checklists/po-master-checklist.md +0 -0
  146. /package/{.bmad-core → bmad-core}/checklists/story-dod-checklist.md +0 -0
  147. /package/{.bmad-core → bmad-core}/checklists/story-draft-checklist.md +0 -0
  148. /package/{.bmad-core → bmad-core}/data/technical-preferences.md +0 -0
  149. /package/{.bmad-core → bmad-core}/tasks/advanced-elicitation.md +0 -0
  150. /package/{.bmad-core → bmad-core}/tasks/brainstorming-techniques.md +0 -0
  151. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-epic.md +0 -0
  152. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-story.md +0 -0
  153. /package/{.bmad-core → bmad-core}/tasks/core-dump.md +0 -0
  154. /package/{.bmad-core → bmad-core}/tasks/correct-course.md +0 -0
  155. /package/{.bmad-core → bmad-core}/tasks/create-deep-research-prompt.md +0 -0
  156. /package/{.bmad-core → bmad-core}/tasks/create-doc.md +0 -0
  157. /package/{.bmad-core → bmad-core}/tasks/create-next-story.md +0 -0
  158. /package/{.bmad-core → bmad-core}/tasks/execute-checklist.md +0 -0
  159. /package/{.bmad-core → bmad-core}/templates/agent-tmpl.md +0 -0
  160. /package/{.bmad-core → bmad-core}/templates/brownfield-prd-tmpl.md +0 -0
  161. /package/{.bmad-core → bmad-core}/templates/competitor-analysis-tmpl.md +0 -0
  162. /package/{.bmad-core → bmad-core}/templates/expansion-pack-plan-tmpl.md +0 -0
  163. /package/{.bmad-core → bmad-core}/templates/front-end-architecture-tmpl.md +0 -0
  164. /package/{.bmad-core → bmad-core}/templates/market-research-tmpl.md +0 -0
  165. /package/{.bmad-core → bmad-core}/templates/project-brief-tmpl.md +0 -0
  166. /package/{.bmad-core → bmad-core}/templates/web-agent-startup-instructions-template.md +0 -0
  167. /package/{.bmad-core → bmad-core}/utils/template-format.md +0 -0
  168. /package/{.bmad-core → bmad-core}/workflows/brownfield-fullstack.yml +0 -0
  169. /package/{.bmad-core → bmad-core}/workflows/brownfield-service.yml +0 -0
  170. /package/{.bmad-core → bmad-core}/workflows/brownfield-ui.yml +0 -0
  171. /package/{.bmad-core → bmad-core}/workflows/greenfield-service.yml +0 -0
  172. /package/{.bmad-core → bmad-core}/workflows/greenfield-ui.yml +0 -0
  173. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/checklists/infrastructure-checklist.md +0 -0
  174. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/review-infrastructure.md +0 -0
  175. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/validate-infrastructure.md +0 -0
  176. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/templates/infrastructure-architecture-tmpl.md +0 -0
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.2.0",
3
+ "version": "4.4.1",
4
4
  "description": "Breakthrough Method of Agile AI-driven Development",
5
5
  "main": "tools/cli.js",
6
6
  "bin": {
7
- "bmad": "./tools/bmad-npx-wrapper.js",
8
- "bmad-method": "./tools/bmad-npx-wrapper.js"
7
+ "bmad": "tools/bmad-npx-wrapper.js",
8
+ "bmad-method": "tools/bmad-npx-wrapper.js"
9
9
  },
10
10
  "scripts": {
11
11
  "build": "node tools/cli.js build",
@@ -23,14 +23,14 @@
23
23
  "prepare": "husky"
24
24
  },
25
25
  "dependencies": {
26
- "@kayvan/markdown-tree-parser": "^1.4.2",
27
- "chalk": "^4.1.2",
28
- "commander": "^9.4.1",
29
- "fs-extra": "^11.1.0",
30
- "glob": "^8.0.3",
31
- "inquirer": "^8.2.5",
26
+ "@kayvan/markdown-tree-parser": "^1.5.0",
27
+ "chalk": "^5.4.1",
28
+ "commander": "^14.0.0",
29
+ "fs-extra": "^11.3.0",
30
+ "glob": "^11.0.3",
31
+ "inquirer": "^12.6.3",
32
32
  "js-yaml": "^4.1.0",
33
- "ora": "^5.4.1"
33
+ "ora": "^8.2.0"
34
34
  },
35
35
  "keywords": [
36
36
  "agile",
@@ -45,10 +45,10 @@
45
45
  "license": "MIT",
46
46
  "repository": {
47
47
  "type": "git",
48
- "url": "https://github.com/bmadcode/BMAD-METHOD.git"
48
+ "url": "git+https://github.com/bmadcode/BMAD-METHOD.git"
49
49
  },
50
50
  "engines": {
51
- "node": ">=14.0.0"
51
+ "node": ">=20.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "husky": "^9.1.7",
@@ -60,14 +60,20 @@
60
60
  "yaml-lint": "^1.7.0"
61
61
  },
62
62
  "lint-staged": {
63
- "*.{yml,yaml}": [
63
+ "**/*.{yml,yaml}": [
64
64
  "node tools/yaml-format.js"
65
65
  ],
66
- "*.md": [
66
+ "**/*.md": [
67
67
  "node tools/yaml-format.js"
68
68
  ],
69
69
  ".roomodes": [
70
70
  "node tools/yaml-format.js"
71
+ ],
72
+ "bmad-core/**/*.yml": [
73
+ "node tools/yaml-format.js"
74
+ ],
75
+ ".github/**/*.yml": [
76
+ "node tools/yaml-format.js"
71
77
  ]
72
78
  }
73
79
  }
@@ -1,5 +1,5 @@
1
- const fs = require('fs').promises;
2
- const path = require('path');
1
+ const fs = require('node:fs').promises;
2
+ const path = require('node:path');
3
3
  const DependencyResolver = require('../lib/dependency-resolver');
4
4
 
5
5
  class WebBuilder {
@@ -7,10 +7,10 @@ class WebBuilder {
7
7
  this.rootDir = options.rootDir || process.cwd();
8
8
  this.outputDirs = options.outputDirs || [
9
9
  path.join(this.rootDir, 'dist'),
10
- path.join(this.rootDir, '.bmad-core', 'web-bundles')
10
+ path.join(this.rootDir, 'bmad-core', 'web-bundles')
11
11
  ];
12
12
  this.resolver = new DependencyResolver(this.rootDir);
13
- this.templatePath = path.join(this.rootDir, '.bmad-core', 'templates', 'web-agent-startup-instructions-template.md');
13
+ this.templatePath = path.join(this.rootDir, 'bmad-core', 'templates', 'web-agent-startup-instructions-template.md');
14
14
  }
15
15
 
16
16
  async cleanOutputDirs() {
@@ -19,6 +19,7 @@ class WebBuilder {
19
19
  await fs.rm(dir, { recursive: true, force: true });
20
20
  console.log(`Cleaned: ${path.relative(this.rootDir, dir)}`);
21
21
  } catch (error) {
22
+ console.debug(`Failed to clean directory ${dir}:`, error.message);
22
23
  // Directory might not exist, that's fine
23
24
  }
24
25
  }
@@ -26,11 +27,11 @@ class WebBuilder {
26
27
 
27
28
  async buildAgents() {
28
29
  const agents = await this.resolver.listAgents();
29
-
30
+
30
31
  for (const agentId of agents) {
31
32
  console.log(` Building agent: ${agentId}`);
32
33
  const bundle = await this.buildAgentBundle(agentId);
33
-
34
+
34
35
  // Write to all output directories
35
36
  for (const outputDir of this.outputDirs) {
36
37
  const outputPath = path.join(outputDir, 'agents');
@@ -45,11 +46,11 @@ class WebBuilder {
45
46
 
46
47
  async buildTeams() {
47
48
  const teams = await this.resolver.listTeams();
48
-
49
+
49
50
  for (const teamId of teams) {
50
51
  console.log(` Building team: ${teamId}`);
51
52
  const bundle = await this.buildTeamBundle(teamId);
52
-
53
+
53
54
  // Write to all output directories
54
55
  for (const outputDir of this.outputDirs) {
55
56
  const outputPath = path.join(outputDir, 'teams');
@@ -65,39 +66,39 @@ class WebBuilder {
65
66
  async buildAgentBundle(agentId) {
66
67
  const dependencies = await this.resolver.resolveAgentDependencies(agentId);
67
68
  const template = await fs.readFile(this.templatePath, 'utf8');
68
-
69
+
69
70
  const sections = [template];
70
-
71
+
71
72
  // Add agent configuration
72
73
  sections.push(this.formatSection(dependencies.agent.path, dependencies.agent.content));
73
-
74
+
74
75
  // Add all dependencies
75
76
  for (const resource of dependencies.resources) {
76
77
  sections.push(this.formatSection(resource.path, resource.content));
77
78
  }
78
-
79
+
79
80
  return sections.join('\n');
80
81
  }
81
82
 
82
83
  async buildTeamBundle(teamId) {
83
84
  const dependencies = await this.resolver.resolveTeamDependencies(teamId);
84
85
  const template = await fs.readFile(this.templatePath, 'utf8');
85
-
86
+
86
87
  const sections = [template];
87
-
88
+
88
89
  // Add team configuration
89
90
  sections.push(this.formatSection(dependencies.team.path, dependencies.team.content));
90
-
91
+
91
92
  // Add all agents
92
93
  for (const agent of dependencies.agents) {
93
94
  sections.push(this.formatSection(agent.path, agent.content));
94
95
  }
95
-
96
+
96
97
  // Add all deduplicated resources
97
98
  for (const resource of dependencies.resources) {
98
99
  sections.push(this.formatSection(resource.path, resource.content));
99
100
  }
100
-
101
+
101
102
  return sections.join('\n');
102
103
  }
103
104
 
@@ -137,6 +138,195 @@ class WebBuilder {
137
138
  }
138
139
  }
139
140
 
141
+ async buildAllExpansionPacks(options = {}) {
142
+ const expansionPacks = await this.listExpansionPacks();
143
+
144
+ for (const packName of expansionPacks) {
145
+ console.log(` Building expansion pack: ${packName}`);
146
+ await this.buildExpansionPack(packName, options);
147
+ }
148
+
149
+ console.log(`Built ${expansionPacks.length} expansion pack bundles`);
150
+ }
151
+
152
+ async buildExpansionPack(packName, options = {}) {
153
+ const packDir = path.join(this.rootDir, 'expansion-packs', packName);
154
+ const outputDirs = [
155
+ path.join(packDir, 'web-bundles'),
156
+ path.join(this.rootDir, 'dist', 'expansion-packs', packName)
157
+ ];
158
+
159
+ // Clean output directories if requested
160
+ if (options.clean !== false) {
161
+ for (const outputDir of outputDirs) {
162
+ try {
163
+ await fs.rm(outputDir, { recursive: true, force: true });
164
+ } catch (error) {
165
+ // Directory might not exist, that's fine
166
+ }
167
+ }
168
+ }
169
+
170
+ // Build individual agents first
171
+ const agentsDir = path.join(packDir, 'agents');
172
+ try {
173
+ const agentFiles = await fs.readdir(agentsDir);
174
+ const agentMarkdownFiles = agentFiles.filter(f => f.endsWith('.md'));
175
+
176
+ if (agentMarkdownFiles.length > 0) {
177
+ console.log(` Building individual agents for ${packName}:`);
178
+
179
+ for (const agentFile of agentMarkdownFiles) {
180
+ const agentName = agentFile.replace('.md', '');
181
+ console.log(` - ${agentName}`);
182
+
183
+ // Build individual agent bundle
184
+ const bundle = await this.buildExpansionAgentBundle(packName, packDir, agentName);
185
+
186
+ // Write to all output directories
187
+ for (const outputDir of outputDirs) {
188
+ const agentsOutputDir = path.join(outputDir, 'agents');
189
+ await fs.mkdir(agentsOutputDir, { recursive: true });
190
+ const outputFile = path.join(agentsOutputDir, `${agentName}.txt`);
191
+ await fs.writeFile(outputFile, bundle, 'utf8');
192
+ }
193
+ }
194
+ }
195
+ } catch (error) {
196
+ console.debug(` No agents directory found for ${packName}`);
197
+ }
198
+
199
+ // Build team bundle
200
+ const agentTeamsDir = path.join(packDir, 'agent-teams');
201
+ try {
202
+ const teamFiles = await fs.readdir(agentTeamsDir);
203
+ const teamFile = teamFiles.find(f => f.startsWith('team-') && f.endsWith('.yml'));
204
+
205
+ if (teamFile) {
206
+ console.log(` Building team bundle for ${packName}`);
207
+ const teamConfigPath = path.join(agentTeamsDir, teamFile);
208
+
209
+ // Build expansion pack as a team bundle
210
+ const bundle = await this.buildExpansionTeamBundle(packName, packDir, teamConfigPath);
211
+
212
+ // Write to all output directories
213
+ for (const outputDir of outputDirs) {
214
+ const teamsOutputDir = path.join(outputDir, 'teams');
215
+ await fs.mkdir(teamsOutputDir, { recursive: true });
216
+ const outputFile = path.join(teamsOutputDir, teamFile.replace('.yml', '.txt'));
217
+ await fs.writeFile(outputFile, bundle, 'utf8');
218
+ console.log(` ✓ Created bundle: ${path.relative(this.rootDir, outputFile)}`);
219
+ }
220
+ } else {
221
+ console.warn(` ⚠ No team configuration found in ${packName}/agent-teams/`);
222
+ }
223
+ } catch (error) {
224
+ console.warn(` ⚠ No agent-teams directory found for ${packName}`);
225
+ }
226
+ }
227
+
228
+ async buildExpansionAgentBundle(packName, packDir, agentName) {
229
+ const template = await fs.readFile(this.templatePath, 'utf8');
230
+ const sections = [template];
231
+
232
+ // Add agent configuration
233
+ const agentPath = path.join(packDir, 'agents', `${agentName}.md`);
234
+ const agentContent = await fs.readFile(agentPath, 'utf8');
235
+ sections.push(this.formatSection(`agents#${agentName}`, agentContent));
236
+
237
+ // Resolve and add agent dependencies from expansion pack
238
+ const agentYaml = agentContent.match(/```yaml\n([\s\S]*?)\n```/);
239
+ if (agentYaml) {
240
+ try {
241
+ const yaml = require('js-yaml');
242
+ const agentConfig = yaml.load(agentYaml[1]);
243
+
244
+ if (agentConfig.dependencies) {
245
+ // Add resources from expansion pack
246
+ for (const [resourceType, resources] of Object.entries(agentConfig.dependencies)) {
247
+ if (Array.isArray(resources)) {
248
+ for (const resourceName of resources) {
249
+ const resourcePath = path.join(packDir, resourceType, `${resourceName}.md`);
250
+ try {
251
+ const resourceContent = await fs.readFile(resourcePath, 'utf8');
252
+ sections.push(this.formatSection(`${resourceType}#${resourceName}`, resourceContent));
253
+ } catch (error) {
254
+ // Resource might not exist in expansion pack, that's ok
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+ } catch (error) {
261
+ console.debug(`Failed to parse agent YAML for ${agentName}:`, error.message);
262
+ }
263
+ }
264
+
265
+ return sections.join('\n');
266
+ }
267
+
268
+ async buildExpansionTeamBundle(packName, packDir, teamConfigPath) {
269
+ const template = await fs.readFile(this.templatePath, 'utf8');
270
+
271
+ const sections = [template];
272
+
273
+ // Add team configuration
274
+ const teamContent = await fs.readFile(teamConfigPath, 'utf8');
275
+ const teamFileName = path.basename(teamConfigPath, '.yml');
276
+ sections.push(this.formatSection(`agent-teams#${teamFileName}`, teamContent));
277
+
278
+ // Add bmad-orchestrator (required for all teams)
279
+ const orchestratorPath = path.join(this.rootDir, 'bmad-core', 'agents', 'bmad-orchestrator.md');
280
+ const orchestratorContent = await fs.readFile(orchestratorPath, 'utf8');
281
+ sections.push(this.formatSection('agents#bmad-orchestrator', orchestratorContent));
282
+
283
+ // Add expansion pack agents
284
+ const agentsDir = path.join(packDir, 'agents');
285
+ try {
286
+ const agentFiles = await fs.readdir(agentsDir);
287
+ for (const agentFile of agentFiles.filter(f => f.endsWith('.md'))) {
288
+ const agentPath = path.join(agentsDir, agentFile);
289
+ const agentContent = await fs.readFile(agentPath, 'utf8');
290
+ const agentName = agentFile.replace('.md', '');
291
+ sections.push(this.formatSection(`agents#${agentName}`, agentContent));
292
+ }
293
+ } catch (error) {
294
+ console.warn(` ⚠ No agents directory found in ${packName}`);
295
+ }
296
+
297
+ // Add expansion pack resources (templates, tasks, checklists)
298
+ const resourceDirs = ['templates', 'tasks', 'checklists', 'workflows', 'data'];
299
+ for (const resourceDir of resourceDirs) {
300
+ const resourcePath = path.join(packDir, resourceDir);
301
+ try {
302
+ const resourceFiles = await fs.readdir(resourcePath);
303
+ for (const resourceFile of resourceFiles.filter(f => f.endsWith('.md') || f.endsWith('.yml'))) {
304
+ const filePath = path.join(resourcePath, resourceFile);
305
+ const fileContent = await fs.readFile(filePath, 'utf8');
306
+ const fileName = resourceFile.replace(/\.(md|yml)$/, '');
307
+ sections.push(this.formatSection(`${resourceDir}#${fileName}`, fileContent));
308
+ }
309
+ } catch (error) {
310
+ // Directory might not exist, that's fine
311
+ }
312
+ }
313
+
314
+ return sections.join('\n');
315
+ }
316
+
317
+ async listExpansionPacks() {
318
+ const expansionPacksDir = path.join(this.rootDir, 'expansion-packs');
319
+ try {
320
+ const entries = await fs.readdir(expansionPacksDir, { withFileTypes: true });
321
+ return entries
322
+ .filter(entry => entry.isDirectory())
323
+ .map(entry => entry.name);
324
+ } catch (error) {
325
+ console.warn('No expansion-packs directory found');
326
+ return [];
327
+ }
328
+ }
329
+
140
330
  listAgents() {
141
331
  return this.resolver.listAgents();
142
332
  }
package/tools/cli.js CHANGED
@@ -18,6 +18,8 @@ program
18
18
  .description('Build web bundles for agents and teams')
19
19
  .option('-a, --agents-only', 'Build only agent bundles')
20
20
  .option('-t, --teams-only', 'Build only team bundles')
21
+ .option('-e, --expansions-only', 'Build only expansion pack bundles')
22
+ .option('--no-expansions', 'Skip building expansion packs')
21
23
  .option('--no-clean', 'Skip cleaning output directories')
22
24
  .action(async (options) => {
23
25
  const builder = new WebBuilder({
@@ -30,14 +32,24 @@ program
30
32
  await builder.cleanOutputDirs();
31
33
  }
32
34
 
33
- if (!options.teamsOnly) {
34
- console.log('Building agent bundles...');
35
- await builder.buildAgents();
36
- }
35
+ if (options.expansionsOnly) {
36
+ console.log('Building expansion pack bundles...');
37
+ await builder.buildAllExpansionPacks({ clean: false });
38
+ } else {
39
+ if (!options.teamsOnly) {
40
+ console.log('Building agent bundles...');
41
+ await builder.buildAgents();
42
+ }
43
+
44
+ if (!options.agentsOnly) {
45
+ console.log('Building team bundles...');
46
+ await builder.buildTeams();
47
+ }
37
48
 
38
- if (!options.agentsOnly) {
39
- console.log('Building team bundles...');
40
- await builder.buildTeams();
49
+ if (!options.noExpansions) {
50
+ console.log('Building expansion pack bundles...');
51
+ await builder.buildAllExpansionPacks({ clean: false });
52
+ }
41
53
  }
42
54
 
43
55
  // Generate IDE configuration folders
@@ -62,6 +74,32 @@ program
62
74
  }
63
75
  });
64
76
 
77
+ program
78
+ .command('build:expansions')
79
+ .description('Build web bundles for all expansion packs')
80
+ .option('--expansion <name>', 'Build specific expansion pack only')
81
+ .option('--no-clean', 'Skip cleaning output directories')
82
+ .action(async (options) => {
83
+ const builder = new WebBuilder({
84
+ rootDir: process.cwd()
85
+ });
86
+
87
+ try {
88
+ if (options.expansion) {
89
+ console.log(`Building expansion pack: ${options.expansion}`);
90
+ await builder.buildExpansionPack(options.expansion, { clean: options.clean });
91
+ } else {
92
+ console.log('Building all expansion packs...');
93
+ await builder.buildAllExpansionPacks({ clean: options.clean });
94
+ }
95
+
96
+ console.log('Expansion pack build completed successfully!');
97
+ } catch (error) {
98
+ console.error('Expansion pack build failed:', error.message);
99
+ process.exit(1);
100
+ }
101
+ });
102
+
65
103
  program
66
104
  .command('list:agents')
67
105
  .description('List all available agents')
@@ -72,6 +110,16 @@ program
72
110
  agents.forEach(agent => console.log(` - ${agent}`));
73
111
  });
74
112
 
113
+ program
114
+ .command('list:expansions')
115
+ .description('List all available expansion packs')
116
+ .action(async () => {
117
+ const builder = new WebBuilder({ rootDir: process.cwd() });
118
+ const expansions = await builder.listExpansionPacks();
119
+ console.log('Available expansion packs:');
120
+ expansions.forEach(expansion => console.log(` - ${expansion}`));
121
+ });
122
+
75
123
  program
76
124
  .command('validate')
77
125
  .description('Validate agent and team configurations')
@@ -33,7 +33,7 @@ installer/
33
33
 
34
34
  ## Usage
35
35
 
36
- ```bash
36
+ ````bash
37
37
  # Interactive installation
38
38
  npx bmad-method install
39
39
 
@@ -55,4 +55,4 @@ npm test
55
55
 
56
56
  # Lint code
57
57
  npm run lint
58
- ```
58
+ ````