bmad-method 4.17.0 → 4.18.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 (45) hide show
  1. package/.claude/commands/bmad-master.md +0 -1
  2. package/CHANGELOG.md +8 -0
  3. package/{bmad-core → common}/tasks/create-doc.md +2 -2
  4. package/{expansion-packs/expansion-creator/common-tasks → common/tasks}/execute-checklist.md +2 -6
  5. package/common/utils/workflow-management.md +69 -0
  6. package/dist/agents/analyst.txt +2 -2
  7. package/dist/agents/architect.txt +4 -8
  8. package/dist/agents/bmad-master.txt +35 -270
  9. package/dist/agents/bmad-orchestrator.txt +33 -187
  10. package/dist/agents/dev.txt +2 -6
  11. package/dist/agents/pm.txt +4 -8
  12. package/dist/agents/po.txt +2 -6
  13. package/dist/agents/sm.txt +2 -6
  14. package/dist/agents/ux-expert.txt +4 -8
  15. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +4 -8
  16. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +2 -6
  17. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +2 -6
  18. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +35 -193
  19. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +2 -2
  20. package/dist/expansion-packs/expansion-creator/agents/bmad-the-creator.txt +5 -5
  21. package/dist/teams/team-all.txt +35 -193
  22. package/dist/teams/team-fullstack.txt +35 -193
  23. package/dist/teams/team-ide-minimal.txt +35 -193
  24. package/dist/teams/team-no-ui.txt +35 -193
  25. package/docs/working-in-the-brownfield.md +2 -2
  26. package/expansion-packs/expansion-creator/tasks/generate-expansion-pack.md +5 -5
  27. package/package.json +1 -1
  28. package/tools/builders/web-builder.js +60 -19
  29. package/tools/installer/config/install.config.yml +0 -85
  30. package/tools/installer/lib/config-loader.js +57 -30
  31. package/tools/installer/lib/file-manager.js +1 -0
  32. package/tools/installer/lib/ide-setup.js +44 -26
  33. package/tools/installer/lib/installer.js +250 -8
  34. package/tools/installer/package.json +1 -1
  35. package/tools/lib/dependency-resolver.js +15 -0
  36. package/bmad-core/tasks/core-dump.md +0 -74
  37. package/bmad-core/tasks/execute-checklist.md +0 -97
  38. package/bmad-core/utils/file-resolution-context.md +0 -10
  39. package/bmad-core/utils/workflow-management.md +0 -223
  40. package/expansion-packs/bmad-infrastructure-devops/tasks/create-doc.md +0 -74
  41. package/expansion-packs/expansion-creator/common-tasks/create-doc.md +0 -74
  42. package/expansion-packs/expansion-creator/utils/template-format.md +0 -26
  43. package/expansion-packs/expansion-creator/utils/workflow-management.md +0 -223
  44. /package/{bmad-core → common}/utils/template-format.md +0 -0
  45. /package/{bmad-core/utils → tools/md-assets}/web-agent-startup-instructions.md +0 -0
@@ -90,6 +90,7 @@ class FileManager {
90
90
  agent: config.agent || null,
91
91
  ide_setup: config.ide || null,
92
92
  ides_setup: config.ides || [],
93
+ expansion_packs: config.expansionPacks || [],
93
94
  files: [],
94
95
  };
95
96
 
