bmad-method 4.6.3 → 4.8.0

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 (50) hide show
  1. package/.prettierignore +0 -1
  2. package/CHANGELOG.md +24 -0
  3. package/README.md +18 -1
  4. package/bmad-core/agents/analyst.md +11 -8
  5. package/bmad-core/agents/architect.md +10 -7
  6. package/bmad-core/agents/bmad-master.md +13 -11
  7. package/bmad-core/agents/bmad-orchestrator.md +3 -0
  8. package/bmad-core/agents/dev.md +19 -14
  9. package/bmad-core/agents/pm.md +8 -5
  10. package/bmad-core/agents/po.md +13 -10
  11. package/bmad-core/agents/qa.md +8 -5
  12. package/bmad-core/agents/sm.md +15 -25
  13. package/bmad-core/agents/ux-expert.md +11 -8
  14. package/bmad-core/core-config.yml +24 -0
  15. package/bmad-core/data/bmad-kb.md +391 -10
  16. package/bmad-core/tasks/create-next-story.md +63 -45
  17. package/bmad-core/utils/file-resolution-context.md +10 -0
  18. package/dist/agents/analyst.txt +404 -17
  19. package/dist/agents/architect.txt +14 -6
  20. package/dist/agents/bmad-master.txt +485 -109
  21. package/dist/agents/bmad-orchestrator.txt +402 -22
  22. package/dist/agents/dev.txt +26 -34
  23. package/dist/agents/pm.txt +9 -5
  24. package/dist/agents/po.txt +10 -10
  25. package/dist/agents/qa.txt +4 -4
  26. package/dist/agents/sm.txt +74 -63
  27. package/dist/agents/ux-expert.txt +9 -7
  28. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +49 -20
  29. package/dist/expansion-packs/expansion-creator/agents/bmad-the-creator.txt +6 -3
  30. package/dist/teams/team-all.txt +561 -158
  31. package/dist/teams/team-fullstack.txt +457 -57
  32. package/dist/teams/team-ide-minimal.txt +516 -133
  33. package/dist/teams/team-no-ui.txt +448 -50
  34. package/docs/bmad-workflow-guide.md +10 -8
  35. package/docs/claude-code-guide.md +1 -1
  36. package/docs/core-architecture.md +4 -4
  37. package/docs/cursor-guide.md +1 -1
  38. package/docs/roo-code-guide.md +1 -1
  39. package/docs/user-guide.md +30 -21
  40. package/docs/windsurf-guide.md +1 -1
  41. package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +3 -0
  42. package/expansion-packs/expansion-creator/templates/agent-tmpl.md +4 -1
  43. package/package.json +1 -1
  44. package/tools/builders/web-builder.js +158 -94
  45. package/tools/installer/bin/bmad.js +34 -2
  46. package/tools/installer/lib/file-manager.js +3 -2
  47. package/tools/installer/lib/ide-setup.js +39 -123
  48. package/tools/installer/lib/installer.js +13 -1
  49. package/tools/installer/package.json +1 -1
  50. /package/bmad-core/{templates/web-agent-startup-instructions-template.md → utils/web-agent-startup-instructions.md} +0 -0
