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.

476 lines (475 loc) 15.2 kB
import { ChildProcess } from "child_process"; import { InspectorClient } from "./inspector-client"; import { BreakpointManager } from "./breakpoint-manager"; import { EvaluationResult, PropertyDescriptor } from "./variable-inspector"; import { SourceMapManager } from "./source-map-manager"; import { CPUProfiler, CPUProfile, ProfileAnalysis } from "./cpu-profiler"; import { MemoryProfiler, HeapSnapshot, MemoryUsage, MemoryLeakAnalysis, MemoryReport } from "./memory-profiler"; import { PerformanceTimeline, PerformanceReport } from "./performance-timeline"; /** * Breakpoint type enumeration */ export declare enum BreakpointType { STANDARD = "standard", LOGPOINT = "logpoint", EXCEPTION = "exception", FUNCTION = "function" } /** * Hit count operator for hit count breakpoints */ export declare enum HitCountOperator { EQUAL = "==", GREATER = ">", GREATER_EQUAL = ">=", LESS = "<", LESS_EQUAL = "<=", MODULO = "%" } /** * Hit count condition for breakpoints */ export interface HitCountCondition { operator: HitCountOperator; value: number; } /** * Breakpoint definition stored in a debug session */ export interface Breakpoint { id: string; file: string; line: number; condition?: string; enabled: boolean; cdpBreakpointId?: string; type?: BreakpointType; logMessage?: string; hitCount?: number; hitCountCondition?: HitCountCondition; functionName?: string; } /** * Watched variable definition */ export interface WatchedVariable { name: string; expression: string; lastValue?: any; } /** * Exception breakpoint configuration */ export interface ExceptionBreakpoint { id: string; breakOnCaught: boolean; breakOnUncaught: boolean; exceptionFilter?: string; enabled: boolean; } /** * Stack frame information */ export interface StackFrame { functionName: string; file: string; line: number; column: number; callFrameId: string; } /** * Debug session state */ export declare enum SessionState { STARTING = "starting", PAUSED = "paused", RUNNING = "running", TERMINATED = "terminated" } /** * Configuration for starting a debug session */ export interface DebugSessionConfig { command: string; args?: string[]; cwd?: string; timeout?: number; } /** * Represents a single debug session with a target process * Tracks session state, breakpoints, and watched variables */ export declare class DebugSession { readonly id: string; private process; private inspector; private state; private breakpointManager; private cdpBreakpointOps; private variableInspector; private sourceMapManager; private watchedVariables; private watchedVariableChanges; private exceptionBreakpoints; private config; private currentCallFrames; private currentFrameIndex; private crashHandlers; private crashError?; private cpuProfiler; private memoryProfiler; private performanceTimeline; constructor(id: string, config: DebugSessionConfig); /** * Start the debug session by spawning the process and connecting the inspector */ start(): Promise<void>; /** * Pause the running process * Waits for the Debugger.paused event to ensure call frames are populated */ pause(): Promise<void>; /** * Resume execution of the paused process */ resume(): Promise<void>; /** * Step over the current line * Executes the current line and pauses at the next line in the same scope */ stepOver(): Promise<void>; /** * Step into the current line * Executes the current line and pauses at the first line inside any called function */ stepInto(): Promise<void>; /** * Step out of the current function * Executes until the current function returns and pauses at the calling location */ stepOut(): Promise<void>; /** * Clean up session resources */ cleanup(): Promise<void>; /** * Get the current session state */ getState(): SessionState; /** * Get the inspector client */ getInspector(): InspectorClient | null; /** * Get the process handle */ getProcess(): ChildProcess | null; /** * Set a breakpoint in the session * Creates the breakpoint and sets it via CDP * Maps TypeScript locations to JavaScript when source maps are available * Requirements: 7.2 */ setBreakpoint(file: string, line: number, condition?: string): Promise<Breakpoint>; /** * Set a logpoint in the session * Creates a logpoint that logs a message without pausing execution * @param file File path where the logpoint should be set * @param line Line number (1-indexed) * @param logMessage Log message template with {variable} interpolation * @returns The created logpoint */ setLogpoint(file: string, line: number, logMessage: string): Promise<Breakpoint>; /** * Set a function breakpoint in the session * Creates a breakpoint that pauses when a function with the given name is called * @param functionName Function name or regex pattern * @returns The created function breakpoint */ setFunctionBreakpoint(functionName: string): Promise<Breakpoint>; /** * Set hit count condition for a breakpoint * @param id Breakpoint identifier * @param condition Hit count condition * @returns The updated breakpoint or undefined if not found */ setBreakpointHitCountCondition(id: string, condition: HitCountCondition): Breakpoint | undefined; /** * Get the breakpoint manager for this session */ getBreakpointManager(): BreakpointManager; /** * Set an exception breakpoint * Configures the debugger to pause on caught and/or uncaught exceptions * @param breakOnCaught Whether to break on caught exceptions * @param breakOnUncaught Whether to break on uncaught exceptions * @param exceptionFilter Optional regex pattern to filter exceptions by type/message * @returns The created exception breakpoint */ setExceptionBreakpoint(breakOnCaught: boolean, breakOnUncaught: boolean, exceptionFilter?: string): Promise<ExceptionBreakpoint>; /** * Remove an exception breakpoint * @param id Exception breakpoint identifier * @returns True if the exception breakpoint was found and removed */ removeExceptionBreakpoint(id: string): Promise<boolean>; /** * Get all exception breakpoints * @returns Array of all exception breakpoints */ getAllExceptionBreakpoints(): ExceptionBreakpoint[]; /** * Get an exception breakpoint by ID * @param id Exception breakpoint identifier * @returns The exception breakpoint or undefined if not found */ getExceptionBreakpoint(id: string): ExceptionBreakpoint | undefined; /** * Get a breakpoint by ID */ getBreakpoint(id: string): Breakpoint | undefined; /** * Get all breakpoints */ getAllBreakpoints(): Breakpoint[]; /** * Remove a breakpoint from the session * Removes from manager and from CDP */ removeBreakpoint(id: string): Promise<boolean>; /** * Toggle a breakpoint's enabled state */ toggleBreakpoint(id: string): Promise<Breakpoint | undefined>; /** * Add a breakpoint to the session (legacy method for compatibility) */ addBreakpoint(breakpoint: Breakpoint): void; /** * Add a watched variable */ addWatchedVariable(variable: WatchedVariable): void; /** * Get a watched variable by name */ getWatchedVariable(name: string): WatchedVariable | undefined; /** * Get all watched variables */ getAllWatchedVariables(): WatchedVariable[]; /** * Remove a watched variable */ removeWatchedVariable(name: string): boolean; /** * Check if the session is active (not terminated) */ isActive(): boolean; /** * Check if the session is paused */ isPaused(): boolean; /** * Evaluate an expression in the current execution context * @param expression The JavaScript expression to evaluate * @param callFrameId Optional call frame ID (uses current frame if not provided) * @returns The evaluation result with type information */ evaluateExpression(expression: string, callFrameId?: string): Promise<EvaluationResult>; /** * Get properties of an object by its object ID * @param objectId The CDP object ID * @returns Array of property descriptors */ getObjectProperties(objectId: string): Promise<PropertyDescriptor[]>; /** * Inspect an object with nested property resolution * @param objectId The CDP object ID * @param maxDepth Maximum depth to traverse (default: 2) * @returns Nested object structure */ inspectObject(objectId: string, maxDepth?: number): Promise<Record<string, any>>; /** * Get the current call frames */ getCurrentCallFrames(): any[]; /** * Get the call stack with formatted stack frames * Returns stack frames with function names, files (absolute paths), and line numbers * Maps JavaScript locations back to TypeScript when source maps are available * Requirements: 4.1, 9.4, 7.3 */ getCallStack(): Promise<StackFrame[]>; /** * Get the call stack synchronously (without source map mapping) * Use getCallStack() for source map support * @deprecated Use getCallStack() instead for source map support */ getCallStackSync(): StackFrame[]; /** * Evaluate watched variables and detect changes * Should be called when the process pauses */ evaluateWatchedVariables(): Promise<Map<string, { oldValue: any; newValue: any; }>>; /** * Get the latest watched variable changes from the last pause * Returns a map of variable names to their old and new values */ getWatchedVariableChanges(): Map<string, { oldValue: any; newValue: any; }>; /** * Clear the watched variable changes */ clearWatchedVariableChanges(): void; /** * Switch context to a different stack frame by index * Updates the current frame for variable inspection * Requirements: 4.2, 4.3 * @param frameIndex The index of the frame to switch to (0 = top frame) */ switchToFrame(frameIndex: number): void; /** * Get the current frame index */ getCurrentFrameIndex(): number; /** * Get the call frame ID for the current frame */ getCurrentCallFrameId(): string | undefined; /** * Get the source map manager for this session */ getSourceMapManager(): SourceMapManager; /** * Map a source location to compiled location using source maps * Requirements: 7.2 */ mapSourceToCompiled(file: string, line: number, column?: number): Promise<import("./source-map-manager").CompiledLocation | null>; /** * Map a compiled location to source location using source maps * Requirements: 7.3 */ mapCompiledToSource(file: string, line: number, column?: number): Promise<import("./source-map-manager").SourceLocation | null>; /** * Handle process exit event * Detects unexpected terminations and cleans up resources * Requirements: 8.1 */ private handleProcessExit; /** * Handle process error event * Detects spawn errors and other process-level errors * Requirements: 8.1 */ private handleProcessError; /** * Register a crash handler callback * The handler will be called when the process crashes or terminates unexpectedly * Multiple handlers can be registered and all will be called * Requirements: 8.1 */ onCrash(handler: (error: Error) => void): void; /** * Get the crash error if the process crashed * Returns undefined if the process terminated normally * Requirements: 8.1 */ getCrashError(): Error | undefined; /** * Check if the process crashed * Returns true if the process terminated unexpectedly * Requirements: 8.1 */ hasCrashed(): boolean; /** * Start CPU profiling * Begins collecting CPU profile data for performance analysis */ startCPUProfile(): Promise<void>; /** * Stop CPU profiling and return the profile data * @returns The captured CPU profile */ stopCPUProfile(): Promise<CPUProfile>; /** * Check if CPU profiling is currently active */ isCPUProfiling(): boolean; /** * Get the CPU profiler instance */ getCPUProfiler(): CPUProfiler | null; /** * Analyze a CPU profile to identify bottlenecks * @param profile The CPU profile to analyze * @returns Analysis results with top functions and bottlenecks */ analyzeCPUProfile(profile: CPUProfile): ProfileAnalysis; /** * Take a heap snapshot for memory analysis * @returns The heap snapshot data */ takeHeapSnapshot(): Promise<HeapSnapshot>; /** * Get current memory usage statistics * @returns Memory usage information */ getMemoryUsage(): Promise<MemoryUsage>; /** * Start tracking heap allocations over time * @param samplingInterval Sampling interval in bytes */ startTrackingHeapObjects(samplingInterval?: number): Promise<void>; /** * Stop tracking heap allocations * @returns The final heap snapshot */ stopTrackingHeapObjects(): Promise<HeapSnapshot>; /** * Detect memory leaks by analyzing heap growth over time * @param durationMs Duration to monitor in milliseconds * @param intervalMs Interval between snapshots in milliseconds * @returns Memory leak analysis */ detectMemoryLeaks(durationMs?: number, intervalMs?: number): Promise<MemoryLeakAnalysis>; /** * Generate a memory usage report * @param snapshot Optional heap snapshot to analyze * @returns Memory usage report */ generateMemoryReport(snapshot?: HeapSnapshot): Promise<MemoryReport>; /** * Get the memory profiler instance */ getMemoryProfiler(): MemoryProfiler | null; /** * Start recording performance events */ startPerformanceRecording(): Promise<void>; /** * Stop recording performance events and get the report * @returns Performance report */ stopPerformanceRecording(): Promise<PerformanceReport>; /** * Check if performance recording is active */ isPerformanceRecording(): boolean; /** * Record a function call timing in the performance timeline * @param functionName Name of the function * @param file File path * @param line Line number * @param duration Duration in microseconds */ recordFunctionCall(functionName: string, file: string, line: number, duration: number): void; /** * Get the performance timeline instance */ getPerformanceTimeline(): PerformanceTimeline | null; }