bmad-method 4.4.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 (126) hide show
  1. package/.claude/commands/bmad-orchestrator.md +65 -6
  2. package/.cursor/rules/bmad-orchestrator.mdc +65 -6
  3. package/.roo/README.md +0 -11
  4. package/.windsurf/rules/bmad-orchestrator.md +65 -6
  5. package/CHANGELOG.md +9 -3
  6. package/{.bmad-core → bmad-core}/agent-teams/team-all.yml +1 -3
  7. package/bmad-core/agent-teams/team-fullstack.yml +18 -0
  8. package/{.bmad-core → bmad-core}/agent-teams/team-no-ui.yml +0 -2
  9. package/bmad-core/agents/bmad-orchestrator.md +128 -0
  10. package/{.bmad-core → bmad-core}/agents/qa.md +11 -17
  11. package/{.bmad-core → bmad-core}/agents/ux-expert.md +14 -20
  12. package/{.bmad-core → bmad-core}/tasks/shard-doc.md +5 -3
  13. package/{.bmad-core → bmad-core}/templates/architecture-tmpl.md +2 -2
  14. package/{.bmad-core → bmad-core}/templates/brownfield-architecture-tmpl.md +6 -6
  15. package/{.bmad-core → bmad-core}/templates/front-end-spec-tmpl.md +6 -6
  16. package/{.bmad-core → bmad-core}/utils/agent-switcher.ide.md +6 -6
  17. package/{.bmad-core → bmad-core}/utils/workflow-management.md +4 -4
  18. package/{.bmad-core → bmad-core}/web-bundles/agents/architect.txt +3 -3
  19. package/{.bmad-core → bmad-core}/web-bundles/agents/bmad-master.txt +10 -10
  20. package/{.bmad-core → bmad-core}/web-bundles/agents/bmad-orchestrator.txt +67 -8
  21. package/{.bmad-core → bmad-core}/web-bundles/agents/pm.txt +1 -1
  22. package/{.bmad-core → bmad-core}/web-bundles/agents/po.txt +1 -1
  23. package/{.bmad-core → bmad-core}/web-bundles/agents/qa.txt +11 -17
  24. package/{.bmad-core → bmad-core}/web-bundles/agents/ux-expert.txt +16 -22
  25. package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/team-game-dev.yml +12 -0
  26. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +58 -0
  27. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +66 -0
  28. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +51 -0
  29. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +201 -0
  30. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +160 -0
  31. package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +254 -0
  32. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +631 -0
  33. package/expansion-packs/bmad-2d-phaser-game-dev/manifest.yml +45 -0
  34. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +111 -0
  35. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +216 -0
  36. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +308 -0
  37. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.md +560 -0
  38. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.md +345 -0
  39. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.md +331 -0
  40. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.md +235 -0
  41. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.md +451 -0
  42. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-designer.txt +1758 -0
  43. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-developer.txt +1444 -0
  44. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/agents/game-sm.txt +674 -0
  45. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/team-game-dev.txt +4395 -0
  46. package/expansion-packs/bmad-2d-phaser-game-dev/web-bundles/teams/team-game-dev.txt +4395 -0
  47. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yml +183 -0
  48. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yml +175 -0
  49. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/README.md +5 -5
  50. package/expansion-packs/bmad-infrastructure-devops/manifest.yml +23 -0
  51. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/templates/infrastructure-platform-from-arch-tmpl.md +0 -0
  52. package/expansion-packs/bmad-infrastructure-devops/web-bundles/agents/infra-devops-platform.txt +2021 -0
  53. package/package.json +3 -3
  54. package/tools/builders/web-builder.js +191 -2
  55. package/tools/cli.js +55 -7
  56. package/tools/installer/bin/bmad.js +65 -7
  57. package/tools/installer/config/install.config.yml +43 -43
  58. package/tools/installer/lib/config-loader.js +39 -2
  59. package/tools/installer/lib/installer.js +126 -0
  60. package/tools/installer/package-lock.json +3 -3
  61. package/tools/installer/package.json +2 -2
  62. package/tools/lib/dependency-resolver.js +1 -1
  63. package/.bmad-core/agent-teams/team-fullstack.yml +0 -26
  64. package/.bmad-core/agents/bmad-orchestrator.md +0 -69
  65. package/.bmad-core/web-bundles/teams/team-all.txt +0 -10262
  66. package/.bmad-core/web-bundles/teams/team-fullstack.txt +0 -9614
  67. package/.bmad-core/web-bundles/teams/team-no-ui.txt +0 -8462
  68. package/expansion-packs/infrastructure-devops/manifest.yml +0 -38
  69. /package/{.bmad-core → bmad-core}/agents/analyst.md +0 -0
  70. /package/{.bmad-core → bmad-core}/agents/architect.md +0 -0
  71. /package/{.bmad-core → bmad-core}/agents/bmad-master.md +0 -0
  72. /package/{.bmad-core → bmad-core}/agents/dev.md +0 -0
  73. /package/{.bmad-core → bmad-core}/agents/pm.md +0 -0
  74. /package/{.bmad-core → bmad-core}/agents/po.md +0 -0
  75. /package/{.bmad-core → bmad-core}/agents/sm.md +0 -0
  76. /package/{.bmad-core → bmad-core}/bmad-core-config.yml +0 -0
  77. /package/{.bmad-core → bmad-core}/checklists/architect-checklist.md +0 -0
  78. /package/{.bmad-core → bmad-core}/checklists/change-checklist.md +0 -0
  79. /package/{.bmad-core → bmad-core}/checklists/pm-checklist.md +0 -0
  80. /package/{.bmad-core → bmad-core}/checklists/po-master-checklist.md +0 -0
  81. /package/{.bmad-core → bmad-core}/checklists/story-dod-checklist.md +0 -0
  82. /package/{.bmad-core → bmad-core}/checklists/story-draft-checklist.md +0 -0
  83. /package/{.bmad-core → bmad-core}/data/bmad-kb.md +0 -0
  84. /package/{.bmad-core → bmad-core}/data/technical-preferences.md +0 -0
  85. /package/{.bmad-core → bmad-core}/tasks/advanced-elicitation.md +0 -0
  86. /package/{.bmad-core → bmad-core}/tasks/brainstorming-techniques.md +0 -0
  87. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-epic.md +0 -0
  88. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-story.md +0 -0
  89. /package/{.bmad-core → bmad-core}/tasks/core-dump.md +0 -0
  90. /package/{.bmad-core → bmad-core}/tasks/correct-course.md +0 -0
  91. /package/{.bmad-core → bmad-core}/tasks/create-deep-research-prompt.md +0 -0
  92. /package/{.bmad-core → bmad-core}/tasks/create-doc.md +0 -0
  93. /package/{.bmad-core → bmad-core}/tasks/create-next-story.md +0 -0
  94. /package/{.bmad-core → bmad-core}/tasks/doc-migration-task.md +0 -0
  95. /package/{.bmad-core → bmad-core}/tasks/document-project.md +0 -0
  96. /package/{.bmad-core → bmad-core}/tasks/execute-checklist.md +0 -0
  97. /package/{.bmad-core → bmad-core}/tasks/generate-ai-frontend-prompt.md +0 -0
  98. /package/{.bmad-core → bmad-core}/tasks/index-docs.md +0 -0
  99. /package/{.bmad-core → bmad-core}/templates/agent-tmpl.md +0 -0
  100. /package/{.bmad-core → bmad-core}/templates/brownfield-prd-tmpl.md +0 -0
  101. /package/{.bmad-core → bmad-core}/templates/competitor-analysis-tmpl.md +0 -0
  102. /package/{.bmad-core → bmad-core}/templates/expansion-pack-plan-tmpl.md +0 -0
  103. /package/{.bmad-core → bmad-core}/templates/front-end-architecture-tmpl.md +0 -0
  104. /package/{.bmad-core → bmad-core}/templates/fullstack-architecture-tmpl.md +0 -0
  105. /package/{.bmad-core → bmad-core}/templates/market-research-tmpl.md +0 -0
  106. /package/{.bmad-core → bmad-core}/templates/prd-tmpl.md +0 -0
  107. /package/{.bmad-core → bmad-core}/templates/project-brief-tmpl.md +0 -0
  108. /package/{.bmad-core → bmad-core}/templates/simple-project-prd-tmpl.md +0 -0
  109. /package/{.bmad-core → bmad-core}/templates/story-tmpl.md +0 -0
  110. /package/{.bmad-core → bmad-core}/templates/web-agent-startup-instructions-template.md +0 -0
  111. /package/{.bmad-core → bmad-core}/utils/template-format.md +0 -0
  112. /package/{.bmad-core → bmad-core}/web-bundles/agents/analyst.txt +0 -0
  113. /package/{.bmad-core → bmad-core}/web-bundles/agents/dev.txt +0 -0
  114. /package/{.bmad-core → bmad-core}/web-bundles/agents/sm.txt +0 -0
  115. /package/{.bmad-core → bmad-core}/workflows/brownfield-fullstack.yml +0 -0
  116. /package/{.bmad-core → bmad-core}/workflows/brownfield-service.yml +0 -0
  117. /package/{.bmad-core → bmad-core}/workflows/brownfield-ui.yml +0 -0
  118. /package/{.bmad-core → bmad-core}/workflows/greenfield-fullstack.yml +0 -0
  119. /package/{.bmad-core → bmad-core}/workflows/greenfield-service.yml +0 -0
  120. /package/{.bmad-core → bmad-core}/workflows/greenfield-ui.yml +0 -0
  121. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/agents/infra-devops-platform.md +0 -0
  122. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/checklists/infrastructure-checklist.md +0 -0
  123. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/create-doc.md +0 -0
  124. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/review-infrastructure.md +0 -0
  125. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/validate-infrastructure.md +0 -0
  126. /package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/templates/infrastructure-architecture-tmpl.md +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.4.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": {
