bmad-method 6.0.0-alpha.10 → 6.0.0-alpha.12

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 (107) hide show
  1. package/CHANGELOG.md +219 -1105
  2. package/README.md +129 -359
  3. package/docs/custom-agent-installation.md +169 -0
  4. package/{v6-open-items.md → docs/v6-open-items.md} +1 -1
  5. package/package.json +4 -2
  6. package/src/core/resources/excalidraw/README.md +160 -0
  7. package/src/core/resources/excalidraw/library-loader.md +50 -0
  8. package/src/modules/bmb/docs/agent-compilation.md +340 -0
  9. package/src/modules/bmb/docs/agent-menu-patterns.md +524 -0
  10. package/src/modules/bmb/docs/expert-agent-architecture.md +364 -0
  11. package/src/modules/bmb/docs/index.md +55 -0
  12. package/src/modules/bmb/docs/module-agent-architecture.md +367 -0
  13. package/src/modules/bmb/docs/simple-agent-architecture.md +288 -0
  14. package/src/modules/bmb/docs/understanding-agent-types.md +184 -0
  15. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +242 -0
  16. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/breakthroughs.md +24 -0
  17. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/instructions.md +108 -0
  18. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/memories.md +46 -0
  19. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/mood-patterns.md +39 -0
  20. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +152 -0
  21. package/src/modules/bmb/reference/agents/module-examples/README.md +50 -0
  22. package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +53 -0
  23. package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +57 -0
  24. package/src/modules/bmb/reference/agents/simple-examples/README.md +223 -0
  25. package/src/modules/bmb/reference/agents/simple-examples/commit-poet.agent.yaml +126 -0
  26. package/src/modules/bmb/reference/readme.md +3 -0
  27. package/src/modules/bmb/workflows/create-agent/agent-validation-checklist.md +174 -0
  28. package/src/modules/bmb/workflows/create-agent/brainstorm-context.md +99 -120
  29. package/src/modules/bmb/workflows/create-agent/communication-presets.csv +61 -0
  30. package/src/modules/bmb/workflows/create-agent/instructions.md +126 -65
  31. package/src/modules/bmb/workflows/create-agent/workflow.yaml +19 -12
  32. package/src/modules/bmb/workflows/edit-agent/README.md +174 -47
  33. package/src/modules/bmb/workflows/edit-agent/instructions.md +397 -33
  34. package/src/modules/bmb/workflows/edit-agent/workflow.yaml +24 -8
  35. package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +1 -1
  36. package/src/modules/bmm/agents/analyst.agent.yaml +2 -2
  37. package/src/modules/bmm/agents/architect.agent.yaml +10 -2
  38. package/src/modules/bmm/agents/dev.agent.yaml +2 -2
  39. package/src/modules/bmm/agents/pm.agent.yaml +7 -3
  40. package/src/modules/bmm/agents/sm.agent.yaml +2 -2
  41. package/src/modules/bmm/agents/tea.agent.yaml +2 -2
  42. package/src/modules/bmm/agents/tech-writer.agent.yaml +15 -3
  43. package/src/modules/bmm/agents/ux-designer.agent.yaml +6 -2
  44. package/src/modules/bmm/docs/README.md +4 -0
  45. package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +5919 -0
  46. package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +2 -0
  47. package/src/modules/bmm/docs/quick-start.md +6 -0
  48. package/src/modules/bmm/docs/scale-adaptive-system.md +6 -0
  49. package/src/modules/bmm/docs/workflows-implementation.md +10 -0
  50. package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.yaml +4 -4
  51. package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/workflow.yaml +5 -5
  52. package/src/modules/bmm/workflows/4-implementation/story-context/workflow.yaml +1 -1
  53. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/instructions.md +7 -8
  54. package/src/modules/bmm/workflows/diagrams/create-dataflow/workflow.yaml +27 -0
  55. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/instructions.md +9 -10
  56. package/src/modules/bmm/workflows/diagrams/create-diagram/workflow.yaml +27 -0
  57. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/instructions.md +4 -5
  58. package/src/modules/bmm/workflows/diagrams/create-flowchart/workflow.yaml +27 -0
  59. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-wireframe/instructions.md +3 -3
  60. package/src/modules/bmm/workflows/diagrams/create-wireframe/workflow.yaml +27 -0
  61. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +18 -30
  62. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +2 -14
  63. package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +2 -14
  64. package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +2 -14
  65. package/src/modules/cis/agents/presentation-master.agent.yaml +60 -0
  66. package/tools/cli/commands/agent-install.js +409 -0
  67. package/tools/cli/installers/lib/core/installer.js +119 -0
  68. package/tools/cli/installers/lib/ide/_base-ide.js +25 -0
  69. package/tools/cli/installers/lib/ide/antigravity.js +463 -0
  70. package/tools/cli/installers/lib/ide/claude-code.js +43 -0
  71. package/tools/cli/installers/lib/ide/codex.js +217 -32
  72. package/tools/cli/installers/lib/ide/cursor.js +48 -0
  73. package/tools/cli/installers/lib/ide/github-copilot.js +74 -0
  74. package/tools/cli/installers/lib/ide/manager.js +35 -0
  75. package/tools/cli/installers/lib/ide/opencode.js +45 -0
  76. package/tools/cli/installers/lib/ide/windsurf.js +47 -0
  77. package/tools/cli/lib/agent/compiler.js +390 -0
  78. package/tools/cli/lib/agent/installer.js +725 -0
  79. package/tools/cli/lib/agent/template-engine.js +152 -0
  80. package/docs/installers-bundlers/web-bundler-usage.md +0 -54
  81. package/src/modules/bmb/workflows/create-agent/README.md +0 -203
  82. package/src/modules/bmb/workflows/create-agent/agent-architecture.md +0 -415
  83. package/src/modules/bmb/workflows/create-agent/agent-command-patterns.md +0 -759
  84. package/src/modules/bmb/workflows/create-agent/agent-types.md +0 -292
  85. package/src/modules/bmb/workflows/create-agent/checklist.md +0 -62
  86. package/src/modules/bmb/workflows/create-agent/communication-styles.md +0 -202
  87. package/src/modules/bmb/workflows/edit-agent/checklist.md +0 -112
  88. package/src/modules/bmb/workflows/redoc/README.md +0 -87
  89. package/src/modules/bmb/workflows/redoc/checklist.md +0 -99
  90. package/src/modules/bmb/workflows/redoc/instructions.md +0 -265
  91. package/src/modules/bmb/workflows/redoc/workflow.yaml +0 -34
  92. package/src/modules/bmm/agents/frame-expert.agent.yaml +0 -42
  93. package/src/modules/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -24
  94. package/src/modules/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -25
  95. package/src/modules/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -28
  96. package/src/modules/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -24
  97. package/src/modules/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
  98. /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/excalidraw-helpers.md +0 -0
  99. /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/validate-json-instructions.md +0 -0
  100. /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/epics-template.md +0 -0
  101. /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/instructions.md +0 -0
  102. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-library.json +0 -0
  103. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-templates.yaml +0 -0
  104. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/checklist.md +0 -0
  105. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/checklist.md +0 -0
  106. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/checklist.md +0 -0
  107. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-wireframe/checklist.md +0 -0
