UNPKG

claude-flow-tbowman01

Version:

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

331 lines (291 loc) 10.3 kB
/** * Process Manager - Handles lifecycle of system processes */ import { EventEmitter } from './event-emitter.js'; import chalk from 'chalk'; import { ProcessInfo, ProcessType, ProcessStatus, ProcessMetrics, SystemStats } from './types.js'; import { Orchestrator } from '../../../core/orchestrator.js'; import { TerminalManager } from '../../../terminal/manager.js'; import { MemoryManager } from '../../../memory/manager.js'; import { CoordinationManager } from '../../../coordination/manager.js'; import { MCPServer } from '../../../mcp/server.js'; import { eventBus } from '../../../core/event-bus.js'; import { logger } from '../../../core/logger.js'; import { configManager } from '../../../core/config.js'; export class ProcessManager extends EventEmitter { private processes: Map<string, ProcessInfo> = new Map(); private orchestrator: Orchestrator | undefined; private terminalManager: TerminalManager | undefined; private memoryManager: MemoryManager | undefined; private coordinationManager: CoordinationManager | undefined; private mcpServer: MCPServer | undefined; private config: any; constructor() { super(); this.initializeProcesses(); } private initializeProcesses(): void { // Define all manageable processes const processDefinitions: ProcessInfo[] = [ { id: 'event-bus', name: 'Event Bus', type: ProcessType.EVENT_BUS, status: ProcessStatus.STOPPED, }, { id: 'orchestrator', name: 'Orchestrator Engine', type: ProcessType.ORCHESTRATOR, status: ProcessStatus.STOPPED, }, { id: 'memory-manager', name: 'Memory Manager', type: ProcessType.MEMORY_MANAGER, status: ProcessStatus.STOPPED, }, { id: 'terminal-pool', name: 'Terminal Pool', type: ProcessType.TERMINAL_POOL, status: ProcessStatus.STOPPED, }, { id: 'mcp-server', name: 'MCP Server', type: ProcessType.MCP_SERVER, status: ProcessStatus.STOPPED, }, { id: 'coordinator', name: 'Coordination Manager', type: ProcessType.COORDINATOR, status: ProcessStatus.STOPPED, }, ]; for (const process of processDefinitions) { this.processes.set(process.id, process); } } async initialize(configPath?: string): Promise<void> { try { this.config = await configManager.load(configPath); this.emit('initialized', { config: this.config }); } catch (error) { this.emit('error', { component: 'ProcessManager', error }); throw error; } } async startProcess(processId: string): Promise<void> { const process = this.processes.get(processId); if (!process) { throw new Error(`Unknown process: ${processId}`); } if (process.status === ProcessStatus.RUNNING) { throw new Error(`Process ${processId} is already running`); } this.updateProcessStatus(processId, ProcessStatus.STARTING); try { switch (process.type) { case ProcessType.EVENT_BUS: // Event bus is already initialized globally process.pid = Deno.pid; break; case ProcessType.MEMORY_MANAGER: this.memoryManager = new MemoryManager(this.config.memory, eventBus, logger); await this.memoryManager.initialize(); break; case ProcessType.TERMINAL_POOL: this.terminalManager = new TerminalManager(this.config.terminal, eventBus, logger); await this.terminalManager.initialize(); break; case ProcessType.COORDINATOR: this.coordinationManager = new CoordinationManager( this.config.coordination, eventBus, logger, ); await this.coordinationManager.initialize(); break; case ProcessType.MCP_SERVER: this.mcpServer = new MCPServer(this.config.mcp, eventBus, logger); await this.mcpServer.start(); break; case ProcessType.ORCHESTRATOR: if ( !this.terminalManager || !this.memoryManager || !this.coordinationManager || !this.mcpServer ) { throw new Error('Required components not initialized'); } this.orchestrator = new Orchestrator( this.config, this.terminalManager, this.memoryManager, this.coordinationManager, this.mcpServer, eventBus, logger, ); await this.orchestrator.initialize(); break; } process.startTime = Date.now(); this.updateProcessStatus(processId, ProcessStatus.RUNNING); this.emit('processStarted', { processId, process }); } catch (error) { this.updateProcessStatus(processId, ProcessStatus.ERROR); process.metrics = { ...process.metrics, lastError: (error as Error).message, }; this.emit('processError', { processId, error }); throw error; } } async stopProcess(processId: string): Promise<void> { const process = this.processes.get(processId); if (!process || process.status !== ProcessStatus.RUNNING) { throw new Error(`Process ${processId} is not running`); } this.updateProcessStatus(processId, ProcessStatus.STOPPING); try { switch (process.type) { case ProcessType.ORCHESTRATOR: if (this.orchestrator) { await this.orchestrator.shutdown(); this.orchestrator = undefined; } break; case ProcessType.MCP_SERVER: if (this.mcpServer) { await this.mcpServer.stop(); this.mcpServer = undefined; } break; case ProcessType.MEMORY_MANAGER: if (this.memoryManager) { await this.memoryManager.shutdown(); this.memoryManager = undefined; } break; case ProcessType.TERMINAL_POOL: if (this.terminalManager) { await this.terminalManager.shutdown(); this.terminalManager = undefined; } break; case ProcessType.COORDINATOR: if (this.coordinationManager) { await this.coordinationManager.shutdown(); this.coordinationManager = undefined; } break; } this.updateProcessStatus(processId, ProcessStatus.STOPPED); this.emit('processStopped', { processId }); } catch (error) { this.updateProcessStatus(processId, ProcessStatus.ERROR); this.emit('processError', { processId, error }); throw error; } } async restartProcess(processId: string): Promise<void> { await this.stopProcess(processId); await new Promise((resolve) => setTimeout(resolve, 1000)); // Brief delay await this.startProcess(processId); } async startAll(): Promise<void> { // Start in dependency order const startOrder = [ 'event-bus', 'memory-manager', 'terminal-pool', 'coordinator', 'mcp-server', 'orchestrator', ]; for (const processId of startOrder) { try { await this.startProcess(processId); } catch (error) { console.error(chalk.red(`Failed to start ${processId}:`), (error as Error).message); // Continue with other processes } } } async stopAll(): Promise<void> { // Stop in reverse dependency order const stopOrder = [ 'orchestrator', 'mcp-server', 'coordinator', 'terminal-pool', 'memory-manager', 'event-bus', ]; for (const processId of stopOrder) { const process = this.processes.get(processId); if (process && process.status === ProcessStatus.RUNNING) { try { await this.stopProcess(processId); } catch (error) { console.error(chalk.red(`Failed to stop ${processId}:`), (error as Error).message); } } } } getProcess(processId: string): ProcessInfo | undefined { return this.processes.get(processId); } getAllProcesses(): ProcessInfo[] { return Array.from(this.processes.values()); } getSystemStats(): SystemStats { const processes = this.getAllProcesses(); const runningProcesses = processes.filter((p) => p.status === ProcessStatus.RUNNING); const stoppedProcesses = processes.filter((p) => p.status === ProcessStatus.STOPPED); const errorProcesses = processes.filter((p) => p.status === ProcessStatus.ERROR); return { totalProcesses: processes.length, runningProcesses: runningProcesses.length, stoppedProcesses: stoppedProcesses.length, errorProcesses: errorProcesses.length, systemUptime: this.getSystemUptime(), totalMemory: this.getTotalMemoryUsage(), totalCpu: this.getTotalCpuUsage(), }; } private updateProcessStatus(processId: string, status: ProcessStatus): void { const process = this.processes.get(processId); if (process) { process.status = status; this.emit('statusChanged', { processId, status }); } } private getSystemUptime(): number { const orchestrator = this.processes.get('orchestrator'); if (orchestrator && orchestrator.startTime) { return Date.now() - orchestrator.startTime; } return 0; } private getTotalMemoryUsage(): number { // Placeholder - would integrate with actual memory monitoring return 0; } private getTotalCpuUsage(): number { // Placeholder - would integrate with actual CPU monitoring return 0; } async getProcessLogs(processId: string, lines: number = 50): Promise<string[]> { // Placeholder - would integrate with actual logging system return [ `[${new Date().toISOString()}] Process ${processId} started`, `[${new Date().toISOString()}] Process ${processId} is running normally`, ]; } }