From 2b21434a45057932bee78d40135c0311339c329d Mon Sep 17 00:00:00 2001 From: Philip Louw Date: Wed, 26 Nov 2025 14:27:54 +0200 Subject: [PATCH] refactor: migrate from Q CLI to Kiro CLI - Rename QCLIGenerator to KiroCLIGenerator - Update output directory from .amazonq/cli-agents to .kiro/agents - Update tool names to Kiro CLI format (read, write, shell) - Update agent configuration format for Kiro CLI compatibility - Update all references in installer and commands - Update package.json script to bmad:generate-kiro-cli - Update manifest.yaml to reference kiro-cli --- .gitignore | 2 +- docs/bmm-workflow-status.yaml | 46 +++++ package-lock.json | 4 +- package.json | 1 + .../cli/commands/generate-kiro-cli-agents.js | 35 ++++ tools/cli/commands/install.js | 12 ++ tools/cli/installers/lib/ide/kiro-cli.js | 165 ++++++++++++++++++ tools/cli/lib/kiro-cli-generator.js | 150 ++++++++++++++++ 8 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 docs/bmm-workflow-status.yaml create mode 100644 tools/cli/commands/generate-kiro-cli-agents.js create mode 100644 tools/cli/installers/lib/ide/kiro-cli.js create mode 100644 tools/cli/lib/kiro-cli-generator.js diff --git a/.gitignore b/.gitignore index 0c3840de..f3fe61a5 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,7 @@ cursor CLAUDE.local.md .serena/ .claude/settings.local.json - +.amazonq # Project-specific .bmad-core .bmad-creator-tools diff --git a/docs/bmm-workflow-status.yaml b/docs/bmm-workflow-status.yaml new file mode 100644 index 00000000..6b7bbcd8 --- /dev/null +++ b/docs/bmm-workflow-status.yaml @@ -0,0 +1,46 @@ +# Workflow Status - BMM Methodology Tracking +# Generated by BMad Master workflow-init +# Project: q-bmad (Brownfield) + +generated: "2025-11-21T10:37:22.564+02:00" +project: "q-bmad" +project_type: "brownfield" +selected_track: "pending_selection" +field_type: "software_development" +workflow_path: "pending_selection" + +# Current Phase: Project Assessment (Brownfield Entry) +current_phase: "assessment" +next_recommended_action: "Select appropriate workflow track based on project complexity" + +# Available Tracks for Brownfield Projects: +available_tracks: + - enterprise-brownfield: "Complex enterprise applications with multiple stakeholders" + - method-brownfield: "Standard business applications following full methodology" + - quick-flow-brownfield: "Simple applications or rapid assessment needs" + +# Assessment Status +workflow_status: + # Phase 0: Project Assessment (Current) + project_assessment: + document-project: "required" + codebase-analysis: "recommended" + tech-debt-audit: "recommended" + requirements-discovery: "optional" + + # Pending track selection - will be populated after assessment + track_selection: "pending" + +# Instructions +instructions: | + BROWNFIELD PROJECT INITIALIZATION COMPLETE + + Next Steps: + 1. Run document-project workflow to assess current state + 2. Choose appropriate track based on project complexity: + - Enterprise: Large, complex systems with multiple teams + - Method: Standard business applications + - Quick-flow: Simple applications or rapid needs + 3. Use workflow-status to get phase-specific recommendations + + Recommended immediate action: analyst → document-project diff --git a/package-lock.json b/package-lock.json index 07a43df8..1eec3e33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmad-method", - "version": "6.0.0-alpha.11", + "version": "6.0.0-alpha.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmad-method", - "version": "6.0.0-alpha.11", + "version": "6.0.0-alpha.12", "license": "MIT", "dependencies": { "@kayvan/markdown-tree-parser": "^1.6.1", diff --git a/package.json b/package.json index 314d5c66..2461db46 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "scripts": { "bmad:agent-install": "node tools/cli/bmad-cli.js agent-install", + "bmad:generate-kiro-cli": "node tools/cli/bmad-cli.js generate-kiro-cli-agents", "bmad:install": "node tools/cli/bmad-cli.js install", "bmad:status": "node tools/cli/bmad-cli.js status", "bundle": "node tools/cli/bundlers/bundle-web.js all", diff --git a/tools/cli/commands/generate-kiro-cli-agents.js b/tools/cli/commands/generate-kiro-cli-agents.js new file mode 100644 index 00000000..576a7eb0 --- /dev/null +++ b/tools/cli/commands/generate-kiro-cli-agents.js @@ -0,0 +1,35 @@ +const chalk = require('chalk'); +const { KiroCLIGenerator } = require('../lib/kiro-cli-generator'); + +const kiroGenerator = new KiroCLIGenerator(); + +module.exports = { + command: 'generate-kiro-cli-agents', + description: 'Generate Kiro CLI agent files from BMAD agent manifest', + options: [ + ['-o, --output ', 'Output directory (default: .kiro/agents)'], + ['-f, --force', 'Overwrite existing files'], + ], + action: async (options) => { + try { + console.log(chalk.cyan('\nšŸ¤– Kiro CLI Agent Generator\n')); + + const result = await kiroGenerator.generateWithOutput(process.cwd(), { + outputDir: options.output, + force: options.force, + }); + + console.log(chalk.cyan(`\nšŸ“Š Generation Summary:`)); + console.log(chalk.green(`āœ… Generated: ${result.generated} agents`)); + console.log(chalk.yellow(`ā­ļø Skipped: ${result.skipped} agents`)); + console.log(chalk.dim(`šŸ“ Output: ${result.outputDir}`)); + + if (result.generated > 0) { + console.log(chalk.cyan('\nšŸŽ‰ Kiro CLI agents ready! You can now use them in Kiro CLI.')); + } + } catch (error) { + console.error(chalk.red('āŒ Error generating Kiro CLI agents:'), error.message); + process.exit(1); + } + }, +}; diff --git a/tools/cli/commands/install.js b/tools/cli/commands/install.js index d2706ee6..ab3fedd8 100644 --- a/tools/cli/commands/install.js +++ b/tools/cli/commands/install.js @@ -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', @@ -57,6 +59,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!')); process.exit(0); diff --git a/tools/cli/installers/lib/ide/kiro-cli.js b/tools/cli/installers/lib/ide/kiro-cli.js new file mode 100644 index 00000000..0e615c61 --- /dev/null +++ b/tools/cli/installers/lib/ide/kiro-cli.js @@ -0,0 +1,165 @@ +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} 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. +Manual regeneration: \`npm run bmad:generate-kiro-cli --force\` + +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} 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 + +Example: kiro-cli chat --agent analyst`; + } + + /** + * Validate Kiro CLI setup + * @param {string} projectDir - Project directory + * @returns {Promise} 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 }; diff --git a/tools/cli/lib/kiro-cli-generator.js b/tools/cli/lib/kiro-cli-generator.js new file mode 100644 index 00000000..2d7ccee9 --- /dev/null +++ b/tools/cli/lib/kiro-cli-generator.js @@ -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 };