UNPKG

@ai-capabilities-suite/mcp-debugger-core

Version:

Core debugging engine for Node.js and TypeScript applications. Provides Inspector Protocol integration, breakpoint management, variable inspection, execution control, profiling, hang detection, and source map support.

137 lines 4.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionManager = void 0; const crypto_1 = require("crypto"); const debug_session_1 = require("./debug-session"); const audit_logger_1 = require("./audit-logger"); /** * Manages multiple concurrent debug sessions * Provides session isolation and lifecycle management */ class SessionManager { constructor(auditLogger) { this.sessions = new Map(); this.auditLogger = auditLogger || new audit_logger_1.AuditLogger(); } /** * Generate a unique session ID */ generateSessionId() { return (0, crypto_1.randomBytes)(16).toString('hex'); } /** * Create a new debug session * @param config Session configuration * @returns The created debug session */ async createSession(config) { const sessionId = this.generateSessionId(); const session = new debug_session_1.DebugSession(sessionId, config); // Store session before starting to ensure it's tracked this.sessions.set(sessionId, session); // Register crash handler to automatically clean up crashed sessions session.onCrash((error) => { // Log crash this.auditLogger.log(sessionId, 'session_crash', { error: error.message }, false, error.message); // Session will clean itself up, we just need to remove it from tracking this.sessions.delete(sessionId); }); try { await session.start(); this.auditLogger.log(sessionId, 'session_create', { command: config.command, args: config.args }, true); return session; } catch (error) { // Remove session if start fails this.sessions.delete(sessionId); this.auditLogger.log(sessionId, 'session_create', { command: config.command, args: config.args }, false, error instanceof Error ? error.message : String(error)); throw error; } } /** * Get a session by ID * @param sessionId Session identifier * @returns The debug session or undefined if not found */ getSession(sessionId) { return this.sessions.get(sessionId); } /** * Get all active sessions * @returns Array of all debug sessions */ getAllSessions() { return Array.from(this.sessions.values()); } /** * Check if a session exists * @param sessionId Session identifier * @returns True if session exists */ hasSession(sessionId) { return this.sessions.has(sessionId); } /** * Remove and cleanup a session * @param sessionId Session identifier * @returns True if session was found and removed */ async removeSession(sessionId) { const session = this.sessions.get(sessionId); if (!session) { this.auditLogger.log(sessionId, 'session_remove', {}, false, 'Session not found'); return false; } try { await session.cleanup(); this.sessions.delete(sessionId); this.auditLogger.log(sessionId, 'session_remove', {}, true); return true; } catch (error) { this.auditLogger.log(sessionId, 'session_remove', {}, false, error instanceof Error ? error.message : String(error)); throw error; } } /** * Cleanup all sessions */ async cleanupAll() { const cleanupPromises = Array.from(this.sessions.values()).map(async (session) => { try { await session.cleanup(); } catch (error) { // Log error but continue with other cleanups console.warn('Error during session cleanup:', error); } }); await Promise.allSettled(cleanupPromises); this.sessions.clear(); } /** * Get the number of active sessions */ getSessionCount() { return this.sessions.size; } /** * Get the audit logger * @returns The audit logger instance */ getAuditLogger() { return this.auditLogger; } /** * Remove terminated sessions */ pruneTerminatedSessions() { for (const [id, session] of this.sessions.entries()) { if (!session.isActive()) { this.sessions.delete(id); } } } } exports.SessionManager = SessionManager; //# sourceMappingURL=session-manager.js.map