@@ -48,7 +48,7 @@
48
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",
@@ -69,7 +69,7 @@
69
69
  ".roomodes": [
70
70
  "node tools/yaml-format.js"
71
71
  ],
72
- ".bmad-core/**/*.yml": [
72
+ "bmad-core/**/*.yml": [
73
73
  "node tools/yaml-format.js"
74
74
  ],
75
75
  ".github/**/*.yml": [
@@ -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() {
@@ -138,6 +138,195 @@ class WebBuilder {
138
138
  }
139
139
  }
140
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
+
141
330
  listAgents() {
142
331
  return this.resolver.listAgents();
143
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')
@@ -47,7 +47,8 @@ program
47
47
  .option('-f, --full', 'Install complete .bmad-core folder')
48
48
  .option('-a, --agent <agent>', 'Install specific agent with dependencies')
49
49
  .option('-d, --directory <path>', 'Installation directory (default: .bmad-core)')
50
- .option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo)')
50
+ .option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo, other)')
51
+ .option('-e, --expansion-packs <packs...>', 'Install specific expansion packs (can specify multiple)')
51
52
  .action(async (options) => {
52
53
  try {
53
54
  await initializeModules();
@@ -61,7 +62,8 @@ program
61
62
  installType: options.full ? 'full' : 'single-agent',
62
63
  agent: options.agent,
63
64
  directory: options.directory || '.bmad-core',
64
- ides: options.ide || []
65
+ ides: (options.ide || []).filter(ide => ide !== 'other'),
66
+ expansionPacks: options.expansionPacks || []
65
67
  };
66
68
  await installer.install(config);
67
69
  }
@@ -100,6 +102,19 @@ program
100
102
  }
101
103
  });
