bmad-method 4.30.2 → 4.30.3

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 (58) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1 -1
  3. package/bmad-core/core-config.yaml +0 -1
  4. package/dist/agents/analyst.txt +1 -1
  5. package/dist/agents/bmad-master.txt +1 -1
  6. package/dist/agents/bmad-orchestrator.txt +1 -1
  7. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +2409 -0
  8. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +1480 -0
  9. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +826 -0
  10. package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +10690 -0
  11. package/dist/teams/team-all.txt +1 -1
  12. package/dist/teams/team-fullstack.txt +1 -1
  13. package/dist/teams/team-ide-minimal.txt +1 -1
  14. package/dist/teams/team-no-ui.txt +1 -1
  15. package/docs/bmad-workflow-guide.md +1 -1
  16. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +2 -2
  17. package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +13 -0
  18. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +72 -0
  19. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +78 -0
  20. package/expansion-packs/{bmad-creator-tools/agents/bmad-the-creator.md → bmad-2d-unity-game-dev/agents/game-sm.md} +26 -28
  21. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +201 -0
  22. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +160 -0
  23. package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +6 -0
  24. package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +251 -0
  25. package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +590 -0
  26. package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +111 -0
  27. package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +217 -0
  28. package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +308 -0
  29. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +545 -0
  30. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +356 -0
  31. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +343 -0
  32. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +256 -0
  33. package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +484 -0
  34. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +183 -0
  35. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +175 -0
  36. package/expansion-packs/bmad-infrastructure-devops/config.yaml +2 -2
  37. package/package.json +4 -8
  38. package/tools/bump-all-versions.js +8 -9
  39. package/tools/bump-expansion-version.js +40 -35
  40. package/tools/installer/bin/bmad.js +8 -21
  41. package/tools/installer/lib/file-manager.js +76 -44
  42. package/tools/installer/lib/ide-base-setup.js +227 -0
  43. package/tools/installer/lib/ide-setup.js +8 -58
  44. package/tools/installer/lib/installer.js +99 -121
  45. package/tools/installer/lib/memory-profiler.js +224 -0
  46. package/tools/installer/lib/module-manager.js +110 -0
  47. package/tools/installer/lib/resource-locator.js +310 -0
  48. package/tools/installer/package.json +1 -1
  49. package/tools/semantic-release-sync-installer.js +20 -21
  50. package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +0 -2008
  51. package/expansion-packs/bmad-creator-tools/README.md +0 -8
  52. package/expansion-packs/bmad-creator-tools/config.yaml +0 -6
  53. package/expansion-packs/bmad-creator-tools/tasks/create-agent.md +0 -200
  54. package/expansion-packs/bmad-creator-tools/tasks/generate-expansion-pack.md +0 -1020
  55. package/expansion-packs/bmad-creator-tools/templates/agent-teams-tmpl.yaml +0 -178
  56. package/expansion-packs/bmad-creator-tools/templates/agent-tmpl.yaml +0 -154
  57. package/expansion-packs/bmad-creator-tools/templates/expansion-pack-plan-tmpl.yaml +0 -120
  58. package/tools/bump-core-version.js +0 -57
@@ -1,42 +1,30 @@
1
1
  const path = require("node:path");
2
+ const fs = require("fs-extra");
3
+ const chalk = require("chalk");
4
+ const ora = require("ora");
5
+ const inquirer = require("inquirer");
2
6
  const fileManager = require("./file-manager");
3
7
  const configLoader = require("./config-loader");
4
8
  const ideSetup = require("./ide-setup");
5
9
  const { extractYamlFromAgent } = require("../../lib/yaml-utils");
6
-
7
- // Dynamic imports for ES modules
8
- let chalk, ora, inquirer;
9
-
10
- // Initialize ES modules
11
- async function initializeModules() {
12
- if (!chalk) {
13
- chalk = (await import("chalk")).default;
14
- ora = (await import("ora")).default;
15
- inquirer = (await import("inquirer")).default;
16
- }
17
- }
10
+ const resourceLocator = require("./resource-locator");
18
11
 
