bmad-method 6.0.0-Beta.1 → 6.0.0-Beta.2

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 (44) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/package.json +1 -1
  3. package/src/bmm/module-help.csv +31 -31
  4. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +1 -1
  5. package/src/core/module-help.csv +8 -8
  6. package/tools/cli/installers/lib/core/installer.js +26 -40
  7. package/tools/cli/installers/lib/ide/_config-driven.js +423 -0
  8. package/tools/cli/installers/lib/ide/codex.js +40 -12
  9. package/tools/cli/installers/lib/ide/manager.js +65 -38
  10. package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
  11. package/tools/cli/installers/lib/ide/platform-codes.yaml +241 -0
  12. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +19 -5
  13. package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +5 -0
  14. package/tools/cli/installers/lib/ide/shared/path-utils.js +166 -50
  15. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +7 -5
  16. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +21 -3
  17. package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
  18. package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
  19. package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
  20. package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
  21. package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
  22. package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
  23. package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
  24. package/tools/cli/installers/lib/ide/templates/split/gemini/body.md +10 -0
  25. package/tools/cli/installers/lib/ide/templates/split/gemini/header.toml +2 -0
  26. package/tools/cli/installers/lib/ide/templates/split/opencode/body.md +10 -0
  27. package/tools/cli/installers/lib/ide/templates/split/opencode/header.md +4 -0
  28. package/tools/cli/lib/ui.js +19 -75
  29. package/tools/cli/installers/lib/ide/STANDARDIZATION_PLAN.md +0 -208
  30. package/tools/cli/installers/lib/ide/antigravity.js +0 -474
  31. package/tools/cli/installers/lib/ide/auggie.js +0 -244
  32. package/tools/cli/installers/lib/ide/claude-code.js +0 -506
  33. package/tools/cli/installers/lib/ide/cline.js +0 -272
  34. package/tools/cli/installers/lib/ide/crush.js +0 -149
  35. package/tools/cli/installers/lib/ide/cursor.js +0 -160
  36. package/tools/cli/installers/lib/ide/gemini.js +0 -301
  37. package/tools/cli/installers/lib/ide/github-copilot.js +0 -383
  38. package/tools/cli/installers/lib/ide/iflow.js +0 -191
  39. package/tools/cli/installers/lib/ide/opencode.js +0 -257
  40. package/tools/cli/installers/lib/ide/qwen.js +0 -372
  41. package/tools/cli/installers/lib/ide/roo.js +0 -273
  42. package/tools/cli/installers/lib/ide/rovo-dev.js +0 -290
  43. package/tools/cli/installers/lib/ide/trae.js +0 -313
  44. package/tools/cli/installers/lib/ide/windsurf.js +0 -258
