UNPKG

claude-coordination-system

Version:

🤖 Multi-Claude Parallel Processing Coordination System - Organize multiple Claude AI instances to work together seamlessly on complex development tasks

442 lines (383 loc) 14.2 kB
/** * Enhanced Terminal Interface for Claude Sync * Preserves all existing symbols and visual indicators */ const chalk = require('chalk'); const { logWorker } = require('./development-logger'); class EnhancedTerminalInterface { constructor(syncClient) { this.syncClient = syncClient; this.sessionId = syncClient.sessionId; this.groupId = syncClient.groupId; // Terminal state this.statusDisplay = { enabled: true, lastUpdate: null, position: 'bottom' }; // Coordination symbols (preserved from original system) this.symbols = { working: '●', // Active working (green) waiting: '◐', // Waiting for coordination (yellow) syncing: '◑', // Syncing with group (blue) coordinating: '◒', // Coordinating tasks (cyan) standby: '○', // Standby mode (gray) error: '✖', // Error state (red) success: '✓', // Success (green) info: 'ℹ' // Information (blue) }; // Status indicators this.currentStatus = 'standby'; this.currentTask = null; this.groupMembers = []; this.fileActivity = []; console.log(chalk.blue('🎨 Enhanced Terminal Interface initialized')); } /** * Start terminal interface */ async start() { // Setup status display this.setupStatusDisplay(); // Setup coordination listeners this.setupCoordinationListeners(); // Show initial status this.showWelcomeMessage(); this.updateStatusDisplay(); // Start status update loop this.startStatusUpdateLoop(); } /** * Stop terminal interface */ async stop() { if (this.statusUpdateTimer) { clearInterval(this.statusUpdateTimer); } this.showFarewellMessage(); } /** * Setup status display */ setupStatusDisplay() { // Initialize status bar area this.statusBar = { height: 3, content: [], visible: true }; } /** * Setup coordination listeners */ setupCoordinationListeners() { this.syncClient.on('client:started', () => { this.updateStatus('working', 'Claude Sync activated'); }); this.syncClient.on('group:member_joined', (member) => { this.groupMembers.push(member); this.showCoordinationUpdate(`${chalk.green('●')} ${member.id} joined ${this.groupId}`); this.updateStatusDisplay(); }); this.syncClient.on('group:member_left', (member) => { this.groupMembers = this.groupMembers.filter(m => m.id !== member.id); this.showCoordinationUpdate(`${chalk.gray('○')} ${member.id} left ${this.groupId}`); this.updateStatusDisplay(); }); this.syncClient.on('coordination:task_received', (task) => { this.currentTask = task; this.updateStatus('coordinating', `Coordinating: ${task.description}`); this.showTaskUpdate(task); }); this.syncClient.on('coordination:file_locked', (lockInfo) => { this.fileActivity.push({ type: 'lock', file: lockInfo.filePath, by: lockInfo.sessionId, timestamp: Date.now() }); this.showFileActivity(lockInfo, 'locked'); }); this.syncClient.on('coordination:file_unlocked', (lockInfo) => { this.fileActivity.push({ type: 'unlock', file: lockInfo.filePath, by: lockInfo.sessionId, timestamp: Date.now() }); this.showFileActivity(lockInfo, 'unlocked'); }); } /** * Show welcome message with coordination info */ showWelcomeMessage() { console.log(chalk.blue('═'.repeat(60))); console.log(chalk.blue('🔄 Claude Coordination System - Enhanced Mode')); console.log(chalk.gray(` Session: ${this.sessionId}`)); console.log(chalk.gray(` Group: ${chalk.cyan(this.groupId)} | Primary: ${this.syncClient.options.primaryTerminal ? 'YES' : 'NO'}`)); console.log(chalk.blue('═'.repeat(60))); // Show symbol legend console.log(chalk.gray('📋 Status Symbols:')); console.log(chalk.gray(` ${chalk.green(this.symbols.working)} Working ${chalk.yellow(this.symbols.waiting)} Waiting ${chalk.blue(this.symbols.syncing)} Syncing`)); console.log(chalk.gray(` ${chalk.cyan(this.symbols.coordinating)} Coordinating ${chalk.gray(this.symbols.standby)} Standby`)); console.log(); // Show coordination commands console.log(chalk.gray('💡 Coordination Commands:')); console.log(chalk.gray(' !coord status - Show detailed status')); console.log(chalk.gray(' !coord members - List group members')); console.log(chalk.gray(' !coord files - Show file activity')); console.log(chalk.gray(' !coord task <desc> - Broadcast task to group')); console.log(chalk.gray(' !coord help - Show all commands')); console.log(); } /** * Show farewell message */ showFarewellMessage() { console.log(); console.log(chalk.yellow('═'.repeat(50))); console.log(chalk.yellow('🔄 Claude Coordination - Session Ended')); console.log(chalk.gray(` Session: ${this.sessionId}`)); console.log(chalk.gray(` Duration: ${this.getSessionDuration()}`)); console.log(chalk.gray(` Group: ${this.groupId} | Files worked: ${this.fileActivity.length}`)); console.log(chalk.yellow('═'.repeat(50))); } /** * Update current status */ updateStatus(status, message = null) { this.currentStatus = status; if (message) { const symbol = this.getStatusSymbol(status); const coloredSymbol = this.getColoredSymbol(status, symbol); console.log(`${coloredSymbol} ${message}`); } this.updateStatusDisplay(); } /** * Get status symbol */ getStatusSymbol(status) { return this.symbols[status] || this.symbols.standby; } /** * Get colored symbol */ getColoredSymbol(status, symbol) { switch (status) { case 'working': return chalk.green(symbol); case 'waiting': return chalk.yellow(symbol); case 'syncing': return chalk.blue(symbol); case 'coordinating': return chalk.cyan(symbol); case 'standby': return chalk.gray(symbol); case 'error': return chalk.red(symbol); case 'success': return chalk.green(symbol); default: return chalk.gray(symbol); } } /** * Show coordination update */ showCoordinationUpdate(message) { if (this.syncClient.options.showCoordination) { console.log(chalk.cyan(`🔄 ${message}`)); } } /** * Show task update */ showTaskUpdate(task) { if (!this.syncClient.options.primaryTerminal) { console.log(chalk.yellow(`📋 Group task received: ${task.description}`)); console.log(chalk.gray(` Coordinating with ${this.groupMembers.length} other members...`)); } } /** * Show file activity */ showFileActivity(lockInfo, action) { if (this.syncClient.options.showCoordination) { const symbol = action === 'locked' ? '🔒' : '🔓'; const color = action === 'locked' ? chalk.cyan : chalk.gray; const fileName = lockInfo.filePath.split('/').pop(); if (lockInfo.sessionId === this.sessionId) { console.log(color(`${symbol} ${fileName} ${action} by me`)); } else { console.log(color(`${symbol} ${fileName} ${action} by ${lockInfo.sessionId}`)); } } } /** * Update status display (terminal status bar) */ updateStatusDisplay() { if (!this.statusDisplay.enabled) return; const symbol = this.getColoredSymbol(this.currentStatus, this.getStatusSymbol(this.currentStatus)); const groupInfo = `${this.groupId}:${this.groupMembers.length + 1}`; const taskInfo = this.currentTask ? ` | ${this.currentTask.description.substring(0, 20)}...` : ''; // This could be implemented as a proper terminal status bar // For now, we'll just track the status internally this.statusDisplay.lastUpdate = Date.now(); } /** * Start status update loop */ startStatusUpdateLoop() { this.statusUpdateTimer = setInterval(() => { this.updateStatusDisplay(); }, 5000); } /** * Handle coordination commands */ async handleCoordinationCommand(command) { const parts = command.split(' '); const action = parts[0]; switch (action) { case 'status': this.showDetailedStatus(); break; case 'members': this.showGroupMembers(); break; case 'files': this.showFileActivity(); break; case 'task': if (parts[1]) { await this.broadcastTask(parts.slice(1).join(' ')); } break; case 'symbols': this.showSymbolLegend(); break; case 'help': this.showCoordinationHelp(); break; default: console.log(chalk.yellow('❓ Unknown command. Type !coord help for available commands.')); } } /** * Show detailed status */ showDetailedStatus() { console.log(chalk.blue('📊 Detailed Coordination Status')); console.log(chalk.gray('─'.repeat(50))); const statusSymbol = this.getColoredSymbol(this.currentStatus, this.getStatusSymbol(this.currentStatus)); console.log(`Status: ${statusSymbol} ${this.currentStatus.toUpperCase()}`); console.log(`Session: ${chalk.cyan(this.sessionId)}`); console.log(`Group: ${chalk.cyan(this.groupId)} (${this.groupMembers.length + 1} members)`); console.log(`Primary Terminal: ${this.syncClient.options.primaryTerminal ? chalk.green('YES') : chalk.yellow('NO')}`); if (this.currentTask) { console.log(`Current Task: ${chalk.cyan(this.currentTask.description)}`); } console.log(`File Activities: ${chalk.cyan(this.fileActivity.length)}`); console.log(`Session Duration: ${chalk.gray(this.getSessionDuration())}`); } /** * Show group members */ showGroupMembers() { console.log(chalk.blue(`👥 Group Members (${this.groupId})`)); console.log(chalk.gray('─'.repeat(40))); // Show this session const mySymbol = this.getColoredSymbol(this.currentStatus, this.getStatusSymbol(this.currentStatus)); const primaryFlag = this.syncClient.options.primaryTerminal ? chalk.yellow(' (primary)') : ''; console.log(`${mySymbol} ${this.sessionId}${primaryFlag}`); // Show other members this.groupMembers.forEach(member => { const memberSymbol = chalk.green(this.symbols.working); console.log(`${memberSymbol} ${member.id || member}`); }); if (this.groupMembers.length === 0) { console.log(chalk.gray(' No other members in this group')); } } /** * Show file activity */ showFileActivityLog() { console.log(chalk.blue('📁 Recent File Activity')); console.log(chalk.gray('─'.repeat(40))); if (this.fileActivity.length === 0) { console.log(chalk.gray(' No file activity yet')); return; } const recent = this.fileActivity.slice(-10); recent.forEach(activity => { const time = new Date(activity.timestamp).toLocaleTimeString(); const symbol = activity.type === 'lock' ? '🔒' : '🔓'; const fileName = activity.file.split('/').pop(); const byMe = activity.by === this.sessionId ? 'me' : activity.by; console.log(`${chalk.gray(time)} ${symbol} ${fileName} by ${byMe}`); }); } /** * Show symbol legend */ showSymbolLegend() { console.log(chalk.blue('🎨 Coordination Symbols')); console.log(chalk.gray('─'.repeat(30))); console.log(`${chalk.green(this.symbols.working)} Working - Actively processing tasks`); console.log(`${chalk.yellow(this.symbols.waiting)} Waiting - Waiting for coordination`); console.log(`${chalk.blue(this.symbols.syncing)} Syncing - Synchronizing with group`); console.log(`${chalk.cyan(this.symbols.coordinating)} Coordinating - Distributing tasks`); console.log(`${chalk.gray(this.symbols.standby)} Standby - Waiting for tasks`); console.log(`${chalk.red(this.symbols.error)} Error - Error state`); console.log(`${chalk.green(this.symbols.success)} Success - Task completed`); } /** * Show coordination help */ showCoordinationHelp() { console.log(chalk.blue('🔄 Claude Coordination Commands')); console.log(chalk.gray('─'.repeat(45))); console.log('!coord status - Show detailed status'); console.log('!coord members - List group members'); console.log('!coord files - Show file activity log'); console.log('!coord task <desc> - Broadcast task to group'); console.log('!coord symbols - Show symbol legend'); console.log('!coord help - Show this help'); console.log(); console.log(chalk.gray('💡 These commands work alongside normal Claude conversation')); console.log(chalk.gray('🔄 Coordination happens transparently in the background')); } /** * Broadcast task to group */ async broadcastTask(taskDescription) { try { await this.syncClient.broadcastTask(taskDescription); console.log(chalk.green(`📋 Task broadcasted to ${this.groupId}: ${taskDescription}`)); } catch (error) { console.log(chalk.red(`❌ Failed to broadcast task: ${error.message}`)); } } /** * Get session duration */ getSessionDuration() { // This would track actual session start time return 'Active'; } /** * Show coordination progress for group tasks */ showCoordinationProgress(progress) { if (!this.syncClient.options.showCoordination) return; console.log(chalk.cyan('📊 Group Progress:')); console.log(chalk.gray(` ${progress.completed}/${progress.total} tasks completed`)); console.log(chalk.gray(` Active: ${progress.active.join(', ')}`)); } /** * Show real-time file coordination */ showFileCoordination(coordination) { if (!this.syncClient.options.showCoordination) return; const files = coordination.files.map(f => f.name).join(', '); console.log(chalk.cyan(`📁 Coordinating files: ${files}`)); } } module.exports = EnhancedTerminalInterface;