bmad-method 4.2.0 → 4.4.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 (90) hide show
  1. package/.bmad-core/agents/analyst.md +14 -20
  2. package/.bmad-core/agents/architect.md +15 -20
  3. package/.bmad-core/agents/bmad-master.md +18 -26
  4. package/.bmad-core/agents/bmad-orchestrator.md +16 -28
  5. package/.bmad-core/agents/dev.md +5 -4
  6. package/.bmad-core/agents/pm.md +11 -16
  7. package/.bmad-core/agents/sm.md +20 -25
  8. package/.bmad-core/bmad-core-config.yml +60 -0
  9. package/.bmad-core/data/bmad-kb.md +12 -1
  10. package/.bmad-core/tasks/doc-migration-task.md +91 -146
  11. package/.bmad-core/tasks/document-project.md +389 -0
  12. package/.bmad-core/tasks/generate-ai-frontend-prompt.md +41 -48
  13. package/.bmad-core/tasks/index-docs.md +8 -3
  14. package/.bmad-core/templates/architecture-tmpl.md +15 -12
  15. package/.bmad-core/templates/fullstack-architecture-tmpl.md +85 -103
  16. package/.bmad-core/templates/prd-tmpl.md +1 -1
  17. package/.bmad-core/templates/simple-project-prd-tmpl.md +461 -0
  18. package/.bmad-core/templates/story-tmpl.md +2 -2
  19. package/.bmad-core/utils/workflow-management.md +14 -15
  20. package/.bmad-core/web-bundles/agents/analyst.txt +26 -21
  21. package/.bmad-core/web-bundles/agents/architect.txt +605 -233
  22. package/.bmad-core/web-bundles/agents/bmad-master.txt +457 -1039
  23. package/.bmad-core/web-bundles/agents/bmad-orchestrator.txt +36 -903
  24. package/.bmad-core/web-bundles/agents/dev.txt +5 -4
  25. package/.bmad-core/web-bundles/agents/pm.txt +476 -17
  26. package/.bmad-core/web-bundles/agents/po.txt +2 -2
  27. package/.bmad-core/web-bundles/agents/sm.txt +22 -27
  28. package/.bmad-core/web-bundles/agents/ux-expert.txt +41 -48
  29. package/.bmad-core/web-bundles/teams/team-all.txt +4394 -4447
  30. package/.bmad-core/web-bundles/teams/team-fullstack.txt +2760 -2809
  31. package/.bmad-core/web-bundles/teams/team-no-ui.txt +2718 -2760
  32. package/.bmad-core/workflows/greenfield-fullstack.yml +3 -3
  33. package/.claude/commands/analyst.md +14 -20
  34. package/.claude/commands/architect.md +15 -20
  35. package/.claude/commands/bmad-master.md +18 -26
  36. package/.claude/commands/bmad-orchestrator.md +16 -28
  37. package/.claude/commands/dev.md +5 -4
  38. package/.claude/commands/pm.md +11 -16
  39. package/.claude/commands/sm.md +20 -25
  40. package/.cursor/rules/analyst.mdc +13 -19
  41. package/.cursor/rules/architect.mdc +14 -19
  42. package/.cursor/rules/bmad-master.mdc +18 -26
  43. package/.cursor/rules/bmad-orchestrator.mdc +15 -27
  44. package/.cursor/rules/dev.mdc +5 -4
  45. package/.cursor/rules/pm.mdc +11 -16
  46. package/.cursor/rules/sm.mdc +19 -24
  47. package/.releaserc.json +2 -1
  48. package/.vscode/settings.json +4 -0
  49. package/.windsurf/rules/analyst.md +13 -19
  50. package/.windsurf/rules/architect.md +14 -19
  51. package/.windsurf/rules/bmad-master.md +18 -26
  52. package/.windsurf/rules/bmad-orchestrator.md +15 -27
  53. package/.windsurf/rules/dev.md +5 -4
  54. package/.windsurf/rules/pm.md +11 -16
  55. package/.windsurf/rules/sm.md +19 -24
  56. package/CHANGELOG.md +120 -2
  57. package/CONTRIBUTING.md +2 -0
  58. package/README.md +20 -2
  59. package/{.bmad-core → creator-tools}/tasks/create-agent.md +10 -12
  60. package/{.bmad-core/tasks/create-expansion-pack.md → creator-tools/tasks/generate-expansion-pack.md} +8 -6
  61. package/docs/bmad-workflow-guide.md +161 -0
  62. package/docs/claude-code-guide.md +119 -0
  63. package/docs/core-architecture.md +213 -0
  64. package/docs/cursor-guide.md +127 -0
  65. package/docs/how-to-contribute-with-pull-requests.md +141 -0
  66. package/docs/roo-code-guide.md +140 -0
  67. package/docs/user-guide.md +1044 -0
  68. package/docs/versioning-and-releases.md +4 -4
  69. package/docs/windsurf-guide.md +127 -0
  70. package/expansion-packs/README.md +1 -111
  71. package/expansion-packs/infrastructure-devops/agents/infra-devops-platform.md +3 -3
  72. package/expansion-packs/infrastructure-devops/tasks/create-doc.md +74 -0
  73. package/package.json +19 -13
  74. package/tools/builders/web-builder.js +16 -15
  75. package/tools/installer/README.md +2 -2
  76. package/tools/installer/bin/bmad.js +50 -29
  77. package/tools/installer/lib/file-manager.js +20 -3
  78. package/tools/installer/lib/ide-setup.js +11 -1
  79. package/tools/installer/lib/installer.js +149 -29
  80. package/tools/installer/package-lock.json +537 -335
  81. package/tools/installer/package.json +7 -7
  82. package/tools/lib/dependency-resolver.js +1 -1
  83. package/tools/semantic-release-sync-installer.js +31 -0
  84. package/tools/sync-installer-version.js +34 -0
  85. package/tools/upgraders/v3-to-v4-upgrader.js +18 -13
  86. package/tools/version-bump.js +33 -26
  87. package/tools/yaml-format.js +54 -25
  88. package/.bmad-core/schemas/agent-team-schema.yml +0 -153
  89. package/.bmad-core/tasks/create-team.md +0 -229
  90. package/.claude/settings.local.json +0 -22
@@ -1,24 +1,34 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { program } = require('commander');
4
- const inquirer = require('inquirer');
5
- const chalk = require('chalk');
6
- const path = require('path');
4
+
5
+ // Dynamic imports for ES modules
6
+ let chalk, inquirer;
7
+
8
+ // Initialize ES modules
9
+ async function initializeModules() {
10
+ if (!chalk) {
11
+ chalk = (await import('chalk')).default;
12
+ inquirer = (await import('inquirer')).default;
13
+ }
14
+ }
7
15
 
8
16
  // Handle both execution contexts (from root via npx or from installer directory)
9
- let version, installer;
17
+ let version;
18
+ let installer;
10
19
  try {
11
20
  // Try installer context first (when run from tools/installer/)
12
21
  version = require('../package.json').version;
13
22
  installer = require('../lib/installer');
14
23
  } catch (e) {
15
24
  // Fall back to root context (when run via npx from GitHub)
25
+ console.log(`Installer context not found (${e.message}), trying root context...`);
16
26
  try {
17
27
  version = require('../../../package.json').version;
18
28
  installer = require('../../../tools/installer/lib/installer');
19
29
  } catch (e2) {
20
- console.error(chalk.red('Error: Could not load required modules. Please ensure you are running from the correct directory.'));
21
- console.error(chalk.yellow('Debug info:'), {
30
+ console.error('Error: Could not load required modules. Please ensure you are running from the correct directory.');
31
+ console.error('Debug info:', {
22
32
  __dirname,
23
33
  cwd: process.cwd(),
24
34
  error: e2.message
@@ -36,25 +46,27 @@ program
36
46
  .description('Install BMAD Method agents and tools')
37
47
  .option('-f, --full', 'Install complete .bmad-core folder')
38
48
  .option('-a, --agent <agent>', 'Install specific agent with dependencies')
39
- .option('-d, --directory <path>', 'Installation directory (default: ./bmad-core)')
40
- .option('-i, --ide <ide>', 'Configure for specific IDE (cursor, claude-code, windsurf, roo)')
49
+ .option('-d, --directory <path>', 'Installation directory (default: .bmad-core)')
50
+ .option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo)')
41
51
  .action(async (options) => {
42
52
  try {
53
+ await initializeModules();
43
54
  if (!options.full && !options.agent) {
44
55
  // Interactive mode
45
- const answers = await promptInstallation(options);
56
+ const answers = await promptInstallation();
46
57
  await installer.install(answers);
47
58
  } else {
48
59
  // Direct mode
49
60
  const config = {
50
61
  installType: options.full ? 'full' : 'single-agent',
51
62
  agent: options.agent,
52
- directory: options.directory || './.bmad-core',
53
- ide: options.ide
63
+ directory: options.directory || '.bmad-core',
64
+ ides: options.ide || []
54
65
  };
55
66
  await installer.install(config);
56
67
  }
57
68
  } catch (error) {
69
+ if (!chalk) await initializeModules();
58
70
  console.error(chalk.red('Installation failed:'), error.message);
59
71
  process.exit(1);
60
72
  }
@@ -65,10 +77,11 @@ program
65
77
  .description('Update existing BMAD installation')
66
78
  .option('--force', 'Force update, overwriting modified files')
67
79
  .option('--dry-run', 'Show what would be updated without making changes')
68
- .action(async (options) => {
80
+ .action(async () => {
69
81
  try {
70
- await installer.update(options);
82
+ await installer.update();
71
83
  } catch (error) {
84
+ if (!chalk) await initializeModules();
72
85
  console.error(chalk.red('Update failed:'), error.message);
73
86
  process.exit(1);
74
87
  }
@@ -81,6 +94,7 @@ program
81
94
  try {
82
95
  await installer.listAgents();
83
96
  } catch (error) {
97
+ if (!chalk) await initializeModules();
84
98
  console.error(chalk.red('Error:'), error.message);
85
99
  process.exit(1);
86
100
  }
@@ -93,27 +107,29 @@ program
93
107
  try {
94
108
  await installer.showStatus();
95
109
  } catch (error) {
110
+ if (!chalk) await initializeModules();
96
111
  console.error(chalk.red('Error:'), error.message);
97
112
  process.exit(1);
98
113
  }
99
114
  });
100
115
 
101
- async function promptInstallation(options) {
116
+ async function promptInstallation() {
117
+ await initializeModules();
102
118
  console.log(chalk.bold.blue(`\nWelcome to BMAD Method Installer v${version}\n`));
103
-
119
+
104
120
  const answers = {};
105
-
121
+
106
122
  // Ask for installation directory
107
123
  const { directory } = await inquirer.prompt([
108
124
  {
109
125
  type: 'input',
110
126
  name: 'directory',
111
127
  message: 'Where would you like to install BMAD?',
112
- default: './.bmad-core'
128
+ default: '.bmad-core'
113
129
  }
114
130
  ]);
115
131
  answers.directory = directory;
116
-
132
+
117
133
  // Ask for installation type
118
134
  const { installType } = await inquirer.prompt([
119
135
  {
@@ -133,7 +149,7 @@ async function promptInstallation(options) {
133
149
  }
134
150
  ]);
135
151
  answers.installType = installType;
136
-
152
+
137
153
  // If single agent, ask which one
138
154
  if (installType === 'single-agent') {
139
155
  const agents = await installer.getAvailableAgents();
@@ -150,24 +166,29 @@ async function promptInstallation(options) {
150
166
  ]);
151
167
  answers.agent = agent;
152
168
  }
153
-
169
+
154
170
  // Ask for IDE configuration
155
- const { ide } = await inquirer.prompt([
171
+ const { ides } = await inquirer.prompt([
156
172
  {
157
- type: 'list',
158
- name: 'ide',
159
- message: 'Which IDE are you using?',
173
+ type: 'checkbox',
174
+ name: 'ides',
175
+ message: 'Which IDE(s) are you using? (Select all that apply)',
160
176
  choices: [
161
177
  { name: 'Cursor', value: 'cursor' },
162
178
  { name: 'Claude Code', value: 'claude-code' },
163
179
  { name: 'Windsurf', value: 'windsurf' },
164
- { name: 'Roo Code', value: 'roo' },
165
- { name: 'Other/Manual setup', value: null }
166
- ]
180
+ { name: 'Roo Code', value: 'roo' }
181
+ ],
182
+ validate: (answer) => {
183
+ if (answer.length < 1) {
184
+ return 'You must choose at least one IDE, or press Ctrl+C to skip IDE setup.';
185
+ }
186
+ return true;
187
+ }
167
188
  }
168
189
  ]);
169
- answers.ide = ide;
170
-
190
+ answers.ides = ides;
191
+
171
192
  return answers;
172
193
  }
173
194
 
@@ -2,7 +2,16 @@ const fs = require("fs-extra");
2
2
  const path = require("path");
3
3
  const crypto = require("crypto");
4
4
  const glob = require("glob");
5
- const chalk = require("chalk");
5
+
6
+ // Dynamic import for ES module
7
+ let chalk;
8
+
9
+ // Initialize ES modules
10
+ async function initializeModules() {
11
+ if (!chalk) {
12
+ chalk = (await import("chalk")).default;
13
+ }
14
+ }
6
15
 
7
16
  class FileManager {
8
17
  constructor() {
@@ -16,6 +25,7 @@ class FileManager {
16
25
  await fs.copy(source, destination);
17
26
  return true;
18
27
  } catch (error) {
28
+ await initializeModules();
19
29
  console.error(chalk.red(`Failed to copy ${source}:`), error.message);
20
30
  return false;
21
31
  }
@@ -27,6 +37,7 @@ class FileManager {
27
37
  await fs.copy(source, destination);
28
38
  return true;
29
39
  } catch (error) {
40
+ await initializeModules();
30
41
  console.error(
31
42
  chalk.red(`Failed to copy directory ${source}:`),
32
43
  error.message
@@ -72,11 +83,12 @@ class FileManager {
72
83
  );
73
84
 
74
85
  const manifest = {
75
- version: require("../package.json").version,
86
+ version: require("../../../package.json").version,
76
87
  installed_at: new Date().toISOString(),
77
88
  install_type: config.installType,
78
89
  agent: config.agent || null,
79
90
  ide_setup: config.ide || null,
91
+ ides_setup: config.ides || [],
80
92
  files: [],
81
93
  };
82
94
 
@@ -145,7 +157,12 @@ class FileManager {
145
157
  }
146
158
 
147
159
  async ensureDirectory(dirPath) {
148
- await fs.ensureDir(dirPath);
160
+ try {
161
+ await fs.ensureDir(dirPath);
162
+ return true;
163
+ } catch (error) {
164
+ throw error;
165
+ }
149
166
  }
150
167
 
151
168
  async pathExists(filePath) {
@@ -1,10 +1,20 @@
1
1
  const path = require("path");
2
2
  const fileManager = require("./file-manager");
3
3
  const configLoader = require("./config-loader");
4
- const chalk = require("chalk");
4
+
5
+ // Dynamic import for ES module
6
+ let chalk;
7
+
8
+ // Initialize ES modules
9
+ async function initializeModules() {
10
+ if (!chalk) {
11
+ chalk = (await import("chalk")).default;
12
+ }
13
+ }
5
14
 
6
15
  class IdeSetup {
7
16
  async setup(ide, installDir, selectedAgent = null) {
17
+ await initializeModules();
8
18
  const ideConfig = await configLoader.getIdeConfiguration(ide);
9
19
 
10
20
  if (!ideConfig) {
@@ -1,18 +1,94 @@
1
- const path = require("path");
2
- const chalk = require("chalk");
3
- const ora = require("ora");
4
- const inquirer = require("inquirer");
1
+ const path = require("node:path");
5
2
  const fileManager = require("./file-manager");
6
3
  const configLoader = require("./config-loader");
7
4
  const ideSetup = require("./ide-setup");
8
5
 
6
+ // Dynamic imports for ES modules
7
+ let chalk, ora, inquirer;
8
+
9
+ // Initialize ES modules
10
+ async function initializeModules() {
11
+ if (!chalk) {
12
+ chalk = (await import("chalk")).default;
13
+ ora = (await import("ora")).default;
14
+ inquirer = (await import("inquirer")).default;
15
+ }
16
+ }
17
+
9
18
  class Installer {
10
19
  async install(config) {
20
+ // Initialize ES modules
21
+ await initializeModules();
22
+
11
23
  const spinner = ora("Analyzing installation directory...").start();
12
24
 
13
25
  try {
14
26
  // Resolve installation directory
15
- const installDir = path.resolve(config.directory);
27
+ let installDir = path.resolve(config.directory);
28
+ if (path.basename(installDir) === '.bmad-core') {
29
+ // If user points directly to .bmad-core, treat its parent as the project root
30
+ installDir = path.dirname(installDir);
31
+ }
32
+
33
+ // Check if directory exists and handle non-existent directories
34
+ if (!(await fileManager.pathExists(installDir))) {
35
+ spinner.stop();
36
+ console.log(chalk.yellow(`\nThe directory ${chalk.bold(installDir)} does not exist.`));
37
+
38
+ const { action } = await inquirer.prompt([
39
+ {
40
+ type: 'list',
41
+ name: 'action',
42
+ message: 'What would you like to do?',
43
+ choices: [
44
+ {
45
+ name: 'Create the directory and continue',
46
+ value: 'create'
47
+ },
48
+ {
49
+ name: 'Choose a different directory',
50
+ value: 'change'
51
+ },
52
+ {
53
+ name: 'Cancel installation',
54
+ value: 'cancel'
55
+ }
56
+ ]
57
+ }
58
+ ]);
59
+
60
+ if (action === 'cancel') {
61
+ console.log(chalk.red('Installation cancelled.'));
62
+ process.exit(0);
63
+ } else if (action === 'change') {
64
+ const { newDirectory } = await inquirer.prompt([
65
+ {
66
+ type: 'input',
67
+ name: 'newDirectory',
68
+ message: 'Enter the new directory path:',
69
+ validate: (input) => {
70
+ if (!input.trim()) {
71
+ return 'Please enter a valid directory path';
72
+ }
73
+ return true;
74
+ }
75
+ }
76
+ ]);
77
+ config.directory = newDirectory;
78
+ return await this.install(config); // Recursive call with new directory
79
+ } else if (action === 'create') {
80
+ try {
81
+ await fileManager.ensureDirectory(installDir);
82
+ console.log(chalk.green(`✓ Created directory: ${installDir}`));
83
+ } catch (error) {
84
+ console.error(chalk.red(`Failed to create directory: ${error.message}`));
85
+ console.error(chalk.yellow('You may need to check permissions or use a different path.'));
86
+ process.exit(1);
87
+ }
88
+ }
89
+
90
+ spinner.start("Analyzing installation directory...");
91
+ }
16
92
 
17
93
  // Detect current state
18
94
  const state = await this.detectInstallationState(installDir);
@@ -53,6 +129,8 @@ class Installer {
53
129
  }
54
130
 
55
131
  async detectInstallationState(installDir) {
132
+ // Ensure modules are initialized
133
+ await initializeModules();
56
134
  const state = {
57
135
  type: "clean",
58
136
  hasV4Manifest: false,
@@ -75,7 +153,7 @@ class Installer {
75
153
  state.type = "v4_existing";
76
154
  state.hasV4Manifest = true;
77
155
  state.hasBmadCore = true;
78
- state.manifest = await fileManager.readManifest(bmadCorePath);
156
+ state.manifest = await fileManager.readManifest(installDir);
79
157
  return state;
80
158
  }
81
159
 
@@ -103,15 +181,17 @@ class Installer {
103
181
  });
104
182
 
105
183
  if (files.length > 0) {
106
- state.type = "unknown_existing";
184
+ // Directory has other files, but no BMAD installation.
185
+ // Treat as clean install but record that it isn't empty.
107
186
  state.hasOtherFiles = true;
108
- return state;
109
187
  }
110
188
 
111
189
  return state; // clean install
112
190
  }
113
191
 
114
192
  async performFreshInstall(config, installDir, spinner) {
193
+ // Ensure modules are initialized
194
+ await initializeModules();
115
195
  spinner.text = "Installing BMAD Method...";
116
196
 
117
197
  let files = [];
@@ -182,9 +262,12 @@ class Installer {
182
262
  }
183
263
 
184
264
  // Set up IDE integration if requested
185
- if (config.ide) {
186
- spinner.text = `Setting up ${config.ide} integration...`;
187
- await ideSetup.setup(config.ide, installDir, config.agent);
265
+ const ides = config.ides || (config.ide ? [config.ide] : []);
266
+ if (ides.length > 0) {
267
+ for (const ide of ides) {
268
+ spinner.text = `Setting up ${ide} integration...`;
269
+ await ideSetup.setup(ide, installDir, config.agent);
270
+ }
188
271
  }
189
272
 
190
273
  // Create manifest
@@ -196,6 +279,8 @@ class Installer {
196
279
  }
197
280
 
198
281
  async handleExistingV4Installation(config, installDir, state, spinner) {
282
+ // Ensure modules are initialized
283
+ await initializeModules();
199
284
  spinner.stop();
200
285
 
201
286
  console.log(chalk.yellow("\n🔍 Found existing BMAD v4 installation"));
@@ -222,7 +307,7 @@ class Installer {
222
307
 
223
308
  switch (action) {
224
309
  case "update":
225
- return await this.performUpdate(installDir, state.manifest, spinner);
310
+ return await this.performUpdate(config, installDir, state.manifest, spinner);
226
311
  case "reinstall":
227
312
  return await this.performReinstall(config, installDir, spinner);
228
313
  case "cancel":
@@ -232,6 +317,8 @@ class Installer {
232
317
  }
233
318
 
234
319
  async handleV3Installation(config, installDir, state, spinner) {
320
+ // Ensure modules are initialized
321
+ await initializeModules();
235
322
  spinner.stop();
236
323
 
237
324
  console.log(
@@ -253,11 +340,12 @@ class Installer {
253
340
  ]);
254
341
 
255
342
  switch (action) {
256
- case "upgrade":
343
+ case "upgrade": {
257
344
  console.log(chalk.cyan("\n📦 Starting v3 to v4 upgrade process..."));
258
345
  const V3ToV4Upgrader = require("../../upgraders/v3-to-v4-upgrader");
259
346
  const upgrader = new V3ToV4Upgrader();
260
347
  return await upgrader.upgrade({ projectPath: installDir });
348
+ }
261
349
  case "alongside":
262
350
  return await this.performFreshInstall(config, installDir, spinner);
263
351
  case "cancel":
@@ -267,6 +355,8 @@ class Installer {
267
355
  }
268
356
 
269
357
  async handleUnknownInstallation(config, installDir, state, spinner) {
358
+ // Ensure modules are initialized
359
+ await initializeModules();
270
360
  spinner.stop();
271
361
 
272
362
  console.log(chalk.yellow("\n⚠️ Directory contains existing files"));
@@ -295,7 +385,7 @@ class Installer {
295
385
  switch (action) {
296
386
  case "force":
297
387
  return await this.performFreshInstall(config, installDir, spinner);
298
- case "different":
388
+ case "different": {
299
389
  const { newDir } = await inquirer.prompt([
300
390
  {
301
391
  type: "input",
@@ -306,13 +396,14 @@ class Installer {
306
396
  ]);
307
397
  config.directory = newDir;
308
398
  return await this.install(config);
399
+ }
309
400
  case "cancel":
310
401
  console.log("Installation cancelled.");
311
402
  return;
312
403
  }
313
404
  }
314
405
 
315
- async performUpdate(installDir, manifest, spinner) {
406
+ async performUpdate(newConfig, installDir, manifest, spinner) {
316
407
  spinner.start("Checking for updates...");
317
408
 
318
409
  try {
@@ -326,7 +417,9 @@ class Installer {
326
417
  if (modifiedFiles.length > 0) {
327
418
  spinner.warn("Found modified files");
328
419
  console.log(chalk.yellow("\nThe following files have been modified:"));
329
- modifiedFiles.forEach((file) => console.log(` - ${file}`));
420
+ for (const file of modifiedFiles) {
421
+ console.log(` - ${file}`);
422
+ }
330
423
 
331
424
  const { action } = await inquirer.prompt([
332
425
  {
@@ -364,7 +457,7 @@ class Installer {
364
457
  installType: manifest.install_type,
365
458
  agent: manifest.agent,
366
459
  directory: installDir,
367
- ide: manifest.ide_setup,
460
+ ide: newConfig.ide || manifest.ide_setup, // Use new IDE choice if provided
368
461
  };
369
462
 
370
463
  await this.performFreshInstall(config, installDir, spinner);
@@ -389,13 +482,16 @@ class Installer {
389
482
  showSuccessMessage(config, installDir) {
390
483
  console.log(chalk.green("\n✓ BMAD Method installed successfully!\n"));
391
484
 
392
- if (config.ide) {
393
- const ideConfig = configLoader.getIdeConfiguration(config.ide);
394
- if (ideConfig && ideConfig.instructions) {
395
- console.log(
396
- chalk.bold("To use BMAD agents in " + ideConfig.name + ":")
397
- );
398
- console.log(ideConfig.instructions);
485
+ const ides = config.ides || (config.ide ? [config.ide] : []);
486
+ if (ides.length > 0) {
487
+ for (const ide of ides) {
488
+ const ideConfig = configLoader.getIdeConfiguration(ide);
489
+ if (ideConfig?.instructions) {
490
+ console.log(
491
+ chalk.bold(`To use BMAD agents in ${ideConfig.name}:`)
492
+ );
493
+ console.log(ideConfig.instructions);
494
+ }
399
495
  }
400
496
  } else {
401
497
  console.log(chalk.yellow("No IDE configuration was set up."));
@@ -405,6 +501,25 @@ class Installer {
405
501
  );
406
502
  }
407
503
 
504
+ // Information about installation components
505
+ console.log(chalk.bold("\n🎯 Installation Summary:"));
506
+ console.log(chalk.green("✓ .bmad-core framework installed with all agents and workflows"));
507
+
508
+ if (ides.length > 0) {
509
+ const ideNames = ides.map(ide => {
510
+ const ideConfig = configLoader.getIdeConfiguration(ide);
511
+ return ideConfig?.name || ide;
512
+ }).join(", ");
513
+ console.log(chalk.green(`✓ IDE rules and configurations set up for: ${ideNames}`));
514
+ }
515
+
516
+ // Information about web bundles
517
+ console.log(chalk.bold("\n📦 Web Bundles Available:"));
518
+ console.log("Self-contained web bundles have been included in your installation:");
519
+ console.log(chalk.cyan(` ${installDir}/.bmad-core/web-bundles/`));
520
+ console.log("These bundles work independently without this installation and can be");
521
+ console.log("shared, moved, or used in other projects as standalone files.");
522
+
408
523
  if (config.installType === "single-agent") {
409
524
  console.log(
410
525
  chalk.dim(
@@ -418,7 +533,9 @@ class Installer {
418
533
  }
419
534
 
420
535
  // Legacy method for backward compatibility
421
- async update(options) {
536
+ async update() {
537
+ // Initialize ES modules
538
+ await initializeModules();
422
539
  console.log(chalk.yellow('The "update" command is deprecated.'));
423
540
  console.log(
424
541
  'Please use "install" instead - it will detect and offer to update existing installations.'
@@ -432,19 +549,20 @@ class Installer {
432
549
  ide: null,
433
550
  };
434
551
  return await this.install(config);
435
- } else {
436
- console.log(chalk.red("No BMAD installation found."));
437
552
  }
553
+ console.log(chalk.red("No BMAD installation found."));
438
554
  }
439
555
 
440
556
  async listAgents() {
557
+ // Initialize ES modules
558
+ await initializeModules();
441
559
  const agents = await configLoader.getAvailableAgents();
442
560
 
443
561
  console.log(chalk.bold("\nAvailable BMAD Agents:\n"));
444
562
 
445
- agents.forEach((agent) => {
563
+ for (const agent of agents) {
446
564
  console.log(chalk.cyan(` ${agent.id.padEnd(20)}`), agent.description);
447
- });
565
+ }
448
566
 
449
567
  console.log(
450
568
  chalk.dim("\nInstall with: npx bmad-method install --agent=<id>\n")
@@ -452,6 +570,8 @@ class Installer {
452
570
  }
453
571
 
454
572
  async showStatus() {
573
+ // Initialize ES modules
574
+ await initializeModules();
455
575
  const installDir = await this.findInstallation();
456
576
 
457
577
  if (!installDir) {