UNPKG

claude-flow-multilang

Version:

Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture

854 lines (731 loc) 23.9 kB
/** * Command Handler for Claude Code Console * Processes and executes console commands */ export class CommandHandler { constructor(terminal, wsClient) { this.terminal = terminal; this.wsClient = wsClient; this.isProcessing = false; // Built-in commands this.builtinCommands = { help: this.showHelp.bind(this), clear: this.clearConsole.bind(this), status: this.showStatus.bind(this), connect: this.connectToServer.bind(this), disconnect: this.disconnectFromServer.bind(this), tools: this.listTools.bind(this), health: this.checkHealth.bind(this), history: this.showHistory.bind(this), export: this.exportSession.bind(this), theme: this.changeTheme.bind(this), version: this.showVersion.bind(this), }; // Claude Flow commands this.claudeFlowCommands = { 'claude-flow': this.executeClaudeFlow.bind(this), swarm: this.executeSwarm.bind(this), init: this.initializeProject.bind(this), config: this.manageConfig.bind(this), memory: this.manageMemory.bind(this), agents: this.manageAgents.bind(this), benchmark: this.runBenchmark.bind(this), sparc: this.executeSparc.bind(this), }; // Direct SPARC mode commands this.sparcModeCommands = { coder: this.executeSparcMode.bind(this, 'coder'), architect: this.executeSparcMode.bind(this, 'architect'), analyst: this.executeSparcMode.bind(this, 'analyst'), researcher: this.executeSparcMode.bind(this, 'researcher'), reviewer: this.executeSparcMode.bind(this, 'reviewer'), tester: this.executeSparcMode.bind(this, 'tester'), debugger: this.executeSparcMode.bind(this, 'debugger'), documenter: this.executeSparcMode.bind(this, 'documenter'), optimizer: this.executeSparcMode.bind(this, 'optimizer'), designer: this.executeSparcMode.bind(this, 'designer'), }; this.allCommands = { ...this.builtinCommands, ...this.claudeFlowCommands, ...this.sparcModeCommands, }; } /** * Process a command */ async processCommand(command) { if (this.isProcessing) { this.terminal.writeWarning('Another command is still processing. Please wait...'); return; } this.isProcessing = true; this.terminal.setLocked(true); try { const { cmd, args } = this.parseCommand(command); if (this.allCommands[cmd]) { await this.allCommands[cmd](args); } else { await this.executeRemoteCommand(cmd, args); } } catch (error) { this.terminal.writeError(error.message); console.error('Command execution error:', error); } finally { this.isProcessing = false; this.terminal.setLocked(false); } } /** * Parse command string into command and arguments */ parseCommand(commandString) { const parts = commandString.trim().split(/\s+/); const cmd = parts[0].toLowerCase(); const args = parts.slice(1); return { cmd, args }; } /** * Show help information */ async showHelp(args) { if (args.length > 0) { const command = args[0].toLowerCase(); if (this.allCommands[command]) { this.showCommandHelp(command); } else { this.terminal.writeError(`Unknown command: ${command}`); } return; } this.terminal.writeInfo('Claude Flow Console Commands:'); this.terminal.writeLine(''); this.terminal.writeInfo('Built-in Commands:'); Object.keys(this.builtinCommands).forEach((cmd) => { this.terminal.writeLine(` ${cmd.padEnd(12)} - ${this.getCommandDescription(cmd)}`); }); this.terminal.writeLine(''); this.terminal.writeInfo('Claude Flow Commands:'); Object.keys(this.claudeFlowCommands).forEach((cmd) => { this.terminal.writeLine(` ${cmd.padEnd(12)} - ${this.getCommandDescription(cmd)}`); }); this.terminal.writeLine(''); this.terminal.writeInfo('Tool Commands (from tools list):'); this.terminal.writeLine(' system/health - Get system health status'); this.terminal.writeLine( ' memory/manage - Manage memory (list, store <key> <value>, retrieve <key>)', ); this.terminal.writeLine( ' agents/manage - Manage agents (list, create <type>, status <id>)', ); this.terminal.writeLine( ' swarm/orchestrate - Swarm operations (status, create, start, stop)', ); this.terminal.writeLine( ' sparc/execute - Execute SPARC modes (coder, architect, etc.)', ); this.terminal.writeLine( ' benchmark/run - Run benchmarks (default, memory, cpu, network)', ); this.terminal.writeLine(' claude-flow/execute - Execute Claude Flow commands'); this.terminal.writeLine(''); this.terminal.writeInfo( 'Use "help <command>" for detailed information about a specific command.', ); this.terminal.writeInfo( 'Use Ctrl+L to clear console, Ctrl+C to interrupt, Tab for autocomplete.', ); } /** * Get command description */ getCommandDescription(command) { const descriptions = { help: 'Show help information', clear: 'Clear console output', status: 'Show connection and system status', connect: 'Connect to Claude Code server', disconnect: 'Disconnect from server', tools: 'List available tools', health: 'Check server health', history: 'Show command history', export: 'Export session data', theme: 'Change console theme', version: 'Show version information', 'claude-flow': 'Execute Claude Flow commands', swarm: 'Manage and execute swarms', init: 'Initialize new project', config: 'Manage configuration', memory: 'Manage memory and data', agents: 'Manage agents', benchmark: 'Run benchmarks', sparc: 'Execute SPARC mode commands', }; return descriptions[command] || 'No description available'; } /** * Show detailed command help */ showCommandHelp(command) { const helpText = { help: ` Usage: help [command] Show help information for all commands or a specific command. Examples: help - Show all commands help claude-flow - Show help for claude-flow command`, clear: ` Usage: clear Clear the console output. You can also use Ctrl+L.`, connect: ` Usage: connect [url] [token] Connect to Claude Code server. Arguments: url - WebSocket URL (default: ws://localhost:3000/ws) token - Authentication token (optional) Examples: connect connect ws://localhost:3000/ws connect ws://localhost:3000/ws my-auth-token`, 'claude-flow': ` Usage: claude-flow <subcommand> [options] Execute Claude Flow commands. Subcommands: start [mode] - Start Claude Flow in specified mode stop - Stop Claude Flow status - Show Claude Flow status modes - List available SPARC modes Examples: claude-flow start coder claude-flow status claude-flow modes`, swarm: ` Usage: swarm <action> [options] Manage and execute swarms. Actions: create <name> - Create new swarm start <name> - Start existing swarm stop <name> - Stop running swarm list - List all swarms status <name> - Show swarm status Examples: swarm create my-swarm swarm start my-swarm swarm list`, }; if (helpText[command]) { this.terminal.writeInfo(helpText[command].trim()); } else { this.terminal.writeInfo(`No detailed help available for: ${command}`); } } /** * Clear console */ async clearConsole() { this.terminal.clear(); this.terminal.writeSuccess('Console cleared'); } /** * Show status */ async showStatus() { const wsStatus = this.wsClient.getStatus(); const terminalStats = this.terminal.getStats(); this.terminal.writeInfo('System Status:'); this.terminal.writeLine(''); this.terminal.writeInfo('Connection:'); this.terminal.writeLine(` Status: ${wsStatus.connected ? 'Connected' : 'Disconnected'}`); this.terminal.writeLine(` URL: ${wsStatus.url || 'Not set'}`); this.terminal.writeLine(` Reconnect attempts: ${wsStatus.reconnectAttempts}`); this.terminal.writeLine(` Queued messages: ${wsStatus.queuedMessages}`); this.terminal.writeLine(` Pending requests: ${wsStatus.pendingRequests}`); this.terminal.writeLine(''); this.terminal.writeInfo('Terminal:'); this.terminal.writeLine(` Total lines: ${terminalStats.totalLines}`); this.terminal.writeLine(` History size: ${terminalStats.historySize}`); this.terminal.writeLine(` Input locked: ${terminalStats.isLocked}`); this.terminal.writeLine(` Current prompt: ${terminalStats.currentPrompt}`); if (wsStatus.connected) { try { const healthStatus = await this.wsClient.getHealthStatus(); this.terminal.writeLine(''); this.terminal.writeInfo('Server Health:'); this.terminal.writeLine(` Status: ${healthStatus.healthy ? 'Healthy' : 'Unhealthy'}`); if (healthStatus.metrics) { Object.entries(healthStatus.metrics).forEach(([key, value]) => { this.terminal.writeLine(` ${key}: ${value}`); }); } } catch (error) { this.terminal.writeWarning('Failed to get server health status'); } } } /** * Connect to server */ async connectToServer(args) { const url = args[0] || 'ws://localhost:3000/ws'; const token = args[1] || ''; this.terminal.writeInfo(`Connecting to ${url}...`); try { await this.wsClient.connect(url, token); // Initialize session await this.wsClient.initializeSession(); this.terminal.writeSuccess('Connected successfully'); this.terminal.setPrompt('claude-flow>'); } catch (error) { this.terminal.writeError(`Connection failed: ${error.message}`); } } /** * Disconnect from server */ async disconnectFromServer() { this.wsClient.disconnect(); this.terminal.writeSuccess('Disconnected from server'); this.terminal.setPrompt('offline>'); } /** * List available tools */ async listTools() { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const tools = await this.wsClient.getAvailableTools(); this.terminal.writeInfo('Available Tools:'); this.terminal.writeLine(''); if (tools && tools.length > 0) { tools.forEach((tool) => { this.terminal.writeLine( ` ${tool.name.padEnd(20)} - ${tool.description || 'No description'}`, ); }); } else { this.terminal.writeWarning('No tools available'); } } catch (error) { this.terminal.writeError(`Failed to list tools: ${error.message}`); } } /** * Check server health */ async checkHealth() { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const health = await this.wsClient.getHealthStatus(); if (health.healthy) { this.terminal.writeSuccess('Server is healthy'); } else { this.terminal.writeError(`Server is unhealthy: ${health.error || 'Unknown error'}`); } if (health.metrics) { this.terminal.writeLine(''); this.terminal.writeInfo('Metrics:'); Object.entries(health.metrics).forEach(([key, value]) => { this.terminal.writeLine(` ${key}: ${value}`); }); } } catch (error) { this.terminal.writeError(`Health check failed: ${error.message}`); } } /** * Show command history */ async showHistory() { const history = this.terminal.history; if (history.length === 0) { this.terminal.writeInfo('No command history'); return; } this.terminal.writeInfo('Command History:'); history.forEach((cmd, index) => { this.terminal.writeLine(` ${(index + 1).toString().padStart(3)}: ${cmd}`); }); } /** * Export session data */ async exportSession(args) { const format = args[0] || 'json'; const sessionData = { timestamp: new Date().toISOString(), terminal: this.terminal.exportHistory(), history: this.terminal.history, status: this.wsClient.getStatus(), }; if (format === 'json') { const blob = new Blob([JSON.stringify(sessionData, null, 2)], { type: 'application/json' }); this.downloadFile(blob, `console-session-${Date.now()}.json`); this.terminal.writeSuccess('Session exported as JSON'); } else { this.terminal.writeError(`Unsupported export format: ${format}`); } } /** * Change theme */ async changeTheme(args) { const theme = args[0]; const validThemes = ['dark', 'light', 'classic', 'matrix']; if (!theme) { this.terminal.writeInfo(`Available themes: ${validThemes.join(', ')}`); return; } if (!validThemes.includes(theme)) { this.terminal.writeError(`Invalid theme: ${theme}`); return; } document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('console_theme', theme); this.terminal.writeSuccess(`Theme changed to: ${theme}`); } /** * Show version information */ async showVersion() { this.terminal.writeInfo('🌊 Claude Flow v2.0.0'); this.terminal.writeLine('Advanced swarm orchestration platform'); this.terminal.writeLine('Built with modern web technologies'); } /** * Execute Claude Flow command */ async executeClaudeFlow(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } if (args.length === 0) { this.terminal.writeError('Usage: claude-flow <subcommand> [options]'); return; } const subcommand = args[0]; const subArgs = args.slice(1); try { const result = await this.wsClient.executeCommand('claude-flow', { subcommand, args: subArgs, }); this.terminal.writeSuccess(`Claude Flow ${subcommand} executed successfully`); if (result && result.output) { this.terminal.writeLine(result.output); } } catch (error) { this.terminal.writeError(`Claude Flow command failed: ${error.message}`); } } /** * Execute swarm command */ async executeSwarm(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const action = args[0] || 'status'; this.terminal.writeInfo(`Executing swarm ${action}...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'swarm/status', arguments: { action, args: args.slice(1) }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess('Swarm command executed successfully'); } } catch (error) { this.terminal.writeError(`Swarm command failed: ${error.message}`); } } /** * Initialize project */ async initializeProject(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } this.terminal.writeWarning('Project initialization not yet implemented in web console'); } /** * Manage configuration */ async manageConfig(args) { this.terminal.writeInfo('Use the Settings panel (⚙️ button) to manage configuration'); } /** * Manage memory */ async manageMemory(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const operation = args[0] || 'list'; const key = args[1]; const value = args.slice(2).join(' '); this.terminal.writeInfo(`Executing memory ${operation}...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'memory/manage', arguments: { operation, key, value }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess('Memory operation completed successfully'); } } catch (error) { this.terminal.writeError(`Memory command failed: ${error.message}`); } } /** * Manage agents */ async manageAgents(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const action = args[0] || 'list'; const agentType = args[1]; const agentId = args[1]; this.terminal.writeInfo(`Executing agents ${action}...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'agents/manage', arguments: { action, agentType, agentId }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess('Agent operation completed successfully'); } } catch (error) { this.terminal.writeError(`Agent command failed: ${error.message}`); } } /** * Run benchmark */ async runBenchmark(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const suite = args[0] || 'default'; const iterations = parseInt(args[1]) || 10; this.terminal.writeInfo(`Running benchmark suite: ${suite}...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'benchmark/run', arguments: { suite, iterations }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess('Benchmark completed successfully'); } } catch (error) { this.terminal.writeError(`Benchmark failed: ${error.message}`); } } /** * Execute SPARC mode */ async executeSparc(args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } if (args.length === 0) { this.terminal.writeInfo('Available SPARC modes:'); const modes = [ 'coder', 'architect', 'analyst', 'researcher', 'reviewer', 'tester', 'debugger', 'documenter', 'optimizer', 'designer', ]; modes.forEach((mode) => { this.terminal.writeLine(` ${mode}`); }); return; } try { const mode = args[0]; const task = args.slice(1).join(' ') || 'General task execution'; const options = {}; this.terminal.writeInfo(`Executing SPARC mode: ${mode}...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'sparc/execute', arguments: { mode, task, options }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess(`SPARC ${mode} mode executed successfully`); } } catch (error) { this.terminal.writeError(`SPARC execution failed: ${error.message}`); } } /** * Execute specific SPARC mode */ async executeSparcMode(mode, args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server'); return; } try { const task = args.join(' ') || `Execute ${mode} mode tasks`; const options = {}; this.terminal.writeInfo(`Executing SPARC ${mode} mode...`); const result = await this.wsClient.sendRequest('tools/call', { name: 'sparc/execute', arguments: { mode, task, options }, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess(`SPARC ${mode} mode executed successfully`); } } catch (error) { this.terminal.writeError(`SPARC ${mode} execution failed: ${error.message}`); } } /** * Execute remote command via WebSocket */ async executeRemoteCommand(command, args) { if (!this.wsClient.isConnected) { this.terminal.writeError('Not connected to server. Use "connect" command first.'); return; } try { // Check if this is a tool name (contains slash) if (command.includes('/')) { return await this.executeToolDirect(command, args); } this.terminal.writeInfo(`Executing remote command: ${command}`); const result = await this.wsClient.executeCommand(command, { args }); if (result && result.output) { this.terminal.writeLine(result.output); } else { this.terminal.writeSuccess('Command executed successfully'); } } catch (error) { this.terminal.writeError(`Remote command failed: ${error.message}`); } } /** * Execute tool directly by name */ async executeToolDirect(toolName, args) { try { this.terminal.writeInfo(`Executing tool: ${toolName}...`); // Prepare arguments based on tool let toolArgs = {}; switch (toolName) { case 'system/health': toolArgs = { detailed: args.includes('--detailed') }; break; case 'memory/manage': toolArgs = { operation: args[0] || 'list', key: args[1], value: args.slice(2).join(' '), }; break; case 'agents/manage': toolArgs = { action: args[0] || 'list', agentType: args[1], agentId: args[1], }; break; case 'swarm/orchestrate': toolArgs = { action: args[0] || 'status', args: args.slice(1), }; break; case 'sparc/execute': toolArgs = { mode: args[0] || 'coder', task: args.slice(1).join(' ') || 'General task execution', options: {}, }; break; case 'benchmark/run': toolArgs = { suite: args[0] || 'default', iterations: parseInt(args[1]) || 10, }; break; case 'claude-flow/execute': toolArgs = { command: args[0] || 'status', args: args.slice(1), }; break; default: toolArgs = { args }; } const result = await this.wsClient.sendRequest('tools/call', { name: toolName, arguments: toolArgs, }); if (result && result.content && result.content[0]) { this.terminal.writeSuccess(result.content[0].text); } else { this.terminal.writeSuccess(`Tool ${toolName} executed successfully`); } } catch (error) { this.terminal.writeError(`Tool execution failed: ${error.message}`); } } /** * Download file helper */ downloadFile(blob, filename) { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } /** * Get command suggestions */ getCommandSuggestions(input) { const allCommands = Object.keys(this.allCommands); return allCommands.filter((cmd) => cmd.startsWith(input.toLowerCase())); } /** * Check if command exists */ hasCommand(command) { return this.allCommands.hasOwnProperty(command.toLowerCase()); } }