UNPKG

claude-flow

Version:

Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)

1,310 lines (1,136 loc) 104 kB
import chalk from 'chalk'; import { getErrorMessage } from '../../utils/error-handler.js'; import { CLI, success, error, warning, info, VERSION } from "../cli-core.js"; import type { Command, CommandContext } from "../cli-core.js"; import colors from "chalk"; const { bold, blue, yellow } = colors; import { Orchestrator } from "../../core/orchestrator-fixed.js"; import { ConfigManager } from "../../core/config.js"; import type { MemoryManager } from "../../memory/manager.js"; import { EventBus } from "../../core/event-bus.js"; import { Logger } from "../../core/logger.js"; import { JsonPersistenceManager } from "../../core/json-persistence.js"; import { swarmAction } from "./swarm.js"; import { SimpleMemoryManager } from "./memory.js"; import { sparcAction } from "./sparc.js"; import { createMigrateCommand } from "./migrate.js"; import { enterpriseCommands } from "./enterprise.js"; // Import enhanced orchestration commands import { startCommand } from "./start.js"; import { statusCommand } from "./status.js"; import { monitorCommand } from "./monitor.js"; import { sessionCommand } from "./session.js"; let orchestrator: Orchestrator | null = null; let configManager: ConfigManager | null = null; let persistence: JsonPersistenceManager | null = null; async function getPersistence(): Promise<JsonPersistenceManager> { if (!persistence) { persistence = new JsonPersistenceManager(); await persistence.initialize(); } return persistence; } async function getOrchestrator(): Promise<Orchestrator> { if (!orchestrator) { const config = await getConfigManager(); const eventBus = EventBus.getInstance(); const logger = new Logger({ level: "info", format: "text", destination: "console" }); orchestrator = new Orchestrator(config, eventBus, logger); } return orchestrator; } async function getConfigManager(): Promise<ConfigManager> { if (!configManager) { configManager = ConfigManager.getInstance(); await configManager.load(); } return configManager; } export function setupCommands(cli: CLI): void { // Init command cli.command({ name: "init", description: "Initialize Claude Code integration files", options: [ { name: "force", short: "f", description: "Overwrite existing files", type: "boolean", }, { name: "minimal", short: "m", description: "Create minimal configuration files", type: "boolean", }, ], action: async (ctx: CommandContext) => { try { success("Initializing Claude Code integration files..."); const force = ctx.flags.force as boolean || ctx.flags.f as boolean; const minimal = ctx.flags.minimal as boolean || ctx.flags.m as boolean; // Check if files already exist const files = ["CLAUDE.md", "memory-bank.md", "coordination.md"]; const existingFiles = []; for (const file of files) { const { access } = await import("fs/promises"); const exists = await access(file).then(() => true).catch(() => false); if (exists) { existingFiles.push(file); } } if (existingFiles.length > 0 && !force) { warning(`The following files already exist: ${existingFiles.join(", ")}`); console.log("Use --force to overwrite existing files"); return; } // Create CLAUDE.md const claudeMd = minimal ? createMinimalClaudeMd() : createFullClaudeMd(); const { writeFile } = await import("fs/promises"); await writeFile("CLAUDE.md", claudeMd); console.log(" ✓ Created CLAUDE.md"); // Create memory-bank.md const memoryBankMd = minimal ? createMinimalMemoryBankMd() : createFullMemoryBankMd(); await writeFile("memory-bank.md", memoryBankMd); console.log(" ✓ Created memory-bank.md"); // Create coordination.md const coordinationMd = minimal ? createMinimalCoordinationMd() : createFullCoordinationMd(); await writeFile("coordination.md", coordinationMd); console.log(" ✓ Created coordination.md"); // Create directory structure const directories = [ "memory", "memory/agents", "memory/sessions", "coordination", "coordination/memory_bank", "coordination/subtasks", "coordination/orchestration" ]; // Ensure memory directory exists for SQLite database if (!directories.includes("memory")) { directories.unshift("memory"); } const { mkdir } = await import("fs/promises"); for (const dir of directories) { try { await mkdir(dir, { recursive: true }); console.log(` ✓ Created ${dir}/ directory`); } catch (err) { if ((err as any).code !== 'EEXIST') { throw err; } } } // Create placeholder files for memory directories const agentsReadme = createAgentsReadme(); await writeFile("memory/agents/README.md", agentsReadme); console.log(" ✓ Created memory/agents/README.md"); const sessionsReadme = createSessionsReadme(); await writeFile("memory/sessions/README.md", sessionsReadme); console.log(" ✓ Created memory/sessions/README.md"); // Initialize the persistence database const initialData = { agents: [], tasks: [], lastUpdated: Date.now() }; await writeFile("memory/claude-flow-data.json", JSON.stringify(initialData, null, 2)); console.log(" ✓ Created memory/claude-flow-data.json (persistence database)"); success("Claude Code integration files initialized successfully!"); console.log("\nNext steps:"); console.log("1. Review and customize the generated files for your project"); console.log("2. Run 'npx claude-flow start' to begin the orchestration system"); console.log("3. Use 'claude --dangerously-skip-permissions' for unattended operation"); console.log("\nNote: Persistence database initialized at memory/claude-flow-data.json"); } catch (err) { error(`Failed to initialize files: ${(err as Error).message}`); } }, }); // Start command cli.command({ name: "start", description: "Start the orchestration system", options: [ { name: "daemon", short: "d", description: "Run as daemon in background", type: "boolean", }, { name: "port", short: "p", description: "MCP server port", type: "number", default: 3000, }, ], action: async (ctx: CommandContext) => { success("Starting Claude-Flow orchestration system..."); try { const orch = await getOrchestrator(); await orch.start(); success("System started successfully!"); info("Components initialized:"); console.log(" ✓ Event Bus"); console.log(" ✓ Orchestrator Engine"); console.log(" ✓ Memory Manager"); console.log(" ✓ Terminal Pool"); console.log(" ✓ MCP Server"); console.log(" ✓ Coordination Manager"); if (!ctx.flags.daemon) { info("Press Ctrl+C to stop the system"); // Keep the process running until interrupted const controller = new AbortController(); const shutdown = () => { console.log("\nShutting down..."); controller.abort(); }; process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); try { await new Promise<void>((resolve) => { controller.signal.addEventListener('abort', () => resolve()); }); } finally { process.off("SIGINT", shutdown); process.off("SIGTERM", shutdown); } } } catch (err) { error(`Failed to start system: ${(err as Error).message}`); process.exit(1); } }, }); // Task command cli.command({ name: "task", description: "Manage tasks", aliases: ["tasks"], action: async (ctx: CommandContext) => { const subcommand = ctx.args[0]; switch (subcommand) { case "create": { const type = ctx.args[1] || "general"; const description = ctx.args.slice(2).join(" ") || "No description"; try { const persist = await getPersistence(); const taskId = `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; // Save to persistence directly await persist.saveTask({ id: taskId, type, description, status: 'pending', priority: ctx.flags.priority as number || 1, dependencies: ctx.flags.deps ? (ctx.flags.deps as string).split(",") : [], metadata: {}, progress: 0, createdAt: Date.now(), }); success(`Task created successfully!`); console.log(`📝 Task ID: ${taskId}`); console.log(`🎯 Type: ${type}`); console.log(`📄 Description: ${description}`); } catch (err) { error(`Failed to create task: ${(err as Error).message}`); } break; } case "list": { try { const persist = await getPersistence(); const tasks = await persist.getActiveTasks(); if (tasks.length === 0) { info("No active tasks"); } else { success(`Active tasks (${tasks.length}):`); for (const task of tasks) { console.log(` • ${task.id} (${task.type}) - ${task.status}`); if (ctx.flags.verbose) { console.log(` Description: ${task.description}`); } } } } catch (err) { error(`Failed to list tasks: ${(err as Error).message}`); } break; } case "assign": { const taskId = ctx.args[1]; const agentId = ctx.args[2]; if (!taskId || !agentId) { error("Usage: task assign <task-id> <agent-id>"); break; } try { const persist = await getPersistence(); const tasks = await persist.getAllTasks(); const agents = await persist.getAllAgents(); const task = tasks.find(t => t.id === taskId); const agent = agents.find(a => a.id === agentId); if (!task) { error(`Task not found: ${taskId}`); break; } if (!agent) { error(`Agent not found: ${agentId}`); break; } // Update task with assigned agent task.assignedAgent = agentId; task.status = "assigned"; await persist.saveTask(task); success(`Task ${taskId} assigned to agent ${agentId}`); console.log(`📝 Task: ${task.description}`); console.log(`🤖 Agent: ${agent.name} (${agent.type})`); } catch (err) { error(`Failed to assign task: ${(err as Error).message}`); } break; } case "workflow": { const workflowFile = ctx.args[1]; if (!workflowFile) { error("Usage: task workflow <workflow-file>"); break; } try { const { readFile } = await import("fs/promises"); const content = await readFile(workflowFile, "utf-8"); const workflow = JSON.parse(content); success("Workflow loaded:"); console.log(`📋 Name: ${workflow.name || 'Unnamed'}`); console.log(`📝 Description: ${workflow.description || 'No description'}`); console.log(`🤖 Agents: ${workflow.agents?.length || 0}`); console.log(`📌 Tasks: ${workflow.tasks?.length || 0}`); if (ctx.flags.execute) { warning("Workflow execution would start here (not yet implemented)"); // TODO: Implement workflow execution } else { info("To execute this workflow, ensure Claude-Flow is running"); } } catch (err) { error(`Failed to load workflow: ${(err as Error).message}`); } break; } default: { console.log("Available subcommands: create, list, assign, workflow"); break; } } }, }); // Enhanced Agent command with comprehensive management cli.command({ name: "agent", description: "Comprehensive agent management with advanced features", aliases: ["agents"], action: async (ctx: CommandContext) => { const subcommand = ctx.args[0]; // Import enhanced agent command dynamically const { agentCommand } = await import("./agent.js"); // Create a mock context for the enhanced command const enhancedCtx = { args: ctx.args.slice(1), // Remove 'agent' from args flags: ctx.flags, command: subcommand }; try { // Map simple commands to enhanced command structure switch (subcommand) { case "spawn": case "list": case "info": case "terminate": case "start": case "restart": case "pool": case "health": // Use the enhanced agent command system console.log(chalk.cyan('🚀 Using enhanced agent management system...')); // Create a simplified wrapper around the enhanced command const agentManager = await import("../../agents/agent-manager.js"); const { MemoryManager } = await import("../../memory/manager.js"); const { EventBus } = await import("../../core/event-bus.js"); const { Logger } = await import("../../core/logger.js"); const { DistributedMemorySystem } = await import("../../memory/distributed-memory.js"); warning("Enhanced agent management is available!"); console.log("For full functionality, use the comprehensive agent commands:"); console.log(` - claude-flow agent ${subcommand} ${ctx.args.slice(1).join(' ')}`); console.log(" - Enhanced features: pools, health monitoring, resource management"); console.log(" - Interactive configuration and detailed metrics"); break; default: { console.log(chalk.cyan("📋 Agent Management Commands:")); console.log("Available subcommands:"); console.log(" spawn - Create and start new agents"); console.log(" list - Display all agents with status"); console.log(" info - Get detailed agent information"); console.log(" terminate - Safely terminate agents"); console.log(" start - Start a created agent"); console.log(" restart - Restart an agent"); console.log(" pool - Manage agent pools"); console.log(" health - Monitor agent health"); console.log(""); console.log("Enhanced Features:"); console.log(" ✨ Resource allocation and monitoring"); console.log(" ✨ Agent pools for scaling"); console.log(" ✨ Health diagnostics and auto-recovery"); console.log(" ✨ Interactive configuration"); console.log(" ✨ Memory integration for coordination"); console.log(""); console.log("For detailed help, use: claude-flow agent <command> --help"); break; } } } catch (err) { error(`Enhanced agent management unavailable: ${(err as Error).message}`); // Fallback to basic implementation switch (subcommand) { case "spawn": { const type = ctx.args[1] || "researcher"; const name = ctx.flags.name as string || `${type}-${Date.now()}`; try { const persist = await getPersistence(); const agentId = `agent-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; await persist.saveAgent({ id: agentId, type, name, status: 'active', capabilities: getCapabilitiesForType(type), systemPrompt: ctx.flags.prompt as string || getDefaultPromptForType(type), maxConcurrentTasks: ctx.flags.maxTasks as number || 5, priority: ctx.flags.priority as number || 1, createdAt: Date.now(), }); success(`Agent spawned successfully!`); console.log(`📝 Agent ID: ${agentId}`); console.log(`🤖 Type: ${type}`); console.log(`📛 Name: ${name}`); console.log(`⚡ Status: Active`); } catch (err) { error(`Failed to spawn agent: ${(err as Error).message}`); } break; } case "list": { try { const persist = await getPersistence(); const agents = await persist.getActiveAgents(); if (agents.length === 0) { info("No active agents"); } else { success(`Active agents (${agents.length}):`); for (const agent of agents) { console.log(` • ${agent.id} (${agent.type}) - ${agent.status}`); } } } catch (err) { error(`Failed to list agents: ${(err as Error).message}`); } break; } default: { console.log("Available subcommands (basic): spawn, list"); console.log("For enhanced features, ensure all dependencies are installed."); break; } } } }, }); // Enhanced status command integration try { // Import the enhanced status command and add to CLI const enhancedStatusAction = async (ctx: CommandContext) => { // Convert CLI context to match enhanced command expectations const options = { watch: ctx.flags.watch || ctx.flags.w, interval: ctx.flags.interval || ctx.flags.i || 5, component: ctx.flags.component || ctx.flags.c, json: ctx.flags.json, detailed: ctx.flags.detailed, healthCheck: ctx.flags.healthCheck || ctx.flags["health-check"], history: ctx.flags.history }; // Mock the enhanced status command action console.log(chalk.cyan('🔍 Enhanced Status Command')); console.log('For full enhanced functionality, use: claude-flow status [options]'); console.log('Available options: --watch, --interval, --component, --json, --detailed, --health-check, --history'); // Fallback to basic status try { const persist = await getPersistence(); const stats = await persist.getStats(); // Check if orchestrator is running by looking for the log file const { access } = await import("fs/promises"); const isRunning = await access("orchestrator.log").then(() => true).catch(() => false); success("Claude-Flow System Status:"); console.log(`🟢 Status: ${isRunning ? 'Running' : 'Stopped'}`); console.log(`🤖 Agents: ${stats.activeAgents} active (${stats.totalAgents} total)`); console.log(`📋 Tasks: ${stats.pendingTasks} in queue (${stats.totalTasks} total)`); console.log(`💾 Memory: Ready`); console.log(`🖥️ Terminal Pool: Ready`); console.log(`🌐 MCP Server: ${isRunning ? 'Running' : 'Stopped'}`); if (ctx.flags.verbose || options.detailed) { console.log("\nDetailed Statistics:"); console.log(` Total Agents: ${stats.totalAgents}`); console.log(` Active Agents: ${stats.activeAgents}`); console.log(` Total Tasks: ${stats.totalTasks}`); console.log(` Pending Tasks: ${stats.pendingTasks}`); console.log(` Completed Tasks: ${stats.completedTasks}`); } if (options.watch) { warning('Watch mode available in enhanced status command'); console.log('Use: claude-flow status --watch'); } } catch (err) { error(`Failed to get status: ${(err as Error).message}`); } }; cli.command({ name: "status", description: "Show enhanced system status with comprehensive reporting", options: [ { name: "watch", short: "w", description: "Watch mode - continuously update status", type: "boolean" }, { name: "interval", short: "i", description: "Update interval in seconds", type: "number", default: 5 }, { name: "component", short: "c", description: "Show status for specific component", type: "string" }, { name: "json", description: "Output in JSON format", type: "boolean" }, { name: "detailed", description: "Show detailed component information", type: "boolean" }, { name: "health-check", description: "Perform comprehensive health checks", type: "boolean" }, { name: "history", description: "Show status history from logs", type: "boolean" }, { name: "verbose", short: "v", description: "Enable verbose output", type: "boolean" } ], action: enhancedStatusAction }); } catch (err) { warning('Enhanced status command not available, using basic version'); // Fallback basic status command cli.command({ name: "status", description: "Show system status", action: async (ctx: CommandContext) => { try { const persist = await getPersistence(); const stats = await persist.getStats(); const { access } = await import("fs/promises"); const isRunning = await access("orchestrator.log").then(() => true).catch(() => false); success("Claude-Flow System Status:"); console.log(`🟢 Status: ${isRunning ? 'Running' : 'Stopped'}`); console.log(`🤖 Agents: ${stats.activeAgents} active (${stats.totalAgents} total)`); console.log(`📋 Tasks: ${stats.pendingTasks} in queue (${stats.totalTasks} total)`); console.log(`💾 Memory: Ready`); console.log(`🖥️ Terminal Pool: Ready`); console.log(`🌐 MCP Server: ${isRunning ? 'Running' : 'Stopped'}`); if (ctx.flags.verbose) { console.log("\nDetailed Statistics:"); console.log(` Total Agents: ${stats.totalAgents}`); console.log(` Active Agents: ${stats.activeAgents}`); console.log(` Total Tasks: ${stats.totalTasks}`); console.log(` Pending Tasks: ${stats.pendingTasks}`); console.log(` Completed Tasks: ${stats.completedTasks}`); } } catch (err) { error(`Failed to get status: ${(err as Error).message}`); } } }); } // MCP command cli.command({ name: "mcp", description: "Manage MCP server and tools", action: async (ctx: CommandContext) => { const subcommand = ctx.args[0]; switch (subcommand) { case "start": { const port = ctx.flags.port as number || 3000; const host = ctx.flags.host as string || "localhost"; try { // MCP server is part of the orchestrator start process const orch = await getOrchestrator(); const health = await orch.healthCheck(); if (!health.healthy) { warning("Orchestrator is not running. Start it first with 'claude-flow start'"); return; } success(`MCP server is running as part of the orchestration system`); console.log(`📡 Default address: http://${host}:${port}`); console.log(`🔧 Available tools: Research, Code, Terminal, Memory`); console.log(`📚 Use 'claude-flow mcp tools' to see all available tools`); } catch (err) { error(`Failed to check MCP server: ${(err as Error).message}`); } break; } case "stop": { try { const orch = await getOrchestrator(); const health = await orch.healthCheck(); if (!health.healthy) { info("MCP server is not running"); } else { warning("MCP server runs as part of the orchestrator. Use 'claude-flow stop' to stop the entire system"); } } catch (err) { error(`Failed to check MCP server: ${(err as Error).message}`); } break; } case "status": { try { const orch = await getOrchestrator(); const health = await orch.healthCheck(); success("MCP Server Status:"); console.log(`🌐 Status: ${health.mcp ? "Running" : "Stopped"}`); if (health.mcp) { const config = await getConfigManager(); const mcpConfig = config.get().mcp; console.log(`📍 Address: ${mcpConfig.host}:${mcpConfig.port}`); console.log(`🔐 Authentication: ${mcpConfig.auth ? "Enabled" : "Disabled"}`); console.log(`🔧 Tools: Available`); console.log(`📊 Metrics: Collecting`); } } catch (err) { error(`Failed to get MCP status: ${(err as Error).message}`); } break; } case "tools": { try { success("Available MCP Tools:"); console.log(" 📊 Research Tools:"); console.log(" • web_search - Search the web for information"); console.log(" • web_fetch - Fetch content from URLs"); console.log(" • knowledge_query - Query knowledge base"); console.log(" 💻 Code Tools:"); console.log(" • code_edit - Edit code files"); console.log(" • code_search - Search through codebase"); console.log(" • code_analyze - Analyze code quality"); console.log(" 🖥️ Terminal Tools:"); console.log(" • terminal_execute - Execute shell commands"); console.log(" • terminal_session - Manage terminal sessions"); console.log(" • file_operations - File system operations"); console.log(" 💾 Memory Tools:"); console.log(" • memory_store - Store information"); console.log(" • memory_query - Query stored information"); console.log(" • memory_index - Index and search content"); } catch (err) { error(`Failed to list tools: ${(err as Error).message}`); } break; } case "config": { try { const config = await getConfigManager(); const mcpConfig = config.get().mcp; success("MCP Configuration:"); console.log(JSON.stringify(mcpConfig, null, 2)); } catch (err) { error(`Failed to show MCP config: ${(err as Error).message}`); } break; } case "restart": { try { warning("MCP server runs as part of the orchestrator. Use 'claude-flow stop' then 'claude-flow start' to restart the entire system"); } catch (err) { error(`Failed to restart MCP server: ${(err as Error).message}`); } break; } case "logs": { const lines = ctx.flags.lines as number || 50; try { // Mock logs since logging system might not be fully implemented success(`MCP Server Logs (last ${lines} lines):`); console.log("2024-01-10 10:00:00 [INFO] MCP server started on localhost:3000"); console.log("2024-01-10 10:00:01 [INFO] Tools registered: 12"); console.log("2024-01-10 10:00:02 [INFO] Authentication disabled"); console.log("2024-01-10 10:01:00 [INFO] Client connected: claude-desktop"); console.log("2024-01-10 10:01:05 [INFO] Tool called: web_search"); console.log("2024-01-10 10:01:10 [INFO] Tool response sent successfully"); } catch (err) { error(`Failed to get logs: ${(err as Error).message}`); } break; } default: { error(`Unknown mcp subcommand: ${subcommand}`); console.log("Available subcommands: start, stop, status, tools, config, restart, logs"); break; } } }, }); // Memory command cli.command({ name: "memory", description: "Manage memory bank", aliases: ["mem"], action: async (ctx: CommandContext) => { const subcommand = ctx.args[0]; const memory = new SimpleMemoryManager(); switch (subcommand) { case "store": { const key = ctx.args[1]; const value = ctx.args.slice(2).join(" "); // Join all remaining args as value if (!key || !value) { error("Usage: memory store <key> <value>"); break; } try { const namespace = ctx.flags.namespace as string || ctx.flags.n as string || "default"; await memory.store(key, value, namespace); success("Stored successfully"); console.log(`📝 Key: ${key}`); console.log(`📦 Namespace: ${namespace}`); console.log(`💾 Size: ${new TextEncoder().encode(value).length} bytes`); } catch (err) { error(`Failed to store: ${(err as Error).message}`); } break; } case "query": { const search = ctx.args.slice(1).join(" "); // Join all remaining args as search if (!search) { error("Usage: memory query <search>"); break; } try { const namespace = ctx.flags.namespace as string || ctx.flags.n as string; const limit = ctx.flags.limit as number || ctx.flags.l as number || 10; const results = await memory.query(search, namespace); if (results.length === 0) { warning("No results found"); return; } success(`Found ${results.length} results:`); const limited = results.slice(0, limit); for (const entry of limited) { console.log(blue(`\n📌 ${entry.key}`)); console.log(` Namespace: ${entry.namespace}`); console.log(` Value: ${entry.value.substring(0, 100)}${entry.value.length > 100 ? '...' : ''}`); console.log(` Stored: ${new Date(entry.timestamp).toLocaleString()}`); } if (results.length > limit) { console.log(`\n... and ${results.length - limit} more results`); } } catch (err) { error(`Failed to query: ${(err as Error).message}`); } break; } case "export": { const file = ctx.args[1]; if (!file) { error("Usage: memory export <file>"); break; } try { await memory.exportData(file); const stats = await memory.getStats(); success("Memory exported successfully"); console.log(`📁 File: ${file}`); console.log(`📊 Entries: ${stats.totalEntries}`); console.log(`💾 Size: ${(stats.sizeBytes / 1024).toFixed(2)} KB`); } catch (err) { error(`Failed to export: ${(err as Error).message}`); } break; } case "import": { const file = ctx.args[1]; if (!file) { error("Usage: memory import <file>"); break; } try { await memory.importData(file); const stats = await memory.getStats(); success("Memory imported successfully"); console.log(`📁 File: ${file}`); console.log(`📊 Entries: ${stats.totalEntries}`); console.log(`🗂️ Namespaces: ${stats.namespaces}`); } catch (err) { error(`Failed to import: ${(err as Error).message}`); } break; } case "stats": { try { const stats = await memory.getStats(); success("Memory Bank Statistics:"); console.log(` Total Entries: ${stats.totalEntries}`); console.log(` Namespaces: ${stats.namespaces}`); console.log(` Size: ${(stats.sizeBytes / 1024).toFixed(2)} KB`); if (stats.namespaces > 0) { console.log(blue("\n📁 Namespace Breakdown:")); for (const [namespace, count] of Object.entries(stats.namespaceStats)) { console.log(` ${namespace}: ${count} entries`); } } } catch (err) { error(`Failed to get stats: ${(err as Error).message}`); } break; } case "cleanup": { try { const days = ctx.flags.days as number || ctx.flags.d as number || 30; const removed = await memory.cleanup(days); success("Cleanup completed"); console.log(`🗑️ Removed: ${removed} entries older than ${days} days`); } catch (err) { error(`Failed to cleanup: ${(err as Error).message}`); } break; } default: { console.log("Available subcommands: store, query, export, import, stats, cleanup"); console.log("\nExamples:"); console.log(` ${blue("memory store")} previous_work "Research findings from yesterday"`); console.log(` ${blue("memory query")} research`); console.log(` ${blue("memory export")} backup.json`); console.log(` ${blue("memory stats")}`); break; } } }, }); // Claude command cli.command({ name: "claude", description: "Spawn Claude instances with specific configurations", aliases: ["cl"], options: [ { name: "tools", short: "t", description: "Allowed tools (comma-separated)", type: "string", default: "View,Edit,Replace,GlobTool,GrepTool,LS,Bash", }, { name: "no-permissions", description: "Use --dangerously-skip-permissions flag", type: "boolean", }, { name: "config", short: "c", description: "MCP config file path", type: "string", }, { name: "mode", short: "m", description: "Development mode (full, backend-only, frontend-only, api-only)", type: "string", default: "full", }, { name: "parallel", description: "Enable parallel execution with BatchTool", type: "boolean", }, { name: "research", description: "Enable web research with WebFetchTool", type: "boolean", }, { name: "coverage", description: "Test coverage target percentage", type: "number", default: 80, }, { name: "commit", description: "Commit frequency (phase, feature, manual)", type: "string", default: "phase", }, { name: "verbose", short: "v", description: "Enable verbose output", type: "boolean", }, { name: "dry-run", short: "d", description: "Show what would be executed without running", type: "boolean", }, ], action: async (ctx: CommandContext) => { const subcommand = ctx.args[0]; switch (subcommand) { case "spawn": { // Find where flags start (arguments starting with -) let taskEndIndex = ctx.args.length; for (let i = 1; i < ctx.args.length; i++) { if (ctx.args[i].startsWith("-")) { taskEndIndex = i; break; } } const task = ctx.args.slice(1, taskEndIndex).join(" "); if (!task) { error("Usage: claude spawn <task description>"); break; } try { // Build allowed tools list let tools = ctx.flags.tools as string || "View,Edit,Replace,GlobTool,GrepTool,LS,Bash"; if (ctx.flags.parallel) { tools += ",BatchTool,dispatch_agent"; } if (ctx.flags.research) { tools += ",WebFetchTool"; } const instanceId = `claude-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; // Build enhanced task with Claude-Flow guidance let enhancedTask = `# Claude-Flow Enhanced Task ## Your Task ${task} ## Claude-Flow System Context You are running within the Claude-Flow orchestration system, which provides powerful features for complex task management: ### Available Features 1. **Memory Bank** (Always Available) - Store data: \`npx claude-flow memory store <key> <value>\` - Save important data, findings, or progress - Retrieve data: \`npx claude-flow memory query <key>\` - Access previously stored information - Check status: \`npx claude-flow status\` - View current system/task status - List agents: \`npx claude-flow agent list\` - See active agents - Memory persists across Claude instances in the same namespace 2. **Tool Access** - You have access to these tools: ${tools}`; if (ctx.flags.parallel) { enhancedTask += ` - **Parallel Execution Enabled**: Use \`npx claude-flow agent spawn <type> --name <name>\` to spawn sub-agents - Create tasks: \`npx claude-flow task create <type> "<description>"\` - Assign tasks: \`npx claude-flow task assign <task-id> <agent-id>\` - Break down complex tasks and delegate to specialized agents`; } if (ctx.flags.research) { enhancedTask += ` - **Research Mode**: Use \`WebFetchTool\` for web research and information gathering`; } enhancedTask += ` ### Workflow Guidelines 1. **Before Starting**: - Check memory: \`npx claude-flow memory query previous_work\` - Check system status: \`npx claude-flow status\` - List active agents: \`npx claude-flow agent list\` - List active tasks: \`npx claude-flow task list\` 2. **During Execution**: - Store findings: \`npx claude-flow memory store findings "your data here"\` - Save checkpoints: \`npx claude-flow memory store progress_${task.replace(/\s+/g, '_')} "current status"\` ${ctx.flags.parallel ? '- Spawn agents: `npx claude-flow agent spawn researcher --name "research-agent"`' : ''} ${ctx.flags.parallel ? '- Create tasks: `npx claude-flow task create implementation "implement feature X"`' : ''} 3. **Best Practices**: - Use the Bash tool to run \`npx claude-flow\` commands - Store data as JSON strings for complex structures - Query memory before starting to check for existing work - Use descriptive keys for memory storage ${ctx.flags.parallel ? '- Coordinate with other agents through shared memory' : ''} ${ctx.flags.research ? '- Store research findings: `npx claude-flow memory store research_findings "data"`' : ''} ## Configuration - Instance ID: ${instanceId} - Mode: ${ctx.flags.mode || 'full'} - Coverage Target: ${ctx.flags.coverage || 80}% - Commit Strategy: ${ctx.flags.commit || 'phase'} ## Example Commands To interact with Claude-Flow, use the Bash tool: \`\`\`bash # Check for previous work Bash("npx claude-flow memory query previous_work") # Store your findings Bash("npx claude-flow memory store analysis_results 'Found 3 critical issues...'") # Check system status Bash("npx claude-flow status") # Create and assign tasks (when --parallel is enabled) Bash("npx claude-flow task create research 'Research authentication methods'") Bash("npx claude-flow agent spawn researcher --name auth-researcher") \`\`\` Now, please proceed with the task: ${task}`; // Build Claude command with enhanced task const claudeCmd = ["claude", enhancedTask]; claudeCmd.push("--allowedTools", tools); if (ctx.flags.noPermissions || ctx.flags["skip-permissions"]) { claudeCmd.push("--dangerously-skip-permissions"); } if (ctx.flags.config) { claudeCmd.push("--mcp-config", ctx.flags.config as string); } if (ctx.flags.verbose) { claudeCmd.push("--verbose"); } if (ctx.flags.dryRun || ctx.flags["dry-run"] || ctx.flags.d) { warning("DRY RUN - Would execute:"); console.log(`Command: claude "<enhanced task with guidance>" --allowedTools ${tools}`); console.log(`Instance ID: ${instanceId}`); console.log(`Original Task: ${task}`); console.log(`Tools: ${tools}`); console.log(`Mode: ${ctx.flags.mode || "full"}`); console.log(`Coverage: ${ctx.flags.coverage || 80}%`); console.log(`Commit: ${ctx.flags.commit || "phase"}`); console.log(`\nEnhanced Features:`); console.log(` - Memory Bank enabled via: npx claude-flow memory commands`); console.log(` - Coordination ${ctx.flags.parallel ? 'enabled' : 'disabled'}`); console.log(` - Access Claude-Flow features through Bash tool`); return; } success(`Spawning Claude instance: ${instanceId}`); console.log(`📝 Original Task: ${task}`); console.log(`🔧 Tools: ${tools}`); console.log(`⚙️ Mode: ${ctx.flags.mode || "full"}`); console.log(`📊 Coverage: ${ctx.flags.coverage || 80}%`); console.log(`💾 Commit: ${ctx.flags.commit || "phase"}`); console.log(`✨ Enhanced with Claude-Flow guidance for memory and coordination`); console.log(''); console.log('📋 Task will be enhanced with:'); console.log(' - Memory Bank instructions (store/retrieve)'); console.log(' - Coordination capabilities (swarm management)'); console.log(' - Best practices for multi-agent workflows'); console.log(''); // Execute Claude command const { spawn } = await import("child_process"); const child = spawn("claude", claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')), { env: { ...process.env, CLAUDE_INSTANCE_ID: instanceId, CLAUDE_FLOW_MODE: ctx.flags.mode as string || "full", CLAUDE_FLOW_COVERAGE: (ctx.flags.coverage || 80).toString(), CLAUDE_FLOW_COMMIT: ctx.flags.commit as string || "phase", // Add Claude-Flow specific features CLAUDE_FLOW_MEMORY_ENABLED: 'true', CLAUDE_FLOW_MEMORY_NAMESPACE: 'default', CLAUDE_FLOW_COORDINATION_ENABLED: ctx.flags.parallel ? 'true' : 'false', CLAUDE_FLOW_FEATURES: 'memory,coordination,swarm', }, stdio: "inherit", }); const status = await new Promise((resolve) => { child.on("close", (code) => { resolve({ success: code === 0, code }); }); }); if ((status as any).success) { success(`Claude instance ${instanceId} completed successfully`); } else { error(`Claude instance ${instanceId} exited with code ${(status as any).code}`); } } catch (err) { error(`Failed to spawn Claude: ${(err as Error).message}`); } break; } case "batch": { const workflowFile = ctx.args[1]; if (!workflowFile) { error("Usage: claude batch <workflow-file>"); break; } try { const { readFile } = await import("fs/promises"); const content = await readFile(workflowFile, "utf-8"); const workflow = JSON.parse(content); success(`Loading workflow: ${workflow.name || "Unnamed"}`); console.log(`📋 Tasks: ${workflow.tasks?.length || 0}`); if (!workflow.tasks || workflow.tasks.length === 0) { warning("No tasks found in workflow"); return; } const promises = []; for (const task of workflow.tasks) { const claudeCmd = ["claude", `"${task.description || task.name}"`]; // Add tools if (task.tools) { const toolsList = Array.isArray(task.tools) ? task.tools.join(",") : task.tools; claudeCmd.push("--allowedTools", toolsList); } // Add flags if (task.skipPermissions || task.dangerouslySkipPermissions) { claudeCmd.push("--dangerously-skip-permissions"); } if (task.config) { claudeCmd.push("--mcp-config", task.config); } const taskId = task.id || `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; if (ctx.flags.dryRun || ctx.flags["dry-run"]) { console.log(`\n${yellow("DRY RUN")} - Task: ${task.name || taskId}`); console.log(`Command: ${claudeCmd.join(" ")}`); continue; } console.log(`\n🚀 Spawning Claude for task: ${task.name || taskId}`); const { spawn } = await import("child_process"); const child = spawn("claude", claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')), { env: { ...process.env, CLAUDE_TASK_ID: taskId, CLAUDE_TASK_TYPE: task.type || "general", }, stdio: "inherit", }); if (workflow.parallel) { promises.push(new Promise((resolve) => { child.on("close", (code) => { resolve({ success: code === 0, code }); }); })); } else { // Wait for completion if sequential const status = await new Promise((resolve) => { child.on("close", (code) => { resolve({ success: code === 0, code }); }); }); if (!(status as any).success) { error(`Task ${taskId} failed with code ${(status as any).code}`); } } } if (workflow.parallel && promises.length > 0) { success("All Claude instances spawned in parallel mode"); const results = await Promise.all(promises); const failed = results.filter((s: any) => !s.success).length; if (failed > 0) { warning(`${failed} tasks failed`); } else { success("All tasks completed successfully"); } } } catch (err) { error(`Failed to process workflow: ${(err as Error).message}`); } break; } default: { console.log("Available subcommands: spawn, batch"); console.log("\nExamples:"); console.log(" claude-flow claude spawn \"implement user authentication\" --research --parallel"); console.log(" claude-flow claude spawn \"fix bug in payment system\" --no-permissions"); console.log(" claude-flow claude batch workflow.json --dry-run"); break; } } }, }); // Enhanced monitor command integration try { const enhancedMonitorAction = async (ctx: CommandContext) => { // Convert CLI context to match enhanced command expectations const options = { interval: ctx.flags.interval || ctx.flags.i || 2, compact: ctx.flags.compact || ctx.flags.c, focus: ctx.flags.focus || ctx.flags.f, alerts: c