@@ -0,0 +1,463 @@
1
+ const path = require('node:path');
2
+ const { BaseIdeSetup } = require('./_base-ide');
3
+ const chalk = require('chalk');
4
+ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
5
+ const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
6
+ const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
7
+ const { AgentCommandGenerator } = require('./shared/agent-command-generator');
8
+ const {
9
+ loadModuleInjectionConfig,
10
+ shouldApplyInjection,
11
+ filterAgentInstructions,
12
+ resolveSubagentFiles,
13
+ } = require('./shared/module-injections');
14
+ const { getAgentsFromBmad, getAgentsFromDir } = require('./shared/bmad-artifacts');
15
+
16
+ /**
17
+ * Google Antigravity IDE setup handler
18
+ *
19
+ * Uses .agent/workflows/ directory for slash commands
20
+ */
21
+ class AntigravitySetup extends BaseIdeSetup {
22
+ constructor() {
23
+ super('antigravity', 'Google Antigravity', false);
24
+ this.configDir = '.agent';
25
+ this.workflowsDir = 'workflows';
26
+ }
27
+
28
+ /**
29
+ * Collect configuration choices before installation
30
+ * @param {Object} options - Configuration options
31
+ * @returns {Object} Collected configuration
32
+ */
33
+ async collectConfiguration(options = {}) {
34
+ const config = {
35
+ subagentChoices: null,
36
+ installLocation: null,
37
+ };
38
+
39
+ const sourceModulesPath = getSourcePath('modules');
40
+ const modules = options.selectedModules || [];
41
+
42
+ for (const moduleName of modules) {
43
+ // Check for Antigravity sub-module injection config in SOURCE directory
44
+ const injectionConfigPath = path.join(sourceModulesPath, moduleName, 'sub-modules', 'antigravity', 'injections.yaml');
45
+
46
+ if (await this.exists(injectionConfigPath)) {
47
+ const fs = require('fs-extra');
48
+ const yaml = require('js-yaml');
49
+
50
+ try {
51
+ // Load injection configuration
52
+ const configContent = await fs.readFile(injectionConfigPath, 'utf8');
53
+ const injectionConfig = yaml.load(configContent);
54
+
55
+ // Ask about subagents if they exist and we haven't asked yet
56
+ if (injectionConfig.subagents && !config.subagentChoices) {
57
+ config.subagentChoices = await this.promptSubagentInstallation(injectionConfig.subagents);
58
+
59
+ if (config.subagentChoices.install !== 'none') {
60
+ // Ask for installation location
61
+ const inquirer = require('inquirer');
62
+ const locationAnswer = await inquirer.prompt([
63
+ {
64
+ type: 'list',
65
+ name: 'location',
66
+ message: 'Where would you like to install Antigravity subagents?',
67
+ choices: [
68
+ { name: 'Project level (.agent/agents/)', value: 'project' },
69
+ { name: 'User level (~/.agent/agents/)', value: 'user' },
70
+ ],
71
+ default: 'project',
72
+ },
73
+ ]);
74
+ config.installLocation = locationAnswer.location;
75
+ }
76
+ }
77
+ } catch (error) {
78
+ console.log(chalk.yellow(` Warning: Failed to process ${moduleName} features: ${error.message}`));
79
+ }
80
+ }
81
+ }
82
+
83
+ return config;
84
+ }
85
+
86
+ /**
87
+ * Cleanup old BMAD installation before reinstalling
88
+ * @param {string} projectDir - Project directory
89
+ */
90
+ async cleanup(projectDir) {
91
+ const fs = require('fs-extra');
92
+ const bmadWorkflowsDir = path.join(projectDir, this.configDir, this.workflowsDir, 'bmad');
93
+
94
+ if (await fs.pathExists(bmadWorkflowsDir)) {
95
+ await fs.remove(bmadWorkflowsDir);
96
+ console.log(chalk.dim(` Removed old BMAD workflows from ${this.name}`));
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Setup Antigravity IDE configuration
102
+ * @param {string} projectDir - Project directory
103
+ * @param {string} bmadDir - BMAD installation directory
104
+ * @param {Object} options - Setup options
105
+ */
106
+ async setup(projectDir, bmadDir, options = {}) {
107
+ // Store project directory for use in processContent
108
+ this.projectDir = projectDir;
109
+
110
+ console.log(chalk.cyan(`Setting up ${this.name}...`));
111
+
112
+ // Clean up old BMAD installation first
113
+ await this.cleanup(projectDir);
114
+
115
+ // Create .agent/workflows directory structure
116
+ const agentDir = path.join(projectDir, this.configDir);
117
+ const workflowsDir = path.join(agentDir, this.workflowsDir);
118
+ const bmadWorkflowsDir = path.join(workflowsDir, 'bmad');
119
+
120
+ await this.ensureDir(bmadWorkflowsDir);
121
+
122
+ // Generate agent launchers using AgentCommandGenerator
123
+ // This creates small launcher files that reference the actual agents in .bmad/
124
+ const agentGen = new AgentCommandGenerator(this.bmadFolderName);
125
+ const { artifacts: agentArtifacts, counts: agentCounts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
126
+
127
+ // Write agent launcher files with FLATTENED naming
128
+ // Antigravity ignores directory structure, so we flatten to: bmad-module-agents-name.md
129
+ // This creates slash commands like /bmad-bmm-agents-dev instead of /dev
130
+ let agentCount = 0;
131
+ for (const artifact of agentArtifacts) {
132
+ const flattenedName = this.flattenFilename(artifact.relativePath);
133
+ const targetPath = path.join(bmadWorkflowsDir, flattenedName);
134
+ await this.writeFile(targetPath, artifact.content);
135
+ agentCount++;
136
+ }
137
+
138
+ // Process Antigravity specific injections for installed modules
139
+ // Use pre-collected configuration if available, or skip if already configured
140
+ if (options.preCollectedConfig && options.preCollectedConfig._alreadyConfigured) {
141
+ // IDE is already configured from previous installation, skip prompting
142
+ // Just process with default/existing configuration
143
+ await this.processModuleInjectionsWithConfig(projectDir, bmadDir, options, {});
144
+ } else if (options.preCollectedConfig) {
145
+ await this.processModuleInjectionsWithConfig(projectDir, bmadDir, options, options.preCollectedConfig);
146
+ } else {
147
+ await this.processModuleInjections(projectDir, bmadDir, options);
148
+ }
149
+
150
+ // Generate workflow commands from manifest (if it exists)
151
+ const workflowGen = new WorkflowCommandGenerator(this.bmadFolderName);
152
+ const { artifacts: workflowArtifacts } = await workflowGen.collectWorkflowArtifacts(bmadDir);
153
+
154
+ // Write workflow-command artifacts with FLATTENED naming
155
+ let workflowCommandCount = 0;
156
+ for (const artifact of workflowArtifacts) {
157
+ if (artifact.type === 'workflow-command') {
158
+ const flattenedName = this.flattenFilename(artifact.relativePath);
159
+ const targetPath = path.join(bmadWorkflowsDir, flattenedName);
160
+ await this.writeFile(targetPath, artifact.content);
161
+ workflowCommandCount++;
162
+ }
163
+ }
164
+
165
+ // Generate task and tool commands from manifests (if they exist)
166
+ const taskToolGen = new TaskToolCommandGenerator();
167
+ const taskToolResult = await taskToolGen.generateTaskToolCommands(projectDir, bmadDir);
168
+
169
+ console.log(chalk.green(`✓ ${this.name} configured:`));
170
+ console.log(chalk.dim(` - ${agentCount} agents installed`));
171
+ if (workflowCommandCount > 0) {
172
+ console.log(chalk.dim(` - ${workflowCommandCount} workflow commands generated`));
173
+ }
174
+ if (taskToolResult.generated > 0) {
175
+ console.log(
176
+ chalk.dim(
177
+ ` - ${taskToolResult.generated} task/tool commands generated (${taskToolResult.tasks} tasks, ${taskToolResult.tools} tools)`,
178
+ ),
179
+ );
180
+ }
181
+ console.log(chalk.dim(` - Workflows directory: ${path.relative(projectDir, bmadWorkflowsDir)}`));
182
+ console.log(chalk.yellow(`\n Note: Antigravity uses flattened slash commands (e.g., /bmad-module-agents-name)`));
183
+
184
+ return {
185
+ success: true,
186
+ agents: agentCount,
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Read and process file content
192
+ */
193
+ async readAndProcess(filePath, metadata) {
194
+ const fs = require('fs-extra');
195
+ const content = await fs.readFile(filePath, 'utf8');
196
+ return this.processContent(content, metadata);
197
+ }
198
+
199
+ /**
200
+ * Override processContent to keep {project-root} placeholder
201
+ */
202
+ processContent(content, metadata = {}) {
203
+ // Use the base class method WITHOUT projectDir to preserve {project-root} placeholder
204
+ return super.processContent(content, metadata);
205
+ }
206
+
207
+ /**
208
+ * Get agents from source modules (not installed location)
209
+ */
210
+ async getAgentsFromSource(sourceDir, selectedModules) {
211
+ const fs = require('fs-extra');
212
+ const agents = [];
213
+
214
+ // Add core agents
215
+ const corePath = getModulePath('core');
216
+ if (await fs.pathExists(path.join(corePath, 'agents'))) {
217
+ const coreAgents = await getAgentsFromDir(path.join(corePath, 'agents'), 'core');
218
+ agents.push(...coreAgents);
219
+ }
220
+
221
+ // Add module agents
222
+ for (const moduleName of selectedModules) {
223
+ const modulePath = path.join(sourceDir, moduleName);
224
+ const agentsPath = path.join(modulePath, 'agents');
225
+
226
+ if (await fs.pathExists(agentsPath)) {
227
+ const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
228
+ agents.push(...moduleAgents);
229
+ }
230
+ }
231
+
232
+ return agents;
233
+ }
234
+
235
+ /**
236
+ * Process module injections with pre-collected configuration
237
+ */
238
+ async processModuleInjectionsWithConfig(projectDir, bmadDir, options, preCollectedConfig) {
239
+ // Get list of installed modules
240
+ const modules = options.selectedModules || [];
241
+ const { subagentChoices, installLocation } = preCollectedConfig;
242
+
243
+ // Get the actual source directory (not the installation directory)
244
+ await this.processModuleInjectionsInternal({
245
+ projectDir,
246
+ modules,
247
+ handler: 'antigravity',
248
+ subagentChoices,
249
+ installLocation,
250
+ interactive: false,
251
+ });
252
+ }
253
+
254
+ /**
255
+ * Process Antigravity specific injections for installed modules
256
+ * Looks for injections.yaml in each module's antigravity sub-module
257
+ */
258
+ async processModuleInjections(projectDir, bmadDir, options) {
259
+ // Get list of installed modules
260
+ const modules = options.selectedModules || [];
261
+ let subagentChoices = null;
262
+ let installLocation = null;
263
+
264
+ // Get the actual source directory (not the installation directory)
265
+ const { subagentChoices: updatedChoices, installLocation: updatedLocation } = await this.processModuleInjectionsInternal({
266
+ projectDir,
267
+ modules,
268
+ handler: 'antigravity',
269
+ subagentChoices,
270
+ installLocation,
271
+ interactive: true,
272
+ });
273
+
274
+ if (updatedChoices) {
275
+ subagentChoices = updatedChoices;
276
+ }
277
+ if (updatedLocation) {
278
+ installLocation = updatedLocation;
279
+ }
280
+ }
281
+
282
+ async processModuleInjectionsInternal({ projectDir, modules, handler, subagentChoices, installLocation, interactive = false }) {
283
+ let choices = subagentChoices;
284
+ let location = installLocation;
285
+
286
+ for (const moduleName of modules) {
287
+ const configData = await loadModuleInjectionConfig(handler, moduleName);
288
+
289
+ if (!configData) {
290
+ continue;
291
+ }
292
+
293
+ const { config, handlerBaseDir } = configData;
294
+
295
+ if (interactive) {
296
+ console.log(chalk.cyan(`\nConfiguring ${moduleName} ${handler} features...`));
297
+ }
298
+
299
+ if (interactive && config.subagents && !choices) {
300
+ choices = await this.promptSubagentInstallation(config.subagents);
301
+
302
+ if (choices.install !== 'none') {
303
+ const inquirer = require('inquirer');
304
+ const locationAnswer = await inquirer.prompt([
305
+ {
306
+ type: 'list',
307
+ name: 'location',
308
+ message: 'Where would you like to install Antigravity subagents?',
309
+ choices: [
310
+ { name: 'Project level (.agent/agents/)', value: 'project' },
311
+ { name: 'User level (~/.agent/agents/)', value: 'user' },
312
+ ],
313
+ default: 'project',
314
+ },
315
+ ]);
316
+ location = locationAnswer.location;
317
+ }
318
+ }
319
+
320
+ if (config.injections && choices && choices.install !== 'none') {
321
+ for (const injection of config.injections) {
322
+ if (shouldApplyInjection(injection, choices)) {
323
+ await this.injectContent(projectDir, injection, choices);
324
+ }
325
+ }
326
+ }
327
+
328
+ if (config.subagents && choices && choices.install !== 'none') {
329
+ await this.copySelectedSubagents(projectDir, handlerBaseDir, config.subagents, choices, location || 'project');
330
+ }
331
+ }
332
+
333
+ return { subagentChoices: choices, installLocation: location };
334
+ }
335
+
336
+ /**
337
+ * Prompt user for subagent installation preferences
338
+ */
339
+ async promptSubagentInstallation(subagentConfig) {
340
+ const inquirer = require('inquirer');
341
+
342
+ // First ask if they want to install subagents
343
+ const { install } = await inquirer.prompt([
344
+ {
345
+ type: 'list',
346
+ name: 'install',
347
+ message: 'Would you like to install Antigravity subagents for enhanced functionality?',
348
+ choices: [
349
+ { name: 'Yes, install all subagents', value: 'all' },
350
+ { name: 'Yes, let me choose specific subagents', value: 'selective' },
351
+ { name: 'No, skip subagent installation', value: 'none' },
352
+ ],
353
+ default: 'all',
354
+ },
355
+ ]);
356
+
357
+ if (install === 'selective') {
358
+ // Show list of available subagents with descriptions
359
+ const subagentInfo = {
360
+ 'market-researcher.md': 'Market research and competitive analysis',
361
+ 'requirements-analyst.md': 'Requirements extraction and validation',
362
+ 'technical-evaluator.md': 'Technology stack evaluation',
363
+ 'epic-optimizer.md': 'Epic and story breakdown optimization',
364
+ 'document-reviewer.md': 'Document quality review',
365
+ };
366
+
367
+ const { selected } = await inquirer.prompt([
368
+ {
369
+ type: 'checkbox',
370
+ name: 'selected',
371
+ message: 'Select subagents to install:',
372
+ choices: subagentConfig.files.map((file) => ({
373
+ name: `${file.replace('.md', '')} - ${subagentInfo[file] || 'Specialized assistant'}`,
374
+ value: file,
375
+ checked: true,
376
+ })),
377
+ },
378
+ ]);
379
+
380
+ return { install: 'selective', selected };
381
+ }
382
+
383
+ return { install };
384
+ }
385
+
386
+ /**
387
+ * Inject content at specified point in file
388
+ */
389
+ async injectContent(projectDir, injection, subagentChoices = null) {
390
+ const fs = require('fs-extra');
391
+ const targetPath = path.join(projectDir, injection.file);
392
+
393
+ if (await this.exists(targetPath)) {
394
+ let content = await fs.readFile(targetPath, 'utf8');
395
+ const marker = `<!-- IDE-INJECT-POINT: ${injection.point} -->`;
396
+
397
+ if (content.includes(marker)) {
398
+ let injectionContent = injection.content;
399
+
400
+ // Filter content if selective subagents chosen
401
+ if (subagentChoices && subagentChoices.install === 'selective' && injection.point === 'pm-agent-instructions') {
402
+ injectionContent = filterAgentInstructions(injection.content, subagentChoices.selected);
403
+ }
404
+
405
+ content = content.replace(marker, injectionContent);
406
+ await fs.writeFile(targetPath, content);
407
+ console.log(chalk.dim(` Injected: ${injection.point} → ${injection.file}`));
408
+ }
409
+ }
410
+ }
411
+
412
+ /**
413
+ * Copy selected subagents to appropriate Antigravity agents directory
414
+ */
415
+ async copySelectedSubagents(projectDir, handlerBaseDir, subagentConfig, choices, location) {
416
+ const fs = require('fs-extra');
417
+ const os = require('node:os');
418
+
419
+ // Determine target directory based on user choice
420
+ let targetDir;
421
+ if (location === 'user') {
422
+ targetDir = path.join(os.homedir(), '.agent', 'agents');
423
+ console.log(chalk.dim(` Installing subagents globally to: ~/.agent/agents/`));
424
+ } else {
425
+ targetDir = path.join(projectDir, '.agent', 'agents');
426
+ console.log(chalk.dim(` Installing subagents to project: .agent/agents/`));
427
+ }
428
+
429
+ // Ensure target directory exists
430
+ await this.ensureDir(targetDir);
431
+
432
+ const resolvedFiles = await resolveSubagentFiles(handlerBaseDir, subagentConfig, choices);
433
+
434
+ let copiedCount = 0;
435
+ for (const resolved of resolvedFiles) {
436
+ try {
437
+ const sourcePath = resolved.absolutePath;
438
+
439
+ const subFolder = path.dirname(resolved.relativePath);
440
+ let targetPath;
441
+ if (subFolder && subFolder !== '.') {
442
+ const targetSubDir = path.join(targetDir, subFolder);
443
+ await this.ensureDir(targetSubDir);
444
+ targetPath = path.join(targetSubDir, path.basename(resolved.file));
445
+ } else {
446
+ targetPath = path.join(targetDir, path.basename(resolved.file));
447
+ }
448
+
449
+ await fs.copyFile(sourcePath, targetPath);
450
+ console.log(chalk.green(` ✓ Installed: ${subFolder === '.' ? '' : `${subFolder}/`}${path.basename(resolved.file, '.md')}`));
451
+ copiedCount++;
452
+ } catch (error) {
453
+ console.log(chalk.yellow(` ⚠ Error copying ${resolved.file}: ${error.message}`));
454
+ }
455
+ }
456
+
457
+ if (copiedCount > 0) {
458
+ console.log(chalk.dim(` Total subagents installed: ${copiedCount}`));
459
+ }
460
+ }
461
+ }
462
+
463
+ module.exports = { AntigravitySetup };
@@ -466,6 +466,49 @@ class ClaudeCodeSetup extends BaseIdeSetup {
466
466
  console.log(chalk.dim(` Total subagents installed: ${copiedCount}`));
467
467
  }
468
468
  }
469
+
470
+ /**
471
+ * Install a custom agent launcher for Claude Code
472
+ * @param {string} projectDir - Project directory
473
+ * @param {string} agentName - Agent name (e.g., "fred-commit-poet")
474
+ * @param {string} agentPath - Path to compiled agent (relative to project root)
475
+ * @param {Object} metadata - Agent metadata
476
+ * @returns {Object|null} Info about created command
477
+ */
478
+ async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
479
+ const customAgentsDir = path.join(projectDir, this.configDir, this.commandsDir, 'bmad', 'custom', 'agents');
480
+
481
+ if (!(await this.exists(path.join(projectDir, this.configDir)))) {
482
+ return null; // IDE not configured for this project
483
+ }
484
+
485
+ await this.ensureDir(customAgentsDir);
486
+
487
+ const launcherContent = `---
488
+ name: '${agentName}'
489
+ description: '${agentName} agent'
490
+ ---
491
+
492
+ You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
493
+
494
+ <agent-activation CRITICAL="TRUE">
495
+ 1. LOAD the FULL agent file from @${agentPath}
496
+ 2. READ its entire contents - this contains the complete agent persona, menu, and instructions
497
+ 3. FOLLOW every step in the <activation> section precisely
498
+ 4. DISPLAY the welcome/greeting as instructed
499
+ 5. PRESENT the numbered menu
500
+ 6. WAIT for user input before proceeding
501
+ </agent-activation>
502
+ `;
503
+
504
+ const launcherPath = path.join(customAgentsDir, `${agentName}.md`);
505
+ await this.writeFile(launcherPath, launcherContent);
506
+
507
+ return {
508
+ path: launcherPath,
509
+ command: `/bmad:custom:agents:${agentName}`,
510
+ };
511
+ }
469
512
  }
470
513
 
471
514
  module.exports = { ClaudeCodeSetup };