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.
- package/CHANGELOG.md +219 -1105
- package/README.md +129 -359
- package/docs/custom-agent-installation.md +169 -0
- package/{v6-open-items.md → docs/v6-open-items.md} +1 -1
- package/package.json +4 -2
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/modules/bmb/docs/agent-compilation.md +340 -0
- package/src/modules/bmb/docs/agent-menu-patterns.md +524 -0
- package/src/modules/bmb/docs/expert-agent-architecture.md +364 -0
- package/src/modules/bmb/docs/index.md +55 -0
- package/src/modules/bmb/docs/module-agent-architecture.md +367 -0
- package/src/modules/bmb/docs/simple-agent-architecture.md +288 -0
- package/src/modules/bmb/docs/understanding-agent-types.md +184 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +242 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/breakthroughs.md +24 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/instructions.md +108 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/memories.md +46 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/mood-patterns.md +39 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +152 -0
- package/src/modules/bmb/reference/agents/module-examples/README.md +50 -0
- package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +53 -0
- package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +57 -0
- package/src/modules/bmb/reference/agents/simple-examples/README.md +223 -0
- package/src/modules/bmb/reference/agents/simple-examples/commit-poet.agent.yaml +126 -0
- package/src/modules/bmb/reference/readme.md +3 -0
- package/src/modules/bmb/workflows/create-agent/agent-validation-checklist.md +174 -0
- package/src/modules/bmb/workflows/create-agent/brainstorm-context.md +99 -120
- package/src/modules/bmb/workflows/create-agent/communication-presets.csv +61 -0
- package/src/modules/bmb/workflows/create-agent/instructions.md +126 -65
- package/src/modules/bmb/workflows/create-agent/workflow.yaml +19 -12
- package/src/modules/bmb/workflows/edit-agent/README.md +174 -47
- package/src/modules/bmb/workflows/edit-agent/instructions.md +397 -33
- package/src/modules/bmb/workflows/edit-agent/workflow.yaml +24 -8
- package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +1 -1
- package/src/modules/bmm/agents/analyst.agent.yaml +2 -2
- package/src/modules/bmm/agents/architect.agent.yaml +10 -2
- package/src/modules/bmm/agents/dev.agent.yaml +2 -2
- package/src/modules/bmm/agents/pm.agent.yaml +7 -3
- package/src/modules/bmm/agents/sm.agent.yaml +2 -2
- package/src/modules/bmm/agents/tea.agent.yaml +2 -2
- package/src/modules/bmm/agents/tech-writer.agent.yaml +15 -3
- package/src/modules/bmm/agents/ux-designer.agent.yaml +6 -2
- package/src/modules/bmm/docs/README.md +4 -0
- package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +5919 -0
- package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +2 -0
- package/src/modules/bmm/docs/quick-start.md +6 -0
- package/src/modules/bmm/docs/scale-adaptive-system.md +6 -0
- package/src/modules/bmm/docs/workflows-implementation.md +10 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.yaml +4 -4
- package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/workflow.yaml +5 -5
- package/src/modules/bmm/workflows/4-implementation/story-context/workflow.yaml +1 -1
- package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/instructions.md +7 -8
- package/src/modules/bmm/workflows/diagrams/create-dataflow/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/instructions.md +9 -10
- package/src/modules/bmm/workflows/diagrams/create-diagram/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/instructions.md +4 -5
- package/src/modules/bmm/workflows/diagrams/create-flowchart/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-wireframe/instructions.md +3 -3
- package/src/modules/bmm/workflows/diagrams/create-wireframe/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +18 -30
- package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +2 -14
- package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +2 -14
- package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +2 -14
- package/src/modules/cis/agents/presentation-master.agent.yaml +60 -0
- package/tools/cli/commands/agent-install.js +409 -0
- package/tools/cli/installers/lib/core/installer.js +119 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +25 -0
- package/tools/cli/installers/lib/ide/antigravity.js +463 -0
- package/tools/cli/installers/lib/ide/claude-code.js +43 -0
- package/tools/cli/installers/lib/ide/codex.js +217 -32
- package/tools/cli/installers/lib/ide/cursor.js +48 -0
- package/tools/cli/installers/lib/ide/github-copilot.js +74 -0
- package/tools/cli/installers/lib/ide/manager.js +35 -0
- package/tools/cli/installers/lib/ide/opencode.js +45 -0
- package/tools/cli/installers/lib/ide/windsurf.js +47 -0
- package/tools/cli/lib/agent/compiler.js +390 -0
- package/tools/cli/lib/agent/installer.js +725 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/docs/installers-bundlers/web-bundler-usage.md +0 -54
- package/src/modules/bmb/workflows/create-agent/README.md +0 -203
- package/src/modules/bmb/workflows/create-agent/agent-architecture.md +0 -415
- package/src/modules/bmb/workflows/create-agent/agent-command-patterns.md +0 -759
- package/src/modules/bmb/workflows/create-agent/agent-types.md +0 -292
- package/src/modules/bmb/workflows/create-agent/checklist.md +0 -62
- package/src/modules/bmb/workflows/create-agent/communication-styles.md +0 -202
- package/src/modules/bmb/workflows/edit-agent/checklist.md +0 -112
- package/src/modules/bmb/workflows/redoc/README.md +0 -87
- package/src/modules/bmb/workflows/redoc/checklist.md +0 -99
- package/src/modules/bmb/workflows/redoc/instructions.md +0 -265
- package/src/modules/bmb/workflows/redoc/workflow.yaml +0 -34
- package/src/modules/bmm/agents/frame-expert.agent.yaml +0 -42
- package/src/modules/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -24
- package/src/modules/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -25
- package/src/modules/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -28
- package/src/modules/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -24
- package/src/modules/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
- /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/excalidraw-helpers.md +0 -0
- /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/validate-json-instructions.md +0 -0
- /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/epics-template.md +0 -0
- /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/instructions.md +0 -0
- /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-library.json +0 -0
- /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-templates.yaml +0 -0
- /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/checklist.md +0 -0
- /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/checklist.md +0 -0
- /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/checklist.md +0 -0
- /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 };
|