/** * DapClient — a minimal Debug Adapter Protocol client for Godot's built-in * debug adapter. * * Godot ships a DAP server in the editor (Editor Settings → Network → Debug * Adapter, default port 6006) alongside its GDScript language server on 6005. * Both are on by default — the editor prints "Debug adapter server started on * port 6006" at startup. Talking to it directly is what lets an agent set a * real breakpoint and read actual frame variables instead of inferring state * from print() output. * * This connection does NOT go through the WebSocket bridge in godot-bridge.ts: * the adapter is a separate TCP listener owned by the editor, so debugger tools * are handled inside the Node server rather than dispatched to the addon. * * Wire format is the same `Content-Length: \r\n\r\n` framing LSP uses, * carrying DAP's seq/type/command envelopes. */ import { EventEmitter } from 'node:events'; export declare const DEFAULT_DAP_PORT = 6006; export type DapState = 'disconnected' | 'initialized' | 'running' | 'stopped' | 'terminated'; export declare class DapError extends Error { readonly command: string; constructor(command: string, message: string); } export declare class DapClient extends EventEmitter { private readonly timeoutMs; private conn; private seq; private pending; /** Breakpoints per source path, kept so they can be re-applied on restart. */ private breakpoints; private configured; private lastStart; capabilities: Record | null; state: DapState; stoppedThreadId: number | null; stoppedReason: string | null; constructor(host?: string, port?: number, timeoutMs?: number); isConnected(): boolean; private handleMessage; private handleEvent; private send; request = Record>(command: string, args?: unknown, timeoutMs?: number): Promise; /** * Resolve on the next `stopped`/`terminated` event, or when `waitMs` elapses. * Callers MUST create this promise BEFORE sending the request that triggers * the event — a breakpoint one line away can fire before an await placed * afterwards would have subscribed, and the wait would then hang for nothing. */ private settle; private waitForEvent; /** Record breakpoints for a file, applying them now if the session is live. */ setBreakpoints(path: string, lines: number[], conditions?: (string | null)[]): Promise>; private applyBreakpoints; /** * Run the DAP handshake: initialize → launch/attach → breakpoints → * configurationDone. * * The `initialized` EVENT (adapter says "ready for breakpoints") is distinct * from the `initialize` RESPONSE, and adapters commonly emit it while the * launch request is still outstanding — so launch is fired without awaiting, * and its failure is surfaced via the 'error' event instead. */ private startError; start(mode: 'launch' | 'attach', args: Record): Promise; /** Why the last launch/attach was refused by the adapter, if it was. */ takeStartError(): string | null; threadId(): number; /** * Issue a resume command (continue/next/stepIn/stepOut) and wait for the * program to settle again before returning. Without the wait these return * instantly with a stale state and no location, which reads as "the step did * nothing". If nothing settles within waitMs (e.g. `continue` with no further * breakpoint) it resolves with the current state. */ resume(command: string, args: Record, waitMs: number): Promise<{ state: DapState; reason: string | null; }>; /** Re-run the last launch/attach, merging any overrides over its args. */ restart(overrideArgs?: Record, waitMs?: number): Promise<{ state: DapState; reason: string | null; }>; close(): void; } //# sourceMappingURL=dap-client.d.ts.map