UNPKG

@debugmcp/mcp-debugger

Version:

Run-time step-through debugging for LLM agents.

364 lines (363 loc) 11.1 kB
/** * Core Debug Adapter Interface for multi-language debugging support * * This interface defines the contract that all language-specific debug adapters * must implement. It abstracts the Debug Adapter Protocol (DAP) operations * while allowing language-specific implementations. * * Design Principles: * - Language agnostic * - Async-first for all operations * - Event-driven for state changes * - Minimal overhead (< 5ms per operation) * * @since 2.0.0 */ import { EventEmitter } from 'events'; import { DebugProtocol } from '@vscode/debugprotocol'; import { DebugLanguage } from '../session/models.js'; /** * Core debug adapter interface that all language adapters must implement */ export interface IDebugAdapter extends EventEmitter { readonly language: DebugLanguage; readonly name: string; /** * Initialize the adapter and validate the environment */ initialize(): Promise<void>; /** * Clean up resources and connections */ dispose(): Promise<void>; /** * Get the current adapter state */ getState(): AdapterState; /** * Check if the adapter is ready for debugging */ isReady(): boolean; /** * Get the current thread ID (if debugging) */ getCurrentThreadId(): number | null; /** * Validate that the environment is properly configured for debugging */ validateEnvironment(): Promise<ValidationResult>; /** * Get list of required dependencies for this adapter */ getRequiredDependencies(): DependencyInfo[]; /** * Resolve the path to the language executable * @param preferredPath Optional user-specified path */ resolveExecutablePath(preferredPath?: string): Promise<string>; /** * Get the default executable name for this language * @example 'python', 'node', 'go' */ getDefaultExecutableName(): string; /** * Get platform-specific paths to search for the executable */ getExecutableSearchPaths(): string[]; /** * Build the command to launch the debug adapter */ buildAdapterCommand(config: AdapterConfig): AdapterCommand; /** * Get the debug adapter module name * @example 'debugpy.adapter', 'node-debug2' */ getAdapterModuleName(): string; /** * Get the command to install the debug adapter * @example 'pip install debugpy', 'npm install -g node-debug2' */ getAdapterInstallCommand(): string; /** * Transform generic launch config to language-specific format */ transformLaunchConfig(config: GenericLaunchConfig): LanguageSpecificLaunchConfig; /** * Get default launch configuration for this language */ getDefaultLaunchConfig(): Partial<GenericLaunchConfig>; /** * Send a DAP request through the adapter */ sendDapRequest<T extends DebugProtocol.Response>(command: string, args?: unknown): Promise<T>; /** * Handle incoming DAP event */ handleDapEvent(event: DebugProtocol.Event): void; /** * Handle incoming DAP response */ handleDapResponse(response: DebugProtocol.Response): void; /** * Connect to the debug adapter */ connect(host: string, port: number): Promise<void>; /** * Disconnect from the debug adapter */ disconnect(): Promise<void>; /** * Check if connected to the debug adapter */ isConnected(): boolean; /** * Get installation instructions for this language's debugger */ getInstallationInstructions(): string; /** * Get error message when executable is missing */ getMissingExecutableError(): string; /** * Translate generic errors to language-specific messages */ translateErrorMessage(error: Error): string; /** * Check if a specific debug feature is supported */ supportsFeature(feature: DebugFeature): boolean; /** * Get requirements for a specific feature */ getFeatureRequirements(feature: DebugFeature): FeatureRequirement[]; /** * Get full capability declaration */ getCapabilities(): AdapterCapabilities; } /** * Adapter state enumeration */ export declare enum AdapterState { UNINITIALIZED = "uninitialized", INITIALIZING = "initializing", READY = "ready", CONNECTED = "connected", DEBUGGING = "debugging", DISCONNECTED = "disconnected", ERROR = "error" } /** * Environment validation result */ export interface ValidationResult { valid: boolean; errors: ValidationError[]; warnings: ValidationWarning[]; } /** * Validation error details */ export interface ValidationError { code: string; message: string; recoverable: boolean; } /** * Validation warning details */ export interface ValidationWarning { code: string; message: string; } /** * Dependency information */ export interface DependencyInfo { name: string; version?: string; required: boolean; installCommand?: string; } /** * Command to launch debug adapter */ export interface AdapterCommand { command: string; args: string[]; env?: Record<string, string>; } /** * Adapter configuration */ export interface AdapterConfig { sessionId: string; executablePath: string; adapterHost: string; adapterPort: number; logDir: string; scriptPath: string; scriptArgs?: string[]; launchConfig: GenericLaunchConfig; } /** * Generic launch configuration (common across languages) */ export interface GenericLaunchConfig { stopOnEntry?: boolean; justMyCode?: boolean; env?: Record<string, string>; cwd?: string; args?: string[]; } /** * Language-specific launch configuration */ export interface LanguageSpecificLaunchConfig extends GenericLaunchConfig { [key: string]: unknown; } /** * Debug features enumeration (from DAP spec) */ export declare enum DebugFeature { CONDITIONAL_BREAKPOINTS = "conditionalBreakpoints", FUNCTION_BREAKPOINTS = "functionBreakpoints", EXCEPTION_BREAKPOINTS = "exceptionBreakpoints", VARIABLE_PAGING = "variablePaging", EVALUATE_FOR_HOVERS = "evaluateForHovers", SET_VARIABLE = "setVariable", SET_EXPRESSION = "setExpression", DATA_BREAKPOINTS = "dataBreakpoints", DISASSEMBLE_REQUEST = "disassembleRequest", TERMINATE_THREADS_REQUEST = "terminateThreadsRequest", DELAYED_STACK_TRACE_LOADING = "delayedStackTraceLoading", LOADED_SOURCES_REQUEST = "loadedSourcesRequest", LOG_POINTS = "logPoints", TERMINATE_REQUEST = "terminateRequest", RESTART_REQUEST = "restartRequest", EXCEPTION_OPTIONS = "exceptionOptions", EXCEPTION_INFO_REQUEST = "exceptionInfoRequest", STEP_BACK = "stepBack", REVERSE_DEBUGGING = "reverseDebugging", STEP_IN_TARGETS_REQUEST = "stepInTargetsRequest" } /** * Feature requirement details */ export interface FeatureRequirement { type: 'dependency' | 'version' | 'configuration'; description: string; required: boolean; } /** * Full adapter capabilities (mirrors DAP capabilities) */ export interface AdapterCapabilities { supportsConfigurationDoneRequest?: boolean; supportsFunctionBreakpoints?: boolean; supportsConditionalBreakpoints?: boolean; supportsHitConditionalBreakpoints?: boolean; supportsEvaluateForHovers?: boolean; exceptionBreakpointFilters?: ExceptionBreakpointFilter[]; supportsStepBack?: boolean; supportsSetVariable?: boolean; supportsRestartFrame?: boolean; supportsGotoTargetsRequest?: boolean; supportsStepInTargetsRequest?: boolean; supportsCompletionsRequest?: boolean; completionTriggerCharacters?: string[]; supportsModulesRequest?: boolean; additionalModuleColumns?: DebugProtocol.ColumnDescriptor[]; supportedChecksumAlgorithms?: DebugProtocol.ChecksumAlgorithm[]; supportsRestartRequest?: boolean; supportsExceptionOptions?: boolean; supportsValueFormattingOptions?: boolean; supportsExceptionInfoRequest?: boolean; supportTerminateDebuggee?: boolean; supportSuspendDebuggee?: boolean; supportsDelayedStackTraceLoading?: boolean; supportsLoadedSourcesRequest?: boolean; supportsLogPoints?: boolean; supportsTerminateThreadsRequest?: boolean; supportsSetExpression?: boolean; supportsTerminateRequest?: boolean; supportsDataBreakpoints?: boolean; supportsReadMemoryRequest?: boolean; supportsWriteMemoryRequest?: boolean; supportsDisassembleRequest?: boolean; supportsCancelRequest?: boolean; supportsBreakpointLocationsRequest?: boolean; supportsClipboardContext?: boolean; supportsSteppingGranularity?: boolean; supportsInstructionBreakpoints?: boolean; supportsExceptionFilterOptions?: boolean; supportsSingleThreadExecutionRequests?: boolean; } /** * Exception breakpoint filter */ export interface ExceptionBreakpointFilter { filter: string; label: string; description?: string; default?: boolean; supportsCondition?: boolean; conditionDescription?: string; } /** * Base adapter error class */ export declare class AdapterError extends Error { code: AdapterErrorCode; recoverable: boolean; constructor(message: string, code: AdapterErrorCode, recoverable?: boolean); } /** * Adapter error codes */ export declare enum AdapterErrorCode { ENVIRONMENT_INVALID = "ENVIRONMENT_INVALID", EXECUTABLE_NOT_FOUND = "EXECUTABLE_NOT_FOUND", ADAPTER_NOT_INSTALLED = "ADAPTER_NOT_INSTALLED", INCOMPATIBLE_VERSION = "INCOMPATIBLE_VERSION", CONNECTION_FAILED = "CONNECTION_FAILED", CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT", CONNECTION_LOST = "CONNECTION_LOST", INVALID_RESPONSE = "INVALID_RESPONSE", UNSUPPORTED_OPERATION = "UNSUPPORTED_OPERATION", DEBUGGER_ERROR = "DEBUGGER_ERROR", SCRIPT_NOT_FOUND = "SCRIPT_NOT_FOUND", PERMISSION_DENIED = "PERMISSION_DENIED", UNKNOWN_ERROR = "UNKNOWN_ERROR" } /** * Events emitted by debug adapters */ export interface AdapterEvents { 'stopped': (event: DebugProtocol.StoppedEvent) => void; 'continued': (event: DebugProtocol.ContinuedEvent) => void; 'terminated': (event: DebugProtocol.TerminatedEvent) => void; 'exited': (event: DebugProtocol.ExitedEvent) => void; 'thread': (event: DebugProtocol.ThreadEvent) => void; 'output': (event: DebugProtocol.OutputEvent) => void; 'breakpoint': (event: DebugProtocol.BreakpointEvent) => void; 'module': (event: DebugProtocol.ModuleEvent) => void; 'initialized': () => void; 'connected': () => void; 'disconnected': () => void; 'error': (error: AdapterError) => void; 'stateChanged': (oldState: AdapterState, newState: AdapterState) => void; } /** * Configuration migration utilities */ export interface ConfigMigration { /** * Transform old Python-specific config to generic config */ migratePythonConfig(oldConfig: Record<string, unknown>): GenericLaunchConfig; /** * Check if a config needs migration */ needsMigration(config: Record<string, unknown>): boolean; }