BMAD-METHOD/.patch/586/ide-setup.js.586.diff.txt

153 lines
6.1 KiB
Plaintext

diff --git a/tools/installer/lib/ide-setup.js b/tools/installer/lib/ide-setup.js
index a3882333..0845c91e 100644
--- a/tools/installer/lib/ide-setup.js
+++ b/tools/installer/lib/ide-setup.js
@@ -72,6 +72,9 @@ class IdeSetup extends BaseIdeSetup {
case 'kilo': {
return this.setupKilocode(installDir, selectedAgent);
}
+ case 'aicockpit': {
+ return this.setupAICockpit(installDir, selectedAgent);
+ }
case 'gemini': {
return this.setupGeminiCli(installDir, selectedAgent);
}
@@ -1921,6 +1924,137 @@ class IdeSetup extends BaseIdeSetup {
return true;
}
+ async setupAICockpit(installDir, selectedAgent) {
+ const ideConfig = await configLoader.getIdeConfiguration('aicockpit');
+ if (!ideConfig) {
+ console.log(chalk.red('✗ AI Cockpit configuration not found in install.config.yaml'));
+ return false;
+ }
+
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
+ const tasks = await this.getAllTaskIds(installDir);
+
+ // 1. Setup .aicockpitmodes file
+ const modesFilePath = path.join(installDir, ideConfig['modes-file']);
+ try {
+ let existingModes = [],
+ existingContent = '';
+ if (await fileManager.pathExists(modesFilePath)) {
+ existingContent = await fileManager.readFile(modesFilePath);
+ for (const match of existingContent.matchAll(/- slug: ([\w-]+)/g)) {
+ existingModes.push(match[1]);
+ }
+ }
+
+ let newModesContent = '';
+
+ for (const agentId of agents) {
+ const slug = agentId.startsWith('bmad-') ? agentId : `bmad-${agentId}`;
+ if (existingModes.includes(slug)) {
+ console.log(chalk.dim(`Skipping ${agentId} - already exists in .aicockpitmodes`));
+ continue;
+ }
+
+ const agentPath = await this.findAgentPath(agentId, installDir);
+ if (!agentPath) {
+ console.log(chalk.red(`✗ Could not find agent file for ${agentId}`));
+ continue;
+ }
+
+ const agentContent = await fileManager.readFile(agentPath);
+ const yamlMatch = agentContent.match(/```ya?ml\r?\n([\s\S]*?)```/);
+ if (!yamlMatch) {
+ console.log(chalk.red(`✗ Could not extract YAML block for ${agentId}`));
+ continue;
+ }
+
+ const yamlContent = yamlMatch[1];
+ const parsedYaml = yaml.load(yamlContent);
+
+ const title = parsedYaml?.agent?.title || (await this.getAgentTitle(agentId, installDir));
+ const icon = parsedYaml?.agent?.icon || '🤖';
+ const roleDefinition = parsedYaml?.persona?.role || `You are a ${title}.`;
+
+ // The custom instructions are the entire agent file content.
+ const customInstructions = agentContent;
+
+ // Indent a string for YAML block scalar
+ const indent = (str) =>
+ str
+ .split('\n')
+ .map((s) => ` ${s}`)
+ .join('\n');
+
+ newModesContent += ` - slug: ${slug}\n`;
+ newModesContent += ` name: '${icon} ${title}'\n`;
+ newModesContent += ` roleDefinition: |\n`;
+ newModesContent += `${indent(roleDefinition)}\n`;
+ newModesContent += ` groups:\n`;
+ newModesContent += ` - read\n`;
+ newModesContent += ` - browser\n`;
+ newModesContent += ` - edit\n`;
+ newModesContent += ` - mcp\n`;
+ newModesContent += ` customInstructions: |\n`;
+ newModesContent += `${indent(customInstructions)}\n`;
+ }
+
+ const finalModesContent = existingContent
+ ? existingContent.trim() + '\n' + newModesContent
+ : 'customModes:\n' + newModesContent;
+
+ await fileManager.writeFile(modesFilePath, finalModesContent);
+ console.log(chalk.green(`✓ Created/updated ${ideConfig['modes-file']} file in project root`));
+ } catch (error) {
+ console.log(chalk.red(`✗ Failed to create ${ideConfig['modes-file']}:`, error.message));
+ return false;
+ }
+
+ // 2. Setup .aicockpit/rules/ directory
+ try {
+ const rulesDir = path.join(installDir, ideConfig['rules-dir']);
+ await fileManager.ensureDirectory(rulesDir);
+ for (const agentId of agents) {
+ const agentPath = await this.findAgentPath(agentId, installDir);
+ if (agentPath) {
+ const agentContent = await fileManager.readFile(agentPath);
+ const rulePath = path.join(rulesDir, `${agentId}.md`);
+ await fileManager.writeFile(rulePath, agentContent);
+ console.log(chalk.green(`✓ Created agent rule: ${agentId}.md`));
+ }
+ }
+ console.log(chalk.green(`✓ Created agent rules in ${ideConfig['rules-dir']}`));
+ } catch (error) {
+ console.log(chalk.red(`✗ Failed to create agent rules:`, error.message));
+ return false;
+ }
+
+ // 3. Setup .aicockpit/workflows/ directory
+ try {
+ const workflowsDir = path.join(installDir, ideConfig['workflows-dir']);
+ await fileManager.ensureDirectory(workflowsDir);
+ for (const taskId of tasks) {
+ const taskPath = await this.findTaskPath(taskId, installDir);
+ if (taskPath) {
+ const taskContent = await fileManager.readFile(taskPath);
+ const workflowPath = path.join(workflowsDir, `${taskId}.md`);
+ await fileManager.writeFile(workflowPath, taskContent);
+ console.log(chalk.green(`✓ Created task workflow: ${taskId}.md`));
+ }
+ }
+ console.log(chalk.green(`✓ Created task workflows in ${ideConfig['workflows-dir']}`));
+ } catch (error) {
+ console.log(chalk.red(`✗ Failed to create task workflows:`, error.message));
+ return false;
+ }
+
+ console.log(chalk.green(`✓ AI Cockpit setup complete!`));
+ console.log(
+ chalk.dim('Custom modes, agent rules, and task workflows are now available in AI Cockpit'),
+ );
+
+ return true;
+ }
+
async setupCline(installDir, selectedAgent) {
const clineRulesDir = path.join(installDir, '.clinerules');
const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);