mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-18 02:05:30 +00:00
agents now are not duplicated and isntead cli commmands load from installed agent files
This commit is contained in:
parent
7eb52520fa
commit
f49a4731e7
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auggie CLI setup handler
|
* Auggie CLI setup handler
|
||||||
@ -27,8 +28,11 @@ class AuggieSetup extends BaseIdeSetup {
|
|||||||
// Clean up old BMAD installation first
|
// Clean up old BMAD installation first
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only)
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only)
|
||||||
const tasks = await this.getTasks(bmadDir, true);
|
const tasks = await this.getTasks(bmadDir, true);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
@ -44,13 +48,10 @@ class AuggieSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(toolsDir);
|
await this.ensureDir(toolsDir);
|
||||||
await this.ensureDir(workflowsDir);
|
await this.ensureDir(workflowsDir);
|
||||||
|
|
||||||
// Install agents
|
// Install agent launchers
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const targetPath = path.join(agentsDir, `${artifact.module}-${artifact.name}.md`);
|
||||||
const commandContent = await this.createAgentCommand(agent, content);
|
await this.writeFile(targetPath, artifact.content);
|
||||||
|
|
||||||
const targetPath = path.join(agentsDir, `${agent.module}-${agent.name}.md`);
|
|
||||||
await this.writeFile(targetPath, commandContent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install tasks
|
// Install tasks
|
||||||
@ -80,10 +81,10 @@ class AuggieSetup extends BaseIdeSetup {
|
|||||||
await this.writeFile(targetPath, commandContent);
|
await this.writeFile(targetPath, commandContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalInstalled = agents.length + tasks.length + tools.length + workflows.length;
|
const totalInstalled = agentArtifacts.length + tasks.length + tools.length + workflows.length;
|
||||||
|
|
||||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||||
console.log(chalk.dim(` - ${agents.length} agents installed`));
|
console.log(chalk.dim(` - ${agentArtifacts.length} agents installed`));
|
||||||
console.log(chalk.dim(` - ${tasks.length} tasks installed`));
|
console.log(chalk.dim(` - ${tasks.length} tasks installed`));
|
||||||
console.log(chalk.dim(` - ${tools.length} tools installed`));
|
console.log(chalk.dim(` - ${tools.length} tools installed`));
|
||||||
console.log(chalk.dim(` - ${workflows.length} workflows installed`));
|
console.log(chalk.dim(` - ${workflows.length} workflows installed`));
|
||||||
@ -92,42 +93,13 @@ class AuggieSetup extends BaseIdeSetup {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
agents: agents.length,
|
agents: agentArtifacts.length,
|
||||||
tasks: tasks.length,
|
tasks: tasks.length,
|
||||||
tools: tools.length,
|
tools: tools.length,
|
||||||
workflows: workflows.length,
|
workflows: workflows.length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create agent command content
|
|
||||||
*/
|
|
||||||
async createAgentCommand(agent, content) {
|
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
|
||||||
|
|
||||||
// Extract description from agent if available
|
|
||||||
const whenToUseMatch = content.match(/whenToUse="([^"]+)"/);
|
|
||||||
const description = whenToUseMatch ? whenToUseMatch[1] : `Activate the ${title} agent`;
|
|
||||||
|
|
||||||
// Get the activation header from central template
|
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
|
||||||
|
|
||||||
return `---
|
|
||||||
description: "${description}"
|
|
||||||
---
|
|
||||||
|
|
||||||
# ${title} Agent
|
|
||||||
|
|
||||||
${activationHeader}
|
|
||||||
|
|
||||||
${content}
|
|
||||||
|
|
||||||
## Module
|
|
||||||
BMAD ${agent.module.toUpperCase()} module
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create task command content
|
* Create task command content
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -4,6 +4,7 @@ const chalk = require('chalk');
|
|||||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const {
|
const {
|
||||||
loadModuleInjectionConfig,
|
loadModuleInjectionConfig,
|
||||||
shouldApplyInjection,
|
shouldApplyInjection,
|
||||||
@ -117,33 +118,24 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
|||||||
|
|
||||||
await this.ensureDir(bmadCommandsDir);
|
await this.ensureDir(bmadCommandsDir);
|
||||||
|
|
||||||
// Get agents from INSTALLED bmad/ directory
|
// Generate agent launchers using AgentCommandGenerator
|
||||||
// Base installer has already built .md files from .agent.yaml sources
|
// This creates small launcher files that reference the actual agents in .bmad/
|
||||||
const agents = await getAgentsFromBmad(bmadDir, options.selectedModules || []);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts, counts: agentCounts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Create directories for each module (including standalone)
|
// Create directories for each module
|
||||||
const modules = new Set();
|
const modules = new Set();
|
||||||
for (const item of agents) modules.add(item.module);
|
for (const artifact of agentArtifacts) {
|
||||||
|
modules.add(artifact.module);
|
||||||
|
}
|
||||||
|
|
||||||
for (const module of modules) {
|
for (const module of modules) {
|
||||||
await this.ensureDir(path.join(bmadCommandsDir, module));
|
await this.ensureDir(path.join(bmadCommandsDir, module));
|
||||||
await this.ensureDir(path.join(bmadCommandsDir, module, 'agents'));
|
await this.ensureDir(path.join(bmadCommandsDir, module, 'agents'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy agents from bmad/ to .claude/commands/
|
// Write agent launcher files
|
||||||
let agentCount = 0;
|
const agentCount = await agentGen.writeAgentLaunchers(bmadCommandsDir, agentArtifacts);
|
||||||
for (const agent of agents) {
|
|
||||||
const sourcePath = agent.path;
|
|
||||||
const targetPath = path.join(bmadCommandsDir, agent.module, 'agents', `${agent.name}.md`);
|
|
||||||
|
|
||||||
const content = await this.readAndProcess(sourcePath, {
|
|
||||||
module: agent.module,
|
|
||||||
name: agent.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.writeFile(targetPath, content);
|
|
||||||
agentCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process Claude Code specific injections for installed modules
|
// Process Claude Code specific injections for installed modules
|
||||||
// Use pre-collected configuration if available, or skip if already configured
|
// Use pre-collected configuration if available, or skip if already configured
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
|||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,23 +89,19 @@ class ClineSetup extends BaseIdeSetup {
|
|||||||
const selectedModules = options.selectedModules || [];
|
const selectedModules = options.selectedModules || [];
|
||||||
const artifacts = [];
|
const artifacts = [];
|
||||||
|
|
||||||
// Get agents
|
// Generate agent launchers
|
||||||
const agents = await getAgentsFromBmad(bmadDir, selectedModules);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
for (const agent of agents) {
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, selectedModules);
|
||||||
const content = await this.readAndProcessWithProject(
|
|
||||||
agent.path,
|
// Process agent launchers with project-specific paths
|
||||||
{
|
for (const agentArtifact of agentArtifacts) {
|
||||||
module: agent.module,
|
const content = agentArtifact.content;
|
||||||
name: agent.name,
|
|
||||||
},
|
|
||||||
projectDir,
|
|
||||||
);
|
|
||||||
|
|
||||||
artifacts.push({
|
artifacts.push({
|
||||||
type: 'agent',
|
type: 'agent',
|
||||||
module: agent.module,
|
module: agentArtifact.module,
|
||||||
sourcePath: agent.path,
|
sourcePath: agentArtifact.sourcePath,
|
||||||
relativePath: path.join(agent.module, 'agents', `${agent.name}.md`),
|
relativePath: agentArtifact.relativePath,
|
||||||
content,
|
content,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -138,7 +135,7 @@ class ClineSetup extends BaseIdeSetup {
|
|||||||
return {
|
return {
|
||||||
artifacts,
|
artifacts,
|
||||||
counts: {
|
counts: {
|
||||||
agents: agents.length,
|
agents: agentArtifacts.length,
|
||||||
tasks: tasks.length,
|
tasks: tasks.length,
|
||||||
workflows: workflowCounts.commands,
|
workflows: workflowCounts.commands,
|
||||||
workflowLaunchers: workflowCounts.launchers,
|
workflowLaunchers: workflowCounts.launchers,
|
||||||
|
|||||||
@ -4,7 +4,8 @@ const os = require('node:os');
|
|||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
const { getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codex setup handler (CLI mode)
|
* Codex setup handler (CLI mode)
|
||||||
@ -92,23 +93,17 @@ class CodexSetup extends BaseIdeSetup {
|
|||||||
const selectedModules = options.selectedModules || [];
|
const selectedModules = options.selectedModules || [];
|
||||||
const artifacts = [];
|
const artifacts = [];
|
||||||
|
|
||||||
const agents = await getAgentsFromBmad(bmadDir, selectedModules);
|
// Generate agent launchers
|
||||||
for (const agent of agents) {
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
const content = await this.readAndProcessWithProject(
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, selectedModules);
|
||||||
agent.path,
|
|
||||||
{
|
|
||||||
module: agent.module,
|
|
||||||
name: agent.name,
|
|
||||||
},
|
|
||||||
projectDir,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
for (const artifact of agentArtifacts) {
|
||||||
artifacts.push({
|
artifacts.push({
|
||||||
type: 'agent',
|
type: 'agent',
|
||||||
module: agent.module,
|
module: artifact.module,
|
||||||
sourcePath: agent.path,
|
sourcePath: artifact.sourcePath,
|
||||||
relativePath: path.join(agent.module, 'agents', `${agent.name}.md`),
|
relativePath: artifact.relativePath,
|
||||||
content,
|
content: artifact.content,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +134,7 @@ class CodexSetup extends BaseIdeSetup {
|
|||||||
return {
|
return {
|
||||||
artifacts,
|
artifacts,
|
||||||
counts: {
|
counts: {
|
||||||
agents: agents.length,
|
agents: agentArtifacts.length,
|
||||||
tasks: tasks.length,
|
tasks: tasks.length,
|
||||||
workflows: workflowCounts.commands,
|
workflows: workflowCounts.commands,
|
||||||
workflowLaunchers: workflowCounts.launchers,
|
workflowLaunchers: workflowCounts.launchers,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crush IDE setup handler
|
* Crush IDE setup handler
|
||||||
@ -28,14 +29,17 @@ class CrushSetup extends BaseIdeSetup {
|
|||||||
|
|
||||||
await this.ensureDir(commandsDir);
|
await this.ensureDir(commandsDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only)
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only)
|
||||||
const tasks = await this.getTasks(bmadDir, true);
|
const tasks = await this.getTasks(bmadDir, true);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
|
|
||||||
// Organize by module
|
// Organize by module
|
||||||
const agentCount = await this.organizeByModule(commandsDir, agents, tasks, tools, workflows, projectDir);
|
const agentCount = await this.organizeByModule(commandsDir, agentArtifacts, tasks, tools, workflows, projectDir);
|
||||||
|
|
||||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||||
console.log(chalk.dim(` - ${agentCount.agents} agent commands created`));
|
console.log(chalk.dim(` - ${agentCount.agents} agent commands created`));
|
||||||
@ -54,10 +58,10 @@ class CrushSetup extends BaseIdeSetup {
|
|||||||
/**
|
/**
|
||||||
* Organize commands by module
|
* Organize commands by module
|
||||||
*/
|
*/
|
||||||
async organizeByModule(commandsDir, agents, tasks, tools, workflows, projectDir) {
|
async organizeByModule(commandsDir, agentArtifacts, tasks, tools, workflows, projectDir) {
|
||||||
// Get unique modules
|
// Get unique modules
|
||||||
const modules = new Set();
|
const modules = new Set();
|
||||||
for (const agent of agents) modules.add(agent.module);
|
for (const artifact of agentArtifacts) modules.add(artifact.module);
|
||||||
for (const task of tasks) modules.add(task.module);
|
for (const task of tasks) modules.add(task.module);
|
||||||
for (const tool of tools) modules.add(tool.module);
|
for (const tool of tools) modules.add(tool.module);
|
||||||
for (const workflow of workflows) modules.add(workflow.module);
|
for (const workflow of workflows) modules.add(workflow.module);
|
||||||
@ -80,13 +84,11 @@ class CrushSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(moduleToolsDir);
|
await this.ensureDir(moduleToolsDir);
|
||||||
await this.ensureDir(moduleWorkflowsDir);
|
await this.ensureDir(moduleWorkflowsDir);
|
||||||
|
|
||||||
// Copy module-specific agents
|
// Write module-specific agent launchers
|
||||||
const moduleAgents = agents.filter((a) => a.module === module);
|
const moduleAgents = agentArtifacts.filter((a) => a.module === module);
|
||||||
for (const agent of moduleAgents) {
|
for (const artifact of moduleAgents) {
|
||||||
const content = await this.readFile(agent.path);
|
const targetPath = path.join(moduleAgentsDir, `${artifact.name}.md`);
|
||||||
const commandContent = await this.createAgentCommand(agent, content, projectDir);
|
await this.writeFile(targetPath, artifact.content);
|
||||||
const targetPath = path.join(moduleAgentsDir, `${agent.name}.md`);
|
|
||||||
await this.writeFile(targetPath, commandContent);
|
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,44 +131,6 @@ class CrushSetup extends BaseIdeSetup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create agent command content
|
|
||||||
*/
|
|
||||||
async createAgentCommand(agent, content, projectDir) {
|
|
||||||
// Extract metadata
|
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
|
||||||
|
|
||||||
const iconMatch = content.match(/icon="([^"]+)"/);
|
|
||||||
const icon = iconMatch ? iconMatch[1] : '🤖';
|
|
||||||
|
|
||||||
// Get the activation header from central template
|
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
|
||||||
|
|
||||||
// Get relative path
|
|
||||||
const relativePath = path.relative(projectDir, agent.path).replaceAll('\\', '/');
|
|
||||||
|
|
||||||
let commandContent = `# /${agent.name} Command
|
|
||||||
|
|
||||||
${activationHeader}
|
|
||||||
|
|
||||||
## ${icon} ${title} Agent
|
|
||||||
|
|
||||||
${content}
|
|
||||||
|
|
||||||
## Command Usage
|
|
||||||
|
|
||||||
This command activates the ${title} agent from the BMAD ${agent.module.toUpperCase()} module.
|
|
||||||
|
|
||||||
## File Reference
|
|
||||||
|
|
||||||
Complete agent definition: [${relativePath}](${relativePath})
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|
||||||
return commandContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create task command content
|
* Create task command content
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cursor IDE setup handler
|
* Cursor IDE setup handler
|
||||||
@ -45,8 +46,14 @@ class CursorSetup extends BaseIdeSetup {
|
|||||||
|
|
||||||
await this.ensureDir(bmadRulesDir);
|
await this.ensureDir(bmadRulesDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only)
|
// Generate agent launchers first
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Convert artifacts to agent format for index creation
|
||||||
|
const agents = agentArtifacts.map((a) => ({ module: a.module, name: a.name }));
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only)
|
||||||
const tasks = await this.getTasks(bmadDir, true);
|
const tasks = await this.getTasks(bmadDir, true);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
@ -63,15 +70,16 @@ class CursorSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(path.join(bmadRulesDir, module, 'workflows'));
|
await this.ensureDir(path.join(bmadRulesDir, module, 'workflows'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process and copy agents
|
// Process and write agent launchers with MDC format
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readAndProcess(agent.path, {
|
// Add MDC metadata header to launcher (but don't call processContent which adds activation headers)
|
||||||
module: agent.module,
|
const content = this.wrapLauncherWithMDC(artifact.content, {
|
||||||
name: agent.name,
|
module: artifact.module,
|
||||||
|
name: artifact.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
const targetPath = path.join(bmadRulesDir, agent.module, 'agents', `${agent.name}.mdc`);
|
const targetPath = path.join(bmadRulesDir, artifact.module, 'agents', `${artifact.name}.mdc`);
|
||||||
|
|
||||||
await this.writeFile(targetPath, content);
|
await this.writeFile(targetPath, content);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
@ -311,6 +319,34 @@ alwaysApply: false
|
|||||||
// Add the MDC header to the processed content
|
// Add the MDC header to the processed content
|
||||||
return mdcHeader + processed;
|
return mdcHeader + processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap launcher content with MDC metadata (without base processing)
|
||||||
|
* Launchers are already complete and should not have activation headers injected
|
||||||
|
*/
|
||||||
|
wrapLauncherWithMDC(launcherContent, metadata = {}) {
|
||||||
|
// Strip the launcher's frontmatter - we'll replace it with MDC frontmatter
|
||||||
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
|
const contentWithoutFrontmatter = launcherContent.replace(frontmatterRegex, '');
|
||||||
|
|
||||||
|
// Extract metadata from launcher frontmatter for MDC description
|
||||||
|
const nameMatch = launcherContent.match(/name:\s*"([^"]+)"/);
|
||||||
|
const name = nameMatch ? nameMatch[1] : metadata.name;
|
||||||
|
|
||||||
|
const description = `BMAD ${metadata.module.toUpperCase()} Agent: ${name}`;
|
||||||
|
|
||||||
|
// Create MDC metadata header
|
||||||
|
const mdcHeader = `---
|
||||||
|
description: ${description}
|
||||||
|
globs:
|
||||||
|
alwaysApply: false
|
||||||
|
---
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Return MDC header + launcher content (without its original frontmatter)
|
||||||
|
return mdcHeader + contentWithoutFrontmatter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { CursorSetup };
|
module.exports = { CursorSetup };
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
|||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gemini CLI setup handler
|
* Gemini CLI setup handler
|
||||||
@ -63,22 +64,24 @@ class GeminiSetup extends BaseIdeSetup {
|
|||||||
// Clean up any existing BMAD files before reinstalling
|
// Clean up any existing BMAD files before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Get agents and tasks
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Get tasks
|
||||||
const tasks = await this.getTasks(bmadDir);
|
const tasks = await this.getTasks(bmadDir);
|
||||||
|
|
||||||
// Install agents as TOML files with bmad- prefix (flat structure)
|
// Install agents as TOML files with bmad- prefix (flat structure)
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const tomlContent = await this.createAgentLauncherToml(artifact);
|
||||||
const tomlContent = await this.createAgentToml(agent, content);
|
|
||||||
|
|
||||||
// Flat structure: bmad-agent-{module}-{name}.toml
|
// Flat structure: bmad-agent-{module}-{name}.toml
|
||||||
const tomlPath = path.join(commandsDir, `bmad-agent-${agent.module}-${agent.name}.toml`);
|
const tomlPath = path.join(commandsDir, `bmad-agent-${artifact.module}-${artifact.name}.toml`);
|
||||||
await this.writeFile(tomlPath, tomlContent);
|
await this.writeFile(tomlPath, tomlContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
|
|
||||||
console.log(chalk.green(` ✓ Added agent: /bmad:agents:${agent.module}:${agent.name}`));
|
console.log(chalk.green(` ✓ Added agent: /bmad:agents:${artifact.module}:${artifact.name}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install tasks as TOML files with bmad- prefix (flat structure)
|
// Install tasks as TOML files with bmad- prefix (flat structure)
|
||||||
@ -109,6 +112,28 @@ class GeminiSetup extends BaseIdeSetup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create agent launcher TOML content from artifact
|
||||||
|
*/
|
||||||
|
async createAgentLauncherToml(artifact) {
|
||||||
|
// Strip frontmatter from launcher content
|
||||||
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
|
const contentWithoutFrontmatter = artifact.content.replace(frontmatterRegex, '').trim();
|
||||||
|
|
||||||
|
// Extract title from launcher frontmatter
|
||||||
|
const titleMatch = artifact.content.match(/description:\s*"([^"]+)"/);
|
||||||
|
const title = titleMatch ? titleMatch[1] : this.formatTitle(artifact.name);
|
||||||
|
|
||||||
|
// Create TOML wrapper around launcher content (without frontmatter)
|
||||||
|
const description = `BMAD ${artifact.module.toUpperCase()} Agent: ${title}`;
|
||||||
|
|
||||||
|
return `description = "${description}"
|
||||||
|
prompt = """
|
||||||
|
${contentWithoutFrontmatter}
|
||||||
|
"""
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create agent TOML content using template
|
* Create agent TOML content using template
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const path = require('node:path');
|
|||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const inquirer = require('inquirer');
|
const inquirer = require('inquirer');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GitHub Copilot setup handler
|
* GitHub Copilot setup handler
|
||||||
@ -104,21 +105,22 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
|||||||
// Clean up any existing BMAD files before reinstalling
|
// Clean up any existing BMAD files before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Get agents
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Create chat mode files with bmad- prefix
|
// Create chat mode files with bmad- prefix
|
||||||
let modeCount = 0;
|
let modeCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const content = artifact.content;
|
||||||
const chatmodeContent = await this.createChatmodeContent(agent, content);
|
const chatmodeContent = await this.createChatmodeContent({ module: artifact.module, name: artifact.name }, content);
|
||||||
|
|
||||||
// Use bmad- prefix: bmad-agent-{module}-{name}.chatmode.md
|
// Use bmad- prefix: bmad-agent-{module}-{name}.chatmode.md
|
||||||
const targetPath = path.join(chatmodesDir, `bmad-agent-${agent.module}-${agent.name}.chatmode.md`);
|
const targetPath = path.join(chatmodesDir, `bmad-agent-${artifact.module}-${artifact.name}.chatmode.md`);
|
||||||
await this.writeFile(targetPath, chatmodeContent);
|
await this.writeFile(targetPath, chatmodeContent);
|
||||||
modeCount++;
|
modeCount++;
|
||||||
|
|
||||||
console.log(chalk.green(` ✓ Created chat mode: bmad-agent-${agent.module}-${agent.name}`));
|
console.log(chalk.green(` ✓ Created chat mode: bmad-agent-${artifact.module}-${artifact.name}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||||
@ -207,21 +209,17 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
|||||||
* Create chat mode content
|
* Create chat mode content
|
||||||
*/
|
*/
|
||||||
async createChatmodeContent(agent, content) {
|
async createChatmodeContent(agent, content) {
|
||||||
// Extract metadata
|
// Extract metadata from launcher frontmatter if present
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
const descMatch = content.match(/description:\s*"([^"]+)"/);
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
const title = descMatch ? descMatch[1] : this.formatTitle(agent.name);
|
||||||
|
|
||||||
const whenToUseMatch = content.match(/whenToUse="([^"]+)"/);
|
const description = `Activates the ${title} agent persona.`;
|
||||||
const description = whenToUseMatch ? whenToUseMatch[1] : `Activates the ${title} agent persona.`;
|
|
||||||
|
|
||||||
// Get the activation header from central template
|
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
|
||||||
|
|
||||||
// Strip any existing frontmatter from the content
|
// Strip any existing frontmatter from the content
|
||||||
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
let cleanContent = content;
|
let cleanContent = content;
|
||||||
if (frontmatterRegex.test(content)) {
|
if (frontmatterRegex.test(content)) {
|
||||||
cleanContent = content.replace(frontmatterRegex, '');
|
cleanContent = content.replace(frontmatterRegex, '').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Available GitHub Copilot tools (November 2025 - Official VS Code Documentation)
|
// Available GitHub Copilot tools (November 2025 - Official VS Code Documentation)
|
||||||
@ -258,8 +256,6 @@ tools: ${JSON.stringify(tools)}
|
|||||||
|
|
||||||
# ${title} Agent
|
# ${title} Agent
|
||||||
|
|
||||||
${activationHeader}
|
|
||||||
|
|
||||||
${cleanContent}
|
${cleanContent}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iFlow CLI setup handler
|
* iFlow CLI setup handler
|
||||||
@ -31,21 +32,23 @@ class IFlowSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(agentsDir);
|
await this.ensureDir(agentsDir);
|
||||||
await this.ensureDir(tasksDir);
|
await this.ensureDir(tasksDir);
|
||||||
|
|
||||||
// Get agents and tasks
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
const tasks = await this.getTasks(bmadDir);
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Setup agents as commands
|
// Setup agents as commands
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const commandContent = await this.createAgentCommand(artifact);
|
||||||
const commandContent = await this.createAgentCommand(agent, content);
|
|
||||||
|
|
||||||
const targetPath = path.join(agentsDir, `${agent.module}-${agent.name}.md`);
|
const targetPath = path.join(agentsDir, `${artifact.module}-${artifact.name}.md`);
|
||||||
await this.writeFile(targetPath, commandContent);
|
await this.writeFile(targetPath, commandContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get tasks
|
||||||
|
const tasks = await this.getTasks(bmadDir);
|
||||||
|
|
||||||
// Setup tasks as commands
|
// Setup tasks as commands
|
||||||
let taskCount = 0;
|
let taskCount = 0;
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
@ -72,29 +75,9 @@ class IFlowSetup extends BaseIdeSetup {
|
|||||||
/**
|
/**
|
||||||
* Create agent command content
|
* Create agent command content
|
||||||
*/
|
*/
|
||||||
async createAgentCommand(agent, content) {
|
async createAgentCommand(artifact) {
|
||||||
// Extract metadata
|
// The launcher content is already complete - just return it as-is
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
return artifact.content;
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
|
||||||
|
|
||||||
// Get the activation header from central template
|
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
|
||||||
|
|
||||||
let commandContent = `# /${agent.name} Command
|
|
||||||
|
|
||||||
${activationHeader}
|
|
||||||
|
|
||||||
## ${title} Agent
|
|
||||||
|
|
||||||
${content}
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
This command activates the ${title} agent from the BMAD ${agent.module.toUpperCase()} module.
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|
||||||
return commandContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KiloCode IDE setup handler
|
* KiloCode IDE setup handler
|
||||||
@ -36,16 +37,17 @@ class KiloSetup extends BaseIdeSetup {
|
|||||||
console.log(chalk.yellow(`Found existing .kilocodemodes file with ${existingModes.length} modes`));
|
console.log(chalk.yellow(`Found existing .kilocodemodes file with ${existingModes.length} modes`));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get agents
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Create modes content
|
// Create modes content
|
||||||
let newModesContent = '';
|
let newModesContent = '';
|
||||||
let addedCount = 0;
|
let addedCount = 0;
|
||||||
let skippedCount = 0;
|
let skippedCount = 0;
|
||||||
|
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const slug = `bmad-${agent.module}-${agent.name}`;
|
const slug = `bmad-${artifact.module}-${artifact.name}`;
|
||||||
|
|
||||||
// Skip if already exists
|
// Skip if already exists
|
||||||
if (existingModes.includes(slug)) {
|
if (existingModes.includes(slug)) {
|
||||||
@ -54,8 +56,7 @@ class KiloSetup extends BaseIdeSetup {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = await this.readFile(agent.path);
|
const modeEntry = await this.createModeEntry(artifact, projectDir);
|
||||||
const modeEntry = await this.createModeEntry(agent, content, projectDir);
|
|
||||||
|
|
||||||
newModesContent += modeEntry;
|
newModesContent += modeEntry;
|
||||||
addedCount++;
|
addedCount++;
|
||||||
@ -90,30 +91,30 @@ class KiloSetup extends BaseIdeSetup {
|
|||||||
/**
|
/**
|
||||||
* Create a mode entry for an agent
|
* Create a mode entry for an agent
|
||||||
*/
|
*/
|
||||||
async createModeEntry(agent, content, projectDir) {
|
async createModeEntry(artifact, projectDir) {
|
||||||
// Extract metadata
|
// Extract metadata from launcher content
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
const titleMatch = artifact.content.match(/title="([^"]+)"/);
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
const title = titleMatch ? titleMatch[1] : this.formatTitle(artifact.name);
|
||||||
|
|
||||||
const iconMatch = content.match(/icon="([^"]+)"/);
|
const iconMatch = artifact.content.match(/icon="([^"]+)"/);
|
||||||
const icon = iconMatch ? iconMatch[1] : '🤖';
|
const icon = iconMatch ? iconMatch[1] : '🤖';
|
||||||
|
|
||||||
const whenToUseMatch = content.match(/whenToUse="([^"]+)"/);
|
const whenToUseMatch = artifact.content.match(/whenToUse="([^"]+)"/);
|
||||||
const whenToUse = whenToUseMatch ? whenToUseMatch[1] : `Use for ${title} tasks`;
|
const whenToUse = whenToUseMatch ? whenToUseMatch[1] : `Use for ${title} tasks`;
|
||||||
|
|
||||||
// Get the activation header from central template
|
// Get the activation header from central template
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
const activationHeader = await this.getAgentCommandHeader();
|
||||||
|
|
||||||
const roleDefinitionMatch = content.match(/roleDefinition="([^"]+)"/);
|
const roleDefinitionMatch = artifact.content.match(/roleDefinition="([^"]+)"/);
|
||||||
const roleDefinition = roleDefinitionMatch
|
const roleDefinition = roleDefinitionMatch
|
||||||
? roleDefinitionMatch[1]
|
? roleDefinitionMatch[1]
|
||||||
: `You are a ${title} specializing in ${title.toLowerCase()} tasks.`;
|
: `You are a ${title} specializing in ${title.toLowerCase()} tasks.`;
|
||||||
|
|
||||||
// Get relative path
|
// Get relative path
|
||||||
const relativePath = path.relative(projectDir, agent.path).replaceAll('\\', '/');
|
const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/');
|
||||||
|
|
||||||
// Build mode entry (KiloCode uses same schema as Roo)
|
// Build mode entry (KiloCode uses same schema as Roo)
|
||||||
const slug = `bmad-${agent.module}-${agent.name}`;
|
const slug = `bmad-${artifact.module}-${artifact.name}`;
|
||||||
let modeEntry = ` - slug: ${slug}\n`;
|
let modeEntry = ` - slug: ${slug}\n`;
|
||||||
modeEntry += ` name: '${icon} ${title}'\n`;
|
modeEntry += ` name: '${icon} ${title}'\n`;
|
||||||
modeEntry += ` roleDefinition: ${roleDefinition}\n`;
|
modeEntry += ` roleDefinition: ${roleDefinition}\n`;
|
||||||
|
|||||||
@ -6,8 +6,7 @@ const yaml = require('js-yaml');
|
|||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { getAgentsFromBmad } = require('./shared/bmad-artifacts');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenCode IDE setup handler
|
* OpenCode IDE setup handler
|
||||||
@ -33,20 +32,17 @@ class OpenCodeSetup extends BaseIdeSetup {
|
|||||||
// Clean up any existing BMAD files before reinstalling
|
// Clean up any existing BMAD files before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
|
// Generate agent launchers
|
||||||
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Install primary agents with flat naming: bmad-agent-{module}-{name}.md
|
// Install primary agents with flat naming: bmad-agent-{module}-{name}.md
|
||||||
// OpenCode agents go in the agent folder (not command folder)
|
// OpenCode agents go in the agent folder (not command folder)
|
||||||
const agents = await getAgentsFromBmad(bmadDir, options.selectedModules || []);
|
|
||||||
|
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const processed = await this.readAndProcess(agent.path, {
|
const agentContent = artifact.content;
|
||||||
module: agent.module,
|
|
||||||
name: agent.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
const agentContent = await this.createAgentContent(processed, agent);
|
|
||||||
// Flat structure in agent folder: bmad-agent-{module}-{name}.md
|
// Flat structure in agent folder: bmad-agent-{module}-{name}.md
|
||||||
const targetPath = path.join(agentsBaseDir, `bmad-agent-${agent.module}-${agent.name}.md`);
|
const targetPath = path.join(agentsBaseDir, `bmad-agent-${artifact.module}-${artifact.name}.md`);
|
||||||
await this.writeFile(targetPath, agentContent);
|
await this.writeFile(targetPath, agentContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const path = require('node:path');
|
|||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Qwen Code setup handler
|
* Qwen Code setup handler
|
||||||
@ -37,15 +38,18 @@ class QwenSetup extends BaseIdeSetup {
|
|||||||
// Clean up old configuration if exists
|
// Clean up old configuration if exists
|
||||||
await this.cleanupOldConfig(qwenDir);
|
await this.cleanupOldConfig(qwenDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only for tools/workflows)
|
// Generate agent launchers
|
||||||
const agents = await getAgentsFromBmad(bmadDir, options.selectedModules || []);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only for tools/workflows)
|
||||||
const tasks = await getTasksFromBmad(bmadDir, options.selectedModules || []);
|
const tasks = await getTasksFromBmad(bmadDir, options.selectedModules || []);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
|
|
||||||
// Create directories for each module (including standalone)
|
// Create directories for each module (including standalone)
|
||||||
const modules = new Set();
|
const modules = new Set();
|
||||||
for (const item of [...agents, ...tasks, ...tools, ...workflows]) modules.add(item.module);
|
for (const item of [...agentArtifacts, ...tasks, ...tools, ...workflows]) modules.add(item.module);
|
||||||
|
|
||||||
for (const module of modules) {
|
for (const module of modules) {
|
||||||
await this.ensureDir(path.join(bmadCommandsDir, module));
|
await this.ensureDir(path.join(bmadCommandsDir, module));
|
||||||
@ -55,20 +59,21 @@ class QwenSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(path.join(bmadCommandsDir, module, 'workflows'));
|
await this.ensureDir(path.join(bmadCommandsDir, module, 'workflows'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create TOML files for each agent
|
// Create TOML files for each agent launcher
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readAndProcess(agent.path, {
|
// Convert markdown launcher content to TOML format
|
||||||
module: agent.module,
|
const tomlContent = this.processAgentLauncherContent(artifact.content, {
|
||||||
name: agent.name,
|
module: artifact.module,
|
||||||
|
name: artifact.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
const targetPath = path.join(bmadCommandsDir, agent.module, 'agents', `${agent.name}.toml`);
|
const targetPath = path.join(bmadCommandsDir, artifact.module, 'agents', `${artifact.name}.toml`);
|
||||||
|
|
||||||
await this.writeFile(targetPath, content);
|
await this.writeFile(targetPath, tomlContent);
|
||||||
|
|
||||||
agentCount++;
|
agentCount++;
|
||||||
console.log(chalk.green(` ✓ Added agent: /bmad:${agent.module}:agents:${agent.name}`));
|
console.log(chalk.green(` ✓ Added agent: /bmad:${artifact.module}:agents:${artifact.name}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create TOML files for each task
|
// Create TOML files for each task
|
||||||
@ -204,6 +209,29 @@ class QwenSetup extends BaseIdeSetup {
|
|||||||
return this.processContent(content, metadata);
|
return this.processContent(content, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process agent launcher content and convert to TOML format
|
||||||
|
* @param {string} launcherContent - Launcher markdown content
|
||||||
|
* @param {Object} metadata - File metadata
|
||||||
|
* @returns {string} TOML formatted content
|
||||||
|
*/
|
||||||
|
processAgentLauncherContent(launcherContent, metadata = {}) {
|
||||||
|
// Strip frontmatter from launcher content
|
||||||
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
|
const contentWithoutFrontmatter = launcherContent.replace(frontmatterRegex, '');
|
||||||
|
|
||||||
|
// Extract title for TOML description
|
||||||
|
const titleMatch = launcherContent.match(/description:\s*"([^"]+)"/);
|
||||||
|
const title = titleMatch ? titleMatch[1] : metadata.name;
|
||||||
|
|
||||||
|
// Create TOML with launcher content (without frontmatter)
|
||||||
|
return `description = "BMAD ${metadata.module.toUpperCase()} Agent: ${title}"
|
||||||
|
prompt = """
|
||||||
|
${contentWithoutFrontmatter.trim()}
|
||||||
|
"""
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override processContent to add TOML metadata header for Qwen
|
* Override processContent to add TOML metadata header for Qwen
|
||||||
* @param {string} content - File content
|
* @param {string} content - File content
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Roo IDE setup handler
|
* Roo IDE setup handler
|
||||||
@ -58,8 +59,9 @@ class RooSetup extends BaseIdeSetup {
|
|||||||
console.log(chalk.yellow(`Found existing .roomodes file with ${existingModes.length} modes`));
|
console.log(chalk.yellow(`Found existing .roomodes file with ${existingModes.length} modes`));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get agents
|
// Generate agent launchers (though Roo will reference the actual .bmad agents)
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
// Always use 'all' permissions - users can customize in .roomodes file
|
// Always use 'all' permissions - users can customize in .roomodes file
|
||||||
const permissionChoice = 'all';
|
const permissionChoice = 'all';
|
||||||
@ -69,8 +71,8 @@ class RooSetup extends BaseIdeSetup {
|
|||||||
let addedCount = 0;
|
let addedCount = 0;
|
||||||
let skippedCount = 0;
|
let skippedCount = 0;
|
||||||
|
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const slug = `bmad-${agent.module}-${agent.name}`;
|
const slug = `bmad-${artifact.module}-${artifact.name}`;
|
||||||
|
|
||||||
// Skip if already exists
|
// Skip if already exists
|
||||||
if (existingModes.includes(slug)) {
|
if (existingModes.includes(slug)) {
|
||||||
@ -79,8 +81,17 @@ class RooSetup extends BaseIdeSetup {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = await this.readFile(agent.path);
|
// Read the actual agent file from .bmad for metadata extraction
|
||||||
const modeEntry = await this.createModeEntry(agent, content, permissionChoice, projectDir);
|
const agentPath = path.join(bmadDir, artifact.module, 'agents', `${artifact.name}.md`);
|
||||||
|
const content = await this.readFile(agentPath);
|
||||||
|
|
||||||
|
// Create mode entry that references the actual .bmad agent
|
||||||
|
const modeEntry = await this.createModeEntry(
|
||||||
|
{ module: artifact.module, name: artifact.name, path: agentPath },
|
||||||
|
content,
|
||||||
|
permissionChoice,
|
||||||
|
projectDir,
|
||||||
|
);
|
||||||
|
|
||||||
newModesContent += modeEntry;
|
newModesContent += modeEntry;
|
||||||
addedCount++;
|
addedCount++;
|
||||||
|
|||||||
@ -0,0 +1,90 @@
|
|||||||
|
const path = require('node:path');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const chalk = require('chalk');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates launcher command files for each agent
|
||||||
|
* Similar to WorkflowCommandGenerator but for agents
|
||||||
|
*/
|
||||||
|
class AgentCommandGenerator {
|
||||||
|
constructor(bmadFolderName = 'bmad') {
|
||||||
|
this.templatePath = path.join(__dirname, '../templates/agent-command-template.md');
|
||||||
|
this.bmadFolderName = bmadFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect agent artifacts for IDE installation
|
||||||
|
* @param {string} bmadDir - BMAD installation directory
|
||||||
|
* @param {Array} selectedModules - Modules to include
|
||||||
|
* @returns {Object} Artifacts array with metadata
|
||||||
|
*/
|
||||||
|
async collectAgentArtifacts(bmadDir, selectedModules = []) {
|
||||||
|
const { getAgentsFromBmad } = require('./bmad-artifacts');
|
||||||
|
|
||||||
|
// Get agents from INSTALLED bmad/ directory
|
||||||
|
const agents = await getAgentsFromBmad(bmadDir, selectedModules);
|
||||||
|
|
||||||
|
const artifacts = [];
|
||||||
|
|
||||||
|
for (const agent of agents) {
|
||||||
|
const launcherContent = await this.generateLauncherContent(agent);
|
||||||
|
artifacts.push({
|
||||||
|
type: 'agent-launcher',
|
||||||
|
module: agent.module,
|
||||||
|
name: agent.name,
|
||||||
|
relativePath: path.join(agent.module, 'agents', `${agent.name}.md`),
|
||||||
|
content: launcherContent,
|
||||||
|
sourcePath: agent.path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
artifacts,
|
||||||
|
counts: {
|
||||||
|
agents: agents.length,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate launcher content for an agent
|
||||||
|
* @param {Object} agent - Agent metadata
|
||||||
|
* @returns {string} Launcher file content
|
||||||
|
*/
|
||||||
|
async generateLauncherContent(agent) {
|
||||||
|
// Load the template
|
||||||
|
const template = await fs.readFile(this.templatePath, 'utf8');
|
||||||
|
|
||||||
|
// Replace template variables
|
||||||
|
return template
|
||||||
|
.replaceAll('{{name}}', agent.name)
|
||||||
|
.replaceAll('{{module}}', agent.module)
|
||||||
|
.replaceAll('{{description}}', agent.description || `${agent.name} agent`)
|
||||||
|
.replaceAll('{bmad_folder}', this.bmadFolderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write agent launcher artifacts to IDE commands directory
|
||||||
|
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
||||||
|
* @param {Array} artifacts - Agent launcher artifacts
|
||||||
|
* @returns {number} Count of launchers written
|
||||||
|
*/
|
||||||
|
async writeAgentLaunchers(baseCommandsDir, artifacts) {
|
||||||
|
let writtenCount = 0;
|
||||||
|
|
||||||
|
for (const artifact of artifacts) {
|
||||||
|
if (artifact.type === 'agent-launcher') {
|
||||||
|
const moduleAgentsDir = path.join(baseCommandsDir, artifact.module, 'agents');
|
||||||
|
await fs.ensureDir(moduleAgentsDir);
|
||||||
|
|
||||||
|
const launcherPath = path.join(moduleAgentsDir, `${artifact.name}.md`);
|
||||||
|
await fs.writeFile(launcherPath, artifact.content);
|
||||||
|
writtenCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return writtenCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { AgentCommandGenerator };
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: '{{name}}'
|
||||||
|
description: '{{description}}'
|
||||||
|
---
|
||||||
|
|
||||||
|
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
||||||
|
|
||||||
|
<agent-activation CRITICAL="TRUE">
|
||||||
|
1. LOAD the FULL agent file from @{bmad_folder}/{{module}}/agents/{{name}}.md
|
||||||
|
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
||||||
|
3. Execute ALL activation steps exactly as written in the agent file
|
||||||
|
4. Follow the agent's persona and menu system precisely
|
||||||
|
5. Stay in character throughout the session
|
||||||
|
</agent-activation>
|
||||||
@ -5,8 +5,8 @@ description: '{{description}}'
|
|||||||
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
|
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
|
||||||
|
|
||||||
<steps CRITICAL="TRUE">
|
<steps CRITICAL="TRUE">
|
||||||
1. Always LOAD the FULL {project-root}/{bmad_folder}/core/tasks/workflow.xml
|
1. Always LOAD the FULL @{bmad_folder}/core/tasks/workflow.xml
|
||||||
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config {{workflow_path}}
|
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{{workflow_path}}
|
||||||
3. Pass the yaml path {{workflow_path}} as 'workflow-config' parameter to the workflow.xml instructions
|
3. Pass the yaml path {{workflow_path}} as 'workflow-config' parameter to the workflow.xml instructions
|
||||||
4. Follow workflow.xml instructions EXACTLY as written to process and follow the specific workflow config and its instructions
|
4. Follow workflow.xml instructions EXACTLY as written to process and follow the specific workflow config and its instructions
|
||||||
5. Save outputs after EACH section when generating any documents from templates
|
5. Save outputs after EACH section when generating any documents from templates
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trae IDE setup handler
|
* Trae IDE setup handler
|
||||||
@ -30,20 +31,22 @@ class TraeSetup extends BaseIdeSetup {
|
|||||||
// Clean up any existing BMAD files before reinstalling
|
// Clean up any existing BMAD files before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only)
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only)
|
||||||
const tasks = await this.getTasks(bmadDir, true);
|
const tasks = await this.getTasks(bmadDir, true);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
|
|
||||||
// Process agents as rules with bmad- prefix
|
// Process agents as rules with bmad- prefix
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const processedContent = await this.createAgentRule(artifact, bmadDir, projectDir);
|
||||||
const processedContent = await this.createAgentRule(agent, content, bmadDir, projectDir);
|
|
||||||
|
|
||||||
// Use bmad- prefix: bmad-agent-{module}-{name}.md
|
// Use bmad- prefix: bmad-agent-{module}-{name}.md
|
||||||
const targetPath = path.join(rulesDir, `bmad-agent-${agent.module}-${agent.name}.md`);
|
const targetPath = path.join(rulesDir, `bmad-agent-${artifact.module}-${artifact.name}.md`);
|
||||||
await this.writeFile(targetPath, processedContent);
|
await this.writeFile(targetPath, processedContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
@ -108,46 +111,29 @@ class TraeSetup extends BaseIdeSetup {
|
|||||||
/**
|
/**
|
||||||
* Create rule content for an agent
|
* Create rule content for an agent
|
||||||
*/
|
*/
|
||||||
async createAgentRule(agent, content, bmadDir, projectDir) {
|
async createAgentRule(artifact, bmadDir, projectDir) {
|
||||||
// Extract metadata from agent content
|
// Strip frontmatter from launcher
|
||||||
const titleMatch = content.match(/title="([^"]+)"/);
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
const title = titleMatch ? titleMatch[1] : this.formatTitle(agent.name);
|
const contentWithoutFrontmatter = artifact.content.replace(frontmatterRegex, '').trim();
|
||||||
|
|
||||||
const iconMatch = content.match(/icon="([^"]+)"/);
|
// Extract metadata from launcher content
|
||||||
const icon = iconMatch ? iconMatch[1] : '🤖';
|
const titleMatch = artifact.content.match(/description:\s*"([^"]+)"/);
|
||||||
|
const title = titleMatch ? titleMatch[1] : this.formatTitle(artifact.name);
|
||||||
// Get the activation header from central template
|
|
||||||
const activationHeader = await this.getAgentCommandHeader();
|
|
||||||
|
|
||||||
// Extract YAML content if available
|
|
||||||
const yamlMatch = content.match(/```ya?ml\r?\n([\s\S]*?)```/);
|
|
||||||
const yamlContent = yamlMatch ? yamlMatch[1] : content;
|
|
||||||
|
|
||||||
// Calculate relative path for reference
|
// Calculate relative path for reference
|
||||||
const relativePath = path.relative(projectDir, agent.path).replaceAll('\\', '/');
|
const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/');
|
||||||
|
|
||||||
let ruleContent = `# ${title} Agent Rule
|
let ruleContent = `# ${title} Agent Rule
|
||||||
|
|
||||||
This rule is triggered when the user types \`@${agent.name}\` and activates the ${title} agent persona.
|
This rule is triggered when the user types \`@${artifact.name}\` and activates the ${title} agent persona.
|
||||||
|
|
||||||
## Agent Activation
|
## Agent Activation
|
||||||
|
|
||||||
${activationHeader}
|
${contentWithoutFrontmatter}
|
||||||
|
|
||||||
Read the full YAML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:
|
|
||||||
|
|
||||||
\`\`\`yaml
|
|
||||||
${yamlContent}
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
## File Reference
|
## File Reference
|
||||||
|
|
||||||
The complete agent definition is available in [${relativePath}](${relativePath}).
|
The full agent definition is located at: \`${relativePath}\`
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
When the user types \`@${agent.name}\`, activate this ${title} persona and follow all instructions defined in the YAML configuration above.
|
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return ruleContent;
|
return ruleContent;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Windsurf IDE setup handler
|
* Windsurf IDE setup handler
|
||||||
@ -31,8 +32,14 @@ class WindsurfSetup extends BaseIdeSetup {
|
|||||||
// Clean up any existing BMAD workflows before reinstalling
|
// Clean up any existing BMAD workflows before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Get agents, tasks, tools, and workflows (standalone only)
|
// Generate agent launchers
|
||||||
const agents = await this.getAgents(bmadDir);
|
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||||
|
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||||
|
|
||||||
|
// Convert artifacts to agent format for module organization
|
||||||
|
const agents = agentArtifacts.map((a) => ({ module: a.module, name: a.name }));
|
||||||
|
|
||||||
|
// Get tasks, tools, and workflows (standalone only)
|
||||||
const tasks = await this.getTasks(bmadDir, true);
|
const tasks = await this.getTasks(bmadDir, true);
|
||||||
const tools = await this.getTools(bmadDir, true);
|
const tools = await this.getTools(bmadDir, true);
|
||||||
const workflows = await this.getWorkflows(bmadDir, true);
|
const workflows = await this.getWorkflows(bmadDir, true);
|
||||||
@ -49,14 +56,13 @@ class WindsurfSetup extends BaseIdeSetup {
|
|||||||
await this.ensureDir(path.join(bmadWorkflowsDir, module, 'workflows'));
|
await this.ensureDir(path.join(bmadWorkflowsDir, module, 'workflows'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process agents as workflows with organized structure
|
// Process agent launchers as workflows with organized structure
|
||||||
let agentCount = 0;
|
let agentCount = 0;
|
||||||
for (const agent of agents) {
|
for (const artifact of agentArtifacts) {
|
||||||
const content = await this.readFile(agent.path);
|
const processedContent = this.createWorkflowContent({ module: artifact.module, name: artifact.name }, artifact.content);
|
||||||
const processedContent = this.createWorkflowContent(agent, content);
|
|
||||||
|
|
||||||
// Organized path: bmad/module/agents/agent-name.md
|
// Organized path: bmad/module/agents/agent-name.md
|
||||||
const targetPath = path.join(bmadWorkflowsDir, agent.module, 'agents', `${agent.name}.md`);
|
const targetPath = path.join(bmadWorkflowsDir, artifact.module, 'agents', `${artifact.name}.md`);
|
||||||
await this.writeFile(targetPath, processedContent);
|
await this.writeFile(targetPath, processedContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
}
|
}
|
||||||
@ -127,13 +133,17 @@ class WindsurfSetup extends BaseIdeSetup {
|
|||||||
* Create workflow content for an agent
|
* Create workflow content for an agent
|
||||||
*/
|
*/
|
||||||
createWorkflowContent(agent, content) {
|
createWorkflowContent(agent, content) {
|
||||||
|
// Strip existing frontmatter from launcher
|
||||||
|
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||||
|
const contentWithoutFrontmatter = content.replace(frontmatterRegex, '');
|
||||||
|
|
||||||
// Create simple Windsurf frontmatter matching original format
|
// Create simple Windsurf frontmatter matching original format
|
||||||
let workflowContent = `---
|
let workflowContent = `---
|
||||||
description: ${agent.name}
|
description: ${agent.name}
|
||||||
auto_execution_mode: 3
|
auto_execution_mode: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
${content}`;
|
${contentWithoutFrontmatter}`;
|
||||||
|
|
||||||
return workflowContent;
|
return workflowContent;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user