19
12
  class Installer {
20
13
  async getCoreVersion() {
21
- const yaml = require("js-yaml");
22
- const fs = require("fs-extra");
23
- const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.yaml");
24
14
  try {
25
- const coreConfigContent = await fs.readFile(coreConfigPath, "utf8");
26
- const coreConfig = yaml.load(coreConfigContent);
27
- return coreConfig.version || "unknown";
15
+ // Always use package.json version
16
+ const packagePath = path.join(__dirname, '..', '..', '..', 'package.json');
17
+ const packageJson = require(packagePath);
18
+ return packageJson.version;
28
19
  } catch (error) {
29
- console.warn("Could not read version from core-config.yaml, using 'unknown'");
20
+ console.warn("Could not read version from package.json, using 'unknown'");
30
21
  return "unknown";
31
22
  }
32
23
  }
33
24
 
34
25
  async install(config) {
35
- // Initialize ES modules
36
- await initializeModules();
37
-
38
26
  const spinner = ora("Analyzing installation directory...").start();
39
-
27
+
40
28
  try {
41
29
  // Store the original CWD where npx was executed
42
30
  const originalCwd = process.env.INIT_CWD || process.env.PWD || process.cwd();
@@ -59,7 +47,7 @@ class Installer {
59
47
  // Check if directory exists and handle non-existent directories
60
48
  if (!(await fileManager.pathExists(installDir))) {
61
49
  spinner.stop();
62
- console.log(chalk.yellow(`\nThe directory ${chalk.bold(installDir)} does not exist.`));
50
+ console.log(`\nThe directory ${installDir} does not exist.`);
63
51
 
64
52
  const { action } = await inquirer.prompt([
65
53
  {
@@ -84,7 +72,7 @@ class Installer {
84
72
  ]);
85
73
 
86
74
  if (action === 'cancel') {
87
- console.log(chalk.red('Installation cancelled.'));
75
+ console.log('Installation cancelled.');
88
76
  process.exit(0);
89
77
  } else if (action === 'change') {
90
78
  const { newDirectory } = await inquirer.prompt([
@@ -106,10 +94,10 @@ class Installer {
106
94
  } else if (action === 'create') {
107
95
  try {
108
96
  await fileManager.ensureDirectory(installDir);
109
- console.log(chalk.green(`✓ Created directory: ${installDir}`));
97
+ console.log(`✓ Created directory: ${installDir}`);
110
98
  } catch (error) {
111
- console.error(chalk.red(`Failed to create directory: ${error.message}`));
112
- console.error(chalk.yellow('You may need to check permissions or use a different path.'));
99
+ console.error(`Failed to create directory: ${error.message}`);
100
+ console.error('You may need to check permissions or use a different path.');
113
101
  process.exit(1);
114
102
  }
115
103
  }
@@ -161,14 +149,17 @@ class Installer {
161
149
  );
162
150
  }
163
151
  } catch (error) {
164
- spinner.fail("Installation failed");
152
+ // Check if modules were initialized
153
+ if (spinner) {
154
+ spinner.fail("Installation failed");
155
+ } else {
156
+ console.error("Installation failed:", error.message);
157
+ }
165
158
  throw error;
166
159
  }
167
160
  }
168
161
 
169
162
  async detectInstallationState(installDir) {
170
- // Ensure modules are initialized
171
- await initializeModules();
172
163
  const state = {
173
164
  type: "clean",
174
165
  hasV4Manifest: false,
@@ -212,8 +203,7 @@ class Installer {
212
203
  }
213
204
 
214
205
  // Check if directory has other files
215
- const glob = require("glob");
216
- const files = glob.sync("**/*", {
206
+ const files = await resourceLocator.findFiles("**/*", {
217
207
  cwd: installDir,
218
208
  nodir: true,
219
209
  ignore: ["**/.git/**", "**/node_modules/**"],
@@ -233,8 +223,6 @@ class Installer {
233
223
  }
234
224
 
235
225
  async performFreshInstall(config, installDir, spinner, options = {}) {
236
- // Ensure modules are initialized
237
- await initializeModules();
238
226
  spinner.text = "Installing BMad Method...";
239
227
 
240
228
  let files = [];
@@ -242,7 +230,7 @@ class Installer {
242
230
  if (config.installType === "full") {
243
231
  // Full installation - copy entire .bmad-core folder as a subdirectory
244
232
  spinner.text = "Copying complete .bmad-core folder...";
245
- const sourceDir = configLoader.getBmadCorePath();
233
+ const sourceDir = resourceLocator.getBmadCorePath();
246
234
  const bmadCoreDestDir = path.join(installDir, ".bmad-core");
247
235
  await fileManager.copyDirectoryWithRootReplacement(sourceDir, bmadCoreDestDir, ".bmad-core");
248
236
 
@@ -251,14 +239,12 @@ class Installer {
251
239
  await this.copyCommonItems(installDir, ".bmad-core", spinner);
252
240
 
253
241
  // Get list of all files for manifest
254
- const glob = require("glob");
255
- files = glob
256
- .sync("**/*", {
257
- cwd: bmadCoreDestDir,
258
- nodir: true,
259
- ignore: ["**/.git/**", "**/node_modules/**"],
260
- })
261
- .map((file) => path.join(".bmad-core", file));
242
+ const foundFiles = await resourceLocator.findFiles("**/*", {
243
+ cwd: bmadCoreDestDir,
244
+ nodir: true,
245
+ ignore: ["**/.git/**", "**/node_modules/**"],
246
+ });
247
+ files = foundFiles.map((file) => path.join(".bmad-core", file));
262
248
  } else if (config.installType === "single-agent") {
263
249
  // Single agent installation
264
250
  spinner.text = `Installing ${config.agent} agent...`;
@@ -275,10 +261,10 @@ class Installer {
275
261
  files.push(`.bmad-core/agents/${config.agent}.md`);
276
262
 
277
263
  // Copy dependencies
278
- const dependencies = await configLoader.getAgentDependencies(
264
+ const { all: dependencies } = await resourceLocator.getAgentDependencies(
279
265
  config.agent
280
266
  );
281
- const sourceBase = configLoader.getBmadCorePath();
267
+ const sourceBase = resourceLocator.getBmadCorePath();
282
268
 
283
269
  for (const dep of dependencies) {
284
270
  spinner.text = `Copying dependency: ${dep}`;
@@ -328,7 +314,7 @@ class Installer {
328
314
 
329
315
  // Get team dependencies
330
316
  const teamDependencies = await configLoader.getTeamDependencies(config.team);
331
- const sourceBase = configLoader.getBmadCorePath();
317
+ const sourceBase = resourceLocator.getBmadCorePath();
332
318
 
333
319
  // Install all team dependencies
334
320
  for (const dep of teamDependencies) {
@@ -415,8 +401,6 @@ class Installer {
415
401
  }
416
402
 
417
403
  async handleExistingV4Installation(config, installDir, state, spinner) {
418
- // Ensure modules are initialized
419
- await initializeModules();
420
404
  spinner.stop();
421
405
 
422
406
  const currentVersion = state.manifest.version;
@@ -443,7 +427,7 @@ class Installer {
443
427
  const hasIntegrityIssues = hasMissingFiles || hasModifiedFiles;
444
428
 
445
429
  if (hasIntegrityIssues) {
446
- console.log(chalk.red("\n⚠️ Installation issues detected:"));
430
+ console.log(chalk.red("\n⚠️ Installation issues detected:"));
447
431
  if (hasMissingFiles) {
448
432
  console.log(chalk.red(` Missing files: ${integrity.missing.length}`));
449
433
  if (integrity.missing.length <= 5) {
@@ -473,7 +457,7 @@ class Installer {
473
457
  let choices = [];
474
458
 
475
459
  if (versionCompare < 0) {
476
- console.log(chalk.cyan("\n⬆️ Upgrade available for BMad core"));
460
+ console.log(chalk.cyan("\n⬆️ Upgrade available for BMad core"));
477
461
  choices.push({ name: `Upgrade BMad core (v${currentVersion} → v${newVersion})`, value: "upgrade" });
478
462
  } else if (versionCompare === 0) {
479
463
  if (hasIntegrityIssues) {
@@ -483,10 +467,10 @@ class Installer {
483
467
  value: "repair"
484
468
  });
485
469
  }
486
- console.log(chalk.yellow("\n⚠️ Same version already installed"));
470
+ console.log(chalk.yellow("\n⚠️ Same version already installed"));
487
471
  choices.push({ name: `Force reinstall BMad core (v${currentVersion} - reinstall)`, value: "reinstall" });
488
472
  } else {
489
- console.log(chalk.yellow("\n⬇️ Installed version is newer than available"));
473
+ console.log(chalk.yellow("\n⬇️ Installed version is newer than available"));
490
474
  choices.push({ name: `Downgrade BMad core (v${currentVersion} → v${newVersion})`, value: "reinstall" });
491
475
  }
492
476
 
@@ -515,7 +499,7 @@ class Installer {
515
499
  return await this.performReinstall(config, installDir, spinner);
516
500
  case "expansions":
517
501
  // Ask which expansion packs to install
518
- const availableExpansionPacks = await this.getAvailableExpansionPacks();
502
+ const availableExpansionPacks = await resourceLocator.getExpansionPacks();
519
503
 
520
504
  if (availableExpansionPacks.length === 0) {
521
505
  console.log(chalk.yellow("No expansion packs available."));
@@ -528,7 +512,7 @@ class Installer {
528
512
  name: 'selectedPacks',
529
513
  message: 'Select expansion packs to install/update:',
530
514
  choices: availableExpansionPacks.map(pack => ({
531
- name: `${pack.name} v${pack.version} - ${pack.description}`,
515
+ name: `${pack.name} (v${pack.version}) .${pack.id}`,
532
516
  value: pack.id,
533
517
  checked: state.expansionPacks[pack.id] !== undefined
534
518
  }))
@@ -557,8 +541,6 @@ class Installer {
557
541
  }
558
542
 
559
543
  async handleV3Installation(config, installDir, state, spinner) {
560
- // Ensure modules are initialized
561
- await initializeModules();
562
544
  spinner.stop();
563
545
 
564
546
  console.log(
@@ -598,8 +580,6 @@ class Installer {
598
580
  }
599
581
 
600
582
  async handleUnknownInstallation(config, installDir, state, spinner) {
601
- // Ensure modules are initialized
602
- await initializeModules();
603
583
  spinner.stop();
604
584
 
605
585
  console.log(chalk.yellow("\n⚠️ Directory contains existing files"));
@@ -740,7 +720,7 @@ class Installer {
740
720
 
741
721
  // Restore missing and modified files
742
722
  spinner.text = "Restoring files...";
743
- const sourceBase = configLoader.getBmadCorePath();
723
+ const sourceBase = resourceLocator.getBmadCorePath();
744
724
  const filesToRestore = [...integrity.missing, ...integrity.modified];
745
725
 
746
726
  for (const file of filesToRestore) {
@@ -915,8 +895,6 @@ class Installer {
915
895
 
916
896
  // Legacy method for backward compatibility
917
897
  async update() {
918
- // Initialize ES modules
919
- await initializeModules();
920
898
  console.log(chalk.yellow('The "update" command is deprecated.'));
921
899
  console.log(
922
900
  'Please use "install" instead - it will detect and offer to update existing installations.'
@@ -935,9 +913,7 @@ class Installer {
935
913
  }
936
914
 
937
915
  async listAgents() {
938
- // Initialize ES modules
939
- await initializeModules();
940
- const agents = await configLoader.getAvailableAgents();
916
+ const agents = await resourceLocator.getAvailableAgents();
941
917
 
942
918
  console.log(chalk.bold("\nAvailable BMad Agents:\n"));
943
919
 
@@ -951,9 +927,7 @@ class Installer {
951
927
  }
952
928
 
953
929
  async listExpansionPacks() {
954
- // Initialize ES modules
955
- await initializeModules();
956
- const expansionPacks = await this.getAvailableExpansionPacks();
930
+ const expansionPacks = await resourceLocator.getExpansionPacks();
957
931
 
958
932
  console.log(chalk.bold("\nAvailable BMad Expansion Packs:\n"));
959
933
 
@@ -978,8 +952,6 @@ class Installer {
978
952
  }
979
953
 
980
954
  async showStatus() {
981
- // Initialize ES modules
982
- await initializeModules();
983
955
  const installDir = await this.findInstallation();
984
956
 
985
957
  if (!installDir) {
@@ -1029,11 +1001,11 @@ class Installer {
1029
1001
  }
1030
1002
 
1031
1003
  async getAvailableAgents() {
1032
- return configLoader.getAvailableAgents();
1004
+ return resourceLocator.getAvailableAgents();
1033
1005
  }
1034
1006
 
1035
1007
  async getAvailableExpansionPacks() {
1036
- return configLoader.getAvailableExpansionPacks();
1008
+ return resourceLocator.getExpansionPacks();
1037
1009
  }
1038
1010
 
1039
1011
  async getAvailableTeams() {
@@ -1046,13 +1018,12 @@ class Installer {
1046
1018
  }
1047
1019
 
1048
1020
  const installedFiles = [];
1049
- const glob = require('glob');
1050
1021
 
1051
1022
  for (const packId of selectedPacks) {
1052
1023
  spinner.text = `Installing expansion pack: ${packId}...`;
1053
1024
 
1054
1025
  try {
1055
- const expansionPacks = await this.getAvailableExpansionPacks();
1026
+ const expansionPacks = await resourceLocator.getExpansionPacks();
1056
1027
  const pack = expansionPacks.find(p => p.id === packId);
1057
1028
 
1058
1029
  if (!pack) {
@@ -1112,7 +1083,7 @@ class Installer {
1112
1083
  spinner.start();
1113
1084
  continue;
1114
1085
  } else if (action === 'cancel') {
1115
- console.log(chalk.red('Installation cancelled.'));
1086
+ console.log('Installation cancelled.');
1116
1087
  process.exit(0);
1117
1088
  } else if (action === 'repair') {
1118
1089
  // Repair the expansion pack
@@ -1151,7 +1122,7 @@ class Installer {
1151
1122
  spinner.start();
1152
1123
  continue;
1153
1124
  } else if (action === 'cancel') {
1154
- console.log(chalk.red('Installation cancelled.'));
1125
+ console.log('Installation cancelled.');
1155
1126
  process.exit(0);
1156
1127
  }
1157
1128
  }
@@ -1161,7 +1132,7 @@ class Installer {
1161
1132
  await fileManager.removeDirectory(expansionDotFolder);
1162
1133
  }
1163
1134
 
1164
- const expansionPackDir = pack.packPath;
1135
+ const expansionPackDir = pack.path;
1165
1136
 
1166
1137
  // Ensure dedicated dot folder exists for this expansion pack
1167
1138
  expansionDotFolder = path.join(installDir, `.${packId}`);
@@ -1187,7 +1158,7 @@ class Installer {
1187
1158
  // Check if folder exists in expansion pack
1188
1159
  if (await fileManager.pathExists(sourceFolder)) {
1189
1160
  // Get all files in this folder
1190
- const files = glob.sync('**/*', {
1161
+ const files = await resourceLocator.findFiles('**/*', {
1191
1162
  cwd: sourceFolder,
1192
1163
  nodir: true
1193
1164
  });
@@ -1236,7 +1207,7 @@ class Installer {
1236
1207
  await this.copyCommonItems(installDir, `.${packId}`, spinner);
1237
1208
 
1238
1209
  // Check and resolve core dependencies
1239
- await this.resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, spinner);
1210
+ await this.resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, pack, spinner);
1240
1211
 
1241
1212
  // Check and resolve core agents referenced by teams
1242
1213
  await this.resolveExpansionPackCoreAgents(installDir, expansionDotFolder, packId, spinner);
@@ -1252,30 +1223,30 @@ class Installer {
1252
1223
  };
1253
1224
 
1254
1225
  // Get all files installed in this expansion pack
1255
- const expansionPackFiles = glob.sync('**/*', {
1226
+ const foundFiles = await resourceLocator.findFiles('**/*', {
1256
1227
  cwd: expansionDotFolder,
1257
1228
  nodir: true
1258
- }).map(f => path.join(`.${packId}`, f));
1229
+ });
1230
+ const expansionPackFiles = foundFiles.map(f => path.join(`.${packId}`, f));
1259
1231
 
1260
1232
  await fileManager.createExpansionPackManifest(installDir, packId, expansionConfig, expansionPackFiles);
1261
1233
 
1262
1234
  console.log(chalk.green(`✓ Installed expansion pack: ${pack.name} to ${`.${packId}`}`));
1263
1235
  } catch (error) {
1264
- console.error(chalk.red(`Failed to install expansion pack ${packId}: ${error.message}`));
1265
- console.error(chalk.red(`Stack trace: ${error.stack}`));
1236
+ console.error(`Failed to install expansion pack ${packId}: ${error.message}`);
1237
+ console.error(`Stack trace: ${error.stack}`);
1266
1238
  }
1267
1239
  }
1268
1240
 
1269
1241
  return installedFiles;
1270
1242
  }
1271
1243
 
1272
- async resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, spinner) {
1273
- const glob = require('glob');
1244
+ async resolveExpansionPackCoreDependencies(installDir, expansionDotFolder, packId, pack, spinner) {
1274
1245
  const yaml = require('js-yaml');
1275
1246
  const fs = require('fs').promises;
1276
1247
 
1277
1248
  // Find all agent files in the expansion pack
1278
- const agentFiles = glob.sync('agents/*.md', {
1249
+ const agentFiles = await resourceLocator.findFiles('agents/*.md', {
1279
1250
  cwd: expansionDotFolder
1280
1251
  });
1281
1252
 
@@ -1295,48 +1266,59 @@ class Installer {
1295
1266
  const deps = dependencies[depType] || [];
1296
1267
 
1297
1268
  for (const dep of deps) {
1298
- const depFileName = dep.endsWith('.md') ? dep : `${dep}.md`;
1269
+ const depFileName = dep.endsWith('.md') || dep.endsWith('.yaml') ? dep :
1270
+ (depType === 'templates' ? `${dep}.yaml` : `${dep}.md`);
1299
1271
  const expansionDepPath = path.join(expansionDotFolder, depType, depFileName);
1300
1272
 
1301
- // Check if dependency exists in expansion pack
1273
+ // Check if dependency exists in expansion pack dot folder
1302
1274
  if (!(await fileManager.pathExists(expansionDepPath))) {
1303
- // Try to find it in core
1304
- const coreDepPath = path.join(configLoader.getBmadCorePath(), depType, depFileName);
1275
+ // Try to find it in expansion pack source
1276
+ const sourceDepPath = path.join(pack.path, depType, depFileName);
1305
1277
 
1306
- if (await fileManager.pathExists(coreDepPath)) {
1307
- spinner.text = `Copying core dependency ${dep} for ${packId}...`;
1308
-
1309
- // Copy from core to expansion pack dot folder with {root} replacement
1278
+ if (await fileManager.pathExists(sourceDepPath)) {
1279
+ // Copy from expansion pack source
1280
+ spinner.text = `Copying ${packId} dependency ${dep}...`;
1310
1281
  const destPath = path.join(expansionDotFolder, depType, depFileName);
1311
- await fileManager.copyFileWithRootReplacement(coreDepPath, destPath, `.${packId}`);
1312
-
1313
- console.log(chalk.dim(` Added core dependency: ${depType}/${depFileName}`));
1282
+ await fileManager.copyFileWithRootReplacement(sourceDepPath, destPath, `.${packId}`);
1283
+ console.log(chalk.dim(` Added ${packId} dependency: ${depType}/${depFileName}`));
1314
1284
  } else {
1315
- console.warn(chalk.yellow(` Warning: Dependency ${depType}/${dep} not found in core or expansion pack`));
1285
+ // Try to find it in core
1286
+ const coreDepPath = path.join(resourceLocator.getBmadCorePath(), depType, depFileName);
1287
+
1288
+ if (await fileManager.pathExists(coreDepPath)) {
1289
+ spinner.text = `Copying core dependency ${dep} for ${packId}...`;
1290
+
1291
+ // Copy from core to expansion pack dot folder with {root} replacement
1292
+ const destPath = path.join(expansionDotFolder, depType, depFileName);
1293
+ await fileManager.copyFileWithRootReplacement(coreDepPath, destPath, `.${packId}`);
1294
+
1295
+ console.log(chalk.dim(` Added core dependency: ${depType}/${depFileName}`));
1296
+ } else {
1297
+ console.warn(chalk.yellow(` Warning: Dependency ${depType}/${dep} not found in core or expansion pack`));
1298
+ }
1299
+ }
1316
1300
  }
1317
- }
1318
1301
  }
1319
1302
  }
1320
1303
  } catch (error) {
1321
- console.warn(chalk.yellow(` Warning: Could not parse agent dependencies: ${error.message}`));
1304
+ console.warn(` Warning: Could not parse agent dependencies: ${error.message}`);
1322
1305
  }
1323
1306
  }
1324
1307
  }
1325
1308
  }
1326
1309
 
1327
1310
  async resolveExpansionPackCoreAgents(installDir, expansionDotFolder, packId, spinner) {
1328
- const glob = require('glob');
1329
1311
  const yaml = require('js-yaml');
1330
1312
  const fs = require('fs').promises;
1331
1313
 
1332
1314
  // Find all team files in the expansion pack
1333
- const teamFiles = glob.sync('agent-teams/*.yaml', {
1315
+ const teamFiles = await resourceLocator.findFiles('agent-teams/*.yaml', {
1334
1316
  cwd: expansionDotFolder
1335
1317
  });
1336
1318
 
1337
1319
  // Also get existing agents in the expansion pack
1338
1320
  const existingAgents = new Set();
1339
- const agentFiles = glob.sync('agents/*.md', {
1321
+ const agentFiles = await resourceLocator.findFiles('agents/*.md', {
1340
1322
  cwd: expansionDotFolder
1341
1323
  });
1342
1324
  for (const agentFile of agentFiles) {
@@ -1362,7 +1344,7 @@ class Installer {
1362
1344
  for (const agentId of agents) {
1363
1345
  if (!existingAgents.has(agentId)) {
1364
1346
  // Agent not in expansion pack, try to get from core
1365
- const coreAgentPath = path.join(configLoader.getBmadCorePath(), 'agents', `${agentId}.md`);
1347
+ const coreAgentPath = path.join(resourceLocator.getBmadCorePath(), 'agents', `${agentId}.md`);
1366
1348
 
1367
1349
  if (await fileManager.pathExists(coreAgentPath)) {
1368
1350
  spinner.text = `Copying core agent ${agentId} for ${packId}...`;
@@ -1389,13 +1371,14 @@ class Installer {
1389
1371
  const deps = dependencies[depType] || [];
1390
1372
 
1391
1373
  for (const dep of deps) {
1392
- const depFileName = dep.endsWith('.md') || dep.endsWith('.yaml') ? dep : `${dep}.md`;
1374
+ const depFileName = dep.endsWith('.md') || dep.endsWith('.yaml') ? dep :
1375
+ (depType === 'templates' ? `${dep}.yaml` : `${dep}.md`);
1393
1376
  const expansionDepPath = path.join(expansionDotFolder, depType, depFileName);
1394
1377
 
1395
1378
  // Check if dependency exists in expansion pack
1396
1379
  if (!(await fileManager.pathExists(expansionDepPath))) {
1397
1380
  // Try to find it in core
1398
- const coreDepPath = path.join(configLoader.getBmadCorePath(), depType, depFileName);
1381
+ const coreDepPath = path.join(resourceLocator.getBmadCorePath(), depType, depFileName);
1399
1382
 
1400
1383
  if (await fileManager.pathExists(coreDepPath)) {
1401
1384
  const destDepPath = path.join(expansionDotFolder, depType, depFileName);
@@ -1415,7 +1398,7 @@ class Installer {
1415
1398
  }
1416
1399
  }
1417
1400
  } catch (error) {
1418
- console.warn(chalk.yellow(` Warning: Could not parse agent ${agentId} dependencies: ${error.message}`));
1401
+ console.warn(` Warning: Could not parse agent ${agentId} dependencies: ${error.message}`);
1419
1402
  }
1420
1403
  }
1421
1404
  } else {
@@ -1424,7 +1407,7 @@ class Installer {
1424
1407
  }
1425
1408
  }
1426
1409
  } catch (error) {
1427
- console.warn(chalk.yellow(` Warning: Could not parse team file ${teamFile}: ${error.message}`));
1410
+ console.warn(` Warning: Could not parse team file ${teamFile}: ${error.message}`);
1428
1411
  }
1429
1412
  }
1430
1413
  }
@@ -1456,15 +1439,13 @@ class Installer {
1456
1439
  }
1457
1440
 
1458
1441
  async installWebBundles(webBundlesDirectory, config, spinner) {
1459
- // Ensure modules are initialized
1460
- await initializeModules();
1461
1442
 
1462
1443
  try {
1463
1444
  // Find the dist directory in the BMad installation
1464
1445
  const distDir = configLoader.getDistPath();
1465
1446
 
1466
1447
  if (!(await fileManager.pathExists(distDir))) {
1467
- console.warn(chalk.yellow('Web bundles not found. Run "npm run build" to generate them.'));
1448
+ console.warn('Web bundles not found. Run "npm run build" to generate them.');
1468
1449
  return;
1469
1450
  }
1470
1451
 
@@ -1522,15 +1503,12 @@ class Installer {
1522
1503
  console.log(chalk.green(`✓ Installed ${copiedCount} selected web bundles to: ${webBundlesDirectory}`));
1523
1504
  }
1524
1505
  } catch (error) {
1525
- console.error(chalk.red(`Failed to install web bundles: ${error.message}`));
1506
+ console.error(`Failed to install web bundles: ${error.message}`);
1526
1507
  }
1527
1508
  }
1528
1509
 
1529
1510
  async copyCommonItems(installDir, targetSubdir, spinner) {
1530
- // Ensure modules are initialized
1531
- await initializeModules();
1532
1511
 
1533
- const glob = require('glob');
1534
1512
  const fs = require('fs').promises;
1535
1513
  const sourceBase = path.dirname(path.dirname(path.dirname(path.dirname(__filename)))); // Go up to project root
1536
1514
  const commonPath = path.join(sourceBase, 'common');
@@ -1539,12 +1517,12 @@ class Installer {
1539
1517
 
1540
1518
  // Check if common/ exists
1541
1519
  if (!(await fileManager.pathExists(commonPath))) {
1542
- console.warn(chalk.yellow('Warning: common/ folder not found'));
1520
+ console.warn('Warning: common/ folder not found');
1543
1521
  return copiedFiles;
1544
1522
  }
1545
1523
 
1546
1524
  // Copy all items from common/ to target
1547
- const commonItems = glob.sync('**/*', {
1525
+ const commonItems = await resourceLocator.findFiles('**/*', {
1548
1526
  cwd: commonPath,
1549
1527
  nodir: true
1550
1528
  });
@@ -1641,7 +1619,7 @@ class Installer {
1641
1619
  if (file.endsWith('install-manifest.yaml')) continue;
1642
1620
 
1643
1621
  const relativePath = file.replace(`.${packId}/`, '');
1644
- const sourcePath = path.join(pack.packPath, relativePath);
1622
+ const sourcePath = path.join(pack.path, relativePath);
1645
1623
  const destPath = path.join(installDir, file);
1646
1624
 
1647
1625
  // Check if this is a common/ file that needs special processing
@@ -1677,8 +1655,8 @@ class Installer {
1677
1655
  }
1678
1656
 
1679
1657
  } catch (error) {
1680
- spinner.fail(`Failed to repair ${pack.name}`);
1681
- console.error(chalk.red(`Error: ${error.message}`));
1658
+ if (spinner) spinner.fail(`Failed to repair ${pack.name}`);
1659
+ console.error(`Error: ${error.message}`);
1682
1660
  }
1683
1661
  }
1684
1662
 
@@ -1730,7 +1708,7 @@ class Installer {
1730
1708
  }
1731
1709
 
1732
1710
  } catch (error) {
1733
- console.warn(chalk.yellow(`Warning: Could not cleanup legacy .yml files: ${error.message}`));
1711
+ console.warn(`Warning: Could not cleanup legacy .yml files: ${error.message}`);
1734
1712
  }
1735
1713
  }
1736
1714