UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

1,152 lines (1,135 loc) • 52.5 kB
/** * V3 CLI Hive Mind Command * Queen-led consensus-based multi-agent coordination * * Updated to support --claude flag for launching interactive Claude Code sessions * PR: Fix #955 - Implement --claude flag for hive-mind spawn command */ import { output } from '../output.js'; import { select, confirm, input } from '../prompt.js'; import { callMCPTool, MCPClientError } from '../mcp-client.js'; import { spawn as childSpawn, execSync } from 'child_process'; import { mkdir, writeFile } from 'fs/promises'; import { join } from 'path'; // Hive topologies const TOPOLOGIES = [ { value: 'hierarchical', label: 'Hierarchical', hint: 'Queen-led with worker agents' }, { value: 'mesh', label: 'Mesh', hint: 'Peer-to-peer coordination' }, { value: 'hierarchical-mesh', label: 'Hierarchical Mesh', hint: 'Queen + peer communication (recommended)' }, { value: 'adaptive', label: 'Adaptive', hint: 'Dynamic topology based on task' } ]; // Consensus strategies const CONSENSUS_STRATEGIES = [ { value: 'byzantine', label: 'Byzantine Fault Tolerant', hint: '2/3 majority, handles malicious actors' }, { value: 'raft', label: 'Raft', hint: 'Leader-based consensus' }, { value: 'gossip', label: 'Gossip', hint: 'Eventually consistent, scalable' }, { value: 'crdt', label: 'CRDT', hint: 'Conflict-free replicated data' }, { value: 'quorum', label: 'Quorum', hint: 'Simple majority voting' } ]; /** * Group workers by their type for prompt generation */ function groupWorkersByType(workers) { const groups = {}; for (const worker of workers) { const type = worker.type || worker.role || 'worker'; if (!groups[type]) { groups[type] = []; } groups[type].push(worker); } return groups; } /** * Generate comprehensive Hive Mind prompt for Claude Code * Ported from v2.7.47 with enhancements for v3 */ function generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags) { const currentTime = new Date().toISOString(); const workerTypes = Object.keys(workerGroups); const queenType = flags.queenType || 'strategic'; const consensusAlgorithm = flags.consensus || 'byzantine'; const topology = flags.topology || 'hierarchical-mesh'; return `🧠 HIVE MIND COLLECTIVE INTELLIGENCE SYSTEM ═══════════════════════════════════════════════ You are the Queen coordinator of a Hive Mind swarm with collective intelligence capabilities. HIVE MIND CONFIGURATION: šŸ“Œ Swarm ID: ${swarmId} šŸ“Œ Swarm Name: ${swarmName} šŸŽÆ Objective: ${objective} šŸ‘‘ Queen Type: ${queenType} šŸ Worker Count: ${workers.length} šŸ”— Topology: ${topology} šŸ¤ Consensus Algorithm: ${consensusAlgorithm} ā° Initialized: ${currentTime} WORKER DISTRIBUTION: ${workerTypes.map(type => `• ${type}: ${workerGroups[type].length} agents`).join('\n')} šŸ”§ AVAILABLE MCP TOOLS FOR HIVE MIND COORDINATION: 1ļøāƒ£ **COLLECTIVE INTELLIGENCE** mcp__claude-flow__hive-mind_consensus - Democratic decision making mcp__claude-flow__hive-mind_memory - Share knowledge across the hive mcp__claude-flow__hive-mind_broadcast - Broadcast to all workers mcp__claude-flow__neural_patterns - Neural pattern recognition 2ļøāƒ£ **QUEEN COORDINATION** mcp__claude-flow__hive-mind_status - Monitor swarm health mcp__claude-flow__task_create - Create and delegate tasks mcp__claude-flow__task_orchestrate - Orchestrate task distribution mcp__claude-flow__agent_spawn - Spawn additional workers 3ļøāƒ£ **WORKER MANAGEMENT** mcp__claude-flow__agent_list - List all active agents mcp__claude-flow__agent_status - Check agent status mcp__claude-flow__agent_metrics - Track worker performance mcp__claude-flow__hive-mind_join - Add agent to hive mcp__claude-flow__hive-mind_leave - Remove agent from hive 4ļøāƒ£ **TASK ORCHESTRATION** mcp__claude-flow__task_create - Create hierarchical tasks mcp__claude-flow__task_status - Track task progress mcp__claude-flow__task_complete - Mark tasks complete mcp__claude-flow__workflow_create - Create workflows 5ļøāƒ£ **MEMORY & LEARNING** mcp__claude-flow__memory_store - Store collective knowledge mcp__claude-flow__memory_retrieve - Access shared memory mcp__claude-flow__memory_search - Search memory patterns mcp__claude-flow__neural_train - Learn from experiences mcp__claude-flow__hooks_intelligence_pattern-store - Store patterns šŸ“‹ HIVE MIND EXECUTION PROTOCOL: 1. **INITIALIZATION PHASE** - Verify all workers are online and responsive - Establish communication channels - Load previous session state if available - Initialize shared memory space 2. **TASK DISTRIBUTION PHASE** - Analyze the objective and decompose into subtasks - Assign tasks based on worker specializations - Set up task dependencies and ordering - Monitor parallel execution 3. **COORDINATION PHASE** - Use consensus for critical decisions - Aggregate results from workers - Resolve conflicts using ${consensusAlgorithm} consensus - Share learnings across the hive 4. **COMPLETION PHASE** - Verify all subtasks are complete - Consolidate results - Store learnings in collective memory - Report final status šŸŽÆ YOUR OBJECTIVE: ${objective} šŸ’” COORDINATION TIPS: • Use mcp__claude-flow__hive-mind_broadcast for swarm-wide announcements • Check worker status regularly with mcp__claude-flow__hive-mind_status • Store important decisions in shared memory for persistence • Use consensus for any decisions affecting multiple workers • Monitor task progress and reassign if workers are blocked šŸš€ BEGIN HIVE MIND COORDINATION NOW! Start by checking the current hive status and then proceed with the objective. `; } /** * Spawn Claude Code with Hive Mind coordination instructions * Ported from v2.7.47 spawnClaudeCodeInstances function */ async function spawnClaudeCodeInstance(swarmId, swarmName, objective, workers, flags) { output.writeln(); output.writeln(output.bold('šŸš€ Launching Claude Code with Hive Mind Coordination')); output.writeln(output.dim('─'.repeat(60))); const spinner = output.createSpinner({ text: 'Preparing Hive Mind coordination prompt...', spinner: 'dots' }); spinner.start(); try { // Generate comprehensive Hive Mind prompt const workerGroups = groupWorkersByType(workers); const hiveMindPrompt = generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags); spinner.succeed('Hive Mind coordination prompt ready!'); // Display coordination summary output.writeln(); output.writeln(output.bold('🧠 Hive Mind Configuration')); output.writeln(output.dim('─'.repeat(60))); output.printList([ `Swarm ID: ${output.highlight(swarmId)}`, `Objective: ${output.highlight(objective)}`, `Queen Type: ${output.highlight(flags.queenType || 'strategic')}`, `Worker Count: ${output.highlight(String(workers.length))}`, `Worker Types: ${output.highlight(Object.keys(workerGroups).join(', '))}`, `Consensus: ${output.highlight(flags.consensus || 'byzantine')}`, `MCP Tools: ${output.success('Full Claude-Flow integration enabled')}` ]); // Ensure sessions directory exists const sessionsDir = join('.hive-mind', 'sessions'); await mkdir(sessionsDir, { recursive: true }); const promptFile = join(sessionsDir, `hive-mind-prompt-${swarmId}.txt`); await writeFile(promptFile, hiveMindPrompt, 'utf8'); output.writeln(); output.printSuccess(`Hive Mind prompt saved to: ${promptFile}`); // Check if claude command exists let claudeAvailable = false; try { execSync('which claude', { stdio: 'ignore' }); claudeAvailable = true; } catch { output.writeln(); output.printWarning('Claude Code CLI not found in PATH'); output.writeln(output.dim('Install it with: npm install -g @anthropic-ai/claude-code')); output.writeln(output.dim('Falling back to displaying instructions...')); } const dryRun = flags.dryRun || flags['dry-run']; if (claudeAvailable && !dryRun) { // Build arguments - flags first, then prompt const claudeArgs = []; // Check for non-interactive mode const isNonInteractive = flags['non-interactive'] || flags.nonInteractive; if (isNonInteractive) { claudeArgs.push('-p'); // Print mode claudeArgs.push('--output-format', 'stream-json'); claudeArgs.push('--verbose'); output.printInfo('Running in non-interactive mode'); } // Add auto-permission flag unless explicitly disabled const skipPermissions = flags['dangerously-skip-permissions'] !== false && !flags['no-auto-permissions']; if (skipPermissions) { claudeArgs.push('--dangerously-skip-permissions'); if (!isNonInteractive) { output.printWarning('Using --dangerously-skip-permissions for seamless hive-mind execution'); } } // Add the prompt as the LAST argument claudeArgs.push(hiveMindPrompt); output.writeln(); output.printInfo('Launching Claude Code...'); output.writeln(output.dim('Press Ctrl+C to pause the session')); // Spawn claude with properly ordered arguments const claudeProcess = childSpawn('claude', claudeArgs, { stdio: 'inherit', shell: false, }); // Set up SIGINT handler for session management let isExiting = false; const sigintHandler = () => { if (isExiting) return; isExiting = true; output.writeln(); output.writeln(); output.printWarning('Pausing session and terminating Claude Code...'); if (claudeProcess && !claudeProcess.killed) { claudeProcess.kill('SIGTERM'); } output.writeln(); output.printSuccess('Session paused'); output.writeln(output.dim(`Prompt file saved at: ${promptFile}`)); output.writeln(output.dim('To resume, run claude with the saved prompt file')); process.exit(0); }; process.on('SIGINT', sigintHandler); process.on('SIGTERM', sigintHandler); // Handle process exit claudeProcess.on('exit', (code) => { // Clean up signal handlers process.removeListener('SIGINT', sigintHandler); process.removeListener('SIGTERM', sigintHandler); if (code === 0) { output.writeln(); output.printSuccess('Claude Code completed successfully'); } else if (code !== null) { output.writeln(); output.printError(`Claude Code exited with code ${code}`); } }); output.writeln(); output.printSuccess('Claude Code launched with Hive Mind coordination'); output.printInfo('The Queen coordinator will orchestrate all worker agents'); output.writeln(output.dim(`Prompt file saved at: ${promptFile}`)); return { success: true, promptFile }; } else if (dryRun) { output.writeln(); output.printInfo('Dry run - would execute Claude Code with prompt:'); output.writeln(output.dim(`Prompt length: ${hiveMindPrompt.length} characters`)); output.writeln(); output.writeln(output.dim('First 500 characters of prompt:')); output.writeln(output.highlight(hiveMindPrompt.substring(0, 500) + '...')); output.writeln(); output.writeln(output.dim(`Full prompt saved to: ${promptFile}`)); return { success: true, promptFile }; } else { // Claude not available - show instructions output.writeln(); output.writeln(output.bold('šŸ“‹ Manual Execution Instructions:')); output.writeln(output.dim('─'.repeat(50))); output.printList([ 'Install Claude Code: npm install -g @anthropic-ai/claude-code', `Run with saved prompt: claude < ${promptFile}`, `Or copy manually: cat ${promptFile} | claude`, `With auto-permissions: claude --dangerously-skip-permissions < ${promptFile}` ]); return { success: true, promptFile }; } } catch (error) { spinner.fail('Failed to prepare Claude Code coordination'); const errorMessage = error instanceof Error ? error.message : String(error); output.printError(`Error: ${errorMessage}`); // Try to save prompt as fallback try { const promptFile = `hive-mind-prompt-${swarmId}-fallback.txt`; const workerGroups = groupWorkersByType(workers); const hiveMindPrompt = generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags); await writeFile(promptFile, hiveMindPrompt, 'utf8'); output.writeln(); output.printSuccess(`Prompt saved to: ${promptFile}`); output.writeln(output.dim('You can run Claude Code manually with the saved prompt')); return { success: false, promptFile, error: errorMessage }; } catch { return { success: false, error: errorMessage }; } } } // Init subcommand const initCommand = { name: 'init', description: 'Initialize a hive mind', options: [ { name: 'topology', short: 't', description: 'Hive topology', type: 'string', choices: TOPOLOGIES.map(t => t.value), default: 'hierarchical-mesh' }, { name: 'consensus', short: 'c', description: 'Consensus strategy', type: 'string', choices: CONSENSUS_STRATEGIES.map(s => s.value), default: 'byzantine' }, { name: 'max-agents', short: 'm', description: 'Maximum agents', type: 'number', default: 15 }, { name: 'persist', short: 'p', description: 'Enable persistent state', type: 'boolean', default: true }, { name: 'memory-backend', description: 'Memory backend (agentdb, sqlite, hybrid)', type: 'string', default: 'hybrid' } ], examples: [ { command: 'claude-flow hive-mind init -t hierarchical-mesh', description: 'Init hierarchical mesh' }, { command: 'claude-flow hive-mind init -c byzantine -m 20', description: 'Init with Byzantine consensus' } ], action: async (ctx) => { let topology = ctx.flags.topology; let consensus = ctx.flags.consensus; if (ctx.interactive && !ctx.flags.topology) { topology = await select({ message: 'Select hive topology:', options: TOPOLOGIES, default: 'hierarchical-mesh' }); } if (ctx.interactive && !ctx.flags.consensus) { consensus = await select({ message: 'Select consensus strategy:', options: CONSENSUS_STRATEGIES, default: 'byzantine' }); } const config = { topology: topology || 'hierarchical-mesh', consensus: consensus || 'byzantine', maxAgents: ctx.flags.maxAgents || 15, persist: ctx.flags.persist, memoryBackend: ctx.flags.memoryBackend || 'hybrid' }; output.writeln(); output.writeln(output.bold('Initializing Hive Mind')); const spinner = output.createSpinner({ text: 'Setting up hive infrastructure...', spinner: 'dots' }); spinner.start(); try { const result = await callMCPTool('hive-mind_init', config); spinner.succeed('Hive Mind initialized'); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } output.writeln(); output.printBox([ `Hive ID: ${result.hiveId ?? 'default'}`, `Queen ID: ${result.queenId ?? 'N/A'}`, `Topology: ${result.topology ?? config.topology}`, `Consensus: ${result.consensus ?? config.consensus}`, `Max Agents: ${config.maxAgents}`, `Memory: ${config.memoryBackend}`, `Status: ${output.success(result.status ?? 'initialized')}` ].join('\n'), 'Hive Mind Configuration'); output.writeln(); output.printInfo('Queen agent is ready to coordinate worker agents'); output.writeln(output.dim(' Use "claude-flow hive-mind spawn" to add workers')); output.writeln(output.dim(' Use "claude-flow hive-mind spawn --claude" to launch Claude Code')); return { success: true, data: result }; } catch (error) { spinner.fail('Failed to initialize'); if (error instanceof MCPClientError) { output.printError(`Init error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Spawn subcommand - UPDATED with --claude flag const spawnCommand = { name: 'spawn', description: 'Spawn worker agents into the hive (use --claude to launch Claude Code)', options: [ { name: 'count', short: 'n', description: 'Number of workers to spawn', type: 'number', default: 1 }, { name: 'role', short: 'r', description: 'Worker role (worker, specialist, scout)', type: 'string', choices: ['worker', 'specialist', 'scout'], default: 'worker' }, { name: 'type', short: 't', description: 'Agent type', type: 'string', default: 'worker' }, { name: 'prefix', short: 'p', description: 'Prefix for worker IDs', type: 'string', default: 'hive-worker' }, // NEW: --claude flag for launching Claude Code { name: 'claude', description: 'Launch Claude Code with hive-mind coordination prompt', type: 'boolean', default: false }, { name: 'objective', short: 'o', description: 'Objective for the hive mind (used with --claude)', type: 'string' }, { name: 'dangerously-skip-permissions', description: 'Skip permission prompts in Claude Code (use with caution)', type: 'boolean', default: true }, { name: 'no-auto-permissions', description: 'Disable automatic permission skipping', type: 'boolean', default: false }, { name: 'dry-run', description: 'Show what would be done without launching Claude Code', type: 'boolean', default: false }, { name: 'non-interactive', description: 'Run Claude Code in non-interactive mode', type: 'boolean', default: false } ], examples: [ { command: 'claude-flow hive-mind spawn -n 5', description: 'Spawn 5 workers' }, { command: 'claude-flow hive-mind spawn -n 3 -r specialist', description: 'Spawn 3 specialists' }, { command: 'claude-flow hive-mind spawn -t coder -p my-coder', description: 'Spawn coder with custom prefix' }, { command: 'claude-flow hive-mind spawn --claude -o "Build a REST API"', description: 'Launch Claude Code with objective' }, { command: 'claude-flow hive-mind spawn -n 5 --claude -o "Research AI patterns"', description: 'Spawn workers and launch Claude Code' } ], action: async (ctx) => { // Parse count with fallback to default const count = ctx.flags.count || 1; const role = ctx.flags.role || 'worker'; const agentType = ctx.flags.type || 'worker'; const prefix = ctx.flags.prefix || 'hive-worker'; const launchClaude = ctx.flags.claude; let objective = ctx.flags.objective || ctx.args.join(' '); output.printInfo(`Spawning ${count} ${role} agent(s)...`); try { const result = await callMCPTool('hive-mind_spawn', { count, role, agentType, prefix, }); // Check for errors from MCP tool if (!result.success) { output.printError(result.error || 'Failed to spawn workers'); return { success: false, exitCode: 1 }; } if (ctx.flags.format === 'json' && !launchClaude) { output.printJson(result); return { success: true, data: result }; } output.writeln(); // Transform workers array to display format const displayData = (result.workers || []).map(w => ({ id: w.agentId, role: w.role, status: 'idle', joinedAt: new Date(w.joinedAt).toLocaleTimeString() })); output.printTable({ columns: [ { key: 'id', header: 'Agent ID', width: 30 }, { key: 'role', header: 'Role', width: 12 }, { key: 'status', header: 'Status', width: 10, format: formatAgentStatus }, { key: 'joinedAt', header: 'Joined', width: 12 } ], data: displayData }); output.writeln(); output.printSuccess(`Spawned ${result.spawned} agent(s)`); output.writeln(output.dim(` Total workers in hive: ${result.totalWorkers}`)); // NEW: Handle --claude flag if (launchClaude) { // Get objective if not provided if (!objective && ctx.interactive) { objective = await input({ message: 'Enter the objective for the hive mind:', validate: (v) => v.length > 0 || 'Objective is required when using --claude' }); } if (!objective) { output.writeln(); output.printWarning('No objective provided. Using default objective.'); objective = 'Coordinate the hive mind workers to complete tasks efficiently.'; } // Get hive status for swarm info let swarmId = result.hiveId || 'default'; let swarmName = 'Hive Mind Swarm'; try { const statusResult = await callMCPTool('hive-mind_status', { includeWorkers: false }); swarmId = statusResult.hiveId || swarmId; } catch { // Use defaults if status call fails } // Convert workers to expected format const workers = (result.workers || []).map(w => ({ agentId: w.agentId, role: w.role, type: agentType, joinedAt: w.joinedAt })); // Launch Claude Code with hive mind prompt const claudeResult = await spawnClaudeCodeInstance(swarmId, swarmName, objective, workers, ctx.flags); if (!claudeResult.success) { return { success: false, exitCode: 1, data: { spawn: result, claude: claudeResult } }; } return { success: true, data: { spawn: result, claude: claudeResult } }; } return { success: true, data: result }; } catch (error) { if (error instanceof MCPClientError) { output.printError(`Spawn error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Status subcommand const statusCommand = { name: 'status', description: 'Show hive mind status', options: [ { name: 'detailed', short: 'd', description: 'Show detailed metrics', type: 'boolean', default: false }, { name: 'watch', short: 'w', description: 'Watch for changes', type: 'boolean', default: false } ], action: async (ctx) => { const detailed = ctx.flags.detailed; try { const result = await callMCPTool('hive-mind_status', { includeMetrics: detailed, includeWorkers: true, }); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } // Handle both simple and complex response formats - cast to flexible type const flexResult = result; const hiveId = result.hiveId ?? flexResult.id ?? 'default'; const status = result.status ?? (flexResult.initialized ? 'running' : 'stopped'); const queen = result.queen ?? { id: 'N/A', status: 'unknown', load: 0, tasksQueued: 0 }; const flexQueen = queen; const queenId = typeof queen === 'object' ? (queen.id ?? flexQueen.agentId ?? 'N/A') : String(queen); const queenLoad = typeof queen === 'object' ? (queen.load ?? 0) : 0; const queenTasks = typeof queen === 'object' ? (queen.tasksQueued ?? 0) : 0; const queenStatus = typeof queen === 'object' ? (queen.status ?? 'active') : 'active'; output.writeln(); output.printBox([ `Hive ID: ${hiveId}`, `Status: ${formatHiveStatus(String(status))}`, `Topology: ${result.topology ?? 'mesh'}`, `Consensus: ${result.consensus ?? 'byzantine'}`, '', `Queen: ${queenId}`, ` Status: ${formatAgentStatus(queenStatus)}`, ` Load: ${(queenLoad * 100).toFixed(1)}%`, ` Queued Tasks: ${queenTasks}` ].join('\n'), 'Hive Mind Status'); // Handle workers array - could be worker objects or just IDs const workers = result.workers ?? []; const workerData = Array.isArray(workers) ? workers.map(w => { if (typeof w === 'string') { return { id: w, type: 'worker', status: 'idle', currentTask: '-', tasksCompleted: 0 }; } const flexWorker = w; return { id: w.id ?? flexWorker.agentId ?? 'unknown', type: w.type ?? flexWorker.agentType ?? 'worker', status: w.status ?? 'idle', currentTask: w.currentTask ?? '-', tasksCompleted: w.tasksCompleted ?? 0 }; }) : []; output.writeln(); output.writeln(output.bold('Worker Agents')); if (workerData.length === 0) { output.printInfo('No workers in hive. Use "claude-flow hive-mind spawn" to add workers.'); } else { output.printTable({ columns: [ { key: 'id', header: 'ID', width: 20 }, { key: 'type', header: 'Type', width: 12 }, { key: 'status', header: 'Status', width: 10, format: formatAgentStatus }, { key: 'currentTask', header: 'Current Task', width: 20, format: (v) => String(v || '-') }, { key: 'tasksCompleted', header: 'Completed', width: 10, align: 'right' } ], data: workerData }); } if (detailed) { const metrics = result.metrics ?? { totalTasks: 0, completedTasks: 0, failedTasks: 0, avgTaskTime: 0, consensusRounds: 0, memoryUsage: '0 MB' }; output.writeln(); output.writeln(output.bold('Metrics')); output.printTable({ columns: [ { key: 'metric', header: 'Metric', width: 20 }, { key: 'value', header: 'Value', width: 15, align: 'right' } ], data: [ { metric: 'Total Tasks', value: metrics.totalTasks ?? 0 }, { metric: 'Completed', value: metrics.completedTasks ?? 0 }, { metric: 'Failed', value: metrics.failedTasks ?? 0 }, { metric: 'Avg Task Time', value: `${(metrics.avgTaskTime ?? 0).toFixed(1)}ms` }, { metric: 'Consensus Rounds', value: metrics.consensusRounds ?? 0 }, { metric: 'Memory Usage', value: metrics.memoryUsage ?? '0 MB' } ] }); const health = result.health ?? { overall: 'healthy', queen: 'healthy', workers: 'healthy', consensus: 'healthy', memory: 'healthy' }; output.writeln(); output.writeln(output.bold('Health')); output.printList([ `Overall: ${formatHealth(health.overall ?? 'healthy')}`, `Queen: ${formatHealth(health.queen ?? 'healthy')}`, `Workers: ${formatHealth(health.workers ?? 'healthy')}`, `Consensus: ${formatHealth(health.consensus ?? 'healthy')}`, `Memory: ${formatHealth(health.memory ?? 'healthy')}` ]); } return { success: true, data: result }; } catch (error) { if (error instanceof MCPClientError) { output.printError(`Status error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Task subcommand const taskCommand = { name: 'task', description: 'Submit tasks to the hive', options: [ { name: 'description', short: 'd', description: 'Task description', type: 'string' }, { name: 'priority', short: 'p', description: 'Task priority', type: 'string', choices: ['low', 'normal', 'high', 'critical'], default: 'normal' }, { name: 'require-consensus', short: 'c', description: 'Require consensus for completion', type: 'boolean', default: false }, { name: 'timeout', description: 'Task timeout in seconds', type: 'number', default: 300 } ], examples: [ { command: 'claude-flow hive-mind task -d "Implement auth module"', description: 'Submit task' }, { command: 'claude-flow hive-mind task -d "Security review" -p critical -c', description: 'Critical task with consensus' } ], action: async (ctx) => { let description = ctx.flags.description || ctx.args.join(' '); if (!description && ctx.interactive) { description = await input({ message: 'Task description:', validate: (v) => v.length > 0 || 'Description is required' }); } if (!description) { output.printError('Task description is required'); return { success: false, exitCode: 1 }; } const priority = ctx.flags.priority; const requireConsensus = ctx.flags.requireConsensus; const timeout = ctx.flags.timeout; output.printInfo('Submitting task to hive...'); try { const result = await callMCPTool('hive-mind_task', { description, priority, requireConsensus, timeout, }); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } output.writeln(); output.printBox([ `Task ID: ${result.taskId}`, `Status: ${formatAgentStatus(result.status)}`, `Priority: ${formatPriority(priority)}`, `Assigned: ${result.assignedTo.join(', ')}`, `Consensus: ${result.requiresConsensus ? 'Yes' : 'No'}`, `Est. Time: ${result.estimatedTime}` ].join('\n'), 'Task Submitted'); output.writeln(); output.printSuccess('Task submitted to hive'); output.writeln(output.dim(` Track with: claude-flow hive-mind task-status ${result.taskId}`)); return { success: true, data: result }; } catch (error) { if (error instanceof MCPClientError) { output.printError(`Task submission error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Optimize memory subcommand const optimizeMemoryCommand = { name: 'optimize-memory', description: 'Optimize hive memory and patterns', options: [ { name: 'aggressive', short: 'a', description: 'Aggressive optimization', type: 'boolean', default: false }, { name: 'threshold', description: 'Quality threshold for pattern retention', type: 'number', default: 0.7 } ], action: async (ctx) => { const aggressive = ctx.flags.aggressive; const threshold = ctx.flags.threshold; output.printInfo('Optimizing hive memory...'); const spinner = output.createSpinner({ text: 'Analyzing patterns...', spinner: 'dots' }); spinner.start(); try { const result = await callMCPTool('hive-mind_optimize-memory', { aggressive, qualityThreshold: threshold, }); spinner.succeed('Memory optimized'); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } output.writeln(); output.printTable({ columns: [ { key: 'metric', header: 'Metric', width: 20 }, { key: 'before', header: 'Before', width: 15, align: 'right' }, { key: 'after', header: 'After', width: 15, align: 'right' } ], data: [ { metric: 'Patterns', before: result.before.patterns, after: result.after.patterns }, { metric: 'Memory', before: result.before.memory, after: result.after.memory } ] }); output.writeln(); output.printList([ `Patterns removed: ${result.removed}`, `Patterns consolidated: ${result.consolidated}`, `Optimization time: ${result.timeMs}ms` ]); return { success: true, data: result }; } catch (error) { spinner.fail('Optimization failed'); if (error instanceof MCPClientError) { output.printError(`Optimization error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Join subcommand const joinCommand = { name: 'join', description: 'Join an agent to the hive mind', options: [ { name: 'agent-id', short: 'a', description: 'Agent ID to join', type: 'string' }, { name: 'role', short: 'r', description: 'Agent role (worker, specialist, scout)', type: 'string', default: 'worker' } ], action: async (ctx) => { const agentId = ctx.args[0] || ctx.flags['agent-id'] || ctx.flags.agentId; if (!agentId) { output.printError('Agent ID is required. Use --agent-id or -a flag, or provide as argument.'); return { success: false, exitCode: 1 }; } try { const result = await callMCPTool('hive-mind_join', { agentId, role: ctx.flags.role }); if (!result.success) { output.printError(result.error || 'Failed'); return { success: false, exitCode: 1 }; } output.printSuccess(`Agent ${agentId} joined hive (${result.totalWorkers} workers)`); return { success: true, data: result }; } catch (error) { output.printError(`Join error: ${error instanceof MCPClientError ? error.message : String(error)}`); return { success: false, exitCode: 1 }; } } }; // Leave subcommand const leaveCommand = { name: 'leave', description: 'Remove an agent from the hive mind', options: [{ name: 'agent-id', short: 'a', description: 'Agent ID to remove', type: 'string' }], action: async (ctx) => { const agentId = ctx.args[0] || ctx.flags['agent-id'] || ctx.flags.agentId; if (!agentId) { output.printError('Agent ID required.'); return { success: false, exitCode: 1 }; } try { const result = await callMCPTool('hive-mind_leave', { agentId }); if (!result.success) { output.printError(result.error || 'Failed'); return { success: false, exitCode: 1 }; } output.printSuccess(`Agent ${agentId} left hive (${result.remainingWorkers} remaining)`); return { success: true, data: result }; } catch (error) { output.printError(`Leave error: ${error instanceof MCPClientError ? error.message : String(error)}`); return { success: false, exitCode: 1 }; } } }; // Consensus subcommand const consensusCommand = { name: 'consensus', description: 'Manage consensus proposals and voting', options: [ { name: 'action', short: 'a', description: 'Consensus action', type: 'string', choices: ['propose', 'vote', 'status', 'list'], default: 'list' }, { name: 'proposal-id', short: 'p', description: 'Proposal ID', type: 'string' }, { name: 'type', short: 't', description: 'Proposal type', type: 'string' }, { name: 'value', description: 'Proposal value', type: 'string' }, { name: 'vote', short: 'v', description: 'Vote (yes/no)', type: 'string' }, { name: 'voter-id', description: 'Voter agent ID', type: 'string' } ], action: async (ctx) => { const action = ctx.flags.action || 'list'; try { const result = await callMCPTool('hive-mind_consensus', { action, proposalId: ctx.flags.proposalId, type: ctx.flags.type, value: ctx.flags.value, vote: ctx.flags.vote === 'yes', voterId: ctx.flags.voterId }); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } if (action === 'list') { output.writeln(output.bold('\nPending Proposals')); const pending = result.pending || []; if (pending.length === 0) output.printInfo('No pending proposals'); else output.printTable({ columns: [{ key: 'proposalId', header: 'ID', width: 30 }, { key: 'type', header: 'Type', width: 12 }], data: pending }); } else if (action === 'propose') { output.printSuccess(`Proposal created: ${result.proposalId}`); } else if (action === 'vote') { output.printSuccess(`Vote recorded (For: ${result.votesFor}, Against: ${result.votesAgainst})`); } return { success: true, data: result }; } catch (error) { output.printError(`Consensus error: ${error instanceof MCPClientError ? error.message : String(error)}`); return { success: false, exitCode: 1 }; } } }; // Broadcast subcommand const broadcastCommand = { name: 'broadcast', description: 'Broadcast a message to all workers in the hive', options: [ { name: 'message', short: 'm', description: 'Message to broadcast', type: 'string', required: true }, { name: 'priority', short: 'p', description: 'Message priority', type: 'string', choices: ['low', 'normal', 'high', 'critical'], default: 'normal' }, { name: 'from', short: 'f', description: 'Sender agent ID', type: 'string' } ], action: async (ctx) => { const message = ctx.args.join(' ') || ctx.flags.message; if (!message) { output.printError('Message required. Use --message or -m flag.'); return { success: false, exitCode: 1 }; } try { const result = await callMCPTool('hive-mind_broadcast', { message, priority: ctx.flags.priority, fromId: ctx.flags.from }); if (!result.success) { output.printError(result.error || 'Failed'); return { success: false, exitCode: 1 }; } output.printSuccess(`Message broadcast to ${result.recipients} workers (ID: ${result.messageId})`); return { success: true, data: result }; } catch (error) { output.printError(`Broadcast error: ${error instanceof MCPClientError ? error.message : String(error)}`); return { success: false, exitCode: 1 }; } } }; // Memory subcommand const memorySubCommand = { name: 'memory', description: 'Access hive shared memory', options: [ { name: 'action', short: 'a', description: 'Memory action', type: 'string', choices: ['get', 'set', 'delete', 'list'], default: 'list' }, { name: 'key', short: 'k', description: 'Memory key', type: 'string' }, { name: 'value', short: 'v', description: 'Value to store', type: 'string' } ], action: async (ctx) => { const action = ctx.flags.action || 'list'; const key = ctx.flags.key; const value = ctx.flags.value; if ((action === 'get' || action === 'delete') && !key) { output.printError('Key required for get/delete.'); return { success: false, exitCode: 1 }; } if (action === 'set' && (!key || value === undefined)) { output.printError('Key and value required for set.'); return { success: false, exitCode: 1 }; } try { const result = await callMCPTool('hive-mind_memory', { action, key, value }); if (ctx.flags.format === 'json') { output.printJson(result); return { success: true, data: result }; } if (action === 'list') { const keys = result.keys || []; output.writeln(output.bold(`\nShared Memory (${result.count} keys)`)); if (keys.length === 0) output.printInfo('No keys in shared memory'); else output.printList(keys.map(k => output.highlight(k))); } else if (action === 'get') { output.writeln(output.bold(`\nKey: ${key}`)); output.writeln(result.exists ? `Value: ${JSON.stringify(result.value, null, 2)}` : 'Key not found'); } else if (action === 'set') { output.printSuccess(`Set ${key} in shared memory`); } else if (action === 'delete') { output.printSuccess(result.deleted ? `Deleted ${key}` : `Key ${key} did not exist`); } return { success: true, data: result }; } catch (error) { output.printError(`Memory error: ${error instanceof MCPClientError ? error.message : String(error)}`); return { success: false, exitCode: 1 }; } } }; // Shutdown subcommand const shutdownCommand = { name: 'shutdown', description: 'Shutdown the hive mind', options: [ { name: 'force', short: 'f', description: 'Force shutdown', type: 'boolean', default: false }, { name: 'save-state', short: 's', description: 'Save state before shutdown', type: 'boolean', default: true } ], action: async (ctx) => { const force = ctx.flags.force; const saveState = ctx.flags.saveState; if (!force && ctx.interactive) { const confirmed = await confirm({ message: 'Shutdown the hive mind? All agents will be terminated.', default: false }); if (!confirmed) { output.printInfo('Operation cancelled'); return { success: true }; } } output.printInfo('Shutting down hive mind...'); const spinner = output.createSpinner({ text: 'Graceful shutdown in progress...', spinner: 'dots' }); spinner.start(); try { const result = await callMCPTool('hive-mind_shutdown', { force, saveState, }); spinner.succeed('Hive mind shutdown complete'); output.writeln(); output.printList([ `Agents terminated: ${result.agentsTerminated}`, `State saved: ${result.stateSaved ? 'Yes' : 'No'}`, `Shutdown time: ${result.shutdownTime}` ]); return { success: true, data: result }; } catch (error) { spinner.fail('Shutdown failed'); if (error instanceof MCPClientError) { output.printError(`Shutdown error: ${error.message}`); } else { output.printError(`Unexpected error: ${String(error)}`); } return { success: false, exitCode: 1 }; } } }; // Main hive-mind command export const hiveMindCommand = { name: 'hive-mind', aliases: ['hive'], description: 'Queen-led consensus-based multi-agent coordination', subcommands: [initCommand, spawnCommand, statusCommand, taskCommand, joinCommand, leaveCommand, consensusCommand, broadcastCommand, memorySubCommand, optimizeMemoryCommand, shutdownCommand], options: [], examples: [ { command: 'claude-flow hive-mind init -t hierarchical-mesh', description: 'Initialize hive' }, { command: 'claude-flow hive-mind spawn -n 5', description: 'Spawn workers' }, { command: 'claude-flow hive-mind spawn --claude -o "Build a feature"', description: 'Launch Claude Code with hive mind' }, { command: 'claude-flow hive-mind task -d "Build feature"', description: 'Submit task' } ], action: async () => { output.writeln(); output.writeln(output.bold('Hive Mind - Consensus-Based Multi-Agent Coordination')); output.writeln(); output.writeln('Usage: claude-flow hive-mind <subcommand> [options]'); output.writeln(); output.writeln('Subcommands:'); output.printList([ `${output.highlight('init')} - Initialize hive mind`, `${output.highlight('spawn')} - Spawn worker agents (use --claude to launch Claude Code)`, `${output.highlight('status')} - Show hive status`, `${output.highlight('task')} - Submit task to hive`, `${output.highlight('join')} - Join an agent to the hive`, `${output.highlight('leave')} - Remove an agent from the hive`, `${output.highlight('consensus')} - Manage consensus proposals`, `${output.highlight('broadcast')} - Broadcast message to workers`, `${output.highlight('memory')} - Access shared memory`, `${output.highlight('optimize-memory')} - Optimize patterns and memory`, `${output.highlight('shutdown')} - Shutdown the hive` ]); output.writeln(); output.writeln('Features:'); output.printList([ 'Queen-led hier