@@ -65,8 +65,9 @@ class IdeSetup {
65
65
  mdcContent += "alwaysApply: false\n";
66
66
  mdcContent += "---\n\n";
67
67
  mdcContent += `# ${agentId.toUpperCase()} Agent Rule\n\n`;
68
- mdcContent += `This rule is triggered when the user types \`@${agentId}\` and activates the ${this.getAgentTitle(
69
- agentId
68
+ mdcContent += `This rule is triggered when the user types \`@${agentId}\` and activates the ${await this.getAgentTitle(
69
+ agentId,
70
+ installDir
70
71
  )} agent persona.\n\n`;
71
72
  mdcContent += "## Agent Activation\n\n";
72
73
  mdcContent +=
@@ -84,8 +85,9 @@ class IdeSetup {
84
85
  mdcContent += "## File Reference\n\n";
85
86
  mdcContent += `The complete agent definition is available in [.bmad-core/agents/${agentId}.md](mdc:.bmad-core/agents/${agentId}.md).\n\n`;
86
87
  mdcContent += "## Usage\n\n";
87
- mdcContent += `When the user types \`@${agentId}\`, activate this ${this.getAgentTitle(
88
- agentId
88
+ mdcContent += `When the user types \`@${agentId}\`, activate this ${await this.getAgentTitle(
89
+ agentId,
90
+ installDir
89
91
  )} persona and follow all instructions defined in the YML configuration above.\n`;
90
92
 
91
93
  await fileManager.writeFile(mdcPath, mdcContent);
@@ -150,8 +152,9 @@ class IdeSetup {
150
152
 
151
153
  // Create MD content (similar to Cursor but without frontmatter)
152
154
  let mdContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
153
- mdContent += `This rule is triggered when the user types \`@${agentId}\` and activates the ${this.getAgentTitle(
154
- agentId
155
+ mdContent += `This rule is triggered when the user types \`@${agentId}\` and activates the ${await this.getAgentTitle(
156
+ agentId,
157
+ installDir
155
158
  )} agent persona.\n\n`;
156
159
  mdContent += "## Agent Activation\n\n";
157
160
  mdContent +=
@@ -169,8 +172,9 @@ class IdeSetup {
169
172
  mdContent += "## File Reference\n\n";
170
173
  mdContent += `The complete agent definition is available in [.bmad-core/agents/${agentId}.md](.bmad-core/agents/${agentId}.md).\n\n`;
171
174
  mdContent += "## Usage\n\n";
172
- mdContent += `When the user types \`@${agentId}\`, activate this ${this.getAgentTitle(
173
- agentId
175
+ mdContent += `When the user types \`@${agentId}\`, activate this ${await this.getAgentTitle(
176
+ agentId,
177
+ installDir
174
178
  )} persona and follow all instructions defined in the YML configuration above.\n`;
175
179
 
176
180
  await fileManager.writeFile(mdPath, mdContent);
@@ -195,20 +199,34 @@ class IdeSetup {
195
199
  return agentFiles.map((file) => path.basename(file, ".md"));
196
200
  }
197
201
 
198
- getAgentTitle(agentId) {
199
- const agentTitles = {
200
- analyst: "Business Analyst",
201
- architect: "Solution Architect",
202
- "bmad-master": "BMAD Master",
203
- "bmad-orchestrator": "BMAD Orchestrator",
204
- dev: "Developer",
205
- pm: "Product Manager",
206
- po: "Product Owner",
207
- qa: "QA Specialist",
208
- sm: "Scrum Master",
209
- "ux-expert": "UX Expert",
210
- };
211
- return agentTitles[agentId] || agentId;
202
+ async getAgentTitle(agentId, installDir) {
203
+ // Try to read the actual agent file to get the title
204
+ let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
205
+ if (!(await fileManager.pathExists(agentPath))) {
206
+ agentPath = path.join(installDir, "agents", `${agentId}.md`);
207
+ }
208
+
209
+ if (await fileManager.pathExists(agentPath)) {
210
+ try {
211
+ const agentContent = await fileManager.readFile(agentPath);
212
+ const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
213
+
214
+ if (yamlMatch) {
215
+ const yaml = yamlMatch[1];
216
+ const titleMatch = yaml.match(/title:\s*(.+)/);
217
+ if (titleMatch) {
218
+ return titleMatch[1].trim();
219
+ }
220
+ }
221
+ } catch (error) {
222
+ console.warn(`Failed to read agent title for ${agentId}: ${error.message}`);
223
+ }
224
+ }
225
+
226
+ // Fallback to formatted agent ID
227
+ return agentId.split('-').map(word =>
228
+ word.charAt(0).toUpperCase() + word.slice(1)
229
+ ).join(' ');
212
230
  }
213
231
 
214
232
  async setupRoo(installDir, selectedAgent) {
@@ -294,7 +312,7 @@ class IdeSetup {
294
312
  const whenToUseMatch = yaml.match(/whenToUse:\s*"(.+)"/);
295
313
  const roleDefinitionMatch = yaml.match(/roleDefinition:\s*"(.+)"/);
296
314
 
297
- const title = titleMatch ? titleMatch[1].trim() : this.getAgentTitle(agentId);
315
+ const title = titleMatch ? titleMatch[1].trim() : await this.getAgentTitle(agentId, installDir);
298
316
  const icon = iconMatch ? iconMatch[1].trim() : "🤖";
299
317
  const whenToUse = whenToUseMatch ? whenToUseMatch[1].trim() : `Use for ${title} tasks`;
300
318
  const roleDefinition = roleDefinitionMatch
@@ -381,8 +399,8 @@ class IdeSetup {
381
399
  const mdPath = path.join(clineRulesDir, `${prefix}-${agentId}.md`);
382
400
 
383
401
  // Create MD content for Cline (focused on project standards and role)
384
- let mdContent = `# ${this.getAgentTitle(agentId)} Agent\n\n`;
385
- mdContent += `This rule defines the ${this.getAgentTitle(agentId)} persona and project standards.\n\n`;
402
+ let mdContent = `# ${await this.getAgentTitle(agentId, installDir)} Agent\n\n`;
403
+ mdContent += `This rule defines the ${await this.getAgentTitle(agentId, installDir)} persona and project standards.\n\n`;
386
404
  mdContent += "## Role Definition\n\n";
387
405
  mdContent +=
388
406
  "When the user types `@" + agentId + "`, adopt this persona and follow these guidelines:\n\n";
@@ -402,7 +420,7 @@ class IdeSetup {
402
420
  mdContent += `- Update relevant project files when making changes\n`;
403
421
  mdContent += `- Reference the complete agent definition in [.bmad-core/agents/${agentId}.md](.bmad-core/agents/${agentId}.md)\n\n`;
404
422
  mdContent += "## Usage\n\n";
405
- mdContent += `Type \`@${agentId}\` to activate this ${this.getAgentTitle(agentId)} persona.\n`;
423
+ mdContent += `Type \`@${agentId}\` to activate this ${await this.getAgentTitle(agentId, installDir)} persona.\n`;
406
424
 
407
425
  await fileManager.writeFile(mdPath, mdContent);
408
426
  console.log(chalk.green(`✓ Created rule: ${prefix}-${agentId}.md`));
@@ -225,6 +225,10 @@ class Installer {
225
225
  const sourceDir = configLoader.getBmadCorePath();
226
226
  const bmadCoreDestDir = path.join(installDir, ".bmad-core");
227
227
  await fileManager.copyDirectory(sourceDir, bmadCoreDestDir);
228
+
229
+ // Copy common/ items to .bmad-core
230
+ spinner.text = "Copying common utilities...";
231
+ await this.copyCommonItems(installDir, ".bmad-core", spinner);
228
232
 
229
233
  // Get list of all files for manifest
230
234
  const glob = require("glob");
@@ -283,6 +287,11 @@ class Installer {
283
287
  }
284
288
  }
285
289
  }
290
+
291
+ // Copy common/ items to .bmad-core
292
+ spinner.text = "Copying common utilities...";
293
+ const commonFiles = await this.copyCommonItems(installDir, ".bmad-core", spinner);
294
+ files.push(...commonFiles);
286
295
  } else if (config.installType === "team") {
287
296
  // Team installation
288
297
  spinner.text = `Installing ${config.team} team...`;
@@ -313,6 +322,11 @@ class Installer {
313
322
  }
314
323
  }
315
324
  }
325
+
326
+ // Copy common/ items to .bmad-core
327
+ spinner.text = "Copying common utilities...";
328
+ const commonFiles = await this.copyCommonItems(installDir, ".bmad-core", spinner);
329
+ files.push(...commonFiles);
316
330
  } else if (config.installType === "expansion-only") {
317
331
  // Expansion-only installation - create minimal .bmad-core structure
318
332
  spinner.text = "Creating minimal .bmad-core structure for expansion packs...";
@@ -341,6 +355,10 @@ class Installer {
341
355
  );
342
356
  files.push(...copiedFiles.map(f => `.bmad-core/${f}`));
343
357
  }
358
+
359
+ // Copy common/ items to .bmad-core
360
+ spinner.text = "Copying common utilities...";
361
+ await this.copyCommonItems(installDir, ".bmad-core", spinner);
344
362
  }
345
363
 
346
364
  // Install expansion packs if requested
@@ -607,8 +625,10 @@ class Installer {
607
625
  console.log(chalk.green("✓ .bmad-core framework installed with all agents and workflows"));
608
626
 
609
627
  if (config.expansionPacks && config.expansionPacks.length > 0) {
610
- const packNames = config.expansionPacks.join(", ");
611
- console.log(chalk.green(`✓ Expansion packs installed: ${packNames}`));
628
+ console.log(chalk.green(`✓ Expansion packs installed:`));
629
+ for (const packId of config.expansionPacks) {
630
+ console.log(chalk.green(` - ${packId} → .${packId}/`));
631
+ }
612
632
  }
613
633
 
614
634
  if (config.includeWebBundles && config.webBundlesDirectory) {
@@ -799,7 +819,11 @@ class Installer {
799
819
 
800
820
  const expansionPackDir = path.dirname(pack.manifestPath);
801
821
 
802
- // Define the folders to copy from expansion packs to .bmad-core
822
+ // Create dedicated dot folder for this expansion pack
823
+ const expansionDotFolder = path.join(installDir, `.${packId}`);
824
+ await fileManager.ensureDirectory(expansionDotFolder);
825
+
826
+ // Define the folders to copy from expansion packs
803
827
  const foldersToSync = [
804
828
  'agents',
805
829
  'agent-teams',
@@ -824,21 +848,35 @@ class Installer {
824
848
  nodir: true
825
849
  });
826
850
 
827
- // Copy each file to the destination
851
+ // Copy each file to the expansion pack's dot folder
828
852
  for (const file of files) {
829
853
  const sourcePath = path.join(sourceFolder, file);
830
- const destPath = path.join(installDir, '.bmad-core', folder, file);
854
+ const destPath = path.join(expansionDotFolder, folder, file);
831
855
 
832
856
  if (await fileManager.copyFile(sourcePath, destPath)) {
833
- installedFiles.push(path.join('.bmad-core', folder, file));
857
+ installedFiles.push(path.join(`.${packId}`, folder, file));
834
858
  }
835
859
  }
836
860
  }
837
861
  }
838
862
 
839
- // Web bundles are now available in the dist/ directory and don't need to be copied
863
+ // Copy manifest to the expansion pack's dot folder
864
+ const manifestDestPath = path.join(expansionDotFolder, 'manifest.yml');
865
+ if (await fileManager.copyFile(pack.manifestPath, manifestDestPath)) {
866
+ installedFiles.push(path.join(`.${packId}`, 'manifest.yml'));
867
+ }
840
868
 
841
- console.log(chalk.green(`✓ Installed expansion pack: ${pack.name}`));
869
+ // Copy common/ items to expansion pack folder
870
+ spinner.text = `Copying common utilities to ${packId}...`;
871
+ await this.copyCommonItems(installDir, `.${packId}`, spinner);
872
+
873
+ // Check and resolve core dependencies
874
+ await this.resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, spinner);
875
+
876
+ // Check and resolve core agents referenced by teams
877
+ await this.resolveExpansionPackCoreAgents(installDir, expansionDotFolder, packId, spinner);
878
+
879
+ console.log(chalk.green(`✓ Installed expansion pack: ${pack.name} to ${`.${packId}`}`));
842
880
  } catch (error) {
843
881
  console.error(chalk.red(`Failed to install expansion pack ${packId}: ${error.message}`));
844
882
  }
@@ -847,6 +885,168 @@ class Installer {
847
885
  return installedFiles;
848
886
  }
849
887
 
888
+ async resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, spinner) {
889
+ const glob = require('glob');
890
+ const yaml = require('yaml');
891
+ const fs = require('fs').promises;
892
+
893
+ // Find all agent files in the expansion pack
894
+ const agentFiles = glob.sync('agents/*.md', {
895
+ cwd: expansionDotFolder
896
+ });
897
+
898
+ for (const agentFile of agentFiles) {
899
+ const agentPath = path.join(expansionDotFolder, agentFile);
900
+ const agentContent = await fs.readFile(agentPath, 'utf8');
901
+
902
+ // Extract YAML frontmatter to check dependencies
903
+ const yamlMatch = agentContent.match(/```yaml\n([\s\S]*?)```/);
904
+ if (yamlMatch) {
905
+ try {
906
+ const agentConfig = yaml.parse(yamlMatch[1]);
907
+ const dependencies = agentConfig.dependencies || {};
908
+
909
+ // Check for core dependencies (those that don't exist in the expansion pack)
910
+ for (const depType of ['tasks', 'templates', 'checklists', 'workflows', 'utils', 'data']) {
911
+ const deps = dependencies[depType] || [];
912
+
913
+ for (const dep of deps) {
914
+ const depFileName = dep.endsWith('.md') ? dep : `${dep}.md`;
915
+ const expansionDepPath = path.join(expansionDotFolder, depType, depFileName);
916
+
917
+ // Check if dependency exists in expansion pack
918
+ if (!(await fileManager.pathExists(expansionDepPath))) {
919
+ // Try to find it in core
920
+ const coreDepPath = path.join(configLoader.getBmadCorePath(), depType, depFileName);
921
+
922
+ if (await fileManager.pathExists(coreDepPath)) {
923
+ spinner.text = `Copying core dependency ${dep} for ${packId}...`;
924
+
925
+ // Copy from core to expansion pack dot folder
926
+ const destPath = path.join(expansionDotFolder, depType, depFileName);
927
+ await fileManager.copyFile(coreDepPath, destPath);
928
+
929
+ console.log(chalk.dim(` Added core dependency: ${depType}/${depFileName}`));
930
+ } else {
931
+ console.warn(chalk.yellow(` Warning: Dependency ${depType}/${dep} not found in core or expansion pack`));
932
+ }
933
+ }
934
+ }
935
+ }
936
+ } catch (error) {
937
+ console.warn(chalk.yellow(` Warning: Could not parse agent dependencies: ${error.message}`));
938
+ }
939
+ }
940
+ }
941
+ }
942
+
943
+ async resolveExpansionPackCoreAgents(installDir, expansionDotFolder, packId, spinner) {
944
+ const glob = require('glob');
945
+ const yaml = require('yaml');
946
+ const fs = require('fs').promises;
947
+
948
+ // Find all team files in the expansion pack
949
+ const teamFiles = glob.sync('agent-teams/*.yml', {
950
+ cwd: expansionDotFolder
951
+ });
952
+
953
+ // Also get existing agents in the expansion pack
954
+ const existingAgents = new Set();
955
+ const agentFiles = glob.sync('agents/*.md', {
956
+ cwd: expansionDotFolder
957
+ });
958
+ for (const agentFile of agentFiles) {
959
+ const agentName = path.basename(agentFile, '.md');
960
+ existingAgents.add(agentName);
961
+ }
962
+
963
+ // Process each team file
964
+ for (const teamFile of teamFiles) {
965
+ const teamPath = path.join(expansionDotFolder, teamFile);
966
+ const teamContent = await fs.readFile(teamPath, 'utf8');
967
+
968
+ try {
969
+ const teamConfig = yaml.parse(teamContent);
970
+ const agents = teamConfig.agents || [];
971
+
972
+ // Add bmad-orchestrator if not present (required for all teams)
973
+ if (!agents.includes('bmad-orchestrator')) {
974
+ agents.unshift('bmad-orchestrator');
975
+ }
976
+
977
+ // Check each agent in the team
978
+ for (const agentId of agents) {
979
+ if (!existingAgents.has(agentId)) {
980
+ // Agent not in expansion pack, try to get from core
981
+ const coreAgentPath = path.join(configLoader.getBmadCorePath(), 'agents', `${agentId}.md`);
982
+
983
+ if (await fileManager.pathExists(coreAgentPath)) {
984
+ spinner.text = `Copying core agent ${agentId} for ${packId}...`;
985
+
986
+ // Copy agent file
987
+ const destPath = path.join(expansionDotFolder, 'agents', `${agentId}.md`);
988
+ await fileManager.copyFile(coreAgentPath, destPath);
989
+ existingAgents.add(agentId);
990
+
991
+ console.log(chalk.dim(` Added core agent: ${agentId}`));
992
+
993
+ // Now resolve this agent's dependencies too
994
+ const agentContent = await fs.readFile(coreAgentPath, 'utf8');
995
+ const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
996
+
997
+ if (yamlMatch) {
998
+ try {
999
+ // Clean up the YAML to handle command descriptions
1000
+ let yamlContent = yamlMatch[1];
1001
+ yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
1002
+
1003
+ const agentConfig = yaml.parse(yamlContent);
1004
+ const dependencies = agentConfig.dependencies || {};
1005
+
1006
+ // Copy all dependencies for this agent
1007
+ for (const depType of ['tasks', 'templates', 'checklists', 'workflows', 'utils', 'data']) {
1008
+ const deps = dependencies[depType] || [];
1009
+
1010
+ for (const dep of deps) {
1011
+ const depFileName = dep.endsWith('.md') || dep.endsWith('.yml') ? dep : `${dep}.md`;
1012
+ const expansionDepPath = path.join(expansionDotFolder, depType, depFileName);
1013
+
1014
+ // Check if dependency exists in expansion pack
1015
+ if (!(await fileManager.pathExists(expansionDepPath))) {
1016
+ // Try to find it in core
1017
+ const coreDepPath = path.join(configLoader.getBmadCorePath(), depType, depFileName);
1018
+
1019
+ if (await fileManager.pathExists(coreDepPath)) {
1020
+ const destDepPath = path.join(expansionDotFolder, depType, depFileName);
1021
+ await fileManager.copyFile(coreDepPath, destDepPath);
1022
+ console.log(chalk.dim(` Added agent dependency: ${depType}/${depFileName}`));
1023
+ } else {
1024
+ // Try common folder
1025
+ const commonDepPath = path.join(this.rootDir, 'common', depType, depFileName);
1026
+ if (await fileManager.pathExists(commonDepPath)) {
1027
+ const destDepPath = path.join(expansionDotFolder, depType, depFileName);
1028
+ await fileManager.copyFile(commonDepPath, destDepPath);
1029
+ console.log(chalk.dim(` Added agent dependency from common: ${depType}/${depFileName}`));
1030
+ }
1031
+ }
1032
+ }
1033
+ }
1034
+ }
1035
+ } catch (error) {
1036
+ console.warn(chalk.yellow(` Warning: Could not parse agent ${agentId} dependencies: ${error.message}`));
1037
+ }
1038
+ }
1039
+ } else {
1040
+ console.warn(chalk.yellow(` Warning: Core agent ${agentId} not found for team ${path.basename(teamFile, '.yml')}`));
1041
+ }
1042
+ }
1043
+ }
1044
+ } catch (error) {
1045
+ console.warn(chalk.yellow(` Warning: Could not parse team file ${teamFile}: ${error.message}`));
1046
+ }
1047
+ }
1048
+ }
1049
+
850
1050
  getWebBundleInfo(config) {
851
1051
  const webBundleType = config.webBundleType || 'all';
852
1052
 
@@ -944,6 +1144,48 @@ class Installer {
944
1144
  }
945
1145
  }
946
1146
 
1147
+ async copyCommonItems(installDir, targetSubdir, spinner) {
1148
+ const glob = require('glob');
1149
+ const fs = require('fs').promises;
1150
+ const sourceBase = path.dirname(path.dirname(path.dirname(path.dirname(__filename)))); // Go up to project root
1151
+ const commonPath = path.join(sourceBase, 'common');
1152
+ const targetPath = path.join(installDir, targetSubdir);
1153
+ const copiedFiles = [];
1154
+
1155
+ // Check if common/ exists
1156
+ if (!(await fileManager.pathExists(commonPath))) {
1157
+ console.warn(chalk.yellow('Warning: common/ folder not found'));
1158
+ return copiedFiles;
1159
+ }
1160
+
1161
+ // Copy all items from common/ to target
1162
+ const commonItems = glob.sync('**/*', {
1163
+ cwd: commonPath,
1164
+ nodir: true
1165
+ });
1166
+
1167
+ for (const item of commonItems) {
1168
+ const sourcePath = path.join(commonPath, item);
1169
+ const destPath = path.join(targetPath, item);
1170
+
1171
+ // Read the file content
1172
+ const content = await fs.readFile(sourcePath, 'utf8');
1173
+
1174
+ // Replace {root} with the target subdirectory
1175
+ const updatedContent = content.replace(/\{root\}/g, targetSubdir);
1176
+
1177
+ // Ensure directory exists
1178
+ await fileManager.ensureDirectory(path.dirname(destPath));
1179
+
1180
+ // Write the updated content
1181
+ await fs.writeFile(destPath, updatedContent, 'utf8');
1182
+ copiedFiles.push(path.join(targetSubdir, item));
1183
+ }
1184
+
1185
+ console.log(chalk.dim(` Added ${commonItems.length} common utilities`));
1186
+ return copiedFiles;
1187
+ }
1188
+
947
1189
  async findInstallation() {
948
1190
  // Look for .bmad-core in current directory or parent directories
949
1191
  let currentDir = process.cwd();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.17.0",
3
+ "version": "4.18.0",
4
4
  "description": "BMAD Method installer - AI-powered Agile development framework",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {
@@ -6,6 +6,7 @@ class DependencyResolver {
6
6
  constructor(rootDir) {
7
7
  this.rootDir = rootDir;
8
8
  this.bmadCore = path.join(rootDir, 'bmad-core');
9
+ this.common = path.join(rootDir, 'common');
9
10
  this.cache = new Map();
10
11
  }
11
12
 
@@ -123,6 +124,7 @@ class DependencyResolver {
123
124
  let content = null;
124
125
  let filePath = null;
125
126
 
127
+ // First try bmad-core
126
128
  for (const ext of extensions) {
127
129
  try {
128
130
  filePath = path.join(this.bmadCore, type, `${id}${ext}`);
@@ -132,6 +134,19 @@ class DependencyResolver {
132
134
  // Try next extension
133
135
  }
134
136
  }
137
+
138
+ // If not found in bmad-core, try common folder
139
+ if (!content) {
140
+ for (const ext of extensions) {
141
+ try {
142
+ filePath = path.join(this.common, type, `${id}${ext}`);
143
+ content = await fs.readFile(filePath, 'utf8');
144
+ break;
145
+ } catch (e) {
146
+ // Try next extension
147
+ }
148
+ }
149
+ }
135
150
 
136
151
  if (!content) {
137
152
  console.warn(`Resource not found: ${type}/${id}`);
@@ -1,74 +0,0 @@
1
- # Core Dump Task
2
-
3
- ## Purpose
4
-
5
- To create a concise memory recording file (`.ai/core-dump-n.md`) that captures the essential context of the current agent session, enabling seamless continuation of work in future agent sessions. This task ensures persistent context across agent conversations while maintaining minimal token usage for efficient context loading.
6
-
7
- ## Inputs for this Task
8
-
9
- - Current session conversation history and accomplishments
10
- - Files created, modified, or deleted during the session
11
- - Key decisions made and procedures followed
12
- - Current project state and next logical steps
13
- - User requests and agent responses that shaped the session
14
-
15
- ## Task Execution Instructions
16
-
17
- ### 0. Check Existing Core Dump
18
-
19
- Before proceeding, check if `.ai/core-dump.md` already exists:
20
-
21
- - If file exists, ask user: "Core dump file exists. Should I: 1. Overwrite, 2. Update, 3. Append or 4. Create new?"
22
- - **Overwrite**: Replace entire file with new content
23
- - **Update**: Merge new session info with existing content, updating relevant sections
24
- - **Append**: Add new session as a separate entry while preserving existing content
25
- - **Create New**: Create a new file, appending the next possible -# to the file, such as core-dump-3.md if 1 and 2 already exist.
26
- - If file doesn't exist, proceed with creation of `core-dump-1.md`
27
-
28
- ### 1. Analyze Session Context
29
-
30
- - Review the entire conversation to identify key accomplishments
31
- - Note any specific tasks, procedures, or workflows that were executed
32
- - Identify important decisions made or problems solved
33
- - Capture the user's working style and preferences observed during the session
34
-
35
- ### 2. Document What Was Accomplished
36
-
37
- - **Primary Actions**: List the main tasks completed concisely
38
- - **Story Progress**: For story work, use format "Tasks Complete: 1-6, 8. Next Task Pending: 7, 9"
39
- - **Problem Solving**: Document any challenges encountered and how they were resolved
40
- - **User Communications**: Summarize key user requests, preferences, and discussion points
41
-
42
- ### 3. Record File System Changes (Concise Format)
43
-
44
- - **Files Created**: `filename.ext` (brief purpose/size)
45
- - **Files Modified**: `filename.ext` (what changed)
46
- - **Files Deleted**: `filename.ext` (why removed)
47
- - Focus on essential details, avoid verbose descriptions
48
-
49
- ### 4. Capture Current Project State
50
-
51
- - **Project Progress**: Where the project stands after this session
52
- - **Current Issues**: Any blockers or problems that need resolution
53
- - **Next Logical Steps**: What would be the natural next actions to take
54
-
55
- ### 5. Create/Update Core Dump File
56
-
57
- Based on user's choice from step 0, handle the file accordingly:
58
-
59
- ### 6. Optimize for Minimal Context
60
-
61
- - Keep descriptions concise but informative
62
- - Use abbreviated formats where possible (file sizes, task numbers)
63
- - Focus on actionable information rather than detailed explanations
64
- - Avoid redundant information that can be found in project documentation
65
- - Prioritize information that would be lost without this recording
66
- - Ensure the file can be quickly scanned and understood
67
-
68
- ### 7. Validate Completeness
69
-
70
- - Verify all significant session activities are captured
71
- - Ensure a future agent could understand the current state
72
- - Check that file changes are accurately recorded
73
- - Confirm next steps are clear and actionable
74
- - Verify user communication style and preferences are noted
@@ -1,97 +0,0 @@
1
- # Checklist Validation Task
2
-
3
- This task provides instructions for validating documentation against checklists. The agent MUST follow these instructions to ensure thorough and systematic validation of documents.
4
-
5
- ## Context
6
-
7
- The BMAD Method uses various checklists to ensure quality and completeness of different artifacts. Each checklist contains embedded prompts and instructions to guide the LLM through thorough validation and advanced elicitation. The checklists automatically identify their required artifacts and guide the validation process.
8
-
9
- ## Available Checklists
10
-
11
- If the user asks or does not specify a specific checklist, list the checklists available to the agent persona. If the task is being run not with a specific agent, tell the user to check the bmad-core/checklists folder to select the appropriate one to run.
12
-
13
- ## Instructions
14
-
15
- 1. **Initial Assessment**
16
-
17
- - If user or the task being run provides a checklist name:
18
- - Try fuzzy matching (e.g. "architecture checklist" -> "architect-checklist")
19
- - If multiple matches found, ask user to clarify
20
- - Load the appropriate checklist from bmad-core/checklists/
21
- - If no checklist specified:
22
- - Ask the user which checklist they want to use
23
- - Present the available options from the files in the checklists folder
24
- - Confirm if they want to work through the checklist:
25
- - Section by section (interactive mode - very time consuming)
26
- - All at once (YOLO mode - recommended for checklists, there will be a summary of sections at the end to discuss)
27
-
28
- 2. **Document and Artifact Gathering**
29
-
30
- - Each checklist will specify its required documents/artifacts at the beginning
31
- - Follow the checklist's specific instructions for what to gather, generally a file can be resolved in the docs folder, if not or unsure, halt and ask or confirm with the user.
32
-
33
- 3. **Checklist Processing**
34
-
35
- If in interactive mode:
36
-
37
- - Work through each section of the checklist one at a time
38
- - For each section:
39
- - Review all items in the section following instructions for that section embedded in the checklist
40
- - Check each item against the relevant documentation or artifacts as appropriate
41
- - Present summary of findings for that section, highlighting warnings, errors and non applicable items (rationale for non-applicability).
42
- - Get user confirmation before proceeding to next section or if any thing major do we need to halt and take corrective action
43
-
44
- If in YOLO mode:
45
-
46
- - Process all sections at once
47
- - Create a comprehensive report of all findings
48
- - Present the complete analysis to the user
49
-
50
- 4. **Validation Approach**
51
-
52
- For each checklist item:
53
-
54
- - Read and understand the requirement
55
- - Look for evidence in the documentation that satisfies the requirement
56
- - Consider both explicit mentions and implicit coverage
57
- - Aside from this, follow all checklist llm instructions
58
- - Mark items as:
59
- - ✅ PASS: Requirement clearly met
60
- - ❌ FAIL: Requirement not met or insufficient coverage
61
- - ⚠️ PARTIAL: Some aspects covered but needs improvement
62
- - N/A: Not applicable to this case
63
-
64
- 5. **Section Analysis**
65
-
66
- For each section:
67
-
68
- - think step by step to calculate pass rate
69
- - Identify common themes in failed items
70
- - Provide specific recommendations for improvement
71
- - In interactive mode, discuss findings with user
72
- - Document any user decisions or explanations
73
-
74
- 6. **Final Report**
75
-
76
- Prepare a summary that includes:
77
-
78
- - Overall checklist completion status
79
- - Pass rates by section
80
- - List of failed items with context
81
- - Specific recommendations for improvement
82
- - Any sections or items marked as N/A with justification
83
-
84
- ## Checklist Execution Methodology
85
-
86
- Each checklist now contains embedded LLM prompts and instructions that will:
87
-
88
- 1. **Guide thorough thinking** - Prompts ensure deep analysis of each section
89
- 2. **Request specific artifacts** - Clear instructions on what documents/access is needed
90
- 3. **Provide contextual guidance** - Section-specific prompts for better validation
91
- 4. **Generate comprehensive reports** - Final summary with detailed findings
92
-
93
- The LLM will:
94
-
95
- - Execute the complete checklist validation
96
- - Present a final report with pass/fail rates and key findings
97
- - Offer to provide detailed analysis of any section, especially those with warnings or failures