bmad-method 4.27.4 → 4.27.6

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 (46) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/CONTRIBUTING.md +2 -2
  3. package/bmad-core/agents/analyst.md +3 -4
  4. package/bmad-core/agents/architect.md +3 -4
  5. package/bmad-core/agents/bmad-master.md +9 -32
  6. package/bmad-core/agents/bmad-orchestrator.md +3 -8
  7. package/bmad-core/agents/dev.md +3 -4
  8. package/bmad-core/agents/pm.md +3 -4
  9. package/bmad-core/agents/po.md +3 -4
  10. package/bmad-core/agents/qa.md +3 -4
  11. package/bmad-core/agents/sm.md +3 -4
  12. package/bmad-core/agents/ux-expert.md +3 -4
  13. package/bmad-core/data/bmad-kb.md +3 -3
  14. package/bmad-core/tasks/create-next-story.md +0 -1
  15. package/bmad-core/tasks/validate-next-story.md +1 -1
  16. package/bmad-core/workflows/brownfield-fullstack.yaml +1 -1
  17. package/bmad-core/workflows/brownfield-service.yaml +1 -1
  18. package/bmad-core/workflows/brownfield-ui.yaml +1 -1
  19. package/bmad-core/workflows/greenfield-fullstack.yaml +1 -1
  20. package/bmad-core/workflows/greenfield-ui.yaml +1 -1
  21. package/dist/agents/analyst.txt +3 -3
  22. package/dist/agents/bmad-master.txt +7 -324
  23. package/dist/agents/bmad-orchestrator.txt +3 -229
  24. package/dist/agents/dev.txt +1 -1
  25. package/dist/agents/po.txt +1 -1
  26. package/dist/agents/sm.txt +0 -1
  27. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +0 -226
  28. package/dist/teams/team-all.txt +9 -236
  29. package/dist/teams/team-fullstack.txt +9 -235
  30. package/dist/teams/team-ide-minimal.txt +4 -231
  31. package/dist/teams/team-no-ui.txt +5 -231
  32. package/{GUIDING-PRINCIPLES.md → docs/GUIDING-PRINCIPLES.md} +19 -13
  33. package/docs/template-markup-references.md +86 -0
  34. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +2 -3
  35. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +2 -3
  36. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +2 -3
  37. package/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.md +2 -3
  38. package/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.md +2 -3
  39. package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +307 -2
  40. package/package.json +1 -1
  41. package/tools/installer/bin/bmad.js +83 -0
  42. package/tools/installer/lib/file-manager.js +105 -2
  43. package/tools/installer/lib/ide-setup.js +41 -33
  44. package/tools/installer/lib/installer.js +62 -26
  45. package/tools/installer/package.json +1 -1
  46. package/bmad-core/utils/plan-management.md +0 -219
