feat(ide-setup): add support for Cline IDE and configuration rules (#262)

This commit is contained in:
Reider Olivér
2025-06-24 04:47:21 +02:00
committed by GitHub
parent 00a9891793
commit 913dbeced6
4 changed files with 92 additions and 14 deletions

View File

@@ -50,7 +50,7 @@ program
.option('-t, --team <team>', 'Install specific team with required agents and dependencies')
.option('-x, --expansion-only', 'Install only expansion packs (no bmad-core)')
.option('-d, --directory <path>', 'Installation directory (default: .bmad-core)')
.option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo, other)')
.option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo, cline, other)')
.option('-e, --expansion-packs <packs...>', 'Install specific expansion packs (can specify multiple)')
.action(async (options) => {
try {
@@ -67,7 +67,7 @@ program
if (options.agent) installType = 'single-agent';
else if (options.team) installType = 'team';
else if (options.expansionOnly) installType = 'expansion-only';
const config = {
installType,
agent: options.agent,
@@ -164,13 +164,13 @@ async function promptInstallation() {
// Check if this is an existing v4 installation
const installDir = path.resolve(answers.directory);
const state = await installer.detectInstallationState(installDir);
if (state.type === 'v4_existing') {
console.log(chalk.yellow('\n🔍 Found existing BMAD v4 installation'));
console.log(` Directory: ${installDir}`);
console.log(` Version: ${state.manifest?.version || 'Unknown'}`);
console.log(` Installed: ${state.manifest?.installed_at ? new Date(state.manifest.installed_at).toLocaleDateString() : 'Unknown'}`);
const { shouldUpdate } = await inquirer.prompt([
{
type: 'confirm',
@@ -179,7 +179,7 @@ async function promptInstallation() {
default: true
}
]);
if (shouldUpdate) {
// Skip other prompts and go directly to update
answers.installType = 'update';
@@ -256,11 +256,11 @@ async function promptInstallation() {
if (installType === 'full' || installType === 'team' || installType === 'expansion-only') {
try {
const availableExpansionPacks = await installer.getAvailableExpansionPacks();
if (availableExpansionPacks.length > 0) {
let choices;
let message;
if (installType === 'expansion-only') {
message = 'Select expansion packs to install (required):'
choices = availableExpansionPacks.map(pack => ({
@@ -274,7 +274,7 @@ async function promptInstallation() {
value: pack.id
}));
}
const { expansionPacks } = await inquirer.prompt([
{
type: 'checkbox',
@@ -289,7 +289,7 @@ async function promptInstallation() {
} : undefined
}
]);
// Use selected expansion packs directly
answers.expansionPacks = expansionPacks;
} else {
@@ -313,11 +313,12 @@ async function promptInstallation() {
{ name: 'Cursor', value: 'cursor' },
{ name: 'Claude Code', value: 'claude-code' },
{ name: 'Windsurf', value: 'windsurf' },
{ name: 'Roo Code', value: 'roo' }
{ name: 'Roo Code', value: 'roo' },
{ name: 'Cline', value: 'cline' }
]
}
]);
// Use selected IDEs directly
answers.ides = ides;

View File

@@ -92,10 +92,15 @@ ide-configurations:
# 3. The AI will adopt that agent's full personality and capabilities
cline:
name: Cline
format: unknown
rule-dir: .clinerules/
format: multi-file
command-suffix: .md
instructions: |
# Cline configuration coming soon
# Manual setup: Copy IDE agent files to your Cline configuration
# To use BMAD agents in Cline:
# 1. Open the Cline chat panel in VS Code
# 2. Type @agent-name (e.g., "@dev", "@pm", "@architect")
# 3. The agent will adopt that persona for the conversation
# 4. Rules are stored in .clinerules/ directory in your project
available-agents:
- id: analyst
name: Business Analyst

View File

@@ -31,6 +31,8 @@ class IdeSetup {
return this.setupWindsurf(installDir, selectedAgent);
case "roo":
return this.setupRoo(installDir, selectedAgent);
case "cline":
return this.setupCline(installDir, selectedAgent);
default:
console.log(chalk.yellow(`\nIDE ${ide} not yet supported`));
return false;
@@ -340,6 +342,75 @@ class IdeSetup {
return true;
}
async setupCline(installDir, selectedAgent) {
const clineRulesDir = path.join(installDir, ".clinerules");
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
await fileManager.ensureDirectory(clineRulesDir);
// Define agent order for numeric prefixes
const agentOrder = {
'bmad-master': 1,
'bmad-orchestrator': 2,
'pm': 3,
'analyst': 4,
'architect': 5,
'po': 6,
'sm': 7,
'dev': 8,
'qa': 9,
'ux-expert': 10
};
for (const agentId of agents) {
// Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, ".bmad-core", "agents", `${agentId}.md`);
if (!(await fileManager.pathExists(agentPath))) {
agentPath = path.join(installDir, "agents", `${agentId}.md`);
}
if (await fileManager.pathExists(agentPath)) {
const agentContent = await fileManager.readFile(agentPath);
// Get numeric prefix for ordering
const order = agentOrder[agentId] || 99;
const prefix = order.toString().padStart(2, '0');
const mdPath = path.join(clineRulesDir, `${prefix}-${agentId}.md`);
// Create MD content for Cline (focused on project standards and role)
let mdContent = `# ${this.getAgentTitle(agentId)} Agent\n\n`;
mdContent += `This rule defines the ${this.getAgentTitle(agentId)} persona and project standards.\n\n`;
mdContent += "## Role Definition\n\n";
mdContent +=
"When the user types `@" + agentId + "`, adopt this persona and follow these guidelines:\n\n";
mdContent += "```yml\n";
// Extract just the YAML content from the agent file
const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
if (yamlMatch) {
mdContent += yamlMatch[1].trim();
} else {
// If no YAML found, include the whole content minus the header
mdContent += agentContent.replace(/^#.*$/m, "").trim();
}
mdContent += "\n```\n\n";
mdContent += "## Project Standards\n\n";
mdContent += `- Always maintain consistency with project documentation in .bmad-core/\n`;
mdContent += `- Follow the agent's specific guidelines and constraints\n`;
mdContent += `- Update relevant project files when making changes\n`;
mdContent += `- Reference the complete agent definition in [.bmad-core/agents/${agentId}.md](.bmad-core/agents/${agentId}.md)\n\n`;
mdContent += "## Usage\n\n";
mdContent += `Type \`@${agentId}\` to activate this ${this.getAgentTitle(agentId)} persona.\n`;
await fileManager.writeFile(mdPath, mdContent);
console.log(chalk.green(`✓ Created rule: ${prefix}-${agentId}.md`));
}
}
console.log(chalk.green(`\n✓ Created Cline rules in ${clineRulesDir}`));
return true;
}
}
module.exports = new IdeSetup();

View File

@@ -561,6 +561,7 @@ class V3ToV4Upgrader {
"claude-code": "Commands created in .claude/commands/",
windsurf: "Rules created in .windsurf/rules/",
roo: "Custom modes created in .roomodes",
cline: "Rules created in .clinerules/",
};
// Setup each selected IDE