@@ -1,290 +0,0 @@
1
- const path = require('node:path');
2
- const fs = require('fs-extra');
3
- const chalk = require('chalk');
4
- const { BaseIdeSetup } = require('./_base-ide');
5
- const { AgentCommandGenerator } = require('./shared/agent-command-generator');
6
- const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
7
- const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
8
-
9
- /**
10
- * Rovo Dev IDE setup handler
11
- *
12
- * Installs BMAD agents as Rovo Dev subagents in .rovodev/subagents/
13
- * Installs workflows and tasks/tools as reference guides in .rovodev/
14
- * Rovo Dev automatically discovers agents and integrates with BMAD like other IDEs
15
- */
16
- class RovoDevSetup extends BaseIdeSetup {
17
- constructor() {
18
- super('rovo-dev', 'Atlassian Rovo Dev', false);
19
- this.configDir = '.rovodev';
20
- this.subagentsDir = 'subagents';
21
- this.workflowsDir = 'workflows';
22
- this.referencesDir = 'references';
23
- }
24
-
25
- /**
26
- * Cleanup old BMAD installation before reinstalling
27
- * @param {string} projectDir - Project directory
28
- */
29
- async cleanup(projectDir) {
30
- const rovoDevDir = path.join(projectDir, this.configDir);
31
-
32
- if (!(await fs.pathExists(rovoDevDir))) {
33
- return;
34
- }
35
-
36
- // Clean BMAD agents from subagents directory
37
- const subagentsDir = path.join(rovoDevDir, this.subagentsDir);
38
- if (await fs.pathExists(subagentsDir)) {
39
- const entries = await fs.readdir(subagentsDir);
40
- const bmadFiles = entries.filter((file) => file.startsWith('bmad') && file.endsWith('.md'));
41
-
42
- for (const file of bmadFiles) {
43
- await fs.remove(path.join(subagentsDir, file));
44
- }
45
- }
46
-
47
- // Clean BMAD workflows from workflows directory
48
- const workflowsDir = path.join(rovoDevDir, this.workflowsDir);
49
- if (await fs.pathExists(workflowsDir)) {
50
- const entries = await fs.readdir(workflowsDir);
51
- const bmadFiles = entries.filter((file) => file.startsWith('bmad') && file.endsWith('.md'));
52
-
53
- for (const file of bmadFiles) {
54
- await fs.remove(path.join(workflowsDir, file));
55
- }
56
- }
57
-
58
- // Clean BMAD tasks/tools from references directory
59
- const referencesDir = path.join(rovoDevDir, this.referencesDir);
60
- if (await fs.pathExists(referencesDir)) {
61
- const entries = await fs.readdir(referencesDir);
62
- const bmadFiles = entries.filter((file) => file.startsWith('bmad') && file.endsWith('.md'));
63
-
64
- for (const file of bmadFiles) {
65
- await fs.remove(path.join(referencesDir, file));
66
- }
67
- }
68
- }
69
-
70
- /**
71
- * Setup Rovo Dev configuration
72
- * @param {string} projectDir - Project directory
73
- * @param {string} bmadDir - BMAD installation directory
74
- * @param {Object} options - Setup options
75
- */
76
- async setup(projectDir, bmadDir, options = {}) {
77
- console.log(chalk.cyan(`Setting up ${this.name}...`));
78
-
79
- // Clean up old BMAD installation first
80
- await this.cleanup(projectDir);
81
-
82
- // Create .rovodev directory structure
83
- const rovoDevDir = path.join(projectDir, this.configDir);
84
- const subagentsDir = path.join(rovoDevDir, this.subagentsDir);
85
- const workflowsDir = path.join(rovoDevDir, this.workflowsDir);
86
- const referencesDir = path.join(rovoDevDir, this.referencesDir);
87
-
88
- await this.ensureDir(subagentsDir);
89
- await this.ensureDir(workflowsDir);
90
- await this.ensureDir(referencesDir);
91
-
92
- // Generate and install agents
93
- const agentGen = new AgentCommandGenerator(this.bmadFolderName);
94
- const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
95
-
96
- let agentCount = 0;
97
- for (const artifact of agentArtifacts) {
98
- const subagentFilename = `bmad-${artifact.module}-${artifact.name}.md`;
99
- const targetPath = path.join(subagentsDir, subagentFilename);
100
- const subagentContent = this.convertToRovoDevSubagent(artifact.content, artifact.name, artifact.module);
101
- await this.writeFile(targetPath, subagentContent);
102
- agentCount++;
103
- }
104
-
105
- // Generate and install workflows
106
- const workflowGen = new WorkflowCommandGenerator(this.bmadFolderName);
107
- const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGen.collectWorkflowArtifacts(bmadDir);
108
-
109
- let workflowCount = 0;
110
- for (const artifact of workflowArtifacts) {
111
- if (artifact.type === 'workflow-command') {
112
- const workflowFilename = path.basename(artifact.relativePath);
113
- const targetPath = path.join(workflowsDir, workflowFilename);
114
- await this.writeFile(targetPath, artifact.content);
115
- workflowCount++;
116
- }
117
- }
118
-
119
- // Generate and install tasks and tools
120
- const taskToolGen = new TaskToolCommandGenerator();
121
- const { tasks: taskCount, tools: toolCount } = await this.generateTaskToolReferences(bmadDir, referencesDir, taskToolGen);
122
-
123
- // Summary output
124
- console.log(chalk.green(`✓ ${this.name} configured:`));
125
- console.log(chalk.dim(` - ${agentCount} agents installed to .rovodev/subagents/`));
126
- if (workflowCount > 0) {
127
- console.log(chalk.dim(` - ${workflowCount} workflows installed to .rovodev/workflows/`));
128
- }
129
- if (taskCount + toolCount > 0) {
130
- console.log(
131
- chalk.dim(` - ${taskCount + toolCount} tasks/tools installed to .rovodev/references/ (${taskCount} tasks, ${toolCount} tools)`),
132
- );
133
- }
134
- console.log(chalk.yellow(`\n Note: Agents are automatically discovered by Rovo Dev`));
135
- console.log(chalk.dim(` - Access agents by typing @ in Rovo Dev to see available options`));
136
- console.log(chalk.dim(` - Workflows and references are available in .rovodev/ directory`));
137
-
138
- return {
139
- success: true,
140
- agents: agentCount,
141
- workflows: workflowCount,
142
- tasks: taskCount,
143
- tools: toolCount,
144
- };
145
- }
146
-
147
- /**
148
- * Generate task and tool reference guides
149
- * @param {string} bmadDir - BMAD directory
150
- * @param {string} referencesDir - References directory
151
- * @param {TaskToolCommandGenerator} taskToolGen - Generator instance
152
- */
153
- async generateTaskToolReferences(bmadDir, referencesDir, taskToolGen) {
154
- const tasks = await taskToolGen.loadTaskManifest(bmadDir);
155
- const tools = await taskToolGen.loadToolManifest(bmadDir);
156
-
157
- const standaloneTasks = tasks ? tasks.filter((t) => t.standalone === 'true' || t.standalone === true) : [];
158
- const standaloneTools = tools ? tools.filter((t) => t.standalone === 'true' || t.standalone === true) : [];
159
-
160
- let taskCount = 0;
161
- for (const task of standaloneTasks) {
162
- const commandContent = taskToolGen.generateCommandContent(task, 'task');
163
- const targetPath = path.join(referencesDir, `bmad-task-${task.module}-${task.name}.md`);
164
- await this.writeFile(targetPath, commandContent);
165
- taskCount++;
166
- }
167
-
168
- let toolCount = 0;
169
- for (const tool of standaloneTools) {
170
- const commandContent = taskToolGen.generateCommandContent(tool, 'tool');
171
- const targetPath = path.join(referencesDir, `bmad-tool-${tool.module}-${tool.name}.md`);
172
- await this.writeFile(targetPath, commandContent);
173
- toolCount++;
174
- }
175
-
176
- return { tasks: taskCount, tools: toolCount };
177
- }
178
-
179
- /**
180
- * Convert BMAD agent launcher to Rovo Dev subagent format
181
- *
182
- * Rovo Dev subagents use Markdown files with YAML frontmatter containing:
183
- * - name: Unique identifier for the subagent
184
- * - description: One-line description of the subagent's purpose
185
- * - tools: Array of tools the subagent can use (optional)
186
- * - model: Specific model for this subagent (optional)
187
- * - load_memory: Whether to load memory files (optional, defaults to true)
188
- *
189
- * @param {string} launcherContent - Original agent launcher content
190
- * @param {string} agentName - Name of the agent
191
- * @param {string} moduleName - Name of the module
192
- * @returns {string} Rovo Dev subagent-formatted content
193
- */
194
- convertToRovoDevSubagent(launcherContent, agentName, moduleName) {
195
- // Extract metadata from the launcher XML
196
- const titleMatch = launcherContent.match(/title="([^"]+)"/);
197
- const title = titleMatch ? titleMatch[1] : this.formatTitle(agentName);
198
-
199
- const descriptionMatch = launcherContent.match(/description="([^"]+)"/);
200
- const description = descriptionMatch ? descriptionMatch[1] : `BMAD agent: ${title}`;
201
-
202
- const roleDefinitionMatch = launcherContent.match(/roleDefinition="([^"]+)"/);
203
- const roleDefinition = roleDefinitionMatch ? roleDefinitionMatch[1] : `You are a specialized agent for ${title.toLowerCase()} tasks.`;
204
-
205
- // Extract the main system prompt from the launcher (content after closing tags)
206
- let systemPrompt = roleDefinition;
207
-
208
- // Try to extract additional instructions from the launcher content
209
- const instructionsMatch = launcherContent.match(/<instructions>([\s\S]*?)<\/instructions>/);
210
- if (instructionsMatch) {
211
- systemPrompt += '\n\n' + instructionsMatch[1].trim();
212
- }
213
-
214
- // Build YAML frontmatter for Rovo Dev subagent
215
- const frontmatter = {
216
- name: `bmad-${moduleName}-${agentName}`,
217
- description: description,
218
- // Note: tools and model can be added by users in their .rovodev/subagents/*.md files
219
- // We don't enforce specific tools since BMAD agents are flexible
220
- };
221
-
222
- // Create YAML frontmatter string with proper quoting for special characters
223
- let yamlContent = '---\n';
224
- yamlContent += `name: ${frontmatter.name}\n`;
225
- // Quote description to handle colons and other special characters in YAML
226
- yamlContent += `description: "${frontmatter.description.replaceAll('"', String.raw`\"`)}"\n`;
227
- yamlContent += '---\n';
228
-
229
- // Combine frontmatter with system prompt
230
- const subagentContent = yamlContent + systemPrompt;
231
-
232
- return subagentContent;
233
- }
234
-
235
- /**
236
- * Detect whether Rovo Dev is already configured in the project
237
- * @param {string} projectDir - Project directory
238
- * @returns {boolean}
239
- */
240
- async detect(projectDir) {
241
- const rovoDevDir = path.join(projectDir, this.configDir);
242
-
243
- if (!(await fs.pathExists(rovoDevDir))) {
244
- return false;
245
- }
246
-
247
- // Check for BMAD agents in subagents directory
248
- const subagentsDir = path.join(rovoDevDir, this.subagentsDir);
249
- if (await fs.pathExists(subagentsDir)) {
250
- try {
251
- const entries = await fs.readdir(subagentsDir);
252
- if (entries.some((entry) => entry.startsWith('bmad') && entry.endsWith('.md'))) {
253
- return true;
254
- }
255
- } catch {
256
- // Continue checking other directories
257
- }
258
- }
259
-
260
- // Check for BMAD workflows in workflows directory
261
- const workflowsDir = path.join(rovoDevDir, this.workflowsDir);
262
- if (await fs.pathExists(workflowsDir)) {
263
- try {
264
- const entries = await fs.readdir(workflowsDir);
265
- if (entries.some((entry) => entry.startsWith('bmad') && entry.endsWith('.md'))) {
266
- return true;
267
- }
268
- } catch {
269
- // Continue checking other directories
270
- }
271
- }
272
-
273
- // Check for BMAD tasks/tools in references directory
274
- const referencesDir = path.join(rovoDevDir, this.referencesDir);
275
- if (await fs.pathExists(referencesDir)) {
276
- try {
277
- const entries = await fs.readdir(referencesDir);
278
- if (entries.some((entry) => entry.startsWith('bmad') && entry.endsWith('.md'))) {
279
- return true;
280
- }
281
- } catch {
282
- // Continue
283
- }
284
- }
285
-
286
- return false;
287
- }
288
- }
289
-
290
- module.exports = { RovoDevSetup };
@@ -1,313 +0,0 @@
1
- const path = require('node:path');
2
- const fs = require('fs-extra');
3
- const { BaseIdeSetup } = require('./_base-ide');
4
- const chalk = require('chalk');
5
- const { AgentCommandGenerator } = require('./shared/agent-command-generator');
6
-
7
- /**
8
- * Trae IDE setup handler
9
- */
10
- class TraeSetup extends BaseIdeSetup {
11
- constructor() {
12
- super('trae', 'Trae');
13
- this.configDir = '.trae';
14
- this.rulesDir = 'rules';
15
- }
16
-
17
- /**
18
- * Setup Trae IDE configuration
19
- * @param {string} projectDir - Project directory
20
- * @param {string} bmadDir - BMAD installation directory
21
- * @param {Object} options - Setup options
22
- */
23
- async setup(projectDir, bmadDir, options = {}) {
24
- console.log(chalk.cyan(`Setting up ${this.name}...`));
25
-
26
- // Create .trae/rules directory
27
- const traeDir = path.join(projectDir, this.configDir);
28
- const rulesDir = path.join(traeDir, this.rulesDir);
29
-
30
- await this.ensureDir(rulesDir);
31
-
32
- // Clean up any existing BMAD files before reinstalling
33
- await this.cleanup(projectDir);
34
-
35
- // Generate agent launchers
36
- const agentGen = new AgentCommandGenerator(this.bmadFolderName);
37
- const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
38
-
39
- // Get tasks, tools, and workflows (standalone only)
40
- const tasks = await this.getTasks(bmadDir, true);
41
- const tools = await this.getTools(bmadDir, true);
42
- const workflows = await this.getWorkflows(bmadDir, true);
43
-
44
- // Process agents as rules with bmad- prefix
45
- let agentCount = 0;
46
- for (const artifact of agentArtifacts) {
47
- const processedContent = await this.createAgentRule(artifact, bmadDir, projectDir);
48
-
49
- // Use bmad- prefix: bmad-agent-{module}-{name}.md
50
- const targetPath = path.join(rulesDir, `bmad-agent-${artifact.module}-${artifact.name}.md`);
51
- await this.writeFile(targetPath, processedContent);
52
- agentCount++;
53
- }
54
-
55
- // Process tasks as rules with bmad- prefix
56
- let taskCount = 0;
57
- for (const task of tasks) {
58
- const content = await this.readFile(task.path);
59
- const processedContent = this.createTaskRule(task, content);
60
-
61
- // Use bmad- prefix: bmad-task-{module}-{name}.md
62
- const targetPath = path.join(rulesDir, `bmad-task-${task.module}-${task.name}.md`);
63
- await this.writeFile(targetPath, processedContent);
64
- taskCount++;
65
- }
66
-
67
- // Process tools as rules with bmad- prefix
68
- let toolCount = 0;
69
- for (const tool of tools) {
70
- const content = await this.readFile(tool.path);
71
- const processedContent = this.createToolRule(tool, content);
72
-
73
- // Use bmad- prefix: bmad-tool-{module}-{name}.md
74
- const targetPath = path.join(rulesDir, `bmad-tool-${tool.module}-${tool.name}.md`);
75
- await this.writeFile(targetPath, processedContent);
76
- toolCount++;
77
- }
78
-
79
- // Process workflows as rules with bmad- prefix
80
- let workflowCount = 0;
81
- for (const workflow of workflows) {
82
- const content = await this.readFile(workflow.path);
83
- const processedContent = this.createWorkflowRule(workflow, content);
84
-
85
- // Use bmad- prefix: bmad-workflow-{module}-{name}.md
86
- const targetPath = path.join(rulesDir, `bmad-workflow-${workflow.module}-${workflow.name}.md`);
87
- await this.writeFile(targetPath, processedContent);
88
- workflowCount++;
89
- }
90
-
91
- const totalRules = agentCount + taskCount + toolCount + workflowCount;
92
-
93
- console.log(chalk.green(`✓ ${this.name} configured:`));
94
- console.log(chalk.dim(` - ${agentCount} agent rules created`));
95
- console.log(chalk.dim(` - ${taskCount} task rules created`));
96
- console.log(chalk.dim(` - ${toolCount} tool rules created`));
97
- console.log(chalk.dim(` - ${workflowCount} workflow rules created`));
98
- console.log(chalk.dim(` - Total: ${totalRules} rules`));
99
- console.log(chalk.dim(` - Rules directory: ${path.relative(projectDir, rulesDir)}`));
100
- console.log(chalk.dim(` - Agents can be activated with @{agent-name}`));
101
-
102
- return {
103
- success: true,
104
- rules: totalRules,
105
- agents: agentCount,
106
- tasks: taskCount,
107
- tools: toolCount,
108
- workflows: workflowCount,
109
- };
110
- }
111
-
112
- /**
113
- * Create rule content for an agent
114
- */
115
- async createAgentRule(artifact, bmadDir, projectDir) {
116
- // Strip frontmatter from launcher
117
- const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
118
- const contentWithoutFrontmatter = artifact.content.replace(frontmatterRegex, '').trim();
119
-
120
- // Extract metadata from launcher content
121
- const titleMatch = artifact.content.match(/description:\s*"([^"]+)"/);
122
- const title = titleMatch ? titleMatch[1] : this.formatTitle(artifact.name);
123
-
124
- // Calculate relative path for reference
125
- const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/');
126
-
127
- let ruleContent = `# ${title} Agent Rule
128
-
129
- This rule is triggered when the user types \`@${artifact.name}\` and activates the ${title} agent persona.
130
-
131
- ## Agent Activation
132
-
133
- ${contentWithoutFrontmatter}
134
-
135
- ## File Reference
136
-
137
- The full agent definition is located at: \`${relativePath}\`
138
- `;
139
-
140
- return ruleContent;
141
- }
142
-
143
- /**
144
- * Create rule content for a task
145
- */
146
- createTaskRule(task, content) {
147
- // Extract task name from content
148
- const nameMatch = content.match(/name="([^"]+)"/);
149
- const taskName = nameMatch ? nameMatch[1] : this.formatTitle(task.name);
150
-
151
- let ruleContent = `# ${taskName} Task Rule
152
-
153
- This rule defines the ${taskName} task workflow.
154
-
155
- ## Task Definition
156
-
157
- When this task is triggered, execute the following workflow:
158
-
159
- ${content}
160
-
161
- ## Usage
162
-
163
- Reference this task with \`@task-${task.name}\` to execute the defined workflow.
164
-
165
- ## Module
166
-
167
- Part of the BMAD ${task.module.toUpperCase()} module.
168
- `;
169
-
170
- return ruleContent;
171
- }
172
-
173
- /**
174
- * Create rule content for a tool
175
- */
176
- createToolRule(tool, content) {
177
- // Extract tool name from content
178
- const nameMatch = content.match(/name="([^"]+)"/);
179
- const toolName = nameMatch ? nameMatch[1] : this.formatTitle(tool.name);
180
-
181
- let ruleContent = `# ${toolName} Tool Rule
182
-
183
- This rule defines the ${toolName} tool.
184
-
185
- ## Tool Definition
186
-
187
- When this tool is triggered, execute the following:
188
-
189
- ${content}
190
-
191
- ## Usage
192
-
193
- Reference this tool with \`@tool-${tool.name}\` to execute it.
194
-
195
- ## Module
196
-
197
- Part of the BMAD ${tool.module.toUpperCase()} module.
198
- `;
199
-
200
- return ruleContent;
201
- }
202
-
203
- /**
204
- * Create rule content for a workflow
205
- */
206
- createWorkflowRule(workflow, content) {
207
- let ruleContent = `# ${workflow.name} Workflow Rule
208
-
209
- This rule defines the ${workflow.name} workflow.
210
-
211
- ## Workflow Description
212
-
213
- ${workflow.description || 'No description provided'}
214
-
215
- ## Workflow Definition
216
-
217
- ${content}
218
-
219
- ## Usage
220
-
221
- Reference this workflow with \`@workflow-${workflow.name}\` to execute the guided workflow.
222
-
223
- ## Module
224
-
225
- Part of the BMAD ${workflow.module.toUpperCase()} module.
226
- `;
227
-
228
- return ruleContent;
229
- }
230
-
231
- /**
232
- * Format agent/task name as title
233
- */
234
- formatTitle(name) {
235
- return name
236
- .split('-')
237
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
238
- .join(' ');
239
- }
240
-
241
- /**
242
- * Cleanup Trae configuration - surgically remove only BMAD files
243
- */
244
- async cleanup(projectDir) {
245
- const fs = require('fs-extra');
246
- const rulesPath = path.join(projectDir, this.configDir, this.rulesDir);
247
-
248
- if (await fs.pathExists(rulesPath)) {
249
- // Remove any bmad* files (cleans up old bmad- and bmad: formats)
250
- const files = await fs.readdir(rulesPath);
251
- let removed = 0;
252
-
253
- for (const file of files) {
254
- if (file.startsWith('bmad') && file.endsWith('.md')) {
255
- await fs.remove(path.join(rulesPath, file));
256
- removed++;
257
- }
258
- }
259
-
260
- if (removed > 0) {
261
- console.log(chalk.dim(` Cleaned up ${removed} existing BMAD rules`));
262
- }
263
- }
264
- }
265
-
266
- /**
267
- * Install a custom agent launcher for Trae
268
- * @param {string} projectDir - Project directory
269
- * @param {string} agentName - Agent name (e.g., "fred-commit-poet")
270
- * @param {string} agentPath - Path to compiled agent (relative to project root)
271
- * @param {Object} metadata - Agent metadata
272
- * @returns {Object} Installation result
273
- */
274
- async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
275
- const traeDir = path.join(projectDir, this.configDir);
276
- const rulesDir = path.join(traeDir, this.rulesDir);
277
-
278
- // Create .trae/rules directory if it doesn't exist
279
- await fs.ensureDir(rulesDir);
280
-
281
- // Create custom agent launcher
282
- const launcherContent = `# ${agentName} Custom Agent
283
-
284
- **⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
285
-
286
- This is a launcher for the custom BMAD agent "${agentName}".
287
-
288
- ## Usage
289
- 1. First run: \`${agentPath}\` to load the complete agent
290
- 2. Then use this rule to activate ${agentName}
291
-
292
- The agent will follow the persona and instructions from the main agent file.
293
-
294
- ---
295
-
296
- *Generated by BMAD Method*`;
297
-
298
- const fileName = `bmad-agent-custom-${agentName.toLowerCase()}.md`;
299
- const launcherPath = path.join(rulesDir, fileName);
300
-
301
- // Write the launcher file
302
- await fs.writeFile(launcherPath, launcherContent, 'utf8');
303
-
304
- return {
305
- ide: 'trae',
306
- path: path.relative(projectDir, launcherPath),
307
- command: agentName,
308
- type: 'custom-agent-launcher',
309
- };
310
- }
311
- }
312
-
313
- module.exports = { TraeSetup };