UNPKG

ai-debug-local-mcp

Version:

๐ŸŽฏ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

918 lines (917 loc) โ€ข 51 kB
#!/usr/bin/env node import { setMaxListeners } from 'events'; import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; // Prevent EventTarget memory leak warnings - temporary safeguard setMaxListeners(20); // Core services import { APIKeyManager } from './api-key-manager.js'; import { CloudAIService } from './cloud-ai-service.js'; import { LocalDebugEngine } from './local-debug-engine.js'; import { AuditEngine } from './audit-engine.js'; import { VersionChecker } from './version-checker.js'; import { BackendDebugEngine } from './backend-debug-engine.js'; import { FlutterQuantumDebugger } from './flutter-quantum-debugger.js'; import { NextJSDebugEngineEnhanced } from './nextjs-debug-engine-enhanced-modular.js'; import { MetaFrameworkDebugEngine } from './meta-framework-debug-engine-modular.js'; import { SmartTestMaintenance } from './smart-test-maintenance.js'; import { FaultInjectionEngine } from './fault-injection-engine.js'; import { ServerCleanup } from './utils/server-cleanup.js'; import { MemoryEfficientLogger } from './utils/memory-efficient-logger.js'; import StartupAwareMemoryManager from './utils/startup-aware-memory-manager.js'; import { UserFriendlyLogger } from './utils/user-friendly-logger.js'; import { MemoryAwareSessionManager } from './utils/memory-aware-session-manager.js'; import { ToolExecutionSafetyWrapper } from './utils/tool-execution-safety.js'; import { BrowserProcessGuardian } from './utils/browser-process-guardian.js'; import { NetworkResilienceManager } from './utils/network-resilience-manager.js'; // Multi-Project Resource Coordination import { SessionRegistry } from './session-registry/index.js'; // Stability Systems import { CrashPrevention } from './utils/crash-prevention.js'; import { ResourceLeakDetector } from './utils/resource-leak-detector.js'; import { ZombieProcessKiller } from './utils/zombie-process-killer.js'; import { ConnectionLock } from './utils/connection-lock.js'; // Handler Registry import { HandlerRegistry } from './handlers/handler-registry.js'; // Import all handlers import { CoreHandler } from './handlers/core-handler.js'; import { FaultHandler } from './handlers/fault-handler.js'; import { MaintenanceHandler } from './handlers/maintenance-handler.js'; import { InteractionHandler } from './handlers/interaction-handler.js'; import { AuditHandler } from './handlers/audit-handler.js'; import { AnalysisHandler } from './handlers/analysis-handler.js'; import { FlutterHandler } from './handlers/flutter-handler.js'; import { NextJSHandler } from './handlers/nextjs-handler.js'; import { HydrationHandler } from './handlers/hydration-handler.js'; import { BundleHandler } from './handlers/bundle-handler.js'; import { RouteHandler } from './handlers/route-handler.js'; import { ProblemHandler } from './handlers/problem-handler.js'; import { MetaFrameworkHandler } from './handlers/meta-framework-handler.js'; import { PhoenixHandler } from './handlers/phoenix-handler.js'; import { EvolutionHandler } from './handlers/evolution-handler.js'; import { ElixirHandler } from './handlers/elixir-handler.js'; import { EctoHandler } from './handlers/ecto-handler.js'; import { LiveViewAdvancedHandler } from './handlers/liveview-advanced-handler.js'; import { PhoenixAdvancedHandler } from './handlers/phoenix-advanced-handler.js'; import { AILLMHandler } from './handlers/ai/ai-llm-handler.js'; import { AIVectorHandler } from './handlers/ai/ai-vector-handler.js'; import { AIRAGHandler } from './handlers/ai/ai-rag-handler.js'; import { AIPromptHandler } from './handlers/ai/ai-prompt-handler.js'; import { GraphQLHandler } from './handlers/graphql/graphql-handler.js'; import { TestGenerationHandler } from './test-generation-handler.js'; import { PhoenixTestGenerationHandler } from './handlers/phoenix-test-generation-handler.js'; import { AITestEnhancementHandler } from './handlers/ai-test-enhancement-handler.js'; import { PerformanceProfilingHandler } from './handlers/performance-profiling-handler.js'; import { DebugDataHandler } from './handlers/debug-data-handler.js'; import { TDDDebugEngine } from './tdd-debug-engine.js'; import { TDDHandler } from './handlers/tdd-handler.js'; import { SerenaIntegrationHandler } from './handlers/serena-integration-handler.js'; import { SubAgentCoordinator } from './handlers/sub-agent-coordinator.js'; import { AIFeedbackHandler } from './handlers/ai-feedback-handler.js'; import { SystemAutomationHandler } from './handlers/system-automation-handler.js'; import { WorkflowOrchestrationHandler } from './handlers/workflow-orchestration-handler.js'; import { SessionStabilityManager } from './handlers/session-stability-manager.js'; /** * AI Debug Local MCP Server - Refactored with proper handler delegation */ export class AIDebugLocalMCPServer { server; sessions = new Map(); handlerRegistry; memoryManager; isMcpMode = false; sessionManager; toolSafety; browserGuardian; networkManager; crashPrevention; pipeIsBroken = false; leakDetector; // Core services apiKeyManager; cloudAI; localEngine; auditEngine; versionChecker; backendEngine; quantumDebugger; faultEngine; tddEngine; sessionRegistry; constructor() { this.server = new Server({ name: 'ai-debug-local', version: '2.16.0', }); // Initialize core services this.versionChecker = new VersionChecker(); this.apiKeyManager = new APIKeyManager(); this.cloudAI = new CloudAIService(); this.localEngine = new LocalDebugEngine(); this.auditEngine = new AuditEngine(); this.backendEngine = new BackendDebugEngine(); this.quantumDebugger = new FlutterQuantumDebugger(); this.faultEngine = new FaultInjectionEngine(); // Initialize basic handler registry (will be enhanced during startup) this.handlerRegistry = new HandlerRegistry(); // Initialize stability systems this.memoryManager = new StartupAwareMemoryManager(); this.sessionManager = new MemoryAwareSessionManager(); this.toolSafety = ToolExecutionSafetyWrapper.getInstance(); this.browserGuardian = BrowserProcessGuardian.getInstance(); this.networkManager = NetworkResilienceManager.getInstance(); this.crashPrevention = CrashPrevention.getInstance(); this.leakDetector = ResourceLeakDetector.getInstance(); // Setup global stdout error handling FIRST this.setupStdoutErrorHandling(); // Initialize Multi-Project Session Registry this.sessionRegistry = new SessionRegistry({ basePort: 9200, defaultQuotas: { maxBrowserInstances: 2, // Conservative limit per project maxMemoryMB: 512, // 512MB per project maxConcurrentSessions: 5, // Max 5 concurrent projects maxIdleTimeMinutes: 30, // Auto-cleanup after 30min idle maxTempDirectorySizeMB: 100 // 100MB temp storage per project }, cleanupIntervalMs: 60000, // Cleanup every minute monitoringIntervalMs: 30000, // Monitor every 30 seconds enableSharedBrowsers: true // Allow intelligent browser sharing }); // Initialize TDD Debug Engine with proven MCP integration patterns this.tddEngine = new TDDDebugEngine(this.sessionManager, this.memoryManager, this.toolSafety); // Setup MCP request handlers this.setupMCPHandlers(); // Pre-register basic handlers synchronously to ensure immediate tool availability // Enhanced handlers will be loaded asynchronously during run() this.registerBasicHandlersSynchronously(); } /** * Pre-register handlers during construction to ensure tools are available immediately */ async preRegisterHandlers() { try { console.log('๐Ÿš€ Pre-registering handlers to ensure immediate tool availability...'); // Check if basic handlers were already registered synchronously if (this.handlerRegistry.getToolCount() > 0) { console.log(`โœ… Basic handlers already registered: ${this.handlerRegistry.getToolCount()} tools available`); // Just enhance the registry with additional handlers await this.enhanceHandlerRegistry(); console.log(`โœ… Enhanced handlers loaded: ${this.handlerRegistry.getToolCount()} total tools available`); return; } // Register basic handlers first await this.registerBasicHandlers(); // Then enhance the registry if possible await this.enhanceHandlerRegistry(); console.log(`โœ… Pre-registration complete: ${this.handlerRegistry.getToolCount()} tools available`); } catch (error) { console.error('โŒ Pre-registration failed:', error); // Fallback to basic handlers only if not already registered if (this.handlerRegistry.getToolCount() === 0) { try { await this.registerBasicHandlers(); console.log(`๐Ÿ›ก๏ธ Fallback complete: ${this.handlerRegistry.getToolCount()} tools available`); } catch (fallbackError) { console.error('โŒ Fallback registration also failed:', fallbackError); } } } } registerBasicHandlersSynchronously() { try { console.log('๐Ÿš€ Registering basic handlers synchronously...'); // Register the most critical handlers immediately this.handlerRegistry.registerHandler(new CoreHandler(this.localEngine, this.apiKeyManager, this.cloudAI)); // System Automation handler (includes mouse controls) this.handlerRegistry.registerHandler(new SystemAutomationHandler()); // Workflow Orchestration handler (revolutionary tool combinations) this.handlerRegistry.registerHandler(new WorkflowOrchestrationHandler()); // TDD Handler this.handlerRegistry.registerHandler(new TDDHandler(this.tddEngine)); // Auto-Update Handler for keeping AI-Debug current (lazy load later) // Will be added in enhanceHandlerRegistry console.log(`โœ… Basic handlers registered: ${this.handlerRegistry.getToolCount()} tools available immediately`); } catch (error) { console.error('โŒ Failed to register basic handlers:', error); } } async registerBasicHandlers() { await this.registerBasicHandlersInRegistry(this.handlerRegistry); } /** * Merge handlers from source registry into target registry */ async mergeRegistries(sourceRegistry, targetRegistry) { try { // Get all tools from source registry const sourceTools = sourceRegistry.getAllTools(); // For each tool, get its handler and register it in target registry for (const tool of sourceTools) { const handler = sourceRegistry.getHandlerForTool(tool.name); if (handler && !targetRegistry.getHandlerForTool(tool.name)) { targetRegistry.registerHandler(handler); } } console.log(`โœ… Merged ${sourceTools.length} tools from source registry`); } catch (error) { console.warn('โš ๏ธ Registry merge failed, continuing with target registry:', error); } } async registerBasicHandlersInRegistry(registry) { // Core handler (inject_debugging, monitor_realtime, close_session, get_subscription_info) registry.registerHandler(new CoreHandler(this.localEngine, this.apiKeyManager, this.cloudAI)); // Debug data handler (get_console_logs, get_network_activity, etc.) registry.registerHandler(new DebugDataHandler(this.localEngine, this.sessions)); // Fault injection handler - Architecture issue fixed! registry.registerHandler(new FaultHandler(this.faultEngine)); // Maintenance handler registry.registerHandler(new MaintenanceHandler(new SmartTestMaintenance())); // Interaction handler (simulate_user_action, take_screenshot) registry.registerHandler(new InteractionHandler(this.localEngine)); // Audit handler (run_audit, mock_network) registry.registerHandler(new AuditHandler(this.auditEngine, this.localEngine)); // Analysis handler (analyze_with_ai, get_debug_report) registry.registerHandler(new AnalysisHandler(this.cloudAI, this.localEngine, this.apiKeyManager)); // Flutter handler (all flutter_* tools) registry.registerHandler(new FlutterHandler(this.localEngine, this.quantumDebugger)); // NextJS handler (all nextjs_* tools) registry.registerHandler(new NextJSHandler(this.localEngine, new NextJSDebugEngineEnhanced())); // Hydration handler registry.registerHandler(new HydrationHandler(this.localEngine)); // Bundle handler registry.registerHandler(new BundleHandler(this.localEngine)); // Route handler registry.registerHandler(new RouteHandler(this.localEngine)); // Problem handler registry.registerHandler(new ProblemHandler(this.localEngine)); // Meta-framework handler registry.registerHandler(new MetaFrameworkHandler(new MetaFrameworkDebugEngine())); // Phoenix handler registry.registerHandler(new PhoenixHandler(this.localEngine)); // Evolution handler registry.registerHandler(new EvolutionHandler()); // Elixir handler registry.registerHandler(new ElixirHandler()); } async registerAllAdditionalHandlers() { try { // Ecto handler this.handlerRegistry.registerHandler(new EctoHandler()); // LiveView Advanced handler this.handlerRegistry.registerHandler(new LiveViewAdvancedHandler()); // Phoenix Advanced handler this.handlerRegistry.registerHandler(new PhoenixAdvancedHandler()); // AI handlers (AI/LLM debugging tools) this.handlerRegistry.registerHandler(new AILLMHandler()); this.handlerRegistry.registerHandler(new AIVectorHandler()); this.handlerRegistry.registerHandler(new AIRAGHandler()); this.handlerRegistry.registerHandler(new AIPromptHandler()); // GraphQL handler this.handlerRegistry.registerHandler(new GraphQLHandler()); // Test Generation handler this.handlerRegistry.registerHandler(new TestGenerationHandler()); // Phoenix Test Generation handler this.handlerRegistry.registerHandler(new PhoenixTestGenerationHandler()); // AI Test Enhancement handler this.handlerRegistry.registerHandler(new AITestEnhancementHandler(this.auditEngine, this.localEngine)); // Performance Profiling handler this.handlerRegistry.registerHandler(new PerformanceProfilingHandler()); // Serena Integration handler this.handlerRegistry.registerHandler(new SerenaIntegrationHandler()); this.handlerRegistry.registerHandler(new SubAgentCoordinator()); // AI Feedback handler this.handlerRegistry.registerHandler(new AIFeedbackHandler()); // Dynamic handlers const { AIFeedbackAnalyticsHandler } = await import('./handlers/ai-feedback-analytics-handler.js'); this.handlerRegistry.registerHandler(new AIFeedbackAnalyticsHandler()); const { AIFeedbackCloudHandler } = await import('./handlers/ai-feedback-cloud-handler.js'); this.handlerRegistry.registerHandler(new AIFeedbackCloudHandler()); const { ValueTrackingHandler } = await import('./handlers/value-tracking-handler.js'); this.handlerRegistry.registerHandler(new ValueTrackingHandler()); const { CircuitBreakerHandler } = await import('./handlers/circuit-breaker-handler.js'); this.handlerRegistry.registerHandler(new CircuitBreakerHandler()); // Auto-Update Handler for keeping AI-Debug current with latest features const { AutoUpdateHandler } = await import('./handlers/auto-update-handler.js'); this.handlerRegistry.registerHandler(new AutoUpdateHandler()); console.log(`โœ… Additional handlers registered successfully`); } catch (error) { console.error('โš ๏ธ Some additional handlers failed to load:', error); } } async registerHandlers() { // Core handler (inject_debugging, monitor_realtime, close_session, get_subscription_info) this.handlerRegistry.registerHandler(new CoreHandler(this.localEngine, this.apiKeyManager, this.cloudAI)); // Debug data handler (get_console_logs, get_network_activity, etc.) this.handlerRegistry.registerHandler(new DebugDataHandler(this.localEngine, this.sessions)); // Fault injection handler - Architecture issue fixed! this.handlerRegistry.registerHandler(new FaultHandler(this.faultEngine)); // Maintenance handler this.handlerRegistry.registerHandler(new MaintenanceHandler(new SmartTestMaintenance())); // Interaction handler (simulate_user_action, take_screenshot) this.handlerRegistry.registerHandler(new InteractionHandler(this.localEngine)); // System Automation handler (control_system_mouse, control_system_keyboard, control_vim_terminal) this.handlerRegistry.registerHandler(new SystemAutomationHandler()); // Workflow Orchestration handler (revolutionary tool combinations) this.handlerRegistry.registerHandler(new WorkflowOrchestrationHandler()); // Audit handler (run_audit, mock_network) this.handlerRegistry.registerHandler(new AuditHandler(this.auditEngine, this.localEngine)); // Analysis handler (analyze_with_ai, get_debug_report) this.handlerRegistry.registerHandler(new AnalysisHandler(this.cloudAI, this.localEngine, this.apiKeyManager)); // Flutter handler (all flutter_* tools) this.handlerRegistry.registerHandler(new FlutterHandler(this.localEngine, this.quantumDebugger)); // NextJS handler (all nextjs_* tools) this.handlerRegistry.registerHandler(new NextJSHandler(this.localEngine, new NextJSDebugEngineEnhanced())); // Hydration handler this.handlerRegistry.registerHandler(new HydrationHandler(this.localEngine)); // Bundle handler this.handlerRegistry.registerHandler(new BundleHandler(this.localEngine)); // Route handler this.handlerRegistry.registerHandler(new RouteHandler(this.localEngine)); // Problem handler this.handlerRegistry.registerHandler(new ProblemHandler(this.localEngine)); // Meta-framework handler this.handlerRegistry.registerHandler(new MetaFrameworkHandler(new MetaFrameworkDebugEngine())); // Phoenix handler this.handlerRegistry.registerHandler(new PhoenixHandler(this.localEngine)); // Evolution handler this.handlerRegistry.registerHandler(new EvolutionHandler()); // Elixir handler this.handlerRegistry.registerHandler(new ElixirHandler()); // Ecto handler this.handlerRegistry.registerHandler(new EctoHandler()); // LiveView Advanced handler this.handlerRegistry.registerHandler(new LiveViewAdvancedHandler()); // Phoenix Advanced handler this.handlerRegistry.registerHandler(new PhoenixAdvancedHandler()); // AI handlers (AI/LLM debugging tools) this.handlerRegistry.registerHandler(new AILLMHandler()); this.handlerRegistry.registerHandler(new AIVectorHandler()); this.handlerRegistry.registerHandler(new AIRAGHandler()); this.handlerRegistry.registerHandler(new AIPromptHandler()); // GraphQL handler (GraphQL debugging tools) this.handlerRegistry.registerHandler(new GraphQLHandler()); // Test Generation handler (AI test generation workflow) this.handlerRegistry.registerHandler(new TestGenerationHandler()); // Phoenix Test Generation handler (Phoenix/LiveView test generation) this.handlerRegistry.registerHandler(new PhoenixTestGenerationHandler()); // AI Test Enhancement handler (Issue #22) - CRITICAL MISSING COMPONENT NOW IMPLEMENTED this.handlerRegistry.registerHandler(new AITestEnhancementHandler(this.auditEngine, this.localEngine)); // Performance Profiling handler (Cycle 28) - Enterprise-grade performance analysis this.handlerRegistry.registerHandler(new PerformanceProfilingHandler()); // TDD Handler (Cycle 30 #1 Priority) - Revolutionary Test-Runtime Bridging with AI-Debug Enforcement this.handlerRegistry.registerHandler(new TDDHandler(this.tddEngine)); // Serena Integration handler - Complementary ecosystem integration this.handlerRegistry.registerHandler(new SerenaIntegrationHandler()); this.handlerRegistry.registerHandler(new SubAgentCoordinator()); // AI Feedback handler - Revolutionary AI-driven tool improvement this.handlerRegistry.registerHandler(new AIFeedbackHandler()); // AI Feedback Analytics handler - Phase 2: Intelligence Engine const { AIFeedbackAnalyticsHandler } = await import('./handlers/ai-feedback-analytics-handler.js'); this.handlerRegistry.registerHandler(new AIFeedbackAnalyticsHandler()); // AI Feedback Cloud handler - Remote Collection & Cloud API const { AIFeedbackCloudHandler } = await import('./handlers/ai-feedback-cloud-handler.js'); this.handlerRegistry.registerHandler(new AIFeedbackCloudHandler()); // Value Tracking handler - Real productivity metrics (not token savings) const { ValueTrackingHandler } = await import('./handlers/value-tracking-handler.js'); this.handlerRegistry.registerHandler(new ValueTrackingHandler()); // Circuit breaker management for tool reliability const { CircuitBreakerHandler } = await import('./handlers/circuit-breaker-handler.js'); const circuitBreakerHandler = new CircuitBreakerHandler(); this.handlerRegistry.registerHandler(circuitBreakerHandler); // Apply Phoenix-specific circuit breaker configuration if in Elixir/Phoenix project const circuitBreakerManager = circuitBreakerHandler.getCircuitBreakerManager(); try { // Check for Phoenix project indicators const fs = require('fs'); const context = { framework: process.env.FRAMEWORK, ecosystem: process.env.ECOSYSTEM, hasFile: (filename) => { try { return fs.existsSync(filename); } catch { return false; } } }; // Apply Phoenix configuration if appropriate circuitBreakerManager.applyPhoenixConfiguration(context); } catch (error) { console.warn('โš ๏ธ Failed to apply Phoenix circuit breaker configuration:', error); } // Phoenix Enhanced handler - Addresses all Elixir/Phoenix feedback const { PhoenixEnhancedHandler } = await import('./handlers/phoenix-enhanced-handler.js'); this.handlerRegistry.registerHandler(new PhoenixEnhancedHandler()); // Phoenix Debugging Tools handler - LiveView, GenServer, PubSub debugging const { PhoenixDebuggingToolsHandler } = await import('./handlers/phoenix-debugging-tools-handler.js'); this.handlerRegistry.registerHandler(new PhoenixDebuggingToolsHandler()); // Test Debugging Helper handler - Registration flow, LiveView diagnostics, visual stability const { TestDebuggingHelperHandler } = await import('./handlers/test-debugging-helper-handler.js'); this.handlerRegistry.registerHandler(new TestDebuggingHelperHandler()); // GraphQL Request Inspector handler - GraphQL debugging, failed query analysis, process tracing const { GraphQLRequestInspectorHandler } = await import('./handlers/graphql-request-inspector-handler.js'); this.handlerRegistry.registerHandler(new GraphQLRequestInspectorHandler()); // LiveView Connection Monitor handler - WebSocket tracking, channel events, lifecycle monitoring const { LiveViewConnectionMonitorHandler } = await import('./handlers/liveview-connection-monitor-handler.js'); this.handlerRegistry.registerHandler(new LiveViewConnectionMonitorHandler()); // Mock Coverage Analyzer handler - Mock detection, validation, generation, accessibility const { MockCoverageAnalyzerHandler } = await import('./handlers/mock-coverage-analyzer-handler.js'); this.handlerRegistry.registerHandler(new MockCoverageAnalyzerHandler()); // Backend Process Inspector handler - Process analysis, GraphQL tracing, mock state inspection, timeline visualization const { BackendProcessInspectorHandler } = await import('./handlers/backend-process-inspector-handler.js'); this.handlerRegistry.registerHandler(new BackendProcessInspectorHandler()); // LiveView Lifecycle handler - Process lifecycle tracking, death analysis, message passing, ETS operations const { LiveViewLifecycleHandler } = await import('./handlers/liveview-lifecycle-handler.js'); this.handlerRegistry.registerHandler(new LiveViewLifecycleHandler()); // Mock State Inspector handler - Cross-process mock state inspection, visibility analysis, timeline tracking // Phoenix LiveView Compatibility handler - P1 LiveView compatibility mode with WebSocket conflict resolution const { PhoenixLiveViewCompatibilityHandler } = await import('./handlers/phoenix-liveview-compatibility-handler.js'); this.handlerRegistry.registerHandler(new PhoenixLiveViewCompatibilityHandler()); const { MockStateInspectorHandler } = await import('./handlers/mock-state-inspector-handler.js'); this.handlerRegistry.registerHandler(new MockStateInspectorHandler()); } setupMCPHandlers() { // Handle list tools request this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: this.handlerRegistry.getAllTools() }; }); // Handle tool calls - delegate to handler registry with safety wrapper this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const toolName = request.params.name; const sessionId = request.params.arguments?.sessionId; // Execute tool with safety wrapper const executionResult = await this.toolSafety.executeTool(toolName, async () => { return await this.handlerRegistry.handleTool(toolName, request.params.arguments, this.sessions); }, { timeout: 60000, // 1 minute timeout for tools maxRetries: 2, retryDelay: 1000 }); if (executionResult.success) { return executionResult.result; } // Handle execution failure const error = executionResult.error; try { const errorMessage = error instanceof Error ? error.message : String(error); const errorStack = error instanceof Error ? error.stack : undefined; console.error(`โŒ Tool failed: ${toolName} - ${errorMessage}`); if (errorStack) { console.error(`Stack trace: ${errorStack}`); } // If it's a session-related error, try to clean up the session if (sessionId && typeof sessionId === 'string' && (errorMessage.includes('browser') || errorMessage.includes('page'))) { console.error(`๐Ÿงน Attempting session cleanup for ${sessionId}`); this.cleanupSession(sessionId).catch(() => { }); } return { content: [{ type: 'text', text: `โŒ **Error in ${toolName}**: ${errorMessage} ๐Ÿ›ก๏ธ The server is still running and other tools should work normally. ${sessionId ? `\n๐Ÿ”„ If you're having browser issues, try starting a new session.` : ''}` }] }; } catch (handleError) { // Fallback error handling console.error(`โŒ Critical error handling failure for ${toolName}:`, handleError); return { content: [{ type: 'text', text: `โŒ Critical error in ${toolName}. Server stability systems engaged.` }] }; } }); } async run() { // Acquire connection lock to prevent multiple simultaneous startups if (!(await ConnectionLock.acquire())) { UserFriendlyLogger.showError('Another AI-Debug instance is starting', 'Please wait a moment and try again'); process.exit(1); } // Detect if running in MCP mode (no TTY = called by Claude) this.isMcpMode = !process.stdout.isTTY || process.stdout.isTTY === undefined; // Configure friendly logging based on mode UserFriendlyLogger.configure(this.isMcpMode); // Show friendly startup message UserFriendlyLogger.showStartup(); // Log initial memory usage (quiet in MCP mode) if (!this.isMcpMode) { MemoryEfficientLogger.logMemoryUsage('startup'); this.memoryManager.logMemoryUsage('startup'); } UserFriendlyLogger.showProgress('Initializing memory management'); // Setup global error handlers to prevent crashes this.setupErrorHandlers(); // Setup cleanup on process exit this.setupExitHandlers(); // Connect transport FIRST for immediate MCP communication const transport = new StdioServerTransport(); // Handle transport disconnect to prevent zombie processes transport.onclose = async () => { console.log('๐Ÿ”Œ MCP transport closed, initiating graceful shutdown...'); await this.gracefulShutdown('transport-close'); }; // Handle stdio stream errors to prevent hanging process.stdin.on('end', () => { console.log('๐Ÿ“จ stdin closed, initiating shutdown...'); this.gracefulShutdown('stdin-end').catch(() => process.exit(1)); }); process.stdin.on('error', (err) => { console.error('โŒ stdin error:', err); this.gracefulShutdown('stdin-error').catch(() => process.exit(1)); }); process.stdout.on('error', (err) => { console.error('โŒ stdout error:', err); this.gracefulShutdown('stdout-error').catch(() => process.exit(1)); }); // Load remaining handlers before server starts accepting requests try { console.log('๐Ÿ”ง Loading enhanced handlers...'); await this.preRegisterHandlers(); } catch (error) { console.error('โš ๏ธ Enhanced handler loading failed, continuing with basic handlers:', error); } await this.server.connect(transport); // Initialize background services (non-blocking) setImmediate(() => { this.setupMemoryAwareSessionCleanup(); this.startStabilityMonitoring(); this.startAdvancedStabilityMonitoring(); this.setupSessionRegistry(); // P0 FIX: Start session health monitoring with proactive healing this.startSessionHealthMonitoring(); }); // Output summary with friendly messages const toolCount = this.handlerRegistry.getToolCount(); const memoryUsage = `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB`; UserFriendlyLogger.showReady(toolCount, memoryUsage); if (!this.isMcpMode) { MemoryEfficientLogger.outputRegistrationSummary(); if (this.apiKeyManager.hasValidKey()) { UserFriendlyLogger.showSuccess('Premium features available with your API key'); } else { console.log('๐Ÿ’ก Free tier active - get API key for AI features'); console.log('๐Ÿ”— Upgrade: https://ai-debug.com/pricing'); } } console.log('๐Ÿ›ก๏ธ Memory-optimized stability features active'); // Log lazy loading stats const lazyStats = this.handlerRegistry.getLazyLoadingStats(); console.log(`๐Ÿš€ Lazy loading: ${lazyStats.enabled ? 'ENABLED' : 'DISABLED'}`); if (lazyStats.enabled) { console.log(` - ${lazyStats.lazyHandlers}/${lazyStats.totalHandlers} handlers using lazy loading`); console.log(` - ${lazyStats.toolsWithDependencies.length} tools with external dependencies`); } // Display memory report const memoryReport = this.sessionManager.getMemoryReport(); console.log(`๐Ÿ’พ Memory Report: ${memoryReport.sessionCount} sessions (${memoryReport.memoryStats.sessions.totalMemoryMB} MB)`); if (memoryReport.memoryStats.pressure.isUnderPressure) { console.log('โš ๏ธ Memory pressure detected - enhanced monitoring active'); } // Log final memory usage MemoryEfficientLogger.logMemoryUsage('ready'); // Force garbage collection if available if (MemoryEfficientLogger.isMemoryPressure()) { console.log('โš ๏ธ Memory pressure detected, optimizing...'); MemoryEfficientLogger.forceGC(); } } /** * Enhance handler registry with feedback-driven improvements * Addresses user feedback from Phoenix LiveView, Flutter, and Python projects * Now includes memory-optimized loading strategies */ async enhanceHandlerRegistry() { try { // Check memory-optimized loading strategy const loadingStrategy = this.memoryManager.getToolLoadingStrategy(); console.log(`๐Ÿ”ง Enhancing handler registry with ${loadingStrategy.strategy} loading strategy`); console.log(`๐Ÿ“ Reason: ${loadingStrategy.reason}`); // Create enhanced registry with feedback improvements (includes basic + enhanced handlers) const enhancedRegistry = await HandlerRegistry.createWithFeedbackHandlers(); // Copy existing basic handlers to enhanced registry to avoid duplicates const currentToolCount = this.handlerRegistry.getToolCount(); if (currentToolCount > 0) { console.log(`โ„น๏ธ Preserving ${currentToolCount} existing tools in enhanced registry`); // We'll merge rather than replace to preserve existing registrations await this.mergeRegistries(this.handlerRegistry, enhancedRegistry); } else { // Register basic handlers in the enhanced registry if none exist await this.registerBasicHandlersInRegistry(enhancedRegistry); } // Replace with enhanced registry that includes both basic and advanced handlers this.handlerRegistry = enhancedRegistry; // Now register ALL the additional handlers beyond the feedback handlers await this.registerAllAdditionalHandlers(); // Debug: Check if Go, Rust, and Lua tools are available in both maps const goProjectInspector = this.handlerRegistry.getTool('go_project_inspector'); const rustProjectInspector = this.handlerRegistry.getTool('rust_project_inspector'); const luaProjectInspector = this.handlerRegistry.getTool('lua_project_inspector'); const goHandler = this.handlerRegistry.getHandlerForTool('go_project_inspector'); const rustHandler = this.handlerRegistry.getHandlerForTool('rust_project_inspector'); const luaHandler = this.handlerRegistry.getHandlerForTool('lua_project_inspector'); console.log('๐Ÿ› Debug - Go tool found:', !!goProjectInspector); console.log('๐Ÿ› Debug - Rust tool found:', !!rustProjectInspector); console.log('๐Ÿ› Debug - Lua tool found:', !!luaProjectInspector); console.log('๐Ÿ› Debug - Go handler found:', !!goHandler); console.log('๐Ÿ› Debug - Rust handler found:', !!rustHandler); console.log('๐Ÿ› Debug - Lua handler found:', !!luaHandler); console.log('๐Ÿ› Debug - Total tools in final registry:', this.handlerRegistry.getToolCount()); console.log('โœ… Handler registry enhanced with:'); console.log(' - Debug Workflow Advisor (AI model guidance)'); console.log(' - Python Backend Debugging (full-stack support)'); console.log(' - Flutter Session Stability (error recovery)'); console.log(' - Enhanced Error Handling (specific diagnostics)'); console.log(' - Tool Dependency Management (workflow guidance)'); } catch (error) { console.error('โš ๏ธ Failed to enhance handler registry:', error); console.log('๐Ÿ›ก๏ธ Continuing with basic registry...'); // Fallback to basic registry await this.registerHandlers(); } } setupErrorHandlers() { // Handle unhandled promise rejections process.on('unhandledRejection', (reason, promise) => { console.error('โŒ Unhandled Rejection at:', promise, 'reason:', reason); console.error('๐Ÿ›ก๏ธ Server continuing with error isolation...'); // Don't exit - let the server continue running }); // Handle uncaught exceptions process.on('uncaughtException', (error) => { console.error('โŒ Uncaught Exception:', error); console.error('๐Ÿ›ก๏ธ Attempting graceful cleanup...'); // Attempt cleanup before exit this.emergencyCleanup().finally(() => { process.exit(1); }); }); // Handle warnings process.on('warning', (warning) => { console.error('โš ๏ธ Warning:', warning.name, warning.message); }); } setupExitHandlers() { ServerCleanup.setupShutdownHandlers(this); // Prevent current process from becoming zombie ZombieProcessKiller.preventCurrentProcessZombie(); // Clean up existing zombie processes on startup ZombieProcessKiller.cleanupZombieProcesses().catch(error => { console.error('โŒ Failed to cleanup zombie processes on startup:', error); }); // Setup periodic zombie cleanup every 5 minutes ZombieProcessKiller.setupPeriodicCleanup(5 * 60 * 1000); // Handle normal exit process.on('exit', (code) => { console.error(`๐Ÿ Process exiting with code ${code}`); }); } async gracefulShutdown(reason) { // Safe logging that won't cause EPIPE errors this.safeLog(`๐Ÿ›‘ Graceful shutdown initiated (${reason})...`); try { // Stop session health monitoring SessionStabilityManager.stopHealthMonitoring(); // Release connection lock await ConnectionLock.release(); // Close all browser sessions if (this.sessions.size > 0) { this.safeLog(`๐Ÿงน Closing ${this.sessions.size} active sessions...`); const closePromises = Array.from(this.sessions.keys()).map(sessionId => this.cleanupSession(sessionId).catch(err => this.safeLog(`Failed to close session ${sessionId}: ${err}`))); await Promise.all(closePromises); } // Force cleanup browser processes await BrowserProcessGuardian.getInstance().forceCleanupAll(); // Give a moment for cleanup to complete await new Promise(resolve => setTimeout(resolve, 100)); this.safeLog('โœ… Graceful shutdown complete'); process.exit(0); } catch (error) { this.safeLog(`โŒ Error during graceful shutdown: ${error}`); process.exit(1); } } /** * Setup global stdout error handling to prevent EPIPE cascades */ setupStdoutErrorHandling() { // Handle stdout errors globally process.stdout.on('error', (error) => { if (error.code === 'EPIPE') { this.pipeIsBroken = true; // Silently exit when pipe is broken (normal for head/tail usage) process.exit(0); } }); // Handle stderr errors process.stderr.on('error', (error) => { if (error.code === 'EPIPE') { this.pipeIsBroken = true; process.exit(0); } }); // Override console methods to be pipe-safe const originalLog = console.log; const originalError = console.error; const originalWarn = console.warn; console.log = (...args) => { if (!this.pipeIsBroken) { try { originalLog.apply(console, args); } catch (error) { if (error.code === 'EPIPE') { this.pipeIsBroken = true; process.exit(0); } } } }; console.error = (...args) => { if (!this.pipeIsBroken) { try { originalError.apply(console, args); } catch (error) { if (error.code === 'EPIPE') { this.pipeIsBroken = true; process.exit(0); } } } }; console.warn = (...args) => { if (!this.pipeIsBroken) { try { originalWarn.apply(console, args); } catch (error) { if (error.code === 'EPIPE') { this.pipeIsBroken = true; process.exit(0); } } } }; } /** * Safe logging that prevents EPIPE errors when stdout is closed */ safeLog(message) { if (!this.pipeIsBroken) { console.log(message); } } setupSessionRegistry() { // Setup event listeners for session registry events this.sessionRegistry.on('session_event', (event) => { MemoryEfficientLogger.logMemoryUsage(`session-event-${event.type}`); if (event.severity === 'warning' || event.severity === 'error') { console.warn(`โš ๏ธ Session ${event.projectId}: ${JSON.stringify(event.data)}`); } }); this.sessionRegistry.on('resource_summary', (summary) => { // Log resource usage for monitoring if (summary.quotaUtilization > 80) { console.warn(`๐Ÿ”ฅ High resource utilization: ${summary.quotaUtilization.toFixed(1)}%`); } }); // Log successful initialization console.log('๐Ÿ—๏ธ Multi-Project Session Registry initialized'); console.log(`๐Ÿ“Š Max concurrent sessions: ${this.sessionRegistry['config'].defaultQuotas.maxConcurrentSessions}`); console.log(`๐Ÿ”Œ Port range: ${this.sessionRegistry['config'].basePort}+`); } setupMemoryAwareSessionCleanup() { // Clean up stale sessions every 3 minutes with memory awareness setInterval(async () => { try { // Use memory-aware session manager for cleanup await this.sessionManager.cleanupExpiredSessions(); // Perform emergency cleanup if memory pressure detected await this.sessionManager.performEmergencyCleanup(); // Also clean up legacy sessions map (for backward compatibility) ServerCleanup.cleanupStaleSessions(this.sessions); } catch (error) { console.error('โš ๏ธ Session cleanup failed:', error); } }, 3 * 60 * 1000); } /** * Start comprehensive stability monitoring */ startStabilityMonitoring() { console.log('๐Ÿ›ก๏ธ Starting comprehensive stability monitoring...'); // Start browser process monitoring this.browserGuardian.startMonitoring(); // Start periodic stability reporting setInterval(() => { this.logStabilityReport(); }, 10 * 60 * 1000); // Every 10 minutes } /** * Start advanced stability monitoring (crash prevention + leak detection) */ startAdvancedStabilityMonitoring() { console.log('๐Ÿšจ Starting advanced crash prevention and leak detection...'); // Start crash prevention monitoring this.crashPrevention.startMonitoring(); // Start resource leak detection this.leakDetector.startMonitoring(); // Set up event handlers for critical situations this.crashPrevention.on('emergencyCleanup', async (data) => { console.error('๐Ÿšจ EMERGENCY CLEANUP TRIGGERED:', data.reason); console.error(' Factors:', data.factors.join(', ')); try { // Perform emergency cleanup await this.emergencyCleanup(); // Force garbage collection if available if (global.gc) { global.gc(); console.error('๐Ÿ—‘๏ธ Emergency garbage collection completed'); } // Clean up all sessions await this.sessionRegistry.emergencyCleanup(); // Clear memory-aware sessions await this.sessionManager.performEmergencyCleanup(); } catch (error) { console.error('โŒ Emergency cleanup failed:', error); } }); this.leakDetector.on('leakDetected', (detection) => { console.warn(`๐Ÿ” ${detection.type.toUpperCase()} LEAK: ${detection.description}`); // Attempt automatic mitigation for critical leaks if (detection.severity === 'critical') { const mitigated = this.leakDetector.attemptLeakMitigation(detection); if (mitigated) { console.warn('โœ… Automatic leak mitigation applied'); } else { console.warn('โŒ Manual intervention required for leak mitigation'); } } }); // Health check interval setInterval(() => { const { health, risk } = this.crashPrevention.performHealthCheck(); if (risk.level === 'high' || risk.level === 'critical') { console.error(`๐Ÿšจ System health warning: ${risk.level.toUpperCase()}`); console.error(` Memory: ${(health.memoryUsage.heapUsed / 1024 / 1024).toFixed(1)}MB`); console.error(` Load: ${health.loadAverage[0].toFixed(2)}`); } }, 2 * 60 * 1000); // Every 2 minutes } /** * P0 FIX: Start session health monitoring with proactive healing * Addresses critical user feedback: "Sessions consistently disconnect after 20-40 seconds" */ startSessionHealthMonitoring() { console.log('๐Ÿฅ Starting proactive session health monitoring...'); // Start health monitoring with 10-second heartbeat as requested in feedback SessionStabilityManager.startHealthMonitoring(this.sessions, 10000); console.log('โœ… Session health monitoring active:'); console.log(' - 10-second health heartbeat'); console.log(' - Automatic session recovery'); console.log(' - Proactive healing before disconnection'); console.log(' - Enhanced error reporting with recovery context'); } /** * Log comprehensive stability report */ logStabilityReport() { const memoryReport = this.sessionManager.getMemoryReport(); const processStats = this.browserGuardian.getProcessStats(); const networkStats = this.networkManager.getNetworkStats(); const executionStats = this.toolSafety.getExecutionStats(); console.log('๐Ÿ“Š STABILITY REPORT:'); console.log(` Memory: ${memoryReport.memoryStats.pressure.heapUsedMB} MB (${memoryReport.memoryStats.pressure.heapUsagePercent}%)`); console.log(` Sessions: ${memoryReport.sessionCount} active`); console.log(` Browser Processes: ${processStats.activeProcesses} active, ${processStats.zombieProcesses} zombies`); console.log(` Network: ${networkStats.successfulRequests}/${networkStats.totalRequests} successful, ${networkStats.circuitBreakerTrips} breaker trips`); console.log(` Tools: ${executionStats.totalTools} monitored, ${executionStats.circuitBreakersOpen} breakers open`); // Alert on concerning metrics if (memoryReport.memoryStats.pressure.isUnderPressure) { console.warn('โš ๏ธ Memory pressure detected!'); } if (processStats.zombieProcesses > 0) { console.warn(`โš ๏ธ ${processStats.zombieProcesses} zombie browser processes d