This commit is contained in:
Philip Louw 2025-11-27 08:17:37 +00:00 committed by GitHub
commit c9f8857f28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 327 additions and 1 deletions

2
.gitignore vendored
View File

@ -42,7 +42,7 @@ cursor
CLAUDE.local.md
.serena/
.claude/settings.local.json
.amazonq
# Project-specific
.bmad-core
.bmad-creator-tools

View File

@ -2,9 +2,11 @@ const chalk = require('chalk');
const path = require('node:path');
const { Installer } = require('../installers/lib/core/installer');
const { UI } = require('../lib/ui');
const { KiroCLIGenerator } = require('../lib/kiro-cli-generator');
const installer = new Installer();
const ui = new UI();
const kiroGenerator = new KiroCLIGenerator();
module.exports = {
command: 'install',
@ -62,6 +64,16 @@ module.exports = {
if (result && result.success) {
console.log(chalk.green('\n✨ Installation complete!'));
console.log(chalk.cyan('BMAD Core and Selected Modules have been installed to:'), chalk.bold(result.path));
// Generate Kiro CLI agents automatically using the installation directory
try {
// Use the directory where BMAD was installed, not current working directory
const installDir = path.dirname(result.path); // Remove .bmad from path to get project root
await kiroGenerator.generateWithOutput(installDir);
} catch (error) {
console.log(chalk.yellow('⚠️ Kiro CLI agent generation failed (non-critical):'), error.message);
}
console.log(chalk.yellow('\nThank you for helping test the early release version of the new BMad Core and BMad Method!'));
console.log(chalk.cyan('Stable Beta coming soon - please read the full readme.md and linked documentation to get started!'));

View File

@ -0,0 +1,164 @@
const path = require('node:path');
const fs = require('fs-extra');
const { BaseIdeSetup } = require('./_base-ide');
const chalk = require('chalk');
const { KiroCLIGenerator } = require('../../../lib/kiro-cli-generator');
/**
* Kiro CLI setup handler
* Generates Kiro CLI agent files from BMAD agent manifest
*/
class KiroCliSetup extends BaseIdeSetup {
constructor() {
super('kiro-cli', 'Kiro CLI');
this.configDir = '.kiro';
this.agentsDir = 'agents';
this.kiroGenerator = new KiroCLIGenerator();
}
/**
* Setup Kiro CLI configuration
* @param {string} projectDir - Project directory
* @param {string} bmadDir - BMAD installation directory
* @param {Object} config - Configuration object
* @returns {Promise<Object>} Setup result
*/
async setup(projectDir, bmadDir, config) {
try {
console.log(chalk.cyan(' Setting up Kiro CLI integration...'));
const outputDir = path.join(projectDir, this.configDir, this.agentsDir);
// Generate Kiro CLI agents from BMAD manifest
const result = await this.kiroGenerator.generateAgents(
projectDir,
outputDir,
true, // Force overwrite to ensure latest versions
);
console.log(chalk.green(` ✅ Generated ${result.generated} Kiro CLI agents`));
if (result.skipped > 0) {
console.log(chalk.dim(` (${result.skipped} agents were up to date)`));
}
// Create a simple readme for Kiro CLI users
const readmePath = path.join(outputDir, 'README.md');
const readmeContent = `# BMAD Kiro CLI Agents
Auto-generated Kiro CLI agents from your BMAD installation.
## Usage
\`\`\`bash
# Use any BMAD agent in Kiro CLI
kiro-cli chat --agent analyst # Strategic Business Analyst
kiro-cli chat --agent architect # System Architect
kiro-cli chat --agent dev # Senior Developer
kiro-cli chat --agent pm # Product Manager
kiro-cli chat --agent sm # Scrum Master
kiro-cli chat --agent tea # Test Architect
kiro-cli chat --agent tech-writer # Technical Writer
kiro-cli chat --agent ux-designer # UX Designer
# Specialist agents
kiro-cli chat --agent codebase-analyzer
kiro-cli chat --agent tech-debt-auditor
kiro-cli chat --agent market-researcher
# ... and many more
\`\`\`
## Features
- **Lazy Loading**: Workflows loaded on-demand for context efficiency
- **File Outputs**: Generate structured deliverables
- **Conversational**: Optimized for Kiro CLI interaction
- **Full BMAD Capabilities**: Access to all workflows and expertise
## Updates
These agents are automatically regenerated when you update BMAD.
Generated: ${new Date().toISOString()}
`;
await fs.writeFile(readmePath, readmeContent);
return {
success: true,
message: `Kiro CLI integration complete with ${result.generated} agents`,
details: {
agentsGenerated: result.generated,
outputDirectory: outputDir,
totalAgents: result.total,
},
};
} catch (error) {
console.error(chalk.red(' ❌ Kiro CLI setup failed:'), error.message);
return {
success: false,
message: `Kiro CLI setup failed: ${error.message}`,
error: error,
};
}
}
/**
* Check if Kiro CLI is available/configured in the project
* @param {string} projectDir - Project directory
* @returns {Promise<boolean>} True if Kiro CLI is detected
*/
async isConfigured(projectDir) {
const kiroDir = path.join(projectDir, this.configDir);
return await fs.pathExists(kiroDir);
}
/**
* Get setup instructions for Kiro CLI
* @returns {string} Setup instructions
*/
getSetupInstructions() {
return `Kiro CLI agents will be generated automatically.
After setup, use: kiro-cli chat --agent <agent-name>
Example: kiro-cli chat --agent analyst`;
}
/**
* Validate Kiro CLI setup
* @param {string} projectDir - Project directory
* @returns {Promise<Object>} Validation result
*/
async validate(projectDir) {
const agentsDir = path.join(projectDir, this.configDir, this.agentsDir);
if (!(await fs.pathExists(agentsDir))) {
return {
valid: false,
message: 'Kiro CLI agents directory not found',
};
}
// Check if we have agent files
const files = await fs.readdir(agentsDir);
const agentFiles = files.filter((f) => f.endsWith('.json'));
if (agentFiles.length === 0) {
return {
valid: false,
message: 'No Kiro CLI agent files found',
};
}
return {
valid: true,
message: `Kiro CLI integration ready with ${agentFiles.length} agents`,
details: {
agentCount: agentFiles.length,
agentsDir: agentsDir,
},
};
}
}
module.exports = { KiroCliSetup };

View File

@ -0,0 +1,150 @@
const fs = require('node:fs');
const path = require('node:path');
const csv = require('csv-parse/sync');
const chalk = require('chalk');
class KiroCLIGenerator {
constructor() {}
/**
* Generate Kiro CLI agent files from BMAD agent manifest
* @param {string} projectRoot - Project root directory
* @param {string} outputDir - Output directory for Kiro CLI agents
* @param {boolean} force - Overwrite existing files
* @returns {Object} Generation results
*/
async generateAgents(projectRoot, outputDir = null, force = false) {
const manifestPath = path.join(projectRoot, '.bmad/_cfg/agent-manifest.csv');
const defaultOutputDir = path.join(projectRoot, '.kiro/agents');
const targetOutputDir = outputDir || defaultOutputDir;
// Validate manifest exists
if (!fs.existsSync(manifestPath)) {
throw new Error(`Agent manifest not found at: ${manifestPath}`);
}
// Create output directory
if (!fs.existsSync(targetOutputDir)) {
fs.mkdirSync(targetOutputDir, { recursive: true });
}
// Read and parse agent manifest
const manifestContent = fs.readFileSync(manifestPath, 'utf8');
const agents = csv.parse(manifestContent, {
columns: true,
skip_empty_lines: true,
});
let generated = 0;
let skipped = 0;
for (const agent of agents) {
const agentJsonPath = path.join(targetOutputDir, `${agent.name}.json`);
const agentPromptPath = path.join(targetOutputDir, `${agent.name}-prompt.md`);
// Skip if files exist and not forcing
if (!force && (fs.existsSync(agentJsonPath) || fs.existsSync(agentPromptPath))) {
skipped++;
continue;
}
// Generate Kiro CLI agent JSON
const kiroAgent = {
name: agent.name,
description: `BMAD ${agent.title} (context optimized) - auto-generated from manifest`,
prompt: `file://./${agent.name}-prompt.md`,
tools: ['read', 'write', 'shell', '@docker_mcp_gateway'],
allowedTools: ['read', 'write', 'shell', '@docker_mcp_gateway'],
mcpServers: {},
resources: ['file://.bmad/bmm/config.yaml'],
model: 'claude-sonnet-4',
};
// Generate Kiro CLI agent prompt
const kiroPrompt = `# ${agent.name} (Context Optimized)
**IMPORTANT**: Only load specific workflow/task details when explicitly needed using fs_read.
Load workflows: \`file://.bmad/bmm/workflows/[name]/workflow.yaml\`
You are ${agent.displayName}, a ${agent.title} ${agent.icon}
## Core Identity
- **Role**: ${agent.role}
- **Identity**: ${agent.identity}
- **Communication Style**: ${agent.communicationStyle}
- **Principles**: ${agent.principles}
## Kiro CLI Optimization
- **Lazy Loading**: Load workflow files only when requested using read tool
- **Context Efficiency**: Minimal initial load, expand on demand
- **File Output**: Generate files as specified in workflows
- **Session Continuity**: Maintain conversation context within Kiro CLI
- **MCP Integration**: Inherits MCP servers from agent configuration
## Available Workflows
Load workflows from: \`.bmad/bmm/workflows/\`
## MCP Server Access
You have access to any MCP servers configured in this agent's configuration.
Use MCP capabilities when they provide better functionality than basic tools.
## Interaction Pattern
1. **Greet user** as ${agent.displayName}
2. **Offer capabilities** based on role and available workflows
3. **Load workflows** on demand using read tool when user requests specific functionality
4. **Execute conversationally** following loaded workflow instructions
5. **Generate outputs** to appropriate file paths
6. **Leverage available MCP servers** when they enhance functionality
## Configuration
- **Project Root**: Use current working directory
- **Config**: Load from .bmad/bmm/config.yaml
- **Output**: Use configured output folder from config
Remember: You are ${agent.displayName} - ${agent.identity}`;
// Write files
fs.writeFileSync(agentJsonPath, JSON.stringify(kiroAgent, null, 2));
fs.writeFileSync(agentPromptPath, kiroPrompt);
generated++;
}
return {
total: agents.length,
generated,
skipped,
outputDir: targetOutputDir,
};
}
/**
* Generate Kiro CLI agents with console output
* @param {string} projectRoot - Project root directory
* @param {Object} options - Generation options
*/
async generateWithOutput(projectRoot, options = {}) {
try {
console.log(chalk.cyan('🤖 Generating Kiro CLI agents...'));
const result = await this.generateAgents(projectRoot, options.outputDir, options.force);
if (result.generated > 0) {
console.log(chalk.green(`✅ Generated ${result.generated} Kiro CLI agents`));
if (result.skipped > 0) {
console.log(chalk.yellow(`⏭️ Skipped ${result.skipped} existing agents`));
}
console.log(chalk.dim(`📁 Output: ${result.outputDir}`));
} else {
console.log(chalk.yellow('⏭️ All Kiro CLI agents already exist (use --force to regenerate)'));
}
return result;
} catch (error) {
console.error(chalk.red('❌ Kiro CLI agent generation failed:'), error.message);
throw error;
}
}
name = 'Kiro CLI Agent Generator';
}
module.exports = { KiroCLIGenerator };