102
104
 
105
+ program
106
+ .command('list:expansions')
107
+ .description('List available expansion packs')
108
+ .action(async () => {
109
+ try {
110
+ await installer.listExpansionPacks();
111
+ } catch (error) {
112
+ if (!chalk) await initializeModules();
113
+ console.error(chalk.red('Error:'), error.message);
114
+ process.exit(1);
115
+ }
116
+ });
117
+
103
118
  program
104
119
  .command('status')
105
120
  .description('Show installation status')
@@ -124,8 +139,13 @@ async function promptInstallation() {
124
139
  {
125
140
  type: 'input',
126
141
  name: 'directory',
127
- message: 'Where would you like to install BMAD?',
128
- default: '.bmad-core'
142
+ message: 'Enter the full path to your project directory where BMAD should be installed:',
143
+ validate: (input) => {
144
+ if (!input.trim()) {
145
+ return 'Please enter a valid project path';
146
+ }
147
+ return true;
148
+ }
129
149
  }
130
150
  ]);
131
151
  answers.directory = directory;
@@ -167,6 +187,41 @@ async function promptInstallation() {
167
187
  answers.agent = agent;
168
188
  }
169
189
 
190
+ // Ask for expansion pack selection (only for full installation)
191
+ if (installType === 'full') {
192
+ try {
193
+ const availableExpansionPacks = await installer.getAvailableExpansionPacks();
194
+
195
+ if (availableExpansionPacks.length > 0) {
196
+ const { expansionPacks } = await inquirer.prompt([
197
+ {
198
+ type: 'checkbox',
199
+ name: 'expansionPacks',
200
+ message: 'Select expansion packs to install (optional):',
201
+ choices: [
202
+ { name: 'BMAD Core only (no expansion packs)', value: 'none', checked: true },
203
+ new inquirer.Separator(' --- Expansion Packs ---'),
204
+ ...availableExpansionPacks.map(pack => ({
205
+ name: `${pack.name} - ${pack.description}`,
206
+ value: pack.id
207
+ }))
208
+ ]
209
+ }
210
+ ]);
211
+
212
+ // Filter out 'none' selection and only include actual expansion packs
213
+ answers.expansionPacks = expansionPacks.filter(pack => pack !== 'none');
214
+ } else {
215
+ answers.expansionPacks = [];
216
+ }
217
+ } catch (error) {
218
+ console.warn(chalk.yellow('Warning: Could not load expansion packs. Continuing without them.'));
219
+ answers.expansionPacks = [];
220
+ }
221
+ } else {
222
+ answers.expansionPacks = [];
223
+ }
224
+
170
225
  // Ask for IDE configuration
