feat: complete custom agent support for ALL remaining IDEs
## Added installCustomAgentLauncher to remaining IDEs: ✅ Qwen (.qwen/commands/BMad/) - TOML format with proper description and prompt fields - Uses existing processAgentLauncherContent method - Format: custom-{agent-name}.toml ✅ Trae (.trae/rules/) - Markdown format with bmad-agent-custom- prefix - Follows existing BMAD naming pattern - Format: bmad-agent-custom-{agent-name}.md ✅ Roo (.roomodes) - YAML format appends to existing customModes section - Creates customModes section if missing - Format: bmad-custom-{agent-name} (slug-based) ✅ Kilo (.kilocodemodes) - YAML format identical to Roo pattern - Handles existing customModes gracefully - Format: bmad-custom-{agent-name} (slug-based) ✅ Auggie (.augment/commands/bmad/) - Frontmatter + Markdown format - Follows existing Auggie command pattern - Format: custom-{agent-name}.md ## Complete IDE Coverage: ALL IDEs now support custom agent installation: - 16 total IDEs with custom agent support - Various formats: TOML, YAML, Markdown, file-based - All include @agentPath references and usage instructions - Proper IDE-specific naming and directory structures Custom agents from .bmad/custom/src/agents/ now install to EVERY configured IDE!
This commit is contained in:
parent
98342f2174
commit
efc2b6d0df
|
|
@ -174,6 +174,57 @@ BMAD ${workflow.module.toUpperCase()} module
|
||||||
console.log(chalk.dim(` Removed old BMAD commands`));
|
console.log(chalk.dim(` Removed old BMAD commands`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a custom agent launcher for Auggie
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||||
|
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||||
|
* @param {Object} metadata - Agent metadata
|
||||||
|
* @returns {Object} Installation result
|
||||||
|
*/
|
||||||
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
|
// Auggie uses .augment/commands directory
|
||||||
|
const location = path.join(projectDir, '.augment', 'commands');
|
||||||
|
const bmadCommandsDir = path.join(location, 'bmad');
|
||||||
|
|
||||||
|
// Create .augment/commands/bmad directory if it doesn't exist
|
||||||
|
await fs.ensureDir(bmadCommandsDir);
|
||||||
|
|
||||||
|
// Create custom agent launcher
|
||||||
|
const launcherContent = `---
|
||||||
|
description: "Use the ${agentName} custom agent"
|
||||||
|
---
|
||||||
|
|
||||||
|
# ${agentName} Custom Agent
|
||||||
|
|
||||||
|
**⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
|
||||||
|
|
||||||
|
This is a launcher for the custom BMAD agent "${agentName}".
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
1. First run: \`${agentPath}\` to load the complete agent
|
||||||
|
2. Then use this command to activate ${agentName}
|
||||||
|
|
||||||
|
The agent will follow the persona and instructions from the main agent file.
|
||||||
|
|
||||||
|
## Module
|
||||||
|
BMAD Custom agent
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fileName = `custom-${agentName.toLowerCase()}.md`;
|
||||||
|
const launcherPath = path.join(bmadCommandsDir, fileName);
|
||||||
|
|
||||||
|
// Write the launcher file
|
||||||
|
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
||||||
|
|
||||||
|
return {
|
||||||
|
ide: 'auggie',
|
||||||
|
path: path.relative(projectDir, launcherPath),
|
||||||
|
command: agentName,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { AuggieSetup };
|
module.exports = { AuggieSetup };
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,77 @@ class KiloSetup extends BaseIdeSetup {
|
||||||
console.log(chalk.dim(`Removed ${removedCount} BMAD modes from .kilocodemodes`));
|
console.log(chalk.dim(`Removed ${removedCount} BMAD modes from .kilocodemodes`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a custom agent launcher for Kilo
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||||
|
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||||
|
* @param {Object} metadata - Agent metadata
|
||||||
|
* @returns {Object} Installation result
|
||||||
|
*/
|
||||||
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
|
const kilocodemodesPath = path.join(projectDir, this.configFile);
|
||||||
|
let existingContent = '';
|
||||||
|
|
||||||
|
// Read existing .kilocodemodes file
|
||||||
|
if (await this.pathExists(kilocodemodesPath)) {
|
||||||
|
existingContent = await this.readFile(kilocodemodesPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create custom agent mode entry
|
||||||
|
const slug = `bmad-custom-${agentName.toLowerCase()}`;
|
||||||
|
const modeEntry = ` - slug: ${slug}
|
||||||
|
name: 'BMAD Custom: ${agentName}'
|
||||||
|
description: |
|
||||||
|
Custom BMAD agent: ${agentName}
|
||||||
|
|
||||||
|
**⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
|
||||||
|
|
||||||
|
This is a launcher for the custom BMAD agent "${agentName}". The agent will follow the persona and instructions from the main agent file.
|
||||||
|
prompt: |
|
||||||
|
@${agentPath}
|
||||||
|
always: false
|
||||||
|
permissions: all
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Check if mode already exists
|
||||||
|
if (existingContent.includes(slug)) {
|
||||||
|
return {
|
||||||
|
ide: 'kilo',
|
||||||
|
path: this.configFile,
|
||||||
|
command: agentName,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
alreadyExists: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build final content
|
||||||
|
let finalContent = '';
|
||||||
|
if (existingContent) {
|
||||||
|
// Find customModes section or add it
|
||||||
|
if (existingContent.includes('customModes:')) {
|
||||||
|
// Append to existing customModes
|
||||||
|
finalContent = existingContent + modeEntry;
|
||||||
|
} else {
|
||||||
|
// Add customModes section
|
||||||
|
finalContent = existingContent.trim() + '\n\ncustomModes:\n' + modeEntry;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create new .kilocodemodes file with customModes
|
||||||
|
finalContent = 'customModes:\n' + modeEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write .kilocodemodes file
|
||||||
|
await this.writeFile(kilocodemodesPath, finalContent);
|
||||||
|
|
||||||
|
return {
|
||||||
|
ide: 'kilo',
|
||||||
|
path: this.configFile,
|
||||||
|
command: slug,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { KiloSetup };
|
module.exports = { KiloSetup };
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,59 @@ ${prompt}
|
||||||
console.log(chalk.dim(`Removed old BMAD configuration from Qwen Code`));
|
console.log(chalk.dim(`Removed old BMAD configuration from Qwen Code`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a custom agent launcher for Qwen
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||||
|
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||||
|
* @param {Object} metadata - Agent metadata
|
||||||
|
* @returns {Object} Installation result
|
||||||
|
*/
|
||||||
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
|
const qwenDir = path.join(projectDir, this.configDir);
|
||||||
|
const commandsDir = path.join(qwenDir, this.commandsDir);
|
||||||
|
const bmadCommandsDir = path.join(commandsDir, this.bmadDir);
|
||||||
|
|
||||||
|
// Create .qwen/commands/BMad directory if it doesn't exist
|
||||||
|
await fs.ensureDir(bmadCommandsDir);
|
||||||
|
|
||||||
|
// Create custom agent launcher in TOML format (same pattern as regular agents)
|
||||||
|
const launcherContent = `# ${agentName} Custom Agent
|
||||||
|
|
||||||
|
**⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
|
||||||
|
|
||||||
|
This is a launcher for the custom BMAD agent "${agentName}".
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
1. First run: \`${agentPath}\` to load the complete agent
|
||||||
|
2. Then use this command to activate ${agentName}
|
||||||
|
|
||||||
|
The agent will follow the persona and instructions from the main agent file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated by BMAD Method*`;
|
||||||
|
|
||||||
|
// Use Qwen's TOML conversion method
|
||||||
|
const tomlContent = this.processAgentLauncherContent(launcherContent, {
|
||||||
|
name: agentName,
|
||||||
|
module: 'custom',
|
||||||
|
});
|
||||||
|
|
||||||
|
const fileName = `custom-${agentName.toLowerCase()}.toml`;
|
||||||
|
const launcherPath = path.join(bmadCommandsDir, fileName);
|
||||||
|
|
||||||
|
// Write the launcher file
|
||||||
|
await fs.writeFile(launcherPath, tomlContent, 'utf8');
|
||||||
|
|
||||||
|
return {
|
||||||
|
ide: 'qwen',
|
||||||
|
path: path.relative(projectDir, launcherPath),
|
||||||
|
command: agentName,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { QwenSetup };
|
module.exports = { QwenSetup };
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,77 @@ class RooSetup extends BaseIdeSetup {
|
||||||
console.log(chalk.dim(`Removed ${removedCount} BMAD modes from .roomodes`));
|
console.log(chalk.dim(`Removed ${removedCount} BMAD modes from .roomodes`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a custom agent launcher for Roo
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||||
|
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||||
|
* @param {Object} metadata - Agent metadata
|
||||||
|
* @returns {Object} Installation result
|
||||||
|
*/
|
||||||
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
|
const roomodesPath = path.join(projectDir, this.configFile);
|
||||||
|
let existingContent = '';
|
||||||
|
|
||||||
|
// Read existing .roomodes file
|
||||||
|
if (await this.pathExists(roomodesPath)) {
|
||||||
|
existingContent = await this.readFile(roomodesPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create custom agent mode entry
|
||||||
|
const slug = `bmad-custom-${agentName.toLowerCase()}`;
|
||||||
|
const modeEntry = ` - slug: ${slug}
|
||||||
|
name: 'BMAD Custom: ${agentName}'
|
||||||
|
description: |
|
||||||
|
Custom BMAD agent: ${agentName}
|
||||||
|
|
||||||
|
**⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
|
||||||
|
|
||||||
|
This is a launcher for the custom BMAD agent "${agentName}". The agent will follow the persona and instructions from the main agent file.
|
||||||
|
prompt: |
|
||||||
|
@${agentPath}
|
||||||
|
always: false
|
||||||
|
permissions: all
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Check if mode already exists
|
||||||
|
if (existingContent.includes(slug)) {
|
||||||
|
return {
|
||||||
|
ide: 'roo',
|
||||||
|
path: this.configFile,
|
||||||
|
command: agentName,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
alreadyExists: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build final content
|
||||||
|
let finalContent = '';
|
||||||
|
if (existingContent) {
|
||||||
|
// Find customModes section or add it
|
||||||
|
if (existingContent.includes('customModes:')) {
|
||||||
|
// Append to existing customModes
|
||||||
|
finalContent = existingContent + modeEntry;
|
||||||
|
} else {
|
||||||
|
// Add customModes section
|
||||||
|
finalContent = existingContent.trim() + '\n\ncustomModes:\n' + modeEntry;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Create new .roomodes file with customModes
|
||||||
|
finalContent = 'customModes:\n' + modeEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write .roomodes file
|
||||||
|
await this.writeFile(roomodesPath, finalContent);
|
||||||
|
|
||||||
|
return {
|
||||||
|
ide: 'roo',
|
||||||
|
path: this.configFile,
|
||||||
|
command: slug,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { RooSetup };
|
module.exports = { RooSetup };
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,52 @@ Part of the BMAD ${workflow.module.toUpperCase()} module.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a custom agent launcher for Trae
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||||
|
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||||
|
* @param {Object} metadata - Agent metadata
|
||||||
|
* @returns {Object} Installation result
|
||||||
|
*/
|
||||||
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
|
const traeDir = path.join(projectDir, this.configDir);
|
||||||
|
const rulesDir = path.join(traeDir, this.rulesDir);
|
||||||
|
|
||||||
|
// Create .trae/rules directory if it doesn't exist
|
||||||
|
await fs.ensureDir(rulesDir);
|
||||||
|
|
||||||
|
// Create custom agent launcher
|
||||||
|
const launcherContent = `# ${agentName} Custom Agent
|
||||||
|
|
||||||
|
**⚠️ IMPORTANT**: Run @${agentPath} first to load the complete agent!
|
||||||
|
|
||||||
|
This is a launcher for the custom BMAD agent "${agentName}".
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
1. First run: \`${agentPath}\` to load the complete agent
|
||||||
|
2. Then use this rule to activate ${agentName}
|
||||||
|
|
||||||
|
The agent will follow the persona and instructions from the main agent file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated by BMAD Method*`;
|
||||||
|
|
||||||
|
const fileName = `bmad-agent-custom-${agentName.toLowerCase()}.md`;
|
||||||
|
const launcherPath = path.join(rulesDir, fileName);
|
||||||
|
|
||||||
|
// Write the launcher file
|
||||||
|
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
||||||
|
|
||||||
|
return {
|
||||||
|
ide: 'trae',
|
||||||
|
path: path.relative(projectDir, launcherPath),
|
||||||
|
command: agentName,
|
||||||
|
type: 'custom-agent-launcher',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { TraeSetup };
|
module.exports = { TraeSetup };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue