bmad-method 4.37.0-beta.6 ā 5.0.0-beta.1
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/.github/workflows/promote-to-stable.yml +144 -0
- package/CHANGELOG.md +27 -2
- package/bmad-core/agents/analyst.md +1 -1
- package/bmad-core/agents/architect.md +2 -3
- package/bmad-core/agents/bmad-master.md +0 -1
- package/bmad-core/agents/bmad-orchestrator.md +9 -10
- package/bmad-core/agents/dev.md +9 -10
- package/bmad-core/agents/po.md +1 -1
- package/bmad-core/agents/qa.md +38 -19
- package/bmad-core/agents/sm.md +1 -1
- package/bmad-core/agents/ux-expert.md +1 -1
- package/bmad-core/checklists/architect-checklist.md +0 -5
- package/bmad-core/checklists/pm-checklist.md +0 -5
- package/bmad-core/checklists/po-master-checklist.md +0 -9
- package/bmad-core/checklists/story-dod-checklist.md +0 -7
- package/bmad-core/checklists/story-draft-checklist.md +0 -3
- package/bmad-core/data/bmad-kb.md +5 -2
- package/bmad-core/data/elicitation-methods.md +20 -0
- package/bmad-core/data/test-levels-framework.md +146 -0
- package/bmad-core/data/test-priorities-matrix.md +172 -0
- package/bmad-core/tasks/create-brownfield-story.md +11 -3
- package/bmad-core/tasks/create-deep-research-prompt.md +0 -11
- package/bmad-core/tasks/document-project.md +15 -13
- package/bmad-core/tasks/facilitate-brainstorming-session.md +1 -1
- package/bmad-core/tasks/index-docs.md +0 -6
- package/bmad-core/tasks/kb-mode-interaction.md +3 -3
- package/bmad-core/tasks/nfr-assess.md +343 -0
- package/bmad-core/tasks/qa-gate.md +159 -0
- package/bmad-core/tasks/review-story.md +243 -74
- package/bmad-core/tasks/risk-profile.md +353 -0
- package/bmad-core/tasks/shard-doc.md +0 -2
- package/bmad-core/tasks/test-design.md +174 -0
- package/bmad-core/tasks/trace-requirements.md +264 -0
- package/bmad-core/templates/qa-gate-tmpl.yaml +102 -0
- package/common/tasks/execute-checklist.md +0 -7
- package/dist/agents/analyst.txt +20 -26
- package/dist/agents/architect.txt +14 -35
- package/dist/agents/bmad-master.txt +40 -70
- package/dist/agents/bmad-orchestrator.txt +28 -5
- package/dist/agents/dev.txt +0 -14
- package/dist/agents/pm.txt +0 -25
- package/dist/agents/po.txt +0 -18
- package/dist/agents/qa.txt +2079 -135
- package/dist/agents/sm.txt +0 -10
- package/dist/agents/ux-expert.txt +0 -7
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +0 -37
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +3 -12
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +0 -7
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +44 -90
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +14 -49
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +0 -46
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -15
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +0 -17
- package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +38 -142
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +0 -2
- package/dist/teams/team-all.txt +2181 -261
- package/dist/teams/team-fullstack.txt +43 -57
- package/dist/teams/team-ide-minimal.txt +2064 -125
- package/dist/teams/team-no-ui.txt +43 -57
- package/docs/enhanced-ide-development-workflow.md +220 -15
- package/docs/user-guide.md +271 -18
- package/docs/working-in-the-brownfield.md +265 -32
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +14 -14
- package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +0 -4
- package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +3 -5
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +0 -1
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +0 -18
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +0 -5
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +0 -8
- package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +0 -7
- package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +0 -4
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +0 -1
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +0 -10
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +0 -18
- package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +0 -3
- package/expansion-packs/bmad-infrastructure-devops/tasks/review-infrastructure.md +0 -1
- package/expansion-packs/bmad-infrastructure-devops/tasks/validate-infrastructure.md +0 -1
- package/package.json +1 -1
- package/tools/installer/bin/bmad.js +33 -32
- package/tools/installer/config/install.config.yaml +11 -1
- package/tools/installer/lib/file-manager.js +1 -1
- package/tools/installer/lib/ide-base-setup.js +1 -1
- package/tools/installer/lib/ide-setup.js +197 -83
- package/tools/installer/lib/installer.js +3 -3
- package/tools/installer/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
const fs = require("fs-extra");
|
|
3
3
|
const yaml = require("js-yaml");
|
|
4
|
-
const chalk = require("chalk");
|
|
5
|
-
const inquirer = require("inquirer");
|
|
4
|
+
const chalk = require("chalk").default || require("chalk");
|
|
5
|
+
const inquirer = require("inquirer").default || require("inquirer");
|
|
6
6
|
const fileManager = require("./file-manager");
|
|
7
7
|
const configLoader = require("./config-loader");
|
|
8
8
|
const { extractYamlFromAgent } = require("../../lib/yaml-utils");
|
|
@@ -17,7 +17,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
17
17
|
|
|
18
18
|
async loadIdeAgentConfig() {
|
|
19
19
|
if (this.ideAgentConfig) return this.ideAgentConfig;
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
try {
|
|
22
22
|
const configPath = path.join(__dirname, '..', 'config', 'ide-agent-config.yaml');
|
|
23
23
|
const configContent = await fs.readFile(configPath, 'utf8');
|
|
@@ -45,6 +45,8 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
45
45
|
return this.setupCursor(installDir, selectedAgent);
|
|
46
46
|
case "claude-code":
|
|
47
47
|
return this.setupClaudeCode(installDir, selectedAgent);
|
|
48
|
+
case "crush":
|
|
49
|
+
return this.setupCrush(installDir, selectedAgent);
|
|
48
50
|
case "windsurf":
|
|
49
51
|
return this.setupWindsurf(installDir, selectedAgent);
|
|
50
52
|
case "trae":
|
|
@@ -88,6 +90,30 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
88
90
|
return true;
|
|
89
91
|
}
|
|
90
92
|
|
|
93
|
+
async setupCrush(installDir, selectedAgent) {
|
|
94
|
+
// Setup bmad-core commands
|
|
95
|
+
const coreSlashPrefix = await this.getCoreSlashPrefix(installDir);
|
|
96
|
+
const coreAgents = selectedAgent ? [selectedAgent] : await this.getCoreAgentIds(installDir);
|
|
97
|
+
const coreTasks = await this.getCoreTaskIds(installDir);
|
|
98
|
+
await this.setupCrushForPackage(installDir, "core", coreSlashPrefix, coreAgents, coreTasks, ".bmad-core");
|
|
99
|
+
|
|
100
|
+
// Setup expansion pack commands
|
|
101
|
+
const expansionPacks = await this.getInstalledExpansionPacks(installDir);
|
|
102
|
+
for (const packInfo of expansionPacks) {
|
|
103
|
+
const packSlashPrefix = await this.getExpansionPackSlashPrefix(packInfo.path);
|
|
104
|
+
const packAgents = await this.getExpansionPackAgents(packInfo.path);
|
|
105
|
+
const packTasks = await this.getExpansionPackTasks(packInfo.path);
|
|
106
|
+
|
|
107
|
+
if (packAgents.length > 0 || packTasks.length > 0) {
|
|
108
|
+
// Use the actual directory name where the expansion pack is installed
|
|
109
|
+
const rootPath = path.relative(installDir, packInfo.path);
|
|
110
|
+
await this.setupCrushForPackage(installDir, packInfo.name, packSlashPrefix, packAgents, packTasks, rootPath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
91
117
|
async setupClaudeCode(installDir, selectedAgent) {
|
|
92
118
|
// Setup bmad-core commands
|
|
93
119
|
const coreSlashPrefix = await this.getCoreSlashPrefix(installDir);
|
|
@@ -101,7 +127,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
101
127
|
const packSlashPrefix = await this.getExpansionPackSlashPrefix(packInfo.path);
|
|
102
128
|
const packAgents = await this.getExpansionPackAgents(packInfo.path);
|
|
103
129
|
const packTasks = await this.getExpansionPackTasks(packInfo.path);
|
|
104
|
-
|
|
130
|
+
|
|
105
131
|
if (packAgents.length > 0 || packTasks.length > 0) {
|
|
106
132
|
// Use the actual directory name where the expansion pack is installed
|
|
107
133
|
const rootPath = path.relative(installDir, packInfo.path);
|
|
@@ -138,13 +164,13 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
138
164
|
// For core, use the normal search
|
|
139
165
|
agentPath = await this.findAgentPath(agentId, installDir);
|
|
140
166
|
}
|
|
141
|
-
|
|
167
|
+
|
|
142
168
|
const commandPath = path.join(agentsDir, `${agentId}.md`);
|
|
143
169
|
|
|
144
170
|
if (agentPath) {
|
|
145
171
|
// Create command file with agent content
|
|
146
172
|
let agentContent = await fileManager.readFile(agentPath);
|
|
147
|
-
|
|
173
|
+
|
|
148
174
|
// Replace {root} placeholder with the appropriate root path for this context
|
|
149
175
|
agentContent = agentContent.replace(/{root}/g, rootPath);
|
|
150
176
|
|
|
@@ -175,13 +201,13 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
175
201
|
// For core, use the normal search
|
|
176
202
|
taskPath = await this.findTaskPath(taskId, installDir);
|
|
177
203
|
}
|
|
178
|
-
|
|
204
|
+
|
|
179
205
|
const commandPath = path.join(tasksDir, `${taskId}.md`);
|
|
180
206
|
|
|
181
207
|
if (taskPath) {
|
|
182
208
|
// Create command file with task content
|
|
183
209
|
let taskContent = await fileManager.readFile(taskPath);
|
|
184
|
-
|
|
210
|
+
|
|
185
211
|
// Replace {root} placeholder with the appropriate root path for this context
|
|
186
212
|
taskContent = taskContent.replace(/{root}/g, rootPath);
|
|
187
213
|
|
|
@@ -200,6 +226,94 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
200
226
|
console.log(chalk.dim(` - Tasks in: ${tasksDir}`));
|
|
201
227
|
}
|
|
202
228
|
|
|
229
|
+
async setupCrushForPackage(installDir, packageName, slashPrefix, agentIds, taskIds, rootPath) {
|
|
230
|
+
const commandsBaseDir = path.join(installDir, ".crush", "commands", slashPrefix);
|
|
231
|
+
const agentsDir = path.join(commandsBaseDir, "agents");
|
|
232
|
+
const tasksDir = path.join(commandsBaseDir, "tasks");
|
|
233
|
+
|
|
234
|
+
// Ensure directories exist
|
|
235
|
+
await fileManager.ensureDirectory(agentsDir);
|
|
236
|
+
await fileManager.ensureDirectory(tasksDir);
|
|
237
|
+
|
|
238
|
+
// Setup agents
|
|
239
|
+
for (const agentId of agentIds) {
|
|
240
|
+
// Find the agent file - for expansion packs, prefer the expansion pack version
|
|
241
|
+
let agentPath;
|
|
242
|
+
if (packageName !== "core") {
|
|
243
|
+
// For expansion packs, first try to find the agent in the expansion pack directory
|
|
244
|
+
const expansionPackPath = path.join(installDir, rootPath, "agents", `${agentId}.md`);
|
|
245
|
+
if (await fileManager.pathExists(expansionPackPath)) {
|
|
246
|
+
agentPath = expansionPackPath;
|
|
247
|
+
} else {
|
|
248
|
+
// Fall back to core if not found in expansion pack
|
|
249
|
+
agentPath = await this.findAgentPath(agentId, installDir);
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
// For core, use the normal search
|
|
253
|
+
agentPath = await this.findAgentPath(agentId, installDir);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const commandPath = path.join(agentsDir, `${agentId}.md`);
|
|
257
|
+
|
|
258
|
+
if (agentPath) {
|
|
259
|
+
// Create command file with agent content
|
|
260
|
+
let agentContent = await fileManager.readFile(agentPath);
|
|
261
|
+
|
|
262
|
+
// Replace {root} placeholder with the appropriate root path for this context
|
|
263
|
+
agentContent = agentContent.replace(/{root}/g, rootPath);
|
|
264
|
+
|
|
265
|
+
// Add command header
|
|
266
|
+
let commandContent = `# /${agentId} Command\n\n`;
|
|
267
|
+
commandContent += `When this command is used, adopt the following agent persona:\n\n`;
|
|
268
|
+
commandContent += agentContent;
|
|
269
|
+
|
|
270
|
+
await fileManager.writeFile(commandPath, commandContent);
|
|
271
|
+
console.log(chalk.green(`ā Created agent command: /${agentId}`));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Setup tasks
|
|
276
|
+
for (const taskId of taskIds) {
|
|
277
|
+
// Find the task file - for expansion packs, prefer the expansion pack version
|
|
278
|
+
let taskPath;
|
|
279
|
+
if (packageName !== "core") {
|
|
280
|
+
// For expansion packs, first try to find the task in the expansion pack directory
|
|
281
|
+
const expansionPackPath = path.join(installDir, rootPath, "tasks", `${taskId}.md`);
|
|
282
|
+
if (await fileManager.pathExists(expansionPackPath)) {
|
|
283
|
+
taskPath = expansionPackPath;
|
|
284
|
+
} else {
|
|
285
|
+
// Fall back to core if not found in expansion pack
|
|
286
|
+
taskPath = await this.findTaskPath(taskId, installDir);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
// For core, use the normal search
|
|
290
|
+
taskPath = await this.findTaskPath(taskId, installDir);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const commandPath = path.join(tasksDir, `${taskId}.md`);
|
|
294
|
+
|
|
295
|
+
if (taskPath) {
|
|
296
|
+
// Create command file with task content
|
|
297
|
+
let taskContent = await fileManager.readFile(taskPath);
|
|
298
|
+
|
|
299
|
+
// Replace {root} placeholder with the appropriate root path for this context
|
|
300
|
+
taskContent = taskContent.replace(/{root}/g, rootPath);
|
|
301
|
+
|
|
302
|
+
// Add command header
|
|
303
|
+
let commandContent = `# /${taskId} Task\n\n`;
|
|
304
|
+
commandContent += `When this command is used, execute the following task:\n\n`;
|
|
305
|
+
commandContent += taskContent;
|
|
306
|
+
|
|
307
|
+
await fileManager.writeFile(commandPath, commandContent);
|
|
308
|
+
console.log(chalk.green(`ā Created task command: /${taskId}`));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
console.log(chalk.green(`\nā Created Crush commands for ${packageName} in ${commandsBaseDir}`));
|
|
313
|
+
console.log(chalk.dim(` - Agents in: ${agentsDir}`));
|
|
314
|
+
console.log(chalk.dim(` - Tasks in: ${tasksDir}`));
|
|
315
|
+
}
|
|
316
|
+
|
|
203
317
|
async setupWindsurf(installDir, selectedAgent) {
|
|
204
318
|
const windsurfRulesDir = path.join(installDir, ".windsurf", "rules");
|
|
205
319
|
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
|
|
@@ -255,17 +369,17 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
255
369
|
async setupTrae(installDir, selectedAgent) {
|
|
256
370
|
const traeRulesDir = path.join(installDir, ".trae", "rules");
|
|
257
371
|
const agents = selectedAgent? [selectedAgent] : await this.getAllAgentIds(installDir);
|
|
258
|
-
|
|
372
|
+
|
|
259
373
|
await fileManager.ensureDirectory(traeRulesDir);
|
|
260
|
-
|
|
374
|
+
|
|
261
375
|
for (const agentId of agents) {
|
|
262
376
|
// Find the agent file
|
|
263
377
|
const agentPath = await this.findAgentPath(agentId, installDir);
|
|
264
|
-
|
|
378
|
+
|
|
265
379
|
if (agentPath) {
|
|
266
380
|
const agentContent = await fileManager.readFile(agentPath);
|
|
267
381
|
const mdPath = path.join(traeRulesDir, `${agentId}.md`);
|
|
268
|
-
|
|
382
|
+
|
|
269
383
|
// Create MD content (similar to Cursor but without frontmatter)
|
|
270
384
|
let mdContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
|
|
271
385
|
mdContent += `This rule is triggered when the user types \`@${agentId}\` and activates the ${await this.getAgentTitle(
|
|
@@ -294,7 +408,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
294
408
|
agentId,
|
|
295
409
|
installDir
|
|
296
410
|
)} persona and follow all instructions defined in the YAML configuration above.\n`;
|
|
297
|
-
|
|
411
|
+
|
|
298
412
|
await fileManager.writeFile(mdPath, mdContent);
|
|
299
413
|
console.log(chalk.green(`ā Created rule: ${agentId}.md`));
|
|
300
414
|
}
|
|
@@ -307,38 +421,38 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
307
421
|
path.join(installDir, ".bmad-core", "agents", `${agentId}.md`),
|
|
308
422
|
path.join(installDir, "agents", `${agentId}.md`)
|
|
309
423
|
];
|
|
310
|
-
|
|
424
|
+
|
|
311
425
|
// Also check expansion pack directories
|
|
312
426
|
const glob = require("glob");
|
|
313
427
|
const expansionDirs = glob.sync(".*/agents", { cwd: installDir });
|
|
314
428
|
for (const expDir of expansionDirs) {
|
|
315
429
|
possiblePaths.push(path.join(installDir, expDir, `${agentId}.md`));
|
|
316
430
|
}
|
|
317
|
-
|
|
431
|
+
|
|
318
432
|
for (const agentPath of possiblePaths) {
|
|
319
433
|
if (await fileManager.pathExists(agentPath)) {
|
|
320
434
|
return agentPath;
|
|
321
435
|
}
|
|
322
436
|
}
|
|
323
|
-
|
|
437
|
+
|
|
324
438
|
return null;
|
|
325
439
|
}
|
|
326
440
|
|
|
327
441
|
async getAllAgentIds(installDir) {
|
|
328
442
|
const glob = require("glob");
|
|
329
443
|
const allAgentIds = [];
|
|
330
|
-
|
|
444
|
+
|
|
331
445
|
// Check core agents in .bmad-core or root
|
|
332
446
|
let agentsDir = path.join(installDir, ".bmad-core", "agents");
|
|
333
447
|
if (!(await fileManager.pathExists(agentsDir))) {
|
|
334
448
|
agentsDir = path.join(installDir, "agents");
|
|
335
449
|
}
|
|
336
|
-
|
|
450
|
+
|
|
337
451
|
if (await fileManager.pathExists(agentsDir)) {
|
|
338
452
|
const agentFiles = glob.sync("*.md", { cwd: agentsDir });
|
|
339
453
|
allAgentIds.push(...agentFiles.map((file) => path.basename(file, ".md")));
|
|
340
454
|
}
|
|
341
|
-
|
|
455
|
+
|
|
342
456
|
// Also check for expansion pack agents in dot folders
|
|
343
457
|
const expansionDirs = glob.sync(".*/agents", { cwd: installDir });
|
|
344
458
|
for (const expDir of expansionDirs) {
|
|
@@ -346,51 +460,51 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
346
460
|
const expAgentFiles = glob.sync("*.md", { cwd: fullExpDir });
|
|
347
461
|
allAgentIds.push(...expAgentFiles.map((file) => path.basename(file, ".md")));
|
|
348
462
|
}
|
|
349
|
-
|
|
463
|
+
|
|
350
464
|
// Remove duplicates
|
|
351
465
|
return [...new Set(allAgentIds)];
|
|
352
466
|
}
|
|
353
467
|
|
|
354
468
|
async getCoreAgentIds(installDir) {
|
|
355
469
|
const allAgentIds = [];
|
|
356
|
-
|
|
470
|
+
|
|
357
471
|
// Check core agents in .bmad-core or root only
|
|
358
472
|
let agentsDir = path.join(installDir, ".bmad-core", "agents");
|
|
359
473
|
if (!(await fileManager.pathExists(agentsDir))) {
|
|
360
474
|
agentsDir = path.join(installDir, "bmad-core", "agents");
|
|
361
475
|
}
|
|
362
|
-
|
|
476
|
+
|
|
363
477
|
if (await fileManager.pathExists(agentsDir)) {
|
|
364
478
|
const glob = require("glob");
|
|
365
479
|
const agentFiles = glob.sync("*.md", { cwd: agentsDir });
|
|
366
480
|
allAgentIds.push(...agentFiles.map((file) => path.basename(file, ".md")));
|
|
367
481
|
}
|
|
368
|
-
|
|
482
|
+
|
|
369
483
|
return [...new Set(allAgentIds)];
|
|
370
484
|
}
|
|
371
485
|
|
|
372
486
|
async getCoreTaskIds(installDir) {
|
|
373
487
|
const allTaskIds = [];
|
|
374
|
-
|
|
488
|
+
|
|
375
489
|
// Check core tasks in .bmad-core or root only
|
|
376
490
|
let tasksDir = path.join(installDir, ".bmad-core", "tasks");
|
|
377
491
|
if (!(await fileManager.pathExists(tasksDir))) {
|
|
378
492
|
tasksDir = path.join(installDir, "bmad-core", "tasks");
|
|
379
493
|
}
|
|
380
|
-
|
|
494
|
+
|
|
381
495
|
if (await fileManager.pathExists(tasksDir)) {
|
|
382
496
|
const glob = require("glob");
|
|
383
497
|
const taskFiles = glob.sync("*.md", { cwd: tasksDir });
|
|
384
498
|
allTaskIds.push(...taskFiles.map((file) => path.basename(file, ".md")));
|
|
385
499
|
}
|
|
386
|
-
|
|
500
|
+
|
|
387
501
|
// Check common tasks
|
|
388
502
|
const commonTasksDir = path.join(installDir, "common", "tasks");
|
|
389
503
|
if (await fileManager.pathExists(commonTasksDir)) {
|
|
390
504
|
const commonTaskFiles = glob.sync("*.md", { cwd: commonTasksDir });
|
|
391
505
|
allTaskIds.push(...commonTaskFiles.map((file) => path.basename(file, ".md")));
|
|
392
506
|
}
|
|
393
|
-
|
|
507
|
+
|
|
394
508
|
return [...new Set(allTaskIds)];
|
|
395
509
|
}
|
|
396
510
|
|
|
@@ -400,20 +514,20 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
400
514
|
path.join(installDir, ".bmad-core", "agents", `${agentId}.md`),
|
|
401
515
|
path.join(installDir, "agents", `${agentId}.md`)
|
|
402
516
|
];
|
|
403
|
-
|
|
517
|
+
|
|
404
518
|
// Also check expansion pack directories
|
|
405
519
|
const glob = require("glob");
|
|
406
520
|
const expansionDirs = glob.sync(".*/agents", { cwd: installDir });
|
|
407
521
|
for (const expDir of expansionDirs) {
|
|
408
522
|
possiblePaths.push(path.join(installDir, expDir, `${agentId}.md`));
|
|
409
523
|
}
|
|
410
|
-
|
|
524
|
+
|
|
411
525
|
for (const agentPath of possiblePaths) {
|
|
412
526
|
if (await fileManager.pathExists(agentPath)) {
|
|
413
527
|
try {
|
|
414
528
|
const agentContent = await fileManager.readFile(agentPath);
|
|
415
529
|
const yamlMatch = agentContent.match(/```ya?ml\r?\n([\s\S]*?)```/);
|
|
416
|
-
|
|
530
|
+
|
|
417
531
|
if (yamlMatch) {
|
|
418
532
|
const yaml = yamlMatch[1];
|
|
419
533
|
const titleMatch = yaml.match(/title:\s*(.+)/);
|
|
@@ -426,9 +540,9 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
426
540
|
}
|
|
427
541
|
}
|
|
428
542
|
}
|
|
429
|
-
|
|
543
|
+
|
|
430
544
|
// Fallback to formatted agent ID
|
|
431
|
-
return agentId.split('-').map(word =>
|
|
545
|
+
return agentId.split('-').map(word =>
|
|
432
546
|
word.charAt(0).toUpperCase() + word.slice(1)
|
|
433
547
|
).join(' ');
|
|
434
548
|
}
|
|
@@ -436,25 +550,25 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
436
550
|
async getAllTaskIds(installDir) {
|
|
437
551
|
const glob = require("glob");
|
|
438
552
|
const allTaskIds = [];
|
|
439
|
-
|
|
553
|
+
|
|
440
554
|
// Check core tasks in .bmad-core or root
|
|
441
555
|
let tasksDir = path.join(installDir, ".bmad-core", "tasks");
|
|
442
556
|
if (!(await fileManager.pathExists(tasksDir))) {
|
|
443
557
|
tasksDir = path.join(installDir, "bmad-core", "tasks");
|
|
444
558
|
}
|
|
445
|
-
|
|
559
|
+
|
|
446
560
|
if (await fileManager.pathExists(tasksDir)) {
|
|
447
561
|
const taskFiles = glob.sync("*.md", { cwd: tasksDir });
|
|
448
562
|
allTaskIds.push(...taskFiles.map((file) => path.basename(file, ".md")));
|
|
449
563
|
}
|
|
450
|
-
|
|
564
|
+
|
|
451
565
|
// Check common tasks
|
|
452
566
|
const commonTasksDir = path.join(installDir, "common", "tasks");
|
|
453
567
|
if (await fileManager.pathExists(commonTasksDir)) {
|
|
454
568
|
const commonTaskFiles = glob.sync("*.md", { cwd: commonTasksDir });
|
|
455
569
|
allTaskIds.push(...commonTaskFiles.map((file) => path.basename(file, ".md")));
|
|
456
570
|
}
|
|
457
|
-
|
|
571
|
+
|
|
458
572
|
// Also check for expansion pack tasks in dot folders
|
|
459
573
|
const expansionDirs = glob.sync(".*/tasks", { cwd: installDir });
|
|
460
574
|
for (const expDir of expansionDirs) {
|
|
@@ -462,7 +576,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
462
576
|
const expTaskFiles = glob.sync("*.md", { cwd: fullExpDir });
|
|
463
577
|
allTaskIds.push(...expTaskFiles.map((file) => path.basename(file, ".md")));
|
|
464
578
|
}
|
|
465
|
-
|
|
579
|
+
|
|
466
580
|
// Check expansion-packs folder tasks
|
|
467
581
|
const expansionPacksDir = path.join(installDir, "expansion-packs");
|
|
468
582
|
if (await fileManager.pathExists(expansionPacksDir)) {
|
|
@@ -473,7 +587,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
473
587
|
allTaskIds.push(...expTaskFiles.map((file) => path.basename(file, ".md")));
|
|
474
588
|
}
|
|
475
589
|
}
|
|
476
|
-
|
|
590
|
+
|
|
477
591
|
// Remove duplicates
|
|
478
592
|
return [...new Set(allTaskIds)];
|
|
479
593
|
}
|
|
@@ -485,16 +599,16 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
485
599
|
path.join(installDir, "bmad-core", "tasks", `${taskId}.md`),
|
|
486
600
|
path.join(installDir, "common", "tasks", `${taskId}.md`)
|
|
487
601
|
];
|
|
488
|
-
|
|
602
|
+
|
|
489
603
|
// Also check expansion pack directories
|
|
490
604
|
const glob = require("glob");
|
|
491
|
-
|
|
605
|
+
|
|
492
606
|
// Check dot folder expansion packs
|
|
493
607
|
const expansionDirs = glob.sync(".*/tasks", { cwd: installDir });
|
|
494
608
|
for (const expDir of expansionDirs) {
|
|
495
609
|
possiblePaths.push(path.join(installDir, expDir, `${taskId}.md`));
|
|
496
610
|
}
|
|
497
|
-
|
|
611
|
+
|
|
498
612
|
// Check expansion-packs folder
|
|
499
613
|
const expansionPacksDir = path.join(installDir, "expansion-packs");
|
|
500
614
|
if (await fileManager.pathExists(expansionPacksDir)) {
|
|
@@ -503,13 +617,13 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
503
617
|
possiblePaths.push(path.join(expansionPacksDir, expDir, `${taskId}.md`));
|
|
504
618
|
}
|
|
505
619
|
}
|
|
506
|
-
|
|
620
|
+
|
|
507
621
|
for (const taskPath of possiblePaths) {
|
|
508
622
|
if (await fileManager.pathExists(taskPath)) {
|
|
509
623
|
return taskPath;
|
|
510
624
|
}
|
|
511
625
|
}
|
|
512
|
-
|
|
626
|
+
|
|
513
627
|
return null;
|
|
514
628
|
}
|
|
515
629
|
|
|
@@ -526,7 +640,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
526
640
|
}
|
|
527
641
|
return "BMad"; // fallback
|
|
528
642
|
}
|
|
529
|
-
|
|
643
|
+
|
|
530
644
|
const configContent = await fileManager.readFile(coreConfigPath);
|
|
531
645
|
const config = yaml.load(configContent);
|
|
532
646
|
return config.slashPrefix || "BMad";
|
|
@@ -538,11 +652,11 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
538
652
|
|
|
539
653
|
async getInstalledExpansionPacks(installDir) {
|
|
540
654
|
const expansionPacks = [];
|
|
541
|
-
|
|
655
|
+
|
|
542
656
|
// Check for dot-prefixed expansion packs in install directory
|
|
543
657
|
const glob = require("glob");
|
|
544
658
|
const dotExpansions = glob.sync(".bmad-*", { cwd: installDir });
|
|
545
|
-
|
|
659
|
+
|
|
546
660
|
for (const dotExpansion of dotExpansions) {
|
|
547
661
|
if (dotExpansion !== ".bmad-core") {
|
|
548
662
|
const packPath = path.join(installDir, dotExpansion);
|
|
@@ -553,15 +667,15 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
553
667
|
});
|
|
554
668
|
}
|
|
555
669
|
}
|
|
556
|
-
|
|
670
|
+
|
|
557
671
|
// Check for expansion-packs directory style
|
|
558
672
|
const expansionPacksDir = path.join(installDir, "expansion-packs");
|
|
559
673
|
if (await fileManager.pathExists(expansionPacksDir)) {
|
|
560
674
|
const packDirs = glob.sync("*", { cwd: expansionPacksDir });
|
|
561
|
-
|
|
675
|
+
|
|
562
676
|
for (const packDir of packDirs) {
|
|
563
677
|
const packPath = path.join(expansionPacksDir, packDir);
|
|
564
|
-
if ((await fileManager.pathExists(packPath)) &&
|
|
678
|
+
if ((await fileManager.pathExists(packPath)) &&
|
|
565
679
|
(await fileManager.pathExists(path.join(packPath, "config.yaml")))) {
|
|
566
680
|
expansionPacks.push({
|
|
567
681
|
name: packDir,
|
|
@@ -570,7 +684,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
570
684
|
}
|
|
571
685
|
}
|
|
572
686
|
}
|
|
573
|
-
|
|
687
|
+
|
|
574
688
|
return expansionPacks;
|
|
575
689
|
}
|
|
576
690
|
|
|
@@ -585,7 +699,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
585
699
|
} catch (error) {
|
|
586
700
|
console.warn(`Failed to read expansion pack slashPrefix from ${packPath}: ${error.message}`);
|
|
587
701
|
}
|
|
588
|
-
|
|
702
|
+
|
|
589
703
|
return path.basename(packPath); // fallback to directory name
|
|
590
704
|
}
|
|
591
705
|
|
|
@@ -594,7 +708,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
594
708
|
if (!(await fileManager.pathExists(agentsDir))) {
|
|
595
709
|
return [];
|
|
596
710
|
}
|
|
597
|
-
|
|
711
|
+
|
|
598
712
|
try {
|
|
599
713
|
const glob = require("glob");
|
|
600
714
|
const agentFiles = glob.sync("*.md", { cwd: agentsDir });
|
|
@@ -610,7 +724,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
610
724
|
if (!(await fileManager.pathExists(tasksDir))) {
|
|
611
725
|
return [];
|
|
612
726
|
}
|
|
613
|
-
|
|
727
|
+
|
|
614
728
|
try {
|
|
615
729
|
const glob = require("glob");
|
|
616
730
|
const taskFiles = glob.sync("*.md", { cwd: tasksDir });
|
|
@@ -688,7 +802,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
688
802
|
newModesContent += ` - slug: ${slug}\n`;
|
|
689
803
|
newModesContent += ` name: '${icon} ${title}'\n`;
|
|
690
804
|
if (permissions) {
|
|
691
|
-
newModesContent += ` description: '${permissions.description}'\n`;
|
|
805
|
+
newModesContent += ` description: '${permissions.description}'\n`;
|
|
692
806
|
}
|
|
693
807
|
newModesContent += ` roleDefinition: ${roleDefinition}\n`;
|
|
694
808
|
newModesContent += ` whenToUse: ${whenToUse}\n`;
|
|
@@ -730,7 +844,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
730
844
|
|
|
731
845
|
return true;
|
|
732
846
|
}
|
|
733
|
-
|
|
847
|
+
|
|
734
848
|
async setupKilocode(installDir, selectedAgent) {
|
|
735
849
|
const filePath = path.join(installDir, ".kilocodemodes");
|
|
736
850
|
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
|
|
@@ -788,7 +902,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
788
902
|
newContent += ` - slug: ${slug}\n`;
|
|
789
903
|
newContent += ` name: '${icon} ${title}'\n`;
|
|
790
904
|
if (agentPermission) {
|
|
791
|
-
newContent += ` description: '${agentPermission.description}'\n`;
|
|
905
|
+
newContent += ` description: '${agentPermission.description}'\n`;
|
|
792
906
|
}
|
|
793
907
|
|
|
794
908
|
newContent += ` roleDefinition: ${roleDefinition}\n`;
|
|
@@ -821,7 +935,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
821
935
|
|
|
822
936
|
return true;
|
|
823
937
|
}
|
|
824
|
-
|
|
938
|
+
|
|
825
939
|
async setupCline(installDir, selectedAgent) {
|
|
826
940
|
const clineRulesDir = path.join(installDir, ".clinerules");
|
|
827
941
|
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
|
|
@@ -891,7 +1005,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
891
1005
|
const settingsContent = await fileManager.readFile(settingsPath);
|
|
892
1006
|
const settings = JSON.parse(settingsContent);
|
|
893
1007
|
let updated = false;
|
|
894
|
-
|
|
1008
|
+
|
|
895
1009
|
// Handle contextFileName property
|
|
896
1010
|
if (settings.contextFileName && Array.isArray(settings.contextFileName)) {
|
|
897
1011
|
const originalLength = settings.contextFileName.length;
|
|
@@ -902,7 +1016,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
902
1016
|
updated = true;
|
|
903
1017
|
}
|
|
904
1018
|
}
|
|
905
|
-
|
|
1019
|
+
|
|
906
1020
|
if (updated) {
|
|
907
1021
|
await fileManager.writeFile(
|
|
908
1022
|
settingsPath,
|
|
@@ -935,7 +1049,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
935
1049
|
|
|
936
1050
|
if (agentPath) {
|
|
937
1051
|
const agentContent = await fileManager.readFile(agentPath);
|
|
938
|
-
|
|
1052
|
+
|
|
939
1053
|
// Create properly formatted agent rule content (similar to trae)
|
|
940
1054
|
let agentRuleContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
|
|
941
1055
|
agentRuleContent += `This rule is triggered when the user types \`*${agentId}\` and activates the ${await this.getAgentTitle(
|
|
@@ -964,7 +1078,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
964
1078
|
agentId,
|
|
965
1079
|
installDir
|
|
966
1080
|
)} persona and follow all instructions defined in the YAML configuration above.\n`;
|
|
967
|
-
|
|
1081
|
+
|
|
968
1082
|
// Add to concatenated content with separator
|
|
969
1083
|
concatenatedContent += agentRuleContent + "\n\n---\n\n";
|
|
970
1084
|
console.log(chalk.green(`ā Added context for @${agentId}`));
|
|
@@ -991,7 +1105,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
991
1105
|
const settingsContent = await fileManager.readFile(settingsPath);
|
|
992
1106
|
const settings = JSON.parse(settingsContent);
|
|
993
1107
|
let updated = false;
|
|
994
|
-
|
|
1108
|
+
|
|
995
1109
|
// Handle contextFileName property
|
|
996
1110
|
if (settings.contextFileName && Array.isArray(settings.contextFileName)) {
|
|
997
1111
|
const originalLength = settings.contextFileName.length;
|
|
@@ -1002,7 +1116,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1002
1116
|
updated = true;
|
|
1003
1117
|
}
|
|
1004
1118
|
}
|
|
1005
|
-
|
|
1119
|
+
|
|
1006
1120
|
if (updated) {
|
|
1007
1121
|
await fileManager.writeFile(
|
|
1008
1122
|
settingsPath,
|
|
@@ -1035,7 +1149,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1035
1149
|
|
|
1036
1150
|
if (agentPath) {
|
|
1037
1151
|
const agentContent = await fileManager.readFile(agentPath);
|
|
1038
|
-
|
|
1152
|
+
|
|
1039
1153
|
// Create properly formatted agent rule content (similar to gemini)
|
|
1040
1154
|
let agentRuleContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
|
|
1041
1155
|
agentRuleContent += `This rule is triggered when the user types \`*${agentId}\` and activates the ${await this.getAgentTitle(
|
|
@@ -1064,7 +1178,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1064
1178
|
agentId,
|
|
1065
1179
|
installDir
|
|
1066
1180
|
)} persona and follow all instructions defined in the YAML configuration above.\n`;
|
|
1067
|
-
|
|
1181
|
+
|
|
1068
1182
|
// Add to concatenated content with separator
|
|
1069
1183
|
concatenatedContent += agentRuleContent + "\n\n---\n\n";
|
|
1070
1184
|
console.log(chalk.green(`ā Added context for *${agentId}`));
|
|
@@ -1082,10 +1196,10 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1082
1196
|
async setupGitHubCopilot(installDir, selectedAgent, spinner = null, preConfiguredSettings = null) {
|
|
1083
1197
|
// Configure VS Code workspace settings first to avoid UI conflicts with loading spinners
|
|
1084
1198
|
await this.configureVsCodeSettings(installDir, spinner, preConfiguredSettings);
|
|
1085
|
-
|
|
1199
|
+
|
|
1086
1200
|
const chatmodesDir = path.join(installDir, ".github", "chatmodes");
|
|
1087
1201
|
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
|
|
1088
|
-
|
|
1202
|
+
|
|
1089
1203
|
await fileManager.ensureDirectory(chatmodesDir);
|
|
1090
1204
|
|
|
1091
1205
|
for (const agentId of agents) {
|
|
@@ -1097,7 +1211,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1097
1211
|
// Create chat mode file with agent content
|
|
1098
1212
|
const agentContent = await fileManager.readFile(agentPath);
|
|
1099
1213
|
const agentTitle = await this.getAgentTitle(agentId, installDir);
|
|
1100
|
-
|
|
1214
|
+
|
|
1101
1215
|
// Extract whenToUse for the description
|
|
1102
1216
|
const yamlMatch = agentContent.match(/```ya?ml\r?\n([\s\S]*?)```/);
|
|
1103
1217
|
let description = `Activates the ${agentTitle} agent persona.`;
|
|
@@ -1107,7 +1221,7 @@ class IdeSetup extends BaseIdeSetup {
|
|
|
1107
1221
|
description = whenToUseMatch[1];
|
|
1108
1222
|
}
|
|
1109
1223
|
}
|
|
1110
|
-
|
|
1224
|
+
|
|
1111
1225
|
let chatmodeContent = `---
|
|
1112
1226
|
description: "${description.replace(/"/g, '\\"')}"
|
|
1113
1227
|
tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems', 'usages', 'editFiles', 'runCommands', 'runTasks', 'runTests', 'search', 'searchResults', 'terminalLastCommand', 'terminalSelection', 'testFailure']
|
|
@@ -1130,9 +1244,9 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1130
1244
|
async configureVsCodeSettings(installDir, spinner, preConfiguredSettings = null) {
|
|
1131
1245
|
const vscodeDir = path.join(installDir, ".vscode");
|
|
1132
1246
|
const settingsPath = path.join(vscodeDir, "settings.json");
|
|
1133
|
-
|
|
1247
|
+
|
|
1134
1248
|
await fileManager.ensureDirectory(vscodeDir);
|
|
1135
|
-
|
|
1249
|
+
|
|
1136
1250
|
// Read existing settings if they exist
|
|
1137
1251
|
let existingSettings = {};
|
|
1138
1252
|
if (await fileManager.pathExists(settingsPath)) {
|
|
@@ -1145,7 +1259,7 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1145
1259
|
existingSettings = {};
|
|
1146
1260
|
}
|
|
1147
1261
|
}
|
|
1148
|
-
|
|
1262
|
+
|
|
1149
1263
|
// Use pre-configured settings if provided, otherwise prompt
|
|
1150
1264
|
let configChoice;
|
|
1151
1265
|
if (preConfiguredSettings && preConfiguredSettings.configChoice) {
|
|
@@ -1157,7 +1271,7 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1157
1271
|
console.log(chalk.blue("š§ Github Copilot Agent Settings Configuration"));
|
|
1158
1272
|
console.log(chalk.dim("BMad works best with specific VS Code settings for optimal agent experience."));
|
|
1159
1273
|
console.log(''); // Add extra spacing
|
|
1160
|
-
|
|
1274
|
+
|
|
1161
1275
|
const response = await inquirer.prompt([
|
|
1162
1276
|
{
|
|
1163
1277
|
type: 'list',
|
|
@@ -1182,9 +1296,9 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1182
1296
|
]);
|
|
1183
1297
|
configChoice = response.configChoice;
|
|
1184
1298
|
}
|
|
1185
|
-
|
|
1299
|
+
|
|
1186
1300
|
let bmadSettings = {};
|
|
1187
|
-
|
|
1301
|
+
|
|
1188
1302
|
if (configChoice === 'skip') {
|
|
1189
1303
|
console.log(chalk.yellow("ā ļø Skipping VS Code settings configuration."));
|
|
1190
1304
|
console.log(chalk.dim("You can manually configure these settings in .vscode/settings.json:"));
|
|
@@ -1196,7 +1310,7 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1196
1310
|
console.log(chalk.dim(" ⢠chat.tools.autoApprove: false"));
|
|
1197
1311
|
return true;
|
|
1198
1312
|
}
|
|
1199
|
-
|
|
1313
|
+
|
|
1200
1314
|
if (configChoice === 'defaults') {
|
|
1201
1315
|
// Use recommended defaults
|
|
1202
1316
|
bmadSettings = {
|
|
@@ -1211,14 +1325,14 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1211
1325
|
} else {
|
|
1212
1326
|
// Manual configuration
|
|
1213
1327
|
console.log(chalk.blue("\nš Let's configure each setting for your preferences:"));
|
|
1214
|
-
|
|
1328
|
+
|
|
1215
1329
|
// Pause spinner during manual configuration prompts
|
|
1216
1330
|
let spinnerWasActive = false;
|
|
1217
1331
|
if (spinner && spinner.isSpinning) {
|
|
1218
1332
|
spinner.stop();
|
|
1219
1333
|
spinnerWasActive = true;
|
|
1220
1334
|
}
|
|
1221
|
-
|
|
1335
|
+
|
|
1222
1336
|
const manualSettings = await inquirer.prompt([
|
|
1223
1337
|
{
|
|
1224
1338
|
type: 'input',
|
|
@@ -1263,7 +1377,7 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1263
1377
|
if (spinner && spinnerWasActive) {
|
|
1264
1378
|
spinner.start();
|
|
1265
1379
|
}
|
|
1266
|
-
|
|
1380
|
+
|
|
1267
1381
|
bmadSettings = {
|
|
1268
1382
|
"chat.agent.enabled": true, // Always enabled - required for BMad agents
|
|
1269
1383
|
"chat.agent.maxRequests": parseInt(manualSettings.maxRequests),
|
|
@@ -1272,16 +1386,16 @@ tools: ['changes', 'codebase', 'fetch', 'findTestFiles', 'githubRepo', 'problems
|
|
|
1272
1386
|
"github.copilot.chat.agent.autoFix": manualSettings.autoFix,
|
|
1273
1387
|
"chat.tools.autoApprove": manualSettings.autoApprove
|
|
1274
1388
|
};
|
|
1275
|
-
|
|
1389
|
+
|
|
1276
1390
|
console.log(chalk.green("ā Custom settings configured"));
|
|
1277
1391
|
}
|
|
1278
|
-
|
|
1392
|
+
|
|
1279
1393
|
// Merge settings (existing settings take precedence to avoid overriding user preferences)
|
|
1280
1394
|
const mergedSettings = { ...bmadSettings, ...existingSettings };
|
|
1281
|
-
|
|
1395
|
+
|
|
1282
1396
|
// Write the updated settings
|
|
1283
1397
|
await fileManager.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
|
1284
|
-
|
|
1398
|
+
|
|
1285
1399
|
console.log(chalk.green("ā VS Code workspace settings configured successfully"));
|
|
1286
1400
|
console.log(chalk.dim(" Settings written to .vscode/settings.json:"));
|
|
1287
1401
|
Object.entries(bmadSettings).forEach(([key, value]) => {
|