171
226
  const { ides } = await inquirer.prompt([
172
227
  {
@@ -177,17 +232,20 @@ async function promptInstallation() {
177
232
  { name: 'Cursor', value: 'cursor' },
178
233
  { name: 'Claude Code', value: 'claude-code' },
179
234
  { name: 'Windsurf', value: 'windsurf' },
180
- { name: 'Roo Code', value: 'roo' }
235
+ { name: 'Roo Code', value: 'roo' },
236
+ { name: 'Other (skip IDE setup)', value: 'other' }
181
237
  ],
182
238
  validate: (answer) => {
183
239
  if (answer.length < 1) {
184
- return 'You must choose at least one IDE, or press Ctrl+C to skip IDE setup.';
240
+ return 'You must choose at least one IDE option.';
185
241
  }
186
242
  return true;
187
243
  }
188
244
  }
189
245
  ]);
190
- answers.ides = ides;
246
+
247
+ // Filter out 'other' from the list and only include actual IDEs
248
+ answers.ides = ides.filter(ide => ide !== 'other');
191
249
 
192
250
  return answers;
193
251
  }
@@ -3,55 +3,55 @@ installation-options:
3
3
  name: Complete BMAD Core
4
4
  description: Copy the entire .bmad-core folder with all agents, templates, and tools
5
5
  action: copy-folder
6
- source: .bmad-core
6
+ source: bmad-core
7
7
  single-agent:
8
8
  name: Single Agent
9
9
  description: Select and install a single agent with its dependencies
10
10
  action: copy-agent
11
11
  agent-dependencies:
12
12
  core-files:
13
- - .bmad-core/utils/template-format.md
13
+ - bmad-core/utils/template-format.md
14
14
  dev:
15
- - .bmad-core/templates/story-tmpl.md
16
- - .bmad-core/checklists/story-dod-checklist.md
15
+ - bmad-core/templates/story-tmpl.md
16
+ - bmad-core/checklists/story-dod-checklist.md
17
17
  pm:
