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
JavaScript
/**
 * 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;