@@ -39,20 +39,13 @@ class IdeSetup {
39
39
 
40
40
  async setupCursor(installDir, selectedAgent) {
41
41
  const cursorRulesDir = path.join(installDir, ".cursor", "rules");
42
- const agents = selectedAgent
43
- ? [selectedAgent]
44
- : await this.getAllAgentIds(installDir);
42
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
45
43
 
46
44
  await fileManager.ensureDirectory(cursorRulesDir);
47
45
 
48
46
  for (const agentId of agents) {
49
47
  // Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
50
- let agentPath = path.join(
51
- installDir,
52
- ".bmad-core",
53
- "agents",
54
- `${agentId}.md`
55
- );
48
+ let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
56
49
  if (!(await fileManager.pathExists(agentPath))) {
57
50
  agentPath = path.join(installDir, "agents", `${agentId}.md`);
58
51
  }
@@ -103,20 +96,13 @@ class IdeSetup {
103
96
 
104
97
  async setupClaudeCode(installDir, selectedAgent) {
105
98
  const commandsDir = path.join(installDir, ".claude", "commands");
106
- const agents = selectedAgent
107
- ? [selectedAgent]
108
- : await this.getAllAgentIds(installDir);
99
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
109
100
 
110
101
  await fileManager.ensureDirectory(commandsDir);
111
102
 
112
103
  for (const agentId of agents) {
113
104
  // Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
114
- let agentPath = path.join(
115
- installDir,
116
- ".bmad-core",
117
- "agents",
118
- `${agentId}.md`
119
- );
105
+ let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
120
106
  if (!(await fileManager.pathExists(agentPath))) {
121
107
  agentPath = path.join(installDir, "agents", `${agentId}.md`);
122
108
  }
@@ -136,29 +122,20 @@ class IdeSetup {
136
122
  }
137
123
  }
138
124
 
139
- console.log(
140
- chalk.green(`\n✓ Created Claude Code commands in ${commandsDir}`)
141
- );
125
+ console.log(chalk.green(`\n✓ Created Claude Code commands in ${commandsDir}`));
142
126
 
143
127
  return true;
144
128
  }
145
129
 
146
130
  async setupWindsurf(installDir, selectedAgent) {
147
131
  const windsurfRulesDir = path.join(installDir, ".windsurf", "rules");
148
- const agents = selectedAgent
149
- ? [selectedAgent]
150
- : await this.getAllAgentIds(installDir);
132
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
151
133
 
152
134
  await fileManager.ensureDirectory(windsurfRulesDir);
153
135
 
154
136
  for (const agentId of agents) {
155
137
  // Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
156
- let agentPath = path.join(
157
- installDir,
158
- ".bmad-core",
159
- "agents",
160
- `${agentId}.md`
161
- );
138
+ let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
162
139
  if (!(await fileManager.pathExists(agentPath))) {
163
140
  agentPath = path.join(installDir, "agents", `${agentId}.md`);
164
141
  }
@@ -197,9 +174,7 @@ class IdeSetup {
197
174
  }
198
175
  }
199
176
 
200
- console.log(
201
- chalk.green(`\n✓ Created Windsurf rules in ${windsurfRulesDir}`)
202
- );
177
+ console.log(chalk.green(`\n✓ Created Windsurf rules in ${windsurfRulesDir}`));
203
178
 
204
179
  return true;
205
180
  }
@@ -233,13 +208,7 @@ class IdeSetup {
233
208
  }
234
209
 
235
210
  async setupRoo(installDir, selectedAgent) {
236
- const agents = selectedAgent
237
- ? [selectedAgent]
238
- : await this.getAllAgentIds(installDir);
239
-
240
- // Create .roo directory first
241
- const rooDir = path.join(installDir, ".roo");
242
- await fileManager.ensureDirectory(rooDir);
211
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
243
212
 
244
213
  // Check for existing .roomodes file in project root
245
214
  const roomodesPath = path.join(installDir, ".roomodes");
@@ -253,11 +222,7 @@ class IdeSetup {
253
222
  for (const match of modeMatches) {
254
223
  existingModes.push(match[1]);
255
224
  }
256
- console.log(
257
- chalk.yellow(
258
- `Found existing .roomodes file with ${existingModes.length} modes`
259
- )
260
- );
225
+ console.log(chalk.yellow(`Found existing .roomodes file with ${existingModes.length} modes`));
261
226
  }
262
227
 
263
228
  // Create new modes content
@@ -265,55 +230,48 @@ class IdeSetup {
265
230
 
266
231
  // Define file permissions for each agent type
267
232
  const agentPermissions = {
268
- 'analyst': {
269
- fileRegex: '\\.(md|txt)$',
270
- description: 'Documentation and text files'
233
+ analyst: {
234
+ fileRegex: "\\.(md|txt)$",
235
+ description: "Documentation and text files",
271
236
  },
272
- 'pm': {
273
- fileRegex: '\\.(md|txt)$',
274
- description: 'Product documentation'
237
+ pm: {
238
+ fileRegex: "\\.(md|txt)$",
239
+ description: "Product documentation",
275
240
  },
276
- 'architect': {
277
- fileRegex: '\\.(md|txt|yml|yaml|json)$',
278
- description: 'Architecture docs and configs'
241
+ architect: {
242
+ fileRegex: "\\.(md|txt|yml|yaml|json)$",
243
+ description: "Architecture docs and configs",
279
244
  },
280
- 'dev': null, // Full edit access
281
- 'qa': {
282
- fileRegex: '\\.(test|spec)\\.(js|ts|jsx|tsx)$|\\.md$',
283
- description: 'Test files and documentation'
245
+ dev: null, // Full edit access
246
+ qa: {
247
+ fileRegex: "\\.(test|spec)\\.(js|ts|jsx|tsx)$|\\.md$",
248
+ description: "Test files and documentation",
284
249
  },
285
- 'ux-expert': {
286
- fileRegex: '\\.(md|css|scss|html|jsx|tsx)$',
287
- description: 'Design-related files'
250
+ "ux-expert": {
251
+ fileRegex: "\\.(md|css|scss|html|jsx|tsx)$",
252
+ description: "Design-related files",
288
253
  },
289
- 'po': {
290
- fileRegex: '\\.(md|txt)$',
291
- description: 'Story and requirement docs'
254
+ po: {
255
+ fileRegex: "\\.(md|txt)$",
256
+ description: "Story and requirement docs",
292
257
  },
293
- 'sm': {
294
- fileRegex: '\\.(md|txt)$',
295
- description: 'Process and planning docs'
258
+ sm: {
259
+ fileRegex: "\\.(md|txt)$",
260
+ description: "Process and planning docs",
296
261
  },
297
- 'bmad-orchestrator': null, // Full edit access
298
- 'bmad-master': null // Full edit access
262
+ "bmad-orchestrator": null, // Full edit access
263
+ "bmad-master": null, // Full edit access
299
264
  };
300
265
 
301
266
  for (const agentId of agents) {
302
267
  // Skip if already exists
303
268
  if (existingModes.includes(`bmad-${agentId}`)) {
304
- console.log(
305
- chalk.dim(`Skipping ${agentId} - already exists in .roomodes`)
306
- );
269
+ console.log(chalk.dim(`Skipping ${agentId} - already exists in .roomodes`));
307
270
  continue;
308
271
  }
309
272
 
310
273
  // Read agent file to extract all information
311
- let agentPath = path.join(
312
- installDir,
313
- ".bmad-core",
314
- "agents",
315
- `${agentId}.md`
316
- );
274
+ let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
317
275
  if (!(await fileManager.pathExists(agentPath))) {
318
276
  agentPath = path.join(installDir, "agents", `${agentId}.md`);
319
277
  }
@@ -334,9 +292,7 @@ class IdeSetup {
334
292
 
335
293
  const title = titleMatch ? titleMatch[1].trim() : this.getAgentTitle(agentId);
336
294
  const icon = iconMatch ? iconMatch[1].trim() : "🤖";
337
- const whenToUse = whenToUseMatch
338
- ? whenToUseMatch[1].trim()
339
- : `Use for ${title} tasks`;
295
+ const whenToUse = whenToUseMatch ? whenToUseMatch[1].trim() : `Use for ${title} tasks`;
340
296
  const roleDefinition = roleDefinitionMatch
341
297
  ? roleDefinitionMatch[1].trim()
342
298
  : `You are a ${title} specializing in ${title.toLowerCase()} tasks and responsibilities.`;
@@ -360,9 +316,7 @@ class IdeSetup {
360
316
  newModesContent += ` - edit\n`;
361
317
  }
362
318
 
363
- console.log(
364
- chalk.green(`✓ Added mode: bmad-${agentId} (${icon} ${title})`)
365
- );
319
+ console.log(chalk.green(`✓ Added mode: bmad-${agentId} (${icon} ${title})`));
366
320
  }
367
321
  }
368
322
  }
@@ -381,46 +335,8 @@ class IdeSetup {
381
335
  await fileManager.writeFile(roomodesPath, roomodesContent);
382
336
  console.log(chalk.green("✓ Created .roomodes file in project root"));
383
337
 
384
- // Create README in .roo directory
385
- const rooReadme = `# Roo Code Custom Modes for BMAD-METHOD
386
-
387
- This directory contains custom mode configurations for Roo Code to enable BMAD agent personalities.
388
-
389
- ## Setup
390
-
391
- The \`.roomodes\` file defines all BMAD agents as custom modes using the proper \`customModes:\` structure. Modes are automatically available in Roo Code when you open this project.
392
-
393
- ## Available Modes
394
-
395
- ${agents.map((id) => `- **bmad-${id}** - ${this.getAgentTitle(id)}`).join("\n")}
396
-
397
- ## Usage
398
-
399
- In Roo Code:
400
- 1. Open the mode selector (usually in the status bar)
401
- 2. Select any BMAD agent mode
402
- 3. The AI will adopt that agent's personality and expertise
403
-
404
- ## File Permissions
405
-
406
- Each agent has specific file access permissions:
407
- - **Analysts, PM, PO, SM**: Limited to documentation files (.md, .txt)
408
- - **Architect**: Architecture docs and configs (.md, .txt, .yml, .yaml, .json)
409
- - **QA**: Test files and documentation
410
- - **UX Expert**: Design-related files (.md, .css, .scss, .html, .jsx, .tsx)
411
- - **Developer, Orchestrator, Master**: Full edit access to all files
412
- `;
413
-
414
- const readmePath = path.join(rooDir, "README.md");
415
- await fileManager.writeFile(readmePath, rooReadme);
416
- console.log(chalk.green("✓ Created .roo/README.md"));
417
-
418
338
  console.log(chalk.green(`\n✓ Roo Code setup complete!`));
419
- console.log(
420
- chalk.dim(
421
- "Custom modes will be available when you open this project in Roo Code"
422
- )
423
- );
339
+ console.log(chalk.dim("Custom modes will be available when you open this project in Roo Code"));
424
340
 
425
341
  return true;
426
342
  }
@@ -102,6 +102,17 @@ class Installer {
102
102
  spinner.start("Analyzing installation directory...");
103
103
  }
104
104
 
105
+ // If this is an update request from early detection, handle it directly
106
+ if (config.installType === 'update') {
107
+ const state = await this.detectInstallationState(installDir);
108
+ if (state.type === 'v4_existing') {
109
+ return await this.performUpdate(config, installDir, state.manifest, spinner);
110
+ } else {
111
+ spinner.fail('No existing v4 installation found to update');
112
+ throw new Error('No existing v4 installation found');
113
+ }
114
+ }
115
+
105
116
  // Detect current state
106
117
  const state = await this.detectInstallationState(installDir);
107
118
 
@@ -541,7 +552,8 @@ class Installer {
541
552
  installType: manifest.install_type,
542
553
  agent: manifest.agent,
543
554
  directory: installDir,
544
- ide: newConfig.ide || manifest.ide_setup, // Use new IDE choice if provided
555
+ ide: newConfig?.ide || manifest.ide_setup, // Use new IDE choice if provided
556
+ ides: newConfig?.ides || manifest.ides_setup || [],
545
557
  };
546
558
 
547
559
  await this.performFreshInstall(config, installDir, spinner);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.6.3",
3
+ "version": "4.8.0",
4
4
  "description": "BMAD Method installer - AI-powered Agile development framework",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {