bmad-method 4.30.1 → 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.
- package/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/bmad-core/core-config.yaml +0 -1
- package/bmad-core/data/bmad-kb.md +1 -1
- package/dist/agents/analyst.txt +1 -1
- package/dist/agents/bmad-master.txt +1 -1
- package/dist/agents/bmad-orchestrator.txt +1 -1
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +2409 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +1480 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +826 -0
- package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +10690 -0
- package/dist/teams/team-all.txt +1 -1
- package/dist/teams/team-fullstack.txt +1 -1
- package/dist/teams/team-ide-minimal.txt +1 -1
- package/dist/teams/team-no-ui.txt +1 -1
- package/docs/bmad-workflow-guide.md +2 -2
- package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +2 -2
- package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +13 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +72 -0
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +78 -0
- package/expansion-packs/{bmad-creator-tools/agents/bmad-the-creator.md → bmad-2d-unity-game-dev/agents/game-sm.md} +26 -28
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +201 -0
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +160 -0
- package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +6 -0
- package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +251 -0
- package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +590 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +111 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +217 -0
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +308 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +545 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +356 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +343 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +256 -0
- package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +484 -0
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +183 -0
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +175 -0
- package/expansion-packs/bmad-infrastructure-devops/config.yaml +2 -2
- package/package.json +4 -8
- package/tools/bump-all-versions.js +8 -9
- package/tools/bump-expansion-version.js +40 -35
- package/tools/installer/bin/bmad.js +8 -21
- package/tools/installer/lib/file-manager.js +76 -44
- package/tools/installer/lib/ide-base-setup.js +227 -0
- package/tools/installer/lib/ide-setup.js +14 -60
- package/tools/installer/lib/installer.js +99 -121
- package/tools/installer/lib/memory-profiler.js +224 -0
- package/tools/installer/lib/module-manager.js +110 -0
- package/tools/installer/lib/resource-locator.js +310 -0
- package/tools/installer/package.json +1 -1
- package/tools/semantic-release-sync-installer.js +20 -21
- package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +0 -2008
- package/expansion-packs/bmad-creator-tools/README.md +0 -8
- package/expansion-packs/bmad-creator-tools/config.yaml +0 -6
- package/expansion-packs/bmad-creator-tools/tasks/create-agent.md +0 -200
- package/expansion-packs/bmad-creator-tools/tasks/generate-expansion-pack.md +0 -1020
- package/expansion-packs/bmad-creator-tools/templates/agent-teams-tmpl.yaml +0 -178
- package/expansion-packs/bmad-creator-tools/templates/agent-tmpl.yaml +0 -154
- package/expansion-packs/bmad-creator-tools/templates/expansion-pack-plan-tmpl.yaml +0 -120
- 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
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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(
|
|
97
|
+
console.log(`✓ Created directory: ${installDir}`);
|
|
110
98
|
} catch (error) {
|
|
111
|
-
console.error(
|
|
112
|
-
console.error(
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
264
|
+
const { all: dependencies } = await resourceLocator.getAgentDependencies(
|
|
279
265
|
config.agent
|
|
280
266
|
);
|
|
281
|
-
const sourceBase =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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}
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1004
|
+
return resourceLocator.getAvailableAgents();
|
|
1033
1005
|
}
|
|
1034
1006
|
|
|
1035
1007
|
async getAvailableExpansionPacks() {
|
|
1036
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
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
|
|
1226
|
+
const foundFiles = await resourceLocator.findFiles('**/*', {
|
|
1256
1227
|
cwd: expansionDotFolder,
|
|
1257
1228
|
nodir: true
|
|
1258
|
-
})
|
|
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(
|
|
1265
|
-
console.error(
|
|
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 =
|
|
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 :
|
|
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
|
|
1304
|
-
const
|
|
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(
|
|
1307
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 :
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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.
|
|
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(
|
|
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(
|
|
1711
|
+
console.warn(`Warning: Could not cleanup legacy .yml files: ${error.message}`);
|
|
1734
1712
|
}
|
|
1735
1713
|
}
|
|
1736
1714
|
|