18
- - .bmad-core/templates/prd-tmpl.md
19
- - .bmad-core/templates/brownfield-prd-tmpl.md
20
- - .bmad-core/checklists/pm-checklist.md
21
- - .bmad-core/checklists/change-checklist.md
22
- - .bmad-core/tasks/advanced-elicitation.md
23
- - .bmad-core/tasks/create-doc.md
24
- - .bmad-core/tasks/correct-course.md
25
- - .bmad-core/tasks/create-deep-research-prompt.md
26
- - .bmad-core/tasks/brownfield-create-epic.md
27
- - .bmad-core/tasks/brownfield-create-story.md
28
- - .bmad-core/tasks/execute-checklist.md
29
- - .bmad-core/tasks/shard-doc.md
18
+ - bmad-core/templates/prd-tmpl.md
19
+ - bmad-core/templates/brownfield-prd-tmpl.md
20
+ - bmad-core/checklists/pm-checklist.md
21
+ - bmad-core/checklists/change-checklist.md
22
+ - bmad-core/tasks/advanced-elicitation.md
23
+ - bmad-core/tasks/create-doc.md
24
+ - bmad-core/tasks/correct-course.md
25
+ - bmad-core/tasks/create-deep-research-prompt.md
26
+ - bmad-core/tasks/brownfield-create-epic.md
27
+ - bmad-core/tasks/brownfield-create-story.md
28
+ - bmad-core/tasks/execute-checklist.md
29
+ - bmad-core/tasks/shard-doc.md
30
30
  architect:
31
- - .bmad-core/templates/architecture-tmpl.md
32
- - .bmad-core/checklists/architect-checklist.md
31
+ - bmad-core/templates/architecture-tmpl.md
32
+ - bmad-core/checklists/architect-checklist.md
33
33
  sm:
