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
JavaScript
#!/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