@@ -244,7 +244,7 @@ class Installer {
244
244
  spinner.text = "Copying complete .bmad-core folder...";
245
245
  const sourceDir = configLoader.getBmadCorePath();
246
246
  const bmadCoreDestDir = path.join(installDir, ".bmad-core");
247
- await fileManager.copyDirectory(sourceDir, bmadCoreDestDir);
247
+ await fileManager.copyDirectoryWithRootReplacement(sourceDir, bmadCoreDestDir, ".bmad-core");
248
248
 
249
249
  // Copy common/ items to .bmad-core
250
250
  spinner.text = "Copying common utilities...";
@@ -263,7 +263,7 @@ class Installer {
263
263
  // Single agent installation
264
264
  spinner.text = `Installing ${config.agent} agent...`;
265
265
 
266
- // Copy agent file
266
+ // Copy agent file with {root} replacement
267
267
  const agentPath = configLoader.getAgentPath(config.agent);
268
268
  const destAgentPath = path.join(
269
269
  installDir,
@@ -271,7 +271,7 @@ class Installer {
271
271
  "agents",
272
272
  `${config.agent}.md`
273
273
  );
274
- await fileManager.copyFile(agentPath, destAgentPath);
274
+ await fileManager.copyFileWithRootReplacement(agentPath, destAgentPath, ".bmad-core");
275
275
  files.push(`.bmad-core/agents/${config.agent}.md`);
276
276
 
277
277
  // Copy dependencies
@@ -284,15 +284,16 @@ class Installer {
284
284
  spinner.text = `Copying dependency: ${dep}`;
285
285
 
286
286
  if (dep.includes("*")) {
287
- // Handle glob patterns
287
+ // Handle glob patterns with {root} replacement
288
288
  const copiedFiles = await fileManager.copyGlobPattern(
289
289
  dep.replace(".bmad-core/", ""),
290
290
  sourceBase,
291
- path.join(installDir, ".bmad-core")
291
+ path.join(installDir, ".bmad-core"),
292
+ ".bmad-core"
292
293
  );
293
294
  files.push(...copiedFiles.map(f => `.bmad-core/${f}`));
294
295
  } else {
295
- // Handle single files
296
+ // Handle single files with {root} replacement if needed
296
297
  const sourcePath = path.join(
297
298
  sourceBase,
298
299
  dep.replace(".bmad-core/", "")
@@ -302,7 +303,16 @@ class Installer {
302
303
  dep
303
304
  );
304
305
 
305
- if (await fileManager.copyFile(sourcePath, destPath)) {
306
+ const needsRootReplacement = dep.endsWith('.md') || dep.endsWith('.yaml') || dep.endsWith('.yml');
307
+ let success = false;
308
+
309
+ if (needsRootReplacement) {
310
+ success = await fileManager.copyFileWithRootReplacement(sourcePath, destPath, ".bmad-core");
311
+ } else {
312
+ success = await fileManager.copyFile(sourcePath, destPath);
313
+ }
314
+
315
+ if (success) {
306
316
  files.push(dep);
307
317
  }
308
318
  }
@@ -325,19 +335,29 @@ class Installer {
325
335
  spinner.text = `Copying team dependency: ${dep}`;
326
336
 
327
337
  if (dep.includes("*")) {
328
- // Handle glob patterns
338
+ // Handle glob patterns with {root} replacement
329
339
  const copiedFiles = await fileManager.copyGlobPattern(
330
340
  dep.replace(".bmad-core/", ""),
331
341
  sourceBase,
332
- path.join(installDir, ".bmad-core")
342
+ path.join(installDir, ".bmad-core"),
343
+ ".bmad-core"
333
344
  );
334
345
  files.push(...copiedFiles.map(f => `.bmad-core/${f}`));
335
346
  } else {
336
- // Handle single files
347
+ // Handle single files with {root} replacement if needed
337
348
  const sourcePath = path.join(sourceBase, dep.replace(".bmad-core/", ""));
338
349
  const destPath = path.join(installDir, dep);
339
350
 
340
- if (await fileManager.copyFile(sourcePath, destPath)) {
351
+ const needsRootReplacement = dep.endsWith('.md') || dep.endsWith('.yaml') || dep.endsWith('.yml');
352
+ let success = false;
353
+
354
+ if (needsRootReplacement) {
355
+ success = await fileManager.copyFileWithRootReplacement(sourcePath, destPath, ".bmad-core");
356
+ } else {
357
+ success = await fileManager.copyFile(sourcePath, destPath);
358
+ }
359
+
360
+ if (success) {
341
361
  files.push(dep);
342
362
  }
343
363
  }
@@ -373,10 +393,17 @@ class Installer {
373
393
  if (ides.length > 0) {
374
394
  for (const ide of ides) {
375
395
  spinner.text = `Setting up ${ide} integration...`;
376
- await ideSetup.setup(ide, installDir, config.agent, spinner);
396
+ const preConfiguredSettings = ide === 'github-copilot' ? config.githubCopilotConfig : null;
397
+ await ideSetup.setup(ide, installDir, config.agent, spinner, preConfiguredSettings);
377
398
  }
378
399
  }
379
400
 
401
+ // Modify core-config.yaml if sharding preferences were provided
402
+ if (config.installType !== "expansion-only" && (config.prdSharded !== undefined || config.architectureSharded !== undefined)) {
403
+ spinner.text = "Configuring document sharding settings...";
404
+ await fileManager.modifyCoreConfig(installDir, config);
405
+ }
406
+
380
407
  // Create manifest (skip for expansion-only installations)
381
408
  if (config.installType !== "expansion-only") {
382
409
  spinner.text = "Creating installation manifest...";
@@ -1165,32 +1192,41 @@ class Installer {
1165
1192
  nodir: true
1166
1193
  });
1167
1194
 
1168
- // Copy each file to the expansion pack's dot folder
1195
+ // Copy each file to the expansion pack's dot folder with {root} replacement
1169
1196
  for (const file of files) {
1170
1197
  const sourcePath = path.join(sourceFolder, file);
1171
1198
  const destPath = path.join(expansionDotFolder, folder, file);
1172
1199
 
1173
- if (await fileManager.copyFile(sourcePath, destPath)) {
1200
+ const needsRootReplacement = file.endsWith('.md') || file.endsWith('.yaml') || file.endsWith('.yml');
1201
+ let success = false;
1202
+
1203
+ if (needsRootReplacement) {
1204
+ success = await fileManager.copyFileWithRootReplacement(sourcePath, destPath, `.${packId}`);
1205
+ } else {
1206
+ success = await fileManager.copyFile(sourcePath, destPath);
1207
+ }
1208
+
1209
+ if (success) {
1174
1210
  installedFiles.push(path.join(`.${packId}`, folder, file));
1175
1211
  }
1176
1212
  }
1177
1213
  }
1178
1214
  }
1179
1215
 
1180
- // Copy config.yaml
1216
+ // Copy config.yaml with {root} replacement
1181
1217
  const configPath = path.join(expansionPackDir, 'config.yaml');
1182
1218
  if (await fileManager.pathExists(configPath)) {
1183
1219
  const configDestPath = path.join(expansionDotFolder, 'config.yaml');
1184
- if (await fileManager.copyFile(configPath, configDestPath)) {
1220
+ if (await fileManager.copyFileWithRootReplacement(configPath, configDestPath, `.${packId}`)) {
1185
1221
  installedFiles.push(path.join(`.${packId}`, 'config.yaml'));
1186
1222
  }
1187
1223
  }
1188
1224
 
1189
- // Copy README if it exists
1225
+ // Copy README if it exists with {root} replacement
1190
1226
  const readmePath = path.join(expansionPackDir, 'README.md');
1191
1227
  if (await fileManager.pathExists(readmePath)) {
1192
1228
  const readmeDestPath = path.join(expansionDotFolder, 'README.md');
1193
- if (await fileManager.copyFile(readmePath, readmeDestPath)) {
1229
+ if (await fileManager.copyFileWithRootReplacement(readmePath, readmeDestPath, `.${packId}`)) {
1194
1230
  installedFiles.push(path.join(`.${packId}`, 'README.md'));
1195
1231
  }
1196
1232
  }
@@ -1251,7 +1287,7 @@ class Installer {
1251
1287
  const yamlContent = extractYamlFromAgent(agentContent);
1252
1288
  if (yamlContent) {
1253
1289
  try {
1254
- const agentConfig = yaml.parse(yamlContent);
1290
+ const agentConfig = yaml.load(yamlContent);
1255
1291
  const dependencies = agentConfig.dependencies || {};
1256
1292
 
1257
1293
  // Check for core dependencies (those that don't exist in the expansion pack)
@@ -1270,9 +1306,9 @@ class Installer {
1270
1306
  if (await fileManager.pathExists(coreDepPath)) {
1271
1307
  spinner.text = `Copying core dependency ${dep} for ${packId}...`;
1272
1308
 
1273
- // Copy from core to expansion pack dot folder
1309
+ // Copy from core to expansion pack dot folder with {root} replacement
1274
1310
  const destPath = path.join(expansionDotFolder, depType, depFileName);
1275
- await fileManager.copyFile(coreDepPath, destPath);
1311
+ await fileManager.copyFileWithRootReplacement(coreDepPath, destPath, `.${packId}`);
1276
1312
 
1277
1313
  console.log(chalk.dim(` Added core dependency: ${depType}/${depFileName}`));
1278
1314
  } else {
@@ -1314,7 +1350,7 @@ class Installer {
1314
1350
  const teamContent = await fs.readFile(teamPath, 'utf8');
1315
1351
 
1316
1352
  try {
1317
- const teamConfig = yaml.parse(teamContent);
1353
+ const teamConfig = yaml.load(teamContent);
1318
1354
  const agents = teamConfig.agents || [];
1319
1355
 
1320
1356
  // Add bmad-orchestrator if not present (required for all teams)
@@ -1331,9 +1367,9 @@ class Installer {
1331
1367
  if (await fileManager.pathExists(coreAgentPath)) {
1332
1368
  spinner.text = `Copying core agent ${agentId} for ${packId}...`;
1333
1369
 
1334
- // Copy agent file
1370
+ // Copy agent file with {root} replacement
1335
1371
  const destPath = path.join(expansionDotFolder, 'agents', `${agentId}.md`);
1336
- await fileManager.copyFile(coreAgentPath, destPath);
1372
+ await fileManager.copyFileWithRootReplacement(coreAgentPath, destPath, `.${packId}`);
1337
1373
  existingAgents.add(agentId);
1338
1374
 
1339
1375
  console.log(chalk.dim(` Added core agent: ${agentId}`));
@@ -1345,7 +1381,7 @@ class Installer {
1345
1381
  if (yamlContent) {
1346
1382
  try {
1347
1383
 
1348
- const agentConfig = yaml.parse(yamlContent);
1384
+ const agentConfig = yaml.load(yamlContent);
1349
1385
  const dependencies = agentConfig.dependencies || {};
1350
1386
 
1351
1387
  // Copy all dependencies for this agent
@@ -1363,7 +1399,7 @@ class Installer {
1363
1399
 
1364
1400
  if (await fileManager.pathExists(coreDepPath)) {
1365
1401
  const destDepPath = path.join(expansionDotFolder, depType, depFileName);
1366
- await fileManager.copyFile(coreDepPath, destDepPath);
1402
+ await fileManager.copyFileWithRootReplacement(coreDepPath, destDepPath, `.${packId}`);
1367
1403
  console.log(chalk.dim(` Added agent dependency: ${depType}/${depFileName}`));
1368
1404
  } else {
1369
1405
  // Try common folder
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.27.4",
3
+ "version": "4.27.6",
4
4
  "description": "BMad Method installer - AI-powered Agile development framework",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {
@@ -1,219 +0,0 @@
1
- # Plan Management Utility
2
-
3
- ## Purpose
4
-
5
- Provides utilities for agents and tasks to interact with workflow plans, check progress, update status, and ensure workflow steps are executed in the appropriate sequence.
6
-
7
- ## Core Functions
8
-
9
- ### 1. Check Plan Existence
10
-
11
- Check for workflow plan:
12
-
13
- 1. Look for docs/workflow-plan.md (default location)
14
- 2. Return plan status to user (exists/not exists) - if not exists then HALT.
15
-
16
- ### 2. Parse Plan Status
17
-
18
- [[LLM: Extract current progress from the plan document]]
19
-
20
- **Plan Parsing Logic:**
21
-
22
- 1. **Identify Step Structure**:
23
- - Look for checkbox lines: `- [ ]` or `- [x]`
24
- - Extract step IDs from comments: `<!-- step-id: X.Y -->`
25
- - Identify agent assignments: `<!-- agent: pm -->`
26
-
27
- 2. **Determine Current State**:
28
- - Last completed step (highest numbered `[x]`)
29
- - Next expected step (first `[ ]` after completed steps)
30
- - Overall progress percentage
31
-
32
- 3. **Extract Metadata**:
33
- - Workflow type from plan header
34
- - Decision points and their status
35
- - Any deviation notes
36
-
37
- ### 3. Sequence Validation
38
-
39
- [[LLM: Check if requested action aligns with plan sequence]]
40
-
41
- **Validation Rules:**
42
-
43
- 1. **Strict Mode** (enforceSequence: true):
44
- - Must complete steps in exact order
45
- - Warn and block if out of sequence
46
- - Require explicit override justification
47
-
48
- 2. **Flexible Mode** (enforceSequence: false):
49
- - Warn about sequence deviation
50
- - Allow with confirmation
51
- - Log deviation reason
52
-
53
- **Warning Templates:**
54
-
55
- ```text
56
- SEQUENCE WARNING:
57
- The workflow plan shows you should complete "{expected_step}" next.
58
- You're attempting to: "{requested_action}"
59
-
60
- In strict mode: Block and require plan update
61
- In flexible mode: Allow with confirmation
62
- ```
63
-
64
- ### 4. Plan Update Operations
65
-
66
- [[LLM: Provide consistent way to update plan progress]]
67
-
68
- **Update Actions:**
69
-
70
- 1. **Mark Step Complete**:
71
- - Change `- [ ]` to `- [x]`
72
- - Add completion timestamp comment
73
- - Update any status metadata
74
-
75
- 2. **Add Deviation Note**:
76
- - Insert note explaining why sequence changed
77
- - Reference the deviation in plan
78
-
79
- 3. **Update Current Step Pointer**:
80
- - Add/move `<!-- current-step -->` marker
81
- - Update last-modified timestamp
82
-
83
- ### 5. Integration Instructions
84
-
85
- [[LLM: How agents and tasks should use this utility]]
86
-
87
- **For Agents (startup sequence)**:
88
-
89
- ```text
90
- 1. Check if plan exists using this utility
91
- 2. If exists:
92
- - Parse current status
93
- - Show user: "Active workflow plan detected. Current step: {X}"
94
- - Suggest: "Next recommended action: {next_step}"
95
- 3. Continue with normal startup
96
- ```
97
-
98
- **For Tasks (pre-execution)**:
99
-
100
- ```text
101
- 1. Check if plan exists
102
- 2. If exists:
103
- - Verify this task aligns with plan
104
- - If not aligned:
105
- - In strict mode: Show warning and stop
106
- - In flexible mode: Show warning and ask for confirmation
107
- 3. After task completion:
108
- - Update plan if task was a planned step
109
- - Add note if task was unplanned
110
- ```
111
-
112
- ### 6. Plan Status Report Format
113
-
114
- [[LLM: Standard format for showing plan status]]
115
-
116
- ```text
117
- 📋 Workflow Plan Status
118
- ━━━━━━━━━━━━━━━━━━━━
119
- Workflow: {workflow_name}
120
- Progress: {X}% complete ({completed}/{total} steps)
121
-
122
- ✅ Completed:
123
- - {completed_step_1}
124
- - {completed_step_2}
125
-
126
- 🔄 Current Step:
127
- - {current_step_description}
128
-
129
- 📌 Upcoming:
130
- - {next_step_1}
131
- - {next_step_2}
132
-
133
- ⚠️ Notes:
134
- - {any_deviations_or_notes}
135
- ```
136
-
137
- ### 7. Decision Point Handling
138
-
139
- [[LLM: Special handling for workflow decision points]]
140
-
141
- When encountering a decision point in the plan:
142
-
143
- 1. **Identify Decision Marker**: `<!-- decision: {decision_id} -->`
144
- 2. **Check Decision Status**: Made/Pending
145
- 3. **If Pending**:
146
- - Block progress until decision made
147
- - Show options to user
148
- - Record decision when made
149
- 4. **If Made**:
150
- - Verify current path aligns with decision
151
- - Warn if attempting alternate path
152
-
153
- ### 8. Plan Abandonment
154
-
155
- [[LLM: Graceful handling when user wants to stop following plan]]
156
-
157
- If user wants to abandon plan:
158
-
159
- 1. Confirm abandonment intent
160
- 2. Add abandonment note to plan
161
- 3. Mark plan as "Abandoned" in header
162
- 4. Stop plan checking for remainder of session
163
- 5. Suggest creating new plan if needed
164
-
165
- ## Usage Examples
166
-
167
- ### Example 1: Agent Startup Check
168
-
169
- ```text
170
- BMad Master starting...
171
-
172
- [Check for plan]
173
- Found active workflow plan: brownfield-fullstack
174
- Progress: 40% complete (4/10 steps)
175
- Current step: Create PRD (pm agent)
176
-
177
- Suggestion: Based on your plan, you should work with the PM agent next.
178
- Use *agent pm to switch, or *plan-status to see full progress.
179
- ```
180
-
181
- ### Example 2: Task Sequence Warning
182
-
183
- ```text
184
- User: *task create-next-story
185
-
186
- [Plan check triggered]
187
- ⚠️ SEQUENCE WARNING:
188
- Your workflow plan indicates the PRD hasn't been created yet.
189
- Creating stories before the PRD may lead to incomplete requirements.
190
-
191
- Would you like to:
192
- 1. Continue anyway (will note deviation in plan)
193
- 2. Switch to creating PRD first (*agent pm)
194
- 3. View plan status (*plan-status)
195
- ```
196
-
197
- ### Example 3: Automatic Plan Update
198
-
199
- ```text
200
- [After completing create-doc task for PRD]
201
-
202
- ✅ Plan Updated: Marked "Create PRD" as complete
203
- 📍 Next step: Create Architecture Document (architect agent)
204
- ```
205
-
206
- ## Implementation Notes
207
-
208
- - This utility should be lightweight and fast
209
- - Plan parsing should be resilient to format variations
210
- - Always preserve user agency - warnings not blocks (unless strict mode)
211
- - Plan updates should be atomic to prevent corruption
212
- - Consider plan versioning for rollback capability
213
-
214
- ## Error Handling
215
-
216
- - Missing plan: Return null, don't error
217
- - Malformed plan: Warn but continue, treat as no plan
218
- - Update failures: Log but don't block task completion
219
- - Parse errors: Fallback to basic text search