34
- - .bmad-core/templates/story-tmpl.md
35
- - .bmad-core/checklists/story-draft-checklist.md
36
- - .bmad-core/workflows/*.yml
34
+ - bmad-core/templates/story-tmpl.md
35
+ - bmad-core/checklists/story-draft-checklist.md
36
+ - bmad-core/workflows/*.yml
37
37
  po:
38
- - .bmad-core/checklists/po-master-checklist.md
39
- - .bmad-core/templates/acceptance-criteria-tmpl.md
38
+ - bmad-core/checklists/po-master-checklist.md
39
+ - bmad-core/templates/acceptance-criteria-tmpl.md
40
40
  analyst:
41
- - .bmad-core/templates/prd-tmpl.md
42
- - .bmad-core/tasks/advanced-elicitation.md
41
+ - bmad-core/templates/prd-tmpl.md
42
+ - bmad-core/tasks/advanced-elicitation.md
43
43
  qa:
44
- - .bmad-core/checklists/story-dod-checklist.md
45
- - .bmad-core/templates/test-plan-tmpl.md
44
+ - bmad-core/checklists/story-dod-checklist.md
45
+ - bmad-core/templates/test-plan-tmpl.md
46
46
  ux-expert:
47
- - .bmad-core/templates/ux-tmpl.md
47
+ - bmad-core/templates/ux-tmpl.md
48
48
  bmad-master:
49
- - .bmad-core/templates/*.md
50
- - .bmad-core/tasks/*.md
51
- - .bmad-core/schemas/*.yml
49
+ - bmad-core/templates/*.md
50
+ - bmad-core/tasks/*.md
51
+ - bmad-core/schemas/*.yml
52
52
  bmad-orchestrator:
53
- - .bmad-core/agent-teams/*.yml
54
- - .bmad-core/workflows/*.yml
53
+ - bmad-core/agent-teams/*.yml
54
+ - bmad-core/workflows/*.yml
55
55
  ide-configurations:
56
56
  cursor:
57
57
  name: Cursor
@@ -99,41 +99,41 @@ ide-configurations:
99
99
  available-agents:
100
100
  - id: analyst
101
101
  name: Business Analyst
102
- file: .bmad-core/agents/analyst.md
102
+ file: bmad-core/agents/analyst.md
103
103
  description: Requirements gathering and analysis
104
104
  - id: pm
105
105
  name: Product Manager
106
- file: .bmad-core/agents/pm.md
106
+ file: bmad-core/agents/pm.md
107
107
  description: Product strategy and roadmap planning
108
108
  - id: architect
109
109
  name: Solution Architect
110
- file: .bmad-core/agents/architect.md
110
+ file: bmad-core/agents/architect.md
111
111
  description: Technical design and architecture
112
112
  - id: po
113
113
  name: Product Owner
114
- file: .bmad-core/agents/po.md
114
+ file: bmad-core/agents/po.md
115
115
  description: Backlog management and prioritization
116
116
  - id: sm
117
117
  name: Scrum Master
118
- file: .bmad-core/agents/sm.md
118
+ file: bmad-core/agents/sm.md
119
119
  description: Agile process and story creation
120
120
  - id: dev
121
121
  name: Developer
122
- file: .bmad-core/agents/dev.md
122
+ file: bmad-core/agents/dev.md
123
123
  description: Code implementation and testing
124
124
  - id: qa
125
125
  name: QA Engineer
126
- file: .bmad-core/agents/qa.md
126
+ file: bmad-core/agents/qa.md
127
127
  description: Quality assurance and testing
128
128
  - id: ux-expert
129
129
  name: UX Expert
130
- file: .bmad-core/agents/ux-expert.md
130
+ file: bmad-core/agents/ux-expert.md
131
131
  description: User experience design
132
132
  - id: bmad-master
133
133
  name: BMAD Master
134
- file: .bmad-core/agents/bmad-master.md
134
+ file: bmad-core/agents/bmad-master.md
135
135
  description: BMAD framework expert and guide
136
136
  - id: bmad-orchestrator
137
137
  name: BMAD Orchestrator
138
- file: .bmad-core/agents/bmad-orchestrator.md
138
+ file: bmad-core/agents/bmad-orchestrator.md
139
139
  description: Multi-agent workflow coordinator
@@ -30,6 +30,43 @@ class ConfigLoader {
30
30
  return config['available-agents'] || [];
31
31
  }
32
32
 
33
+ async getAvailableExpansionPacks() {
34
+ const expansionPacksDir = path.join(this.getBmadCorePath(), '..', 'expansion-packs');
35
+
36
+ try {
37
+ const entries = await fs.readdir(expansionPacksDir, { withFileTypes: true });
38
+ const expansionPacks = [];
39
+
40
+ for (const entry of entries) {
41
+ if (entry.isDirectory()) {
42
+ const manifestPath = path.join(expansionPacksDir, entry.name, 'manifest.yml');
43
+
44
+ try {
45
+ const manifestContent = await fs.readFile(manifestPath, 'utf8');
46
+ const manifest = yaml.load(manifestContent);
47
+
48
+ expansionPacks.push({
49
+ id: entry.name,
50
+ name: manifest.name || entry.name,
51
+ description: manifest.description || 'No description available',
52
+ version: manifest.version || '1.0.0',
53
+ author: manifest.author || 'Unknown',
54
+ manifestPath: manifestPath,
55
+ dependencies: manifest.dependencies || []
56
+ });
57
+ } catch (error) {
58
+ console.warn(`Failed to read manifest for expansion pack ${entry.name}: ${error.message}`);
59
+ }
60
+ }
61
+ }
62
+
63
+ return expansionPacks;
64
+ } catch (error) {
65
+ console.warn(`Failed to read expansion packs directory: ${error.message}`);
66
+ return [];
67
+ }
68
+ }
69
+
33
70
  async getAgentDependencies(agentId) {
34
71
  // Use DependencyResolver to dynamically parse agent dependencies
35
72
  const DependencyResolver = require('../../lib/dependency-resolver');
@@ -77,8 +114,8 @@ class ConfigLoader {
77
114
  }
78
115
 
79
116
  getBmadCorePath() {
80
- // Get the path to .bmad-core relative to the installer (now under tools)
81
- return path.join(__dirname, '..', '..', '..', '.bmad-core');
117
+ // Get the path to bmad-core relative to the installer (now under tools)
118
+ return path.join(__dirname, '..', '..', '..', 'bmad-core');
82
119
  }
83
120
 
84
121
  getAgentPath(agentId) {