agent-debugger 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -0
- package/bin/agent-debugger +2 -0
- package/dist/src/adapters/base.d.ts +45 -0
- package/dist/src/adapters/base.d.ts.map +1 -0
- package/dist/src/adapters/base.js +3 -0
- package/dist/src/adapters/base.js.map +1 -0
- package/dist/src/adapters/go.d.ts +27 -0
- package/dist/src/adapters/go.d.ts.map +1 -0
- package/dist/src/adapters/go.js +144 -0
- package/dist/src/adapters/go.js.map +1 -0
- package/dist/src/adapters/node.d.ts +27 -0
- package/dist/src/adapters/node.d.ts.map +1 -0
- package/dist/src/adapters/node.js +197 -0
- package/dist/src/adapters/node.js.map +1 -0
- package/dist/src/adapters/python.d.ts +27 -0
- package/dist/src/adapters/python.d.ts.map +1 -0
- package/dist/src/adapters/python.js +152 -0
- package/dist/src/adapters/python.js.map +1 -0
- package/dist/src/adapters/registry.d.ts +10 -0
- package/dist/src/adapters/registry.d.ts.map +1 -0
- package/dist/src/adapters/registry.js +45 -0
- package/dist/src/adapters/registry.js.map +1 -0
- package/dist/src/adapters/rust.d.ts +27 -0
- package/dist/src/adapters/rust.d.ts.map +1 -0
- package/dist/src/adapters/rust.js +149 -0
- package/dist/src/adapters/rust.js.map +1 -0
- package/dist/src/cli.d.ts +4 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +326 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/daemon.d.ts +3 -0
- package/dist/src/daemon.d.ts.map +1 -0
- package/dist/src/daemon.js +136 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/dap-client.d.ts +35 -0
- package/dist/src/dap-client.d.ts.map +1 -0
- package/dist/src/dap-client.js +256 -0
- package/dist/src/dap-client.js.map +1 -0
- package/dist/src/dap-types.d.ts +52 -0
- package/dist/src/dap-types.d.ts.map +1 -0
- package/dist/src/dap-types.js +3 -0
- package/dist/src/dap-types.js.map +1 -0
- package/dist/src/protocol.d.ts +253 -0
- package/dist/src/protocol.d.ts.map +1 -0
- package/dist/src/protocol.js +50 -0
- package/dist/src/protocol.js.map +1 -0
- package/dist/src/session.d.ts +30 -0
- package/dist/src/session.d.ts.map +1 -0
- package/dist/src/session.js +407 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/util/paths.d.ts +5 -0
- package/dist/src/util/paths.d.ts.map +1 -0
- package/dist/src/util/paths.js +7 -0
- package/dist/src/util/paths.js.map +1 -0
- package/dist/src/util/ports.d.ts +3 -0
- package/dist/src/util/ports.d.ts.map +1 -0
- package/dist/src/util/ports.js +19 -0
- package/dist/src/util/ports.js.map +1 -0
- package/dist/test/protocol.test.d.ts +2 -0
- package/dist/test/protocol.test.d.ts.map +1 -0
- package/dist/test/protocol.test.js +25 -0
- package/dist/test/protocol.test.js.map +1 -0
- package/package.json +55 -0
- package/skills/agent-debugger/SKILL.md +225 -0
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# agent-debugger
|
|
2
|
+
|
|
3
|
+
CLI debugger for AI agents. Set breakpoints, inspect variables, evaluate expressions, and step through code — in Python, JavaScript, Go, Rust, C, and C++.
|
|
4
|
+
|
|
5
|
+
Built on the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) (DAP), the same protocol that powers VS Code's debugger. One CLI, multiple language backends.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g agent-debugger
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Node.js >= 18.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Start a debug session, paused at line 25
|
|
19
|
+
agent-debugger start app.py --break app.py:25
|
|
20
|
+
|
|
21
|
+
# Inspect variables at the breakpoint
|
|
22
|
+
agent-debugger vars
|
|
23
|
+
|
|
24
|
+
# Evaluate any expression in the current scope
|
|
25
|
+
agent-debugger eval "type(data['age'])"
|
|
26
|
+
|
|
27
|
+
# Continue to the next breakpoint
|
|
28
|
+
agent-debugger continue
|
|
29
|
+
|
|
30
|
+
# Done
|
|
31
|
+
agent-debugger close
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
| Command | Description |
|
|
37
|
+
|---------|-------------|
|
|
38
|
+
| `start <script> [options]` | Start a debug session |
|
|
39
|
+
| `vars` | List local variables in the current frame |
|
|
40
|
+
| `eval <expression>` | Evaluate an expression in the current scope |
|
|
41
|
+
| `step [into\|out]` | Step over, into a function, or out of a function |
|
|
42
|
+
| `continue` | Resume execution until the next breakpoint |
|
|
43
|
+
| `stack` | Show the call stack |
|
|
44
|
+
| `break <file:line[:condition]>` | Add a breakpoint mid-session |
|
|
45
|
+
| `source [file] [line]` | Show source code around the current line |
|
|
46
|
+
| `status` | Show session state and current location |
|
|
47
|
+
| `close` | End the debug session and clean up |
|
|
48
|
+
|
|
49
|
+
### Start Options
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
agent-debugger start <script> [options]
|
|
53
|
+
|
|
54
|
+
Options:
|
|
55
|
+
--break, -b <file:line[:condition]> Set a breakpoint (repeatable)
|
|
56
|
+
--runtime <path> Path to language runtime (e.g. python, node)
|
|
57
|
+
--stop-on-entry Pause on the first line
|
|
58
|
+
--args <...> Arguments to pass to the script
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Breakpoints
|
|
62
|
+
|
|
63
|
+
Multiple breakpoints and conditional breakpoints are supported:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Multiple breakpoints
|
|
67
|
+
agent-debugger start app.py --break app.py:25 --break app.py:40
|
|
68
|
+
|
|
69
|
+
# Conditional breakpoint — only pause when the condition is true
|
|
70
|
+
agent-debugger start app.py --break "app.py:30:i == 50"
|
|
71
|
+
|
|
72
|
+
# Add a breakpoint to a running session
|
|
73
|
+
agent-debugger break app.py:60
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Supported Languages
|
|
77
|
+
|
|
78
|
+
| Language | Extensions | Debug Adapter | Setup |
|
|
79
|
+
|----------|------------|---------------|-------|
|
|
80
|
+
| Python | `.py` | [debugpy](https://github.com/microsoft/debugpy) | `pip install debugpy` |
|
|
81
|
+
| JavaScript | `.js`, `.mjs`, `.cjs` | @vscode/js-debug | VS Code installed, or `JS_DEBUG_PATH` env var |
|
|
82
|
+
| TypeScript | `.ts`, `.mts`, `.tsx` | @vscode/js-debug | Same as JavaScript |
|
|
83
|
+
| Go | `.go` | Delve | `go install github.com/go-delve/delve/cmd/dlv@latest` |
|
|
84
|
+
| Rust | `.rs` | CodeLLDB | `CODELLDB_PATH` env var |
|
|
85
|
+
| C/C++ | `.c`, `.cpp`, `.cc` | CodeLLDB | Same as Rust |
|
|
86
|
+
|
|
87
|
+
### Language-specific setup
|
|
88
|
+
|
|
89
|
+
**Python** — install debugpy in the environment you want to debug:
|
|
90
|
+
```bash
|
|
91
|
+
pip install debugpy
|
|
92
|
+
|
|
93
|
+
# Use a specific Python interpreter
|
|
94
|
+
agent-debugger start app.py --break app.py:10 --runtime /path/to/venv/bin/python
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**JavaScript/TypeScript** — requires VS Code's js-debug extension, which ships with any VS Code install. The adapter auto-detects it from `~/.vscode/extensions/`. To use a custom location:
|
|
98
|
+
```bash
|
|
99
|
+
export JS_DEBUG_PATH=/path/to/ms-vscode.js-debug-x.x.x
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Go** — install Delve:
|
|
103
|
+
```bash
|
|
104
|
+
go install github.com/go-delve/delve/cmd/dlv@latest
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Rust/C/C++** — set the path to the CodeLLDB adapter binary:
|
|
108
|
+
```bash
|
|
109
|
+
export CODELLDB_PATH=/path/to/codelldb/adapter/codelldb
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## How It Works
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
CLI (stateless) ──unix socket──▶ Daemon (session state) ──TCP/DAP──▶ Debug Adapter
|
|
116
|
+
(debugpy, dlv, etc.)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- **CLI** (`agent-debugger`): Stateless client. Parses arguments, sends JSON commands over a Unix socket, prints results.
|
|
120
|
+
- **Daemon**: Background process that manages the debug session. Spawns the debug adapter, connects via DAP, and translates CLI commands into DAP requests.
|
|
121
|
+
- **Debug Adapter**: Language-specific process (debugpy, Delve, js-debug, CodeLLDB) that implements the Debug Adapter Protocol.
|
|
122
|
+
|
|
123
|
+
The daemon starts automatically on the first command and shuts down when the session closes. Only one debug session runs at a time.
|
|
124
|
+
|
|
125
|
+
## Programmatic API
|
|
126
|
+
|
|
127
|
+
The `Session` class is exported for use as a library:
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
import { Session } from "agent-debugger";
|
|
131
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** Base adapter interface for debug adapters. */
|
|
2
|
+
import type { ChildProcess } from "node:child_process";
|
|
3
|
+
import type { DAPClient } from "../dap-client.js";
|
|
4
|
+
import type { StackFrame, Variable } from "../dap-types.js";
|
|
5
|
+
import type { CommandResult } from "../protocol.js";
|
|
6
|
+
export interface SpawnResult {
|
|
7
|
+
process: ChildProcess;
|
|
8
|
+
port: number;
|
|
9
|
+
}
|
|
10
|
+
export interface LaunchOpts {
|
|
11
|
+
program: string;
|
|
12
|
+
args?: string[];
|
|
13
|
+
cwd?: string;
|
|
14
|
+
stopOnEntry?: boolean;
|
|
15
|
+
/** Path to language runtime (e.g. python3, node, dlv) */
|
|
16
|
+
runtimePath?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface InitFlowOpts extends LaunchOpts {
|
|
19
|
+
breakpoints?: Array<{
|
|
20
|
+
file: string;
|
|
21
|
+
lines: number[];
|
|
22
|
+
conditions?: Array<string | null>;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export interface AdapterConfig {
|
|
26
|
+
name: string;
|
|
27
|
+
/** Check if the debug adapter is installed. Returns null if OK, error message if not. */
|
|
28
|
+
checkInstalled(runtimePath?: string): Promise<string | null>;
|
|
29
|
+
/** Spawn the debug adapter process. Returns the child process and DAP port. */
|
|
30
|
+
spawn(opts: LaunchOpts): Promise<SpawnResult>;
|
|
31
|
+
/** Arguments for the DAP initialize request. */
|
|
32
|
+
initializeArgs(): Record<string, unknown>;
|
|
33
|
+
/** Arguments for the DAP launch request. */
|
|
34
|
+
launchArgs(opts: LaunchOpts): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Adapter-specific DAP initialization flow.
|
|
37
|
+
* Handles quirks like debugpy's deferred launch response.
|
|
38
|
+
*/
|
|
39
|
+
initFlow(client: DAPClient, opts: InitFlowOpts): Promise<CommandResult>;
|
|
40
|
+
/** Filter internal frames (e.g. debugpy/pydevd internals). */
|
|
41
|
+
isInternalFrame(frame: StackFrame): boolean;
|
|
42
|
+
/** Filter internal variables (e.g. __dunder__ vars). */
|
|
43
|
+
isInternalVariable(v: Variable): boolean;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IAEb,yFAAyF;IACzF,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE7D,+EAA+E;IAC/E,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9C,gDAAgD;IAChD,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1C,4CAA4C;IAC5C,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEtD;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAExE,8DAA8D;IAC9D,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC;IAE5C,wDAAwD;IACxD,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,iDAAiD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Go debug adapter — dlv (Delve). */
|
|
2
|
+
import type { DAPClient } from "../dap-client.js";
|
|
3
|
+
import type { StackFrame, Variable } from "../dap-types.js";
|
|
4
|
+
import type { CommandResult } from "../protocol.js";
|
|
5
|
+
import type { AdapterConfig, SpawnResult, LaunchOpts, InitFlowOpts } from "./base.js";
|
|
6
|
+
export declare class GoAdapter implements AdapterConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
checkInstalled(): Promise<string | null>;
|
|
9
|
+
spawn(opts: LaunchOpts): Promise<SpawnResult>;
|
|
10
|
+
initializeArgs(): Record<string, unknown>;
|
|
11
|
+
launchArgs(opts: LaunchOpts): Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* Delve DAP init flow (aligned with Python/debugpy pattern):
|
|
14
|
+
* 1. initialize
|
|
15
|
+
* 2. launch (async — response may be deferred)
|
|
16
|
+
* 3. wait for initialized event
|
|
17
|
+
* 4. setBreakpoints
|
|
18
|
+
* 5. setExceptionBreakpoints
|
|
19
|
+
* 6. configurationDone
|
|
20
|
+
* 7. wait for deferred launch response
|
|
21
|
+
* 8. wait for stopped event
|
|
22
|
+
*/
|
|
23
|
+
initFlow(client: DAPClient, opts: InitFlowOpts): Promise<CommandResult>;
|
|
24
|
+
isInternalFrame(frame: StackFrame): boolean;
|
|
25
|
+
isInternalVariable(v: Variable): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=go.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.d.ts","sourceRoot":"","sources":["../../../src/adapters/go.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAGtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGtF,qBAAa,SAAU,YAAW,aAAa;IAC7C,IAAI,SAAQ;IAEN,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IASxC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAanD,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYzC,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYrD;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA4E7E,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAM3C,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;CAGzC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/** Go debug adapter — dlv (Delve). */
|
|
2
|
+
import { spawn as cpSpawn } from "node:child_process";
|
|
3
|
+
import { getFreePort } from "../util/ports.js";
|
|
4
|
+
export class GoAdapter {
|
|
5
|
+
name = "go";
|
|
6
|
+
async checkInstalled() {
|
|
7
|
+
try {
|
|
8
|
+
await execCheck("dlv", ["version"]);
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return "Delve not found. Run: go install github.com/go-delve/delve/cmd/dlv@latest";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async spawn(opts) {
|
|
16
|
+
const port = await getFreePort();
|
|
17
|
+
const proc = cpSpawn("dlv", ["dap", "--listen", `127.0.0.1:${port}`], {
|
|
18
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
19
|
+
cwd: opts.cwd,
|
|
20
|
+
});
|
|
21
|
+
return { process: proc, port };
|
|
22
|
+
}
|
|
23
|
+
initializeArgs() {
|
|
24
|
+
return {
|
|
25
|
+
clientID: "agent-debugger",
|
|
26
|
+
clientName: "agent-debugger",
|
|
27
|
+
adapterID: "dlv",
|
|
28
|
+
pathFormat: "path",
|
|
29
|
+
linesStartAt1: true,
|
|
30
|
+
columnsStartAt1: true,
|
|
31
|
+
supportsVariableType: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
launchArgs(opts) {
|
|
35
|
+
return {
|
|
36
|
+
type: "go",
|
|
37
|
+
request: "launch",
|
|
38
|
+
mode: "debug",
|
|
39
|
+
program: opts.program,
|
|
40
|
+
stopOnEntry: opts.stopOnEntry ?? false,
|
|
41
|
+
args: opts.args || [],
|
|
42
|
+
cwd: opts.cwd,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Delve DAP init flow (aligned with Python/debugpy pattern):
|
|
47
|
+
* 1. initialize
|
|
48
|
+
* 2. launch (async — response may be deferred)
|
|
49
|
+
* 3. wait for initialized event
|
|
50
|
+
* 4. setBreakpoints
|
|
51
|
+
* 5. setExceptionBreakpoints
|
|
52
|
+
* 6. configurationDone
|
|
53
|
+
* 7. wait for deferred launch response
|
|
54
|
+
* 8. wait for stopped event
|
|
55
|
+
*/
|
|
56
|
+
async initFlow(client, opts) {
|
|
57
|
+
// 1. Initialize
|
|
58
|
+
const initResp = await client.request("initialize", this.initializeArgs());
|
|
59
|
+
if (!initResp.success) {
|
|
60
|
+
return { error: `Initialize failed: ${initResp.message || "unknown"}` };
|
|
61
|
+
}
|
|
62
|
+
// 2. Launch (async — Delve may defer response until configurationDone)
|
|
63
|
+
const launchSeq = client.requestAsync("launch", this.launchArgs(opts));
|
|
64
|
+
// 3. Wait for initialized event
|
|
65
|
+
const initialized = await client.waitForEvent("initialized", 10000);
|
|
66
|
+
if (!initialized) {
|
|
67
|
+
return { error: "Timeout waiting for initialized event" };
|
|
68
|
+
}
|
|
69
|
+
// 4. Set breakpoints
|
|
70
|
+
const bpResults = [];
|
|
71
|
+
if (opts.breakpoints?.length) {
|
|
72
|
+
for (const bp of opts.breakpoints) {
|
|
73
|
+
const bpArgs = {
|
|
74
|
+
source: { path: bp.file },
|
|
75
|
+
breakpoints: bp.lines.map((line, i) => {
|
|
76
|
+
const entry = { line };
|
|
77
|
+
if (bp.conditions?.[i])
|
|
78
|
+
entry.condition = bp.conditions[i];
|
|
79
|
+
return entry;
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
const resp = await client.request("setBreakpoints", bpArgs);
|
|
83
|
+
if (resp.success && resp.body) {
|
|
84
|
+
const bps = resp.body.breakpoints;
|
|
85
|
+
if (bps) {
|
|
86
|
+
for (const b of bps) {
|
|
87
|
+
bpResults.push({
|
|
88
|
+
file: bp.file,
|
|
89
|
+
line: b.line ?? 0,
|
|
90
|
+
verified: b.verified ?? false,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// 5. Exception breakpoints (empty = no exception breaking, required by spec)
|
|
98
|
+
await client.request("setExceptionBreakpoints", { filters: [] });
|
|
99
|
+
// 6. configurationDone
|
|
100
|
+
await client.request("configurationDone");
|
|
101
|
+
// 7. Wait for the deferred launch response
|
|
102
|
+
const launchResp = await client.waitForResponse(launchSeq, 15000);
|
|
103
|
+
if (!launchResp.success) {
|
|
104
|
+
return { error: `Launch failed: ${launchResp.message || "unknown"}` };
|
|
105
|
+
}
|
|
106
|
+
// 8. Wait for stopped event (breakpoint hit or entry)
|
|
107
|
+
const stopped = await client.waitForEvent("stopped", 15000);
|
|
108
|
+
if (stopped) {
|
|
109
|
+
const body = (stopped.body || {});
|
|
110
|
+
return {
|
|
111
|
+
status: "paused",
|
|
112
|
+
reason: body.reason || "unknown",
|
|
113
|
+
breakpoints: bpResults,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Program may have finished without hitting breakpoint
|
|
117
|
+
const terminated = client.drainEvents("terminated");
|
|
118
|
+
if (terminated.length) {
|
|
119
|
+
return { status: "terminated", message: "Program finished without hitting breakpoint" };
|
|
120
|
+
}
|
|
121
|
+
return { status: "running", breakpoints: bpResults };
|
|
122
|
+
}
|
|
123
|
+
isInternalFrame(frame) {
|
|
124
|
+
const path = frame.source?.path || "";
|
|
125
|
+
const name = frame.name || "";
|
|
126
|
+
return path.includes("/runtime/") || name.startsWith("runtime.");
|
|
127
|
+
}
|
|
128
|
+
isInternalVariable(v) {
|
|
129
|
+
return false; // Go doesn't have dunder-style internals
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function execCheck(cmd, args) {
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
const proc = cpSpawn(cmd, args, { stdio: "pipe" });
|
|
135
|
+
proc.on("close", (code) => {
|
|
136
|
+
if (code === 0)
|
|
137
|
+
resolve();
|
|
138
|
+
else
|
|
139
|
+
reject(new Error(`${cmd} exited with code ${code}`));
|
|
140
|
+
});
|
|
141
|
+
proc.on("error", reject);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../../src/adapters/go.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Node.js debug adapter — @vscode/js-debug (dapDebugServer). */
|
|
2
|
+
import type { DAPClient } from "../dap-client.js";
|
|
3
|
+
import type { StackFrame, Variable } from "../dap-types.js";
|
|
4
|
+
import type { CommandResult } from "../protocol.js";
|
|
5
|
+
import type { AdapterConfig, SpawnResult, LaunchOpts, InitFlowOpts } from "./base.js";
|
|
6
|
+
export declare class NodeAdapter implements AdapterConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
checkInstalled(): Promise<string | null>;
|
|
9
|
+
spawn(opts: LaunchOpts): Promise<SpawnResult>;
|
|
10
|
+
initializeArgs(): Record<string, unknown>;
|
|
11
|
+
launchArgs(opts: LaunchOpts): Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* js-debug DAP init flow (aligned with Python/debugpy pattern):
|
|
14
|
+
* 1. initialize
|
|
15
|
+
* 2. launch (async — response may be deferred until configurationDone)
|
|
16
|
+
* 3. wait for initialized event
|
|
17
|
+
* 4. setBreakpoints
|
|
18
|
+
* 5. setExceptionBreakpoints
|
|
19
|
+
* 6. configurationDone
|
|
20
|
+
* 7. wait for deferred launch response
|
|
21
|
+
* 8. wait for stopped event
|
|
22
|
+
*/
|
|
23
|
+
initFlow(client: DAPClient, opts: InitFlowOpts): Promise<CommandResult>;
|
|
24
|
+
isInternalFrame(frame: StackFrame): boolean;
|
|
25
|
+
isInternalVariable(v: Variable): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/adapters/node.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAMjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAiCtF,qBAAa,WAAY,YAAW,aAAa;IAC/C,IAAI,SAAU;IAER,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqBxC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAiBnD,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAazC,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAiBrD;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA4E7E,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAK3C,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;CAGzC"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/** Node.js debug adapter — @vscode/js-debug (dapDebugServer). */
|
|
2
|
+
import { spawn as cpSpawn } from "node:child_process";
|
|
3
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
4
|
+
import { resolve as pathResolve } from "node:path";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { getFreePort } from "../util/ports.js";
|
|
7
|
+
/** Locate dapDebugServer.js from js-debug. */
|
|
8
|
+
function findJsDebugPath() {
|
|
9
|
+
// 1. Explicit env var
|
|
10
|
+
const envPath = process.env.JS_DEBUG_PATH;
|
|
11
|
+
if (envPath) {
|
|
12
|
+
const candidate = pathResolve(envPath, "src", "dapDebugServer.js");
|
|
13
|
+
if (existsSync(candidate))
|
|
14
|
+
return candidate;
|
|
15
|
+
// Maybe they pointed directly at dapDebugServer.js
|
|
16
|
+
if (existsSync(envPath) && envPath.endsWith("dapDebugServer.js"))
|
|
17
|
+
return envPath;
|
|
18
|
+
}
|
|
19
|
+
// 2. Auto-detect from VS Code extensions
|
|
20
|
+
const vscodeExtDir = pathResolve(homedir(), ".vscode", "extensions");
|
|
21
|
+
if (existsSync(vscodeExtDir)) {
|
|
22
|
+
try {
|
|
23
|
+
const entries = readdirSync(vscodeExtDir)
|
|
24
|
+
.filter((e) => e.startsWith("ms-vscode.js-debug-"))
|
|
25
|
+
.sort();
|
|
26
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
27
|
+
const candidate = pathResolve(vscodeExtDir, entries[i], "src", "dapDebugServer.js");
|
|
28
|
+
if (existsSync(candidate))
|
|
29
|
+
return candidate;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// directory read failed
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
export class NodeAdapter {
|
|
39
|
+
name = "node";
|
|
40
|
+
async checkInstalled() {
|
|
41
|
+
// Check node is available
|
|
42
|
+
try {
|
|
43
|
+
await execCheck("node", ["--version"]);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return "Node.js not found in PATH";
|
|
47
|
+
}
|
|
48
|
+
// Check js-debug is available
|
|
49
|
+
const jsDebugPath = findJsDebugPath();
|
|
50
|
+
if (!jsDebugPath) {
|
|
51
|
+
return [
|
|
52
|
+
"@vscode/js-debug not found.",
|
|
53
|
+
"Install VS Code (which bundles js-debug), or set JS_DEBUG_PATH to the js-debug extension directory.",
|
|
54
|
+
" e.g. JS_DEBUG_PATH=~/.vscode/extensions/ms-vscode.js-debug-1.x.x",
|
|
55
|
+
].join("\n");
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
async spawn(opts) {
|
|
60
|
+
const jsDebugPath = findJsDebugPath();
|
|
61
|
+
if (!jsDebugPath)
|
|
62
|
+
throw new Error("js-debug not found (run checkInstalled first)");
|
|
63
|
+
const port = await getFreePort();
|
|
64
|
+
// dapDebugServer.js <port> starts a DAP server on the given TCP port
|
|
65
|
+
const proc = cpSpawn("node", [jsDebugPath, String(port)], {
|
|
66
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
67
|
+
cwd: opts.cwd,
|
|
68
|
+
});
|
|
69
|
+
return { process: proc, port };
|
|
70
|
+
}
|
|
71
|
+
initializeArgs() {
|
|
72
|
+
return {
|
|
73
|
+
clientID: "agent-debugger",
|
|
74
|
+
clientName: "agent-debugger",
|
|
75
|
+
adapterID: "js-debug",
|
|
76
|
+
pathFormat: "path",
|
|
77
|
+
linesStartAt1: true,
|
|
78
|
+
columnsStartAt1: true,
|
|
79
|
+
supportsVariableType: true,
|
|
80
|
+
supportsRunInTerminalRequest: false,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
launchArgs(opts) {
|
|
84
|
+
const args = {
|
|
85
|
+
type: "pwa-node",
|
|
86
|
+
request: "launch",
|
|
87
|
+
program: opts.program,
|
|
88
|
+
console: "internalConsole",
|
|
89
|
+
stopOnEntry: opts.stopOnEntry ?? false,
|
|
90
|
+
};
|
|
91
|
+
if (opts.args?.length) {
|
|
92
|
+
args.args = opts.args;
|
|
93
|
+
}
|
|
94
|
+
if (opts.cwd) {
|
|
95
|
+
args.cwd = opts.cwd;
|
|
96
|
+
}
|
|
97
|
+
return args;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* js-debug DAP init flow (aligned with Python/debugpy pattern):
|
|
101
|
+
* 1. initialize
|
|
102
|
+
* 2. launch (async — response may be deferred until configurationDone)
|
|
103
|
+
* 3. wait for initialized event
|
|
104
|
+
* 4. setBreakpoints
|
|
105
|
+
* 5. setExceptionBreakpoints
|
|
106
|
+
* 6. configurationDone
|
|
107
|
+
* 7. wait for deferred launch response
|
|
108
|
+
* 8. wait for stopped event
|
|
109
|
+
*/
|
|
110
|
+
async initFlow(client, opts) {
|
|
111
|
+
// 1. Initialize
|
|
112
|
+
const initResp = await client.request("initialize", this.initializeArgs());
|
|
113
|
+
if (!initResp.success) {
|
|
114
|
+
return { error: `Initialize failed: ${initResp.message || "unknown"}` };
|
|
115
|
+
}
|
|
116
|
+
// 2. Launch (async — response may be deferred until configurationDone)
|
|
117
|
+
const launchSeq = client.requestAsync("launch", this.launchArgs(opts));
|
|
118
|
+
// 3. Wait for initialized event
|
|
119
|
+
const initialized = await client.waitForEvent("initialized", 10000);
|
|
120
|
+
if (!initialized) {
|
|
121
|
+
return { error: "Timeout waiting for initialized event" };
|
|
122
|
+
}
|
|
123
|
+
// 4. Set breakpoints
|
|
124
|
+
const bpResults = [];
|
|
125
|
+
if (opts.breakpoints?.length) {
|
|
126
|
+
for (const bp of opts.breakpoints) {
|
|
127
|
+
const bpArgs = {
|
|
128
|
+
source: { path: bp.file },
|
|
129
|
+
breakpoints: bp.lines.map((line, i) => {
|
|
130
|
+
const entry = { line };
|
|
131
|
+
if (bp.conditions?.[i])
|
|
132
|
+
entry.condition = bp.conditions[i];
|
|
133
|
+
return entry;
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
const resp = await client.request("setBreakpoints", bpArgs);
|
|
137
|
+
if (resp.success && resp.body) {
|
|
138
|
+
const bps = resp.body.breakpoints;
|
|
139
|
+
if (bps) {
|
|
140
|
+
for (const b of bps) {
|
|
141
|
+
bpResults.push({
|
|
142
|
+
file: bp.file,
|
|
143
|
+
line: b.line ?? 0,
|
|
144
|
+
verified: b.verified ?? false,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// 5. Exception breakpoints (empty = no exception breaking)
|
|
152
|
+
await client.request("setExceptionBreakpoints", { filters: [] });
|
|
153
|
+
// 6. configurationDone
|
|
154
|
+
await client.request("configurationDone");
|
|
155
|
+
// 7. Wait for the deferred launch response
|
|
156
|
+
const launchResp = await client.waitForResponse(launchSeq, 15000);
|
|
157
|
+
if (!launchResp.success) {
|
|
158
|
+
return { error: `Launch failed: ${launchResp.message || "unknown"}` };
|
|
159
|
+
}
|
|
160
|
+
// 8. Wait for stopped event (breakpoint hit or entry)
|
|
161
|
+
const stopped = await client.waitForEvent("stopped", 15000);
|
|
162
|
+
if (stopped) {
|
|
163
|
+
const body = (stopped.body || {});
|
|
164
|
+
return {
|
|
165
|
+
status: "paused",
|
|
166
|
+
reason: body.reason || "unknown",
|
|
167
|
+
breakpoints: bpResults,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// Program may have finished without hitting breakpoint
|
|
171
|
+
const terminated = client.drainEvents("terminated");
|
|
172
|
+
if (terminated.length) {
|
|
173
|
+
return { status: "terminated", message: "Program finished without hitting breakpoint" };
|
|
174
|
+
}
|
|
175
|
+
return { status: "running", breakpoints: bpResults };
|
|
176
|
+
}
|
|
177
|
+
isInternalFrame(frame) {
|
|
178
|
+
const path = frame.source?.path || "";
|
|
179
|
+
return path.includes("node:internal") || path.includes("node_modules");
|
|
180
|
+
}
|
|
181
|
+
isInternalVariable(v) {
|
|
182
|
+
return v.name === "this" || v.name === "__proto__";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function execCheck(cmd, args) {
|
|
186
|
+
return new Promise((resolve, reject) => {
|
|
187
|
+
const proc = cpSpawn(cmd, args, { stdio: "pipe" });
|
|
188
|
+
proc.on("close", (code) => {
|
|
189
|
+
if (code === 0)
|
|
190
|
+
resolve();
|
|
191
|
+
else
|
|
192
|
+
reject(new Error(`${cmd} exited with code ${code}`));
|
|
193
|
+
});
|
|
194
|
+
proc.on("error", reject);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/adapters/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Python debug adapter — debugpy. */
|
|
2
|
+
import type { DAPClient } from "../dap-client.js";
|
|
3
|
+
import type { StackFrame, Variable } from "../dap-types.js";
|
|
4
|
+
import type { CommandResult } from "../protocol.js";
|
|
5
|
+
import type { AdapterConfig, SpawnResult, LaunchOpts, InitFlowOpts } from "./base.js";
|
|
6
|
+
export declare class PythonAdapter implements AdapterConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
checkInstalled(runtimePath?: string): Promise<string | null>;
|
|
9
|
+
spawn(opts: LaunchOpts): Promise<SpawnResult>;
|
|
10
|
+
initializeArgs(): Record<string, unknown>;
|
|
11
|
+
launchArgs(opts: LaunchOpts): Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* debugpy-specific init flow:
|
|
14
|
+
* 1. initialize
|
|
15
|
+
* 2. launch (async — response deferred until configurationDone)
|
|
16
|
+
* 3. wait for initialized event
|
|
17
|
+
* 4. setBreakpoints
|
|
18
|
+
* 5. setExceptionBreakpoints
|
|
19
|
+
* 6. configurationDone
|
|
20
|
+
* 7. wait for deferred launch response
|
|
21
|
+
* 8. wait for stopped event
|
|
22
|
+
*/
|
|
23
|
+
initFlow(client: DAPClient, opts: InitFlowOpts): Promise<CommandResult>;
|
|
24
|
+
isInternalFrame(frame: StackFrame): boolean;
|
|
25
|
+
isInternalVariable(v: Variable): boolean;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=python.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../../src/adapters/python.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAGtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGtF,qBAAa,aAAc,YAAW,aAAa;IACjD,IAAI,SAAY;IAEV,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAU5D,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAWnD,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAazC,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAqBrD;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA4E7E,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAK3C,kBAAkB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;CAGzC"}
|