bmad-method 4.27.6 → 4.29.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 (46) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bmad-core/agents/bmad-master.md +2 -4
  3. package/bmad-core/agents/bmad-orchestrator.md +0 -3
  4. package/bmad-core/core-config.yaml +1 -5
  5. package/bmad-core/data/bmad-kb.md +2 -2
  6. package/bmad-core/tasks/correct-course.md +9 -12
  7. package/bmad-core/tasks/create-brownfield-story.md +10 -61
  8. package/bmad-core/tasks/create-deep-research-prompt.md +5 -17
  9. package/bmad-core/tasks/create-next-story.md +3 -4
  10. package/bmad-core/tasks/document-project.md +37 -13
  11. package/bmad-core/tasks/facilitate-brainstorming-session.md +1 -1
  12. package/bmad-core/tasks/generate-ai-frontend-prompt.md +1 -1
  13. package/bmad-core/tasks/kb-mode-interaction.md +8 -3
  14. package/bmad-core/tasks/review-story.md +3 -3
  15. package/bmad-core/tasks/shard-doc.md +5 -9
  16. package/common/tasks/create-doc.md +4 -0
  17. package/dist/agents/analyst.txt +43 -31
  18. package/dist/agents/architect.txt +42 -30
  19. package/dist/agents/bmad-master.txt +61 -602
  20. package/dist/agents/bmad-orchestrator.txt +7 -548
  21. package/dist/agents/pm.txt +19 -38
  22. package/dist/agents/po.txt +14 -21
  23. package/dist/agents/qa.txt +3 -3
  24. package/dist/agents/sm.txt +11 -15
  25. package/dist/agents/ux-expert.txt +6 -18
  26. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +5 -17
  27. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +50 -579
  28. package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +5 -17
  29. package/dist/teams/team-all.txt +70 -607
  30. package/dist/teams/team-fullstack.txt +65 -601
  31. package/dist/teams/team-ide-minimal.txt +26 -575
  32. package/dist/teams/team-no-ui.txt +64 -600
  33. package/docs/agentic-tools/claude-code-guide.md +1 -1
  34. package/docs/agentic-tools/gemini-cli-guide.md +6 -7
  35. package/docs/bmad-workflow-guide.md +1 -0
  36. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +1 -0
  37. package/expansion-packs/bmad-creator-tools/config.yaml +1 -0
  38. package/expansion-packs/bmad-infrastructure-devops/config.yaml +1 -0
  39. package/package.json +1 -1
  40. package/tools/installer/config/install.config.yaml +7 -6
  41. package/tools/installer/lib/ide-setup.js +406 -49
  42. package/tools/installer/package.json +1 -1
  43. package/tools/upgraders/v3-to-v4-upgrader.js +1 -1
  44. package/bmad-core/tasks/create-workflow-plan.md +0 -289
  45. package/bmad-core/tasks/doc-migration-task.md +0 -143
  46. package/bmad-core/tasks/update-workflow-plan.md +0 -248
@@ -7,7 +7,7 @@ For the complete workflow, see the [BMad Workflow Guide](../bmad-workflow-guide.
7
7
  When running `npx bmad-method install`, select **Claude Code** as your IDE. This creates:
8
8
 
9
9
  - `.bmad-core/` folder with all agents
10
- - `.claude/commands/` folder with agent command files (`.md`)
10
+ - `.claude/commands/BMad` folder with agent command files (`.md`)
11
11
 
12
12
  ## Using BMad Agents in Claude Code
13
13
 
@@ -6,23 +6,22 @@ For the complete workflow, see the [BMad Workflow Guide](../bmad-workflow-guide.
6
6
 
7
7
  When running `npx bmad-method install`, select **Gemini CLI** as your IDE. This creates:
8
8
 
9
- - `.gemini/agents/` directory with all agent context files
10
- - `.gemini/settings.json` configured to load all agents automatically
9
+ - `.gemini/bmad-method/` directory with all agent context in GEMINI.md file
11
10
 
12
11
  ## Using BMad Agents with Gemini CLI
13
12
 
14
13
  Simply mention the agent in your prompt:
15
14
 
16
- - "As @dev, implement the login feature"
17
- - "Acting as @architect, review this system design"
18
- - "@sm, create the next story for our project"
15
+ - "As \*dev, implement the login feature"
16
+ - "Acting as \*architect, review this system design"
17
+ - "\*sm, create the next story for our project"
19
18
 
20
19
  The Gemini CLI automatically loads the appropriate agent context.
21
20
 
22
21
  ## Gemini CLI-Specific Features
23
22
 
24
- - **Context files**: All agents loaded as context in `.gemini/agents/`
25
- - **Automatic loading**: Settings.json ensures agents are always available
23
+ - **Context files**: All agents loaded as context in `.gemini/bmad-method/GEMINI.md`
24
+ - **Automatic loading**: GEMINI.md ensures agents are always available
26
25
  - **Natural language**: No special syntax needed, just mention the agent
27
26
 
28
27
  ## Tips for Gemini CLI Users
@@ -111,6 +111,7 @@ Follow the SM → Dev cycle for systematic story development:
111
111
 
112
112
  - **Claude Code**: `/agent-name` (e.g., `/bmad-master`)
113
113
  - **Cursor**: `@agent-name` (e.g., `@bmad-master`)
114
+ - **Gemini CLI**: `*agent-name` (e.g., `*bmad-master`)
114
115
  - **Windsurf**: `@agent-name` (e.g., `@bmad-master`)
115
116
  - **Trae**: `@agent-name` (e.g., `@bmad-master`)
116
117
  - **Roo Code**: Select mode from mode selector (e.g., `bmad-bmad-master`)
@@ -5,3 +5,4 @@ description: >-
5
5
  2D Game Development expansion pack for BMad Method - Phaser 3 & TypeScript
6
6
  focused
7
7
  author: Brian (BMad)
8
+ slashPrefix: bmad2dp
@@ -3,3 +3,4 @@ version: 1.7.0
3
3
  short-title: Tools for creating BMad framework components
4
4
  description: Tools for creating and extending BMad framework components.
5
5
  author: Brian (BMad)
6
+ slashPrefix: bmadCreator
@@ -6,3 +6,4 @@ description: >-
6
6
  DevOps capabilities. It's designed for teams that need to define, implement,
7
7
  and manage cloud infrastructure alongside their application development.
8
8
  author: Brian (BMad)
9
+ slashPrefix: bmadInfraDevOps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.27.6",
3
+ "version": "4.29.0",
4
4
  "description": "Breakthrough Method of Agile AI-driven Development",
5
5
  "main": "tools/cli.js",
6
6
  "bin": {
@@ -21,7 +21,7 @@ ide-configurations:
21
21
  # 3. The agent will adopt that persona for the conversation
22
22
  claude-code:
23
23
  name: Claude Code
24
- rule-dir: .claude/commands/
24
+ rule-dir: .claude/commands/BMad/
25
25
  format: multi-file
26
26
  command-suffix: .md
27
27
  instructions: |
@@ -68,13 +68,14 @@ ide-configurations:
68
68
  # 4. Rules are stored in .clinerules/ directory in your project
69
69
  gemini:
70
70
  name: Gemini CLI
71
- rule-dir: .gemini/agents/
72
- format: context-files
71
+ rule-dir: .gemini/bmad-method/
72
+ format: single-file
73
+ command-suffix: .md
73
74
  instructions: |
74
75
  # To use BMad agents with the Gemini CLI:
75
- # 1. The installer creates a .gemini/ directory in your project.
76
- # 2. It also configures .gemini/settings.json to load all agent files.
77
- # 3. Simply mention the agent in your prompt (e.g., "As @dev, ...").
76
+ # 1. The installer creates a .gemini/bmad-method/ directory in your project.
77
+ # 2. It concatenates all agent files into a single GEMINI.md file.
78
+ # 3. Simply mention the agent in your prompt (e.g., "As *dev, ...").
78
79
  # 4. The Gemini CLI will automatically have the context for that agent.
79
80
  github-copilot:
80
81
  name: Github Copilot
@@ -131,19 +131,64 @@ class IdeSetup {
131
131
  }
132
132
 
133
133
  async setupClaudeCode(installDir, selectedAgent) {
134
- const commandsDir = path.join(installDir, ".claude", "commands");
135
- const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
134
+ // Setup bmad-core commands
135
+ const coreSlashPrefix = await this.getCoreSlashPrefix(installDir);
136
+ const coreAgents = selectedAgent ? [selectedAgent] : await this.getCoreAgentIds(installDir);
137
+ const coreTasks = await this.getCoreTaskIds(installDir);
138
+ await this.setupClaudeCodeForPackage(installDir, "core", coreSlashPrefix, coreAgents, coreTasks, ".bmad-core");
139
+
140
+ // Setup expansion pack commands
141
+ const expansionPacks = await this.getInstalledExpansionPacks(installDir);
142
+ for (const packInfo of expansionPacks) {
143
+ const packSlashPrefix = await this.getExpansionPackSlashPrefix(packInfo.path);
144
+ const packAgents = await this.getExpansionPackAgents(packInfo.path);
145
+ const packTasks = await this.getExpansionPackTasks(packInfo.path);
146
+
147
+ if (packAgents.length > 0 || packTasks.length > 0) {
148
+ // Use the actual directory name where the expansion pack is installed
149
+ const rootPath = path.relative(installDir, packInfo.path);
150
+ await this.setupClaudeCodeForPackage(installDir, packInfo.name, packSlashPrefix, packAgents, packTasks, rootPath);
151
+ }
152
+ }
136
153
 
137
- await fileManager.ensureDirectory(commandsDir);
154
+ return true;
155
+ }
138
156
 
139
- for (const agentId of agents) {
140
- // Find the agent file
141
- const agentPath = await this.findAgentPath(agentId, installDir);
142
- const commandPath = path.join(commandsDir, `${agentId}.md`);
157
+ async setupClaudeCodeForPackage(installDir, packageName, slashPrefix, agentIds, taskIds, rootPath) {
158
+ const commandsBaseDir = path.join(installDir, ".claude", "commands", slashPrefix);
159
+ const agentsDir = path.join(commandsBaseDir, "agents");
160
+ const tasksDir = path.join(commandsBaseDir, "tasks");
161
+
162
+ // Ensure directories exist
163
+ await fileManager.ensureDirectory(agentsDir);
164
+ await fileManager.ensureDirectory(tasksDir);
165
+
166
+ // Setup agents
167
+ for (const agentId of agentIds) {
168
+ // Find the agent file - for expansion packs, prefer the expansion pack version
169
+ let agentPath;
170
+ if (packageName !== "core") {
171
+ // For expansion packs, first try to find the agent in the expansion pack directory
172
+ const expansionPackPath = path.join(installDir, rootPath, "agents", `${agentId}.md`);
173
+ if (await fileManager.pathExists(expansionPackPath)) {
174
+ agentPath = expansionPackPath;
175
+ } else {
176
+ // Fall back to core if not found in expansion pack
177
+ agentPath = await this.findAgentPath(agentId, installDir);
178
+ }
179
+ } else {
180
+ // For core, use the normal search
181
+ agentPath = await this.findAgentPath(agentId, installDir);
182
+ }
183
+
184
+ const commandPath = path.join(agentsDir, `${agentId}.md`);
143
185
 
144
186
  if (agentPath) {
145
187
  // Create command file with agent content
146
- const agentContent = await fileManager.readFile(agentPath);
188
+ let agentContent = await fileManager.readFile(agentPath);
189
+
190
+ // Replace {root} placeholder with the appropriate root path for this context
191
+ agentContent = agentContent.replace(/{root}/g, rootPath);
147
192
 
148
193
  // Add command header
149
194
  let commandContent = `# /${agentId} Command\n\n`;
@@ -151,13 +196,50 @@ class IdeSetup {
151
196
  commandContent += agentContent;
152
197
 
153
198
  await fileManager.writeFile(commandPath, commandContent);
154
- console.log(chalk.green(`✓ Created command: /${agentId}`));
199
+ console.log(chalk.green(`✓ Created agent command: /${agentId}`));
155
200
  }
156
201
  }
157
202
 
158
- console.log(chalk.green(`\n✓ Created Claude Code commands in ${commandsDir}`));
203
+ // Setup tasks
204
+ for (const taskId of taskIds) {
205
+ // Find the task file - for expansion packs, prefer the expansion pack version
206
+ let taskPath;
207
+ if (packageName !== "core") {
208
+ // For expansion packs, first try to find the task in the expansion pack directory
209
+ const expansionPackPath = path.join(installDir, rootPath, "tasks", `${taskId}.md`);
210
+ if (await fileManager.pathExists(expansionPackPath)) {
211
+ taskPath = expansionPackPath;
212
+ } else {
213
+ // Fall back to core if not found in expansion pack
214
+ taskPath = await this.findTaskPath(taskId, installDir);
215
+ }
216
+ } else {
217
+ // For core, use the normal search
218
+ taskPath = await this.findTaskPath(taskId, installDir);
219
+ }
220
+
221
+ const commandPath = path.join(tasksDir, `${taskId}.md`);
159
222
 
160
- return true;
223
+ if (taskPath) {
224
+ // Create command file with task content
225
+ let taskContent = await fileManager.readFile(taskPath);
226
+
227
+ // Replace {root} placeholder with the appropriate root path for this context
228
+ taskContent = taskContent.replace(/{root}/g, rootPath);
229
+
230
+ // Add command header
231
+ let commandContent = `# /${taskId} Task\n\n`;
232
+ commandContent += `When this command is used, execute the following task:\n\n`;
233
+ commandContent += taskContent;
234
+
235
+ await fileManager.writeFile(commandPath, commandContent);
236
+ console.log(chalk.green(`✓ Created task command: /${taskId}`));
237
+ }
238
+ }
239
+
240
+ console.log(chalk.green(`\n✓ Created Claude Code commands for ${packageName} in ${commandsBaseDir}`));
241
+ console.log(chalk.dim(` - Agents in: ${agentsDir}`));
242
+ console.log(chalk.dim(` - Tasks in: ${tasksDir}`));
161
243
  }
162
244
 
163
245
  async setupWindsurf(installDir, selectedAgent) {
@@ -311,6 +393,49 @@ class IdeSetup {
311
393
  return [...new Set(allAgentIds)];
312
394
  }
313
395
 
396
+ async getCoreAgentIds(installDir) {
397
+ const allAgentIds = [];
398
+
399
+ // Check core agents in .bmad-core or root only
400
+ let agentsDir = path.join(installDir, ".bmad-core", "agents");
401
+ if (!(await fileManager.pathExists(agentsDir))) {
402
+ agentsDir = path.join(installDir, "bmad-core", "agents");
403
+ }
404
+
405
+ if (await fileManager.pathExists(agentsDir)) {
406
+ const glob = require("glob");
407
+ const agentFiles = glob.sync("*.md", { cwd: agentsDir });
408
+ allAgentIds.push(...agentFiles.map((file) => path.basename(file, ".md")));
409
+ }
410
+
411
+ return [...new Set(allAgentIds)];
412
+ }
413
+
414
+ async getCoreTaskIds(installDir) {
415
+ const allTaskIds = [];
416
+
417
+ // Check core tasks in .bmad-core or root only
418
+ let tasksDir = path.join(installDir, ".bmad-core", "tasks");
419
+ if (!(await fileManager.pathExists(tasksDir))) {
420
+ tasksDir = path.join(installDir, "bmad-core", "tasks");
421
+ }
422
+
423
+ if (await fileManager.pathExists(tasksDir)) {
424
+ const glob = require("glob");
425
+ const taskFiles = glob.sync("*.md", { cwd: tasksDir });
426
+ allTaskIds.push(...taskFiles.map((file) => path.basename(file, ".md")));
427
+ }
428
+
429
+ // Check common tasks
430
+ const commonTasksDir = path.join(installDir, "common", "tasks");
431
+ if (await fileManager.pathExists(commonTasksDir)) {
432
+ const commonTaskFiles = glob.sync("*.md", { cwd: commonTasksDir });
433
+ allTaskIds.push(...commonTaskFiles.map((file) => path.basename(file, ".md")));
434
+ }
435
+
436
+ return [...new Set(allTaskIds)];
437
+ }
438
+
314
439
  async getAgentTitle(agentId, installDir) {
315
440
  // Try to find the agent file in various locations
316
441
  const possiblePaths = [
@@ -350,6 +475,194 @@ class IdeSetup {
350
475
  ).join(' ');
351
476
  }
352
477
 
478
+ async getAllTaskIds(installDir) {
479
+ const glob = require("glob");
480
+ const allTaskIds = [];
481
+
482
+ // Check core tasks in .bmad-core or root
483
+ let tasksDir = path.join(installDir, ".bmad-core", "tasks");
484
+ if (!(await fileManager.pathExists(tasksDir))) {
485
+ tasksDir = path.join(installDir, "bmad-core", "tasks");
486
+ }
487
+
488
+ if (await fileManager.pathExists(tasksDir)) {
489
+ const taskFiles = glob.sync("*.md", { cwd: tasksDir });
490
+ allTaskIds.push(...taskFiles.map((file) => path.basename(file, ".md")));
491
+ }
492
+
493
+ // Check common tasks
494
+ const commonTasksDir = path.join(installDir, "common", "tasks");
495
+ if (await fileManager.pathExists(commonTasksDir)) {
496
+ const commonTaskFiles = glob.sync("*.md", { cwd: commonTasksDir });
497
+ allTaskIds.push(...commonTaskFiles.map((file) => path.basename(file, ".md")));
498
+ }
499
+
500
+ // Also check for expansion pack tasks in dot folders
501
+ const expansionDirs = glob.sync(".*/tasks", { cwd: installDir });
502
+ for (const expDir of expansionDirs) {
503
+ const fullExpDir = path.join(installDir, expDir);
504
+ const expTaskFiles = glob.sync("*.md", { cwd: fullExpDir });
505
+ allTaskIds.push(...expTaskFiles.map((file) => path.basename(file, ".md")));
506
+ }
507
+
508
+ // Check expansion-packs folder tasks
509
+ const expansionPacksDir = path.join(installDir, "expansion-packs");
510
+ if (await fileManager.pathExists(expansionPacksDir)) {
511
+ const expPackDirs = glob.sync("*/tasks", { cwd: expansionPacksDir });
512
+ for (const expDir of expPackDirs) {
513
+ const fullExpDir = path.join(expansionPacksDir, expDir);
514
+ const expTaskFiles = glob.sync("*.md", { cwd: fullExpDir });
515
+ allTaskIds.push(...expTaskFiles.map((file) => path.basename(file, ".md")));
516
+ }
517
+ }
518
+
519
+ // Remove duplicates
520
+ return [...new Set(allTaskIds)];
521
+ }
522
+
523
+ async findTaskPath(taskId, installDir) {
524
+ // Try to find the task file in various locations
525
+ const possiblePaths = [
526
+ path.join(installDir, ".bmad-core", "tasks", `${taskId}.md`),
527
+ path.join(installDir, "bmad-core", "tasks", `${taskId}.md`),
528
+ path.join(installDir, "common", "tasks", `${taskId}.md`)
529
+ ];
530
+
531
+ // Also check expansion pack directories
532
+ const glob = require("glob");
533
+
534
+ // Check dot folder expansion packs
535
+ const expansionDirs = glob.sync(".*/tasks", { cwd: installDir });
536
+ for (const expDir of expansionDirs) {
537
+ possiblePaths.push(path.join(installDir, expDir, `${taskId}.md`));
538
+ }
539
+
540
+ // Check expansion-packs folder
541
+ const expansionPacksDir = path.join(installDir, "expansion-packs");
542
+ if (await fileManager.pathExists(expansionPacksDir)) {
543
+ const expPackDirs = glob.sync("*/tasks", { cwd: expansionPacksDir });
544
+ for (const expDir of expPackDirs) {
545
+ possiblePaths.push(path.join(expansionPacksDir, expDir, `${taskId}.md`));
546
+ }
547
+ }
548
+
549
+ for (const taskPath of possiblePaths) {
550
+ if (await fileManager.pathExists(taskPath)) {
551
+ return taskPath;
552
+ }
553
+ }
554
+
555
+ return null;
556
+ }
557
+
558
+ async getCoreSlashPrefix(installDir) {
559
+ try {
560
+ const coreConfigPath = path.join(installDir, ".bmad-core", "core-config.yaml");
561
+ if (!(await fileManager.pathExists(coreConfigPath))) {
562
+ // Try bmad-core directory
563
+ const altConfigPath = path.join(installDir, "bmad-core", "core-config.yaml");
564
+ if (await fileManager.pathExists(altConfigPath)) {
565
+ const configContent = await fileManager.readFile(altConfigPath);
566
+ const config = yaml.load(configContent);
567
+ return config.slashPrefix || "BMad";
568
+ }
569
+ return "BMad"; // fallback
570
+ }
571
+
572
+ const configContent = await fileManager.readFile(coreConfigPath);
573
+ const config = yaml.load(configContent);
574
+ return config.slashPrefix || "BMad";
575
+ } catch (error) {
576
+ console.warn(`Failed to read core slashPrefix, using default 'BMad': ${error.message}`);
577
+ return "BMad";
578
+ }
579
+ }
580
+
581
+ async getInstalledExpansionPacks(installDir) {
582
+ const expansionPacks = [];
583
+
584
+ // Check for dot-prefixed expansion packs in install directory
585
+ const glob = require("glob");
586
+ const dotExpansions = glob.sync(".bmad-*", { cwd: installDir });
587
+
588
+ for (const dotExpansion of dotExpansions) {
589
+ if (dotExpansion !== ".bmad-core") {
590
+ const packPath = path.join(installDir, dotExpansion);
591
+ const packName = dotExpansion.substring(1); // remove the dot
592
+ expansionPacks.push({
593
+ name: packName,
594
+ path: packPath
595
+ });
596
+ }
597
+ }
598
+
599
+ // Check for expansion-packs directory style
600
+ const expansionPacksDir = path.join(installDir, "expansion-packs");
601
+ if (await fileManager.pathExists(expansionPacksDir)) {
602
+ const packDirs = glob.sync("*", { cwd: expansionPacksDir });
603
+
604
+ for (const packDir of packDirs) {
605
+ const packPath = path.join(expansionPacksDir, packDir);
606
+ if ((await fileManager.pathExists(packPath)) &&
607
+ (await fileManager.pathExists(path.join(packPath, "config.yaml")))) {
608
+ expansionPacks.push({
609
+ name: packDir,
610
+ path: packPath
611
+ });
612
+ }
613
+ }
614
+ }
615
+
616
+ return expansionPacks;
617
+ }
618
+
619
+ async getExpansionPackSlashPrefix(packPath) {
620
+ try {
621
+ const configPath = path.join(packPath, "config.yaml");
622
+ if (await fileManager.pathExists(configPath)) {
623
+ const configContent = await fileManager.readFile(configPath);
624
+ const config = yaml.load(configContent);
625
+ return config.slashPrefix || path.basename(packPath);
626
+ }
627
+ } catch (error) {
628
+ console.warn(`Failed to read expansion pack slashPrefix from ${packPath}: ${error.message}`);
629
+ }
630
+
631
+ return path.basename(packPath); // fallback to directory name
632
+ }
633
+
634
+ async getExpansionPackAgents(packPath) {
635
+ const agentsDir = path.join(packPath, "agents");
636
+ if (!(await fileManager.pathExists(agentsDir))) {
637
+ return [];
638
+ }
639
+
640
+ try {
641
+ const glob = require("glob");
642
+ const agentFiles = glob.sync("*.md", { cwd: agentsDir });
643
+ return agentFiles.map(file => path.basename(file, ".md"));
644
+ } catch (error) {
645
+ console.warn(`Failed to read expansion pack agents from ${packPath}: ${error.message}`);
646
+ return [];
647
+ }
648
+ }
649
+
650
+ async getExpansionPackTasks(packPath) {
651
+ const tasksDir = path.join(packPath, "tasks");
652
+ if (!(await fileManager.pathExists(tasksDir))) {
653
+ return [];
654
+ }
655
+
656
+ try {
657
+ const glob = require("glob");
658
+ const taskFiles = glob.sync("*.md", { cwd: tasksDir });
659
+ return taskFiles.map(file => path.basename(file, ".md"));
660
+ } catch (error) {
661
+ console.warn(`Failed to read expansion pack tasks from ${packPath}: ${error.message}`);
662
+ return [];
663
+ }
664
+ }
665
+
353
666
  async setupRoo(installDir, selectedAgent) {
354
667
  const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
355
668
 
@@ -509,15 +822,56 @@ class IdeSetup {
509
822
  return true;
510
823
  }
511
824
 
512
- async setupGeminiCli(installDir, selectedAgent) {
825
+ async setupGeminiCli(installDir) {
513
826
  await initializeModules();
514
827
  const geminiDir = path.join(installDir, ".gemini");
515
- const agentsContextDir = path.join(geminiDir, "agents");
516
- await fileManager.ensureDirectory(agentsContextDir);
828
+ const bmadMethodDir = path.join(geminiDir, "bmad-method");
829
+ await fileManager.ensureDirectory(bmadMethodDir);
830
+
831
+ // Update logic for existing settings.json
832
+ const settingsPath = path.join(geminiDir, "settings.json");
833
+ if (await fileManager.pathExists(settingsPath)) {
834
+ try {
835
+ const settingsContent = await fileManager.readFile(settingsPath);
836
+ const settings = JSON.parse(settingsContent);
837
+ let updated = false;
838
+
839
+ // Handle contextFileName property
840
+ if (settings.contextFileName && Array.isArray(settings.contextFileName)) {
841
+ const originalLength = settings.contextFileName.length;
842
+ settings.contextFileName = settings.contextFileName.filter(
843
+ (fileName) => !fileName.startsWith("agents/")
844
+ );
845
+ if (settings.contextFileName.length !== originalLength) {
846
+ updated = true;
847
+ }
848
+ }
849
+
850
+ if (updated) {
851
+ await fileManager.writeFile(
852
+ settingsPath,
853
+ JSON.stringify(settings, null, 2)
854
+ );
855
+ console.log(chalk.green("✓ Updated .gemini/settings.json - removed agent file references"));
856
+ }
857
+ } catch (error) {
858
+ console.warn(
859
+ chalk.yellow("Could not update .gemini/settings.json"),
860
+ error
861
+ );
862
+ }
863
+ }
864
+
865
+ // Remove old agents directory
866
+ const agentsDir = path.join(geminiDir, "agents");
867
+ if (await fileManager.pathExists(agentsDir)) {
868
+ await fileManager.removeDirectory(agentsDir);
869
+ console.log(chalk.green("✓ Removed old .gemini/agents directory"));
870
+ }
517
871
 
518
872
  // Get all available agents
519
873
  const agents = await this.getAllAgentIds(installDir);
520
- const agentContextFiles = [];
874
+ let concatenatedContent = "";
521
875
 
522
876
  for (const agentId of agents) {
523
877
  // Find the source agent file
@@ -525,43 +879,46 @@ class IdeSetup {
525
879
 
526
880
  if (agentPath) {
527
881
  const agentContent = await fileManager.readFile(agentPath);
528
- const contextFilePath = path.join(agentsContextDir, `${agentId}.md`);
529
-
530
- // Copy the agent content directly into its own context file
531
- await fileManager.writeFile(contextFilePath, agentContent);
532
-
533
- // Store the relative path for settings.json
534
- const relativePath = path.relative(geminiDir, contextFilePath);
535
- agentContextFiles.push(relativePath.replace(/\\/g, '/')); // Ensure forward slashes for consistency
536
- console.log(chalk.green(`✓ Created context file for @${agentId}`));
537
- }
538
- }
539
-
540
- console.log(chalk.green(`\n✓ Created individual agent context files in ${agentsContextDir}`));
541
-
542
- // Add GEMINI.md to the context files array
543
- agentContextFiles.push("GEMINI.md");
544
-
545
- // Create or update settings.json
546
- const settingsPath = path.join(geminiDir, "settings.json");
547
- let settings = {};
548
-
549
- if (await fileManager.pathExists(settingsPath)) {
550
- try {
551
- const existingSettings = await fileManager.readFile(settingsPath);
552
- settings = JSON.parse(existingSettings);
553
- console.log(chalk.yellow("Found existing .gemini/settings.json. Merging settings..."));
554
- } catch (e) {
555
- console.error(chalk.red("Error parsing existing settings.json. It will be overwritten."), e);
556
- settings = {};
882
+
883
+ // Create properly formatted agent rule content (similar to trae)
884
+ let agentRuleContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
885
+ agentRuleContent += `This rule is triggered when the user types \`*${agentId}\` and activates the ${await this.getAgentTitle(
886
+ agentId,
887
+ installDir
888
+ )} agent persona.\n\n`;
889
+ agentRuleContent += "## Agent Activation\n\n";
890
+ agentRuleContent +=
891
+ "CRITICAL: Read the full YAML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:\n\n";
892
+ agentRuleContent += "```yaml\n";
893
+ // Extract just the YAML content from the agent file
894
+ const yamlContent = extractYamlFromAgent(agentContent);
895
+ if (yamlContent) {
896
+ agentRuleContent += yamlContent;
897
+ }
898
+ else {
899
+ // If no YAML found, include the whole content minus the header
900
+ agentRuleContent += agentContent.replace(/^#.*$/m, "").trim();
901
+ }
902
+ agentRuleContent += "\n```\n\n";
903
+ agentRuleContent += "## File Reference\n\n";
904
+ const relativePath = path.relative(installDir, agentPath).replace(/\\/g, '/');
905
+ agentRuleContent += `The complete agent definition is available in [${relativePath}](${relativePath}).\n\n`;
906
+ agentRuleContent += "## Usage\n\n";
907
+ agentRuleContent += `When the user types \`*${agentId}\`, activate this ${await this.getAgentTitle(
908
+ agentId,
909
+ installDir
910
+ )} persona and follow all instructions defined in the YAML configuration above.\n`;
911
+
912
+ // Add to concatenated content with separator
913
+ concatenatedContent += agentRuleContent + "\n\n---\n\n";
914
+ console.log(chalk.green(`✓ Added context for @${agentId}`));
557
915
  }
558
916
  }
559
917
 
560
- // Set contextFileName to our new array of files
561
- settings.contextFileName = agentContextFiles;
562
-
563
- await fileManager.writeFile(settingsPath, JSON.stringify(settings, null, 2));
564
- console.log(chalk.green(`✓ Configured .gemini/settings.json to load all agent context files.`));
918
+ // Write the concatenated content to GEMINI.md
919
+ const geminiMdPath = path.join(bmadMethodDir, "GEMINI.md");
920
+ await fileManager.writeFile(geminiMdPath, concatenatedContent);
921
+ console.log(chalk.green(`\n✓ Created GEMINI.md in ${bmadMethodDir}`));
565
922
 
566
923
  return true;
567
924
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.27.6",
3
+ "version": "4.29.0",
4
4
  "description": "BMad Method installer - AI-powered Agile development framework",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {
@@ -558,7 +558,7 @@ class V3ToV4Upgrader {
558
558
  try {
559
559
  const ideMessages = {
560
560
  cursor: "Rules created in .cursor/rules/",
561
- "claude-code": "Commands created in .claude/commands/",
561
+ "claude-code": "Commands created in .claude/commands/BMad/",
562
562
  windsurf: "Rules created in .windsurf/rules/",
563
563
  trae: "Rules created in.trae/rules/",
564
564
  roo: "Custom modes created in .roomodes",