@debugmcp/mcp-debugger
Version:
Run-time step-through debugging for LLM agents.
212 lines (211 loc) • 5.55 kB
TypeScript
/**
* Core interfaces and types for the DAP Proxy system
* These abstractions enable dependency injection and testability
*/
import { ChildProcess, SpawnOptions } from 'child_process';
import { DebugProtocol } from '@vscode/debugprotocol';
export interface ProxyInitPayload {
cmd: 'init';
sessionId: string;
executablePath: string;
adapterHost: string;
adapterPort: number;
logDir: string;
scriptPath: string;
scriptArgs?: string[];
stopOnEntry?: boolean;
justMyCode?: boolean;
initialBreakpoints?: {
file: string;
line: number;
condition?: string;
}[];
dryRunSpawn?: boolean;
adapterCommand?: {
command: string;
args: string[];
env?: Record<string, string>;
};
}
export interface DapCommandPayload {
cmd: 'dap';
requestId: string;
dapCommand: string;
dapArgs?: unknown;
sessionId: string;
}
export interface TerminatePayload {
cmd: 'terminate';
sessionId: string;
}
export type ParentCommand = ProxyInitPayload | DapCommandPayload | TerminatePayload;
export interface ProxyMessage {
type: 'status' | 'dapResponse' | 'dapEvent' | 'error';
sessionId: string;
[key: string]: unknown;
}
export interface StatusMessage extends ProxyMessage {
type: 'status';
status: string;
code?: number | null;
signal?: NodeJS.Signals | null;
command?: string;
script?: string;
}
export interface DapResponseMessage extends ProxyMessage {
type: 'dapResponse';
requestId: string;
success: boolean;
body?: unknown;
response?: DebugProtocol.Response;
error?: string;
}
export interface DapEventMessage extends ProxyMessage {
type: 'dapEvent';
event: string;
body: unknown;
}
export interface ErrorMessage extends ProxyMessage {
type: 'error';
message: string;
}
/**
* Logger interface for dependency injection
*/
export interface ILogger {
info(message: string, ...args: unknown[]): void;
error(message: string, ...args: unknown[]): void;
debug(message: string, ...args: unknown[]): void;
warn(message: string, ...args: unknown[]): void;
}
/**
* File system operations abstraction
*/
export interface IFileSystem {
ensureDir(path: string): Promise<void>;
pathExists(path: string): Promise<boolean>;
}
/**
* Process spawning abstraction
*/
export interface IProcessSpawner {
spawn(command: string, args: string[], options: SpawnOptions): ChildProcess;
}
/**
* DAP client abstraction matching MinimalDapClient interface
*/
export interface IDapClient {
connect(): Promise<void>;
sendRequest<T = unknown>(command: string, args?: unknown): Promise<T>;
disconnect(): void;
/**
* Reject all pending requests, clear timers, dispose resources.
* Should be idempotent.
*/
shutdown(reason?: string): void;
on(event: string, handler: (...args: any[]) => void): void;
off(event: string, handler: (...args: any[]) => void): void;
once(event: string, handler: (...args: any[]) => void): void;
removeAllListeners(): void;
}
/**
* Factory for creating DAP clients
*/
export interface IDapClientFactory {
create(host: string, port: number): IDapClient;
}
/**
* Message sender abstraction for IPC communication
*/
export interface IMessageSender {
send(message: unknown): void;
}
/**
* Logger factory for delayed initialization
*/
export interface ILoggerFactory {
(sessionId: string, logDir: string): Promise<ILogger>;
}
/**
* Configuration for spawning the debug adapter
*/
export interface AdapterConfig {
executablePath: string;
host: string;
port: number;
logDir: string;
cwd?: string;
env?: NodeJS.ProcessEnv;
}
/**
* Spawn result from adapter manager
*/
export interface AdapterSpawnResult {
process: ChildProcess;
pid: number;
}
/**
* Proxy worker state for state machine pattern
*/
export declare enum ProxyState {
UNINITIALIZED = "uninitialized",
INITIALIZING = "initializing",
CONNECTED = "connected",
SHUTTING_DOWN = "shutting_down",
TERMINATED = "terminated"
}
/**
* Request tracking information
*/
export interface TrackedRequest {
requestId: string;
command: string;
timer: NodeJS.Timeout;
timestamp: number;
}
/**
* Request tracker interface
*/
export interface IRequestTracker {
track(requestId: string, command: string, timeoutMs: number): void;
complete(requestId: string): void;
clear(): void;
getPending(): Map<string, TrackedRequest>;
}
/**
* All dependencies needed by DapProxyWorker
*/
export interface DapProxyDependencies {
loggerFactory: ILoggerFactory;
fileSystem: IFileSystem;
processSpawner: IProcessSpawner;
dapClientFactory: IDapClientFactory;
messageSender: IMessageSender;
}
/**
* Extended launch arguments with required program field
*/
export interface ExtendedLaunchArgs extends DebugProtocol.LaunchRequestArguments {
program: string;
stopOnEntry?: boolean;
noDebug?: boolean;
args?: string[];
cwd?: string;
console?: string;
justMyCode?: boolean;
[key: string]: unknown;
}
/**
* Extended initialize arguments with our custom fields
*/
export interface ExtendedInitializeArgs extends DebugProtocol.InitializeRequestArguments {
clientID: string;
clientName: string;
adapterID: string;
pathFormat: 'path';
linesStartAt1: boolean;
columnsStartAt1: boolean;
supportsVariableType: boolean;
supportsRunInTerminalRequest: boolean;
locale: string;
}