dap-mcp-server 0.1.10 → 0.1.12
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 +5 -2
- package/SKILL.md +175 -28
- package/TODO.md +32 -0
- package/build/adapters/builtin.js +27 -3
- package/build/adapters/builtin.js.map +1 -1
- package/build/dap/dap-client.d.ts +71 -4
- package/build/dap/dap-client.js +324 -53
- package/build/dap/dap-client.js.map +1 -1
- package/build/dap/types.d.ts +29 -7
- package/build/server.js +229 -34
- package/build/server.js.map +1 -1
- package/build/session/inspect.d.ts +64 -0
- package/build/session/inspect.js +116 -0
- package/build/session/inspect.js.map +1 -0
- package/build/session/run.d.ts +52 -0
- package/build/session/run.js +111 -0
- package/build/session/run.js.map +1 -0
- package/build/session/session.d.ts +8 -9
- package/build/session/session.js +67 -9
- package/build/session/session.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/builtin.ts +28 -3
- package/src/adapters/registry.test.ts +3 -2
- package/src/dap/dap-client.test.ts +31 -0
- package/src/dap/dap-client.ts +402 -52
- package/src/dap/types.ts +30 -7
- package/src/integration/debug-lifecycle.test.ts +21 -0
- package/src/server.ts +254 -34
- package/src/session/inspect.test.ts +126 -0
- package/src/session/inspect.ts +160 -0
- package/src/session/run.test.ts +74 -0
- package/src/session/run.ts +144 -0
- package/src/session/session.test.ts +42 -0
- package/src/session/session.ts +68 -21
- package/src/test-fixtures/mock-adapter.js +23 -1
- package/src/test-fixtures/no-stop-adapter.js +77 -0
- package/src/test-fixtures/tcp-mock-adapter.js +87 -0
package/README.md
CHANGED
|
@@ -24,12 +24,15 @@ Additional adapters (e.g. Node.js via js-debug) can be registered via the `confi
|
|
|
24
24
|
|
|
25
25
|
| Tool | Description |
|
|
26
26
|
|------|-------------|
|
|
27
|
-
| `
|
|
27
|
+
| `debug_inspect` | **One-shot:** launch → run to breakpoint → evaluate expressions → disconnect. Use first when you just need a value at a line. |
|
|
28
|
+
| `debug_run` | **One-shot:** launch → run to completion → return all output. Combine with logpoints for printf-style debugging without editing source. |
|
|
29
|
+
| `debug_launch` | Start an interactive debug session (launch a program with breakpoints) |
|
|
28
30
|
| `debug_attach` | Attach to a running process |
|
|
29
31
|
| `debug_restart` | Restart with the same configuration |
|
|
30
32
|
| `debug_disconnect` | End a debug session |
|
|
31
|
-
| `set_breakpoints` | Set/replace breakpoints in a file |
|
|
33
|
+
| `set_breakpoints` | Set/replace breakpoints in a file (use `logMessage` for logpoints) |
|
|
32
34
|
| `set_exception_breakpoints` | Break on exceptions |
|
|
35
|
+
| `list_breakpoints` | List currently-registered breakpoints for a session |
|
|
33
36
|
| `get_state` | Get threads, stack trace, scopes, and variables |
|
|
34
37
|
| `evaluate` | Evaluate an expression in the debuggee context |
|
|
35
38
|
| `step` | Continue, next, stepIn, stepOut, or pause |
|
package/SKILL.md
CHANGED
|
@@ -7,56 +7,203 @@ description: Use when debugging a program — when you need to set breakpoints,
|
|
|
7
7
|
|
|
8
8
|
You have access to a real debugger via the `dap` MCP server. **Use it instead of adding print/log statements** whenever you need to understand runtime behavior, track down a bug, or verify a fix.
|
|
9
9
|
|
|
10
|
-
## When to
|
|
10
|
+
## When to switch from print() to the debugger
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
- You need to inspect the value of variables at a specific point in execution
|
|
14
|
-
- You suspect a logic error in a loop, conditional, or data transformation
|
|
15
|
-
- A function returns an unexpected result and you want to trace the execution path
|
|
16
|
-
- You want to verify your fix actually changes behavior at the right point
|
|
12
|
+
Reach for the debugger — don't keep guessing — when any of these are true:
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
- **Your first fix attempt was wrong.** Stop iterating on guesses. Inspect actual values.
|
|
15
|
+
- **You're about to add 3+ print statements.** Use a logpoint instead (see below) — same information, no code edits.
|
|
16
|
+
- **You need a value on iteration N of a loop.** Use `hitCondition: "N"` instead of conditional prints.
|
|
17
|
+
- **A test fails with a non-obvious traceback.** Launch the test under the debugger; you'll see locals at the failure site.
|
|
18
|
+
- **You're reasoning about state that's modified across many call sites.** A conditional breakpoint on the value beats grepping for assignments.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
Print debugging is fine for: trivial one-line checks, scripts you'll throw away in the next message, or when you genuinely just want to see "did this code path execute?".
|
|
21
|
+
|
|
22
|
+
## Logpoints — print debugging without editing code
|
|
23
|
+
|
|
24
|
+
A **logpoint** is a breakpoint that doesn't pause execution. It just emits a formatted message every time it's hit. This is the single most useful feature for AI agents.
|
|
25
|
+
|
|
26
|
+
Set it via the `logMessage` field on a breakpoint:
|
|
22
27
|
|
|
23
28
|
```
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
program: "/absolute/path/to/file.py",
|
|
27
|
-
stopOnEntry: false,
|
|
29
|
+
set_breakpoints({
|
|
30
|
+
file: "/abs/path/src/foo.py",
|
|
28
31
|
breakpoints: [
|
|
29
|
-
{
|
|
32
|
+
{ line: 42, logMessage: "x={x} y={y} state={self.state}" },
|
|
33
|
+
{ line: 88, logMessage: "iteration {i}: items={len(items)}" }
|
|
30
34
|
]
|
|
31
35
|
})
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
Then `step({ action: "continue" })` and let the program run. Retrieve every log with `get_output`. You get the same information as inserting `print(f"x={x} y={y}")` at five places — without touching the source file, without re-running, and with the program's natural execution preserved.
|
|
39
|
+
|
|
40
|
+
**When to use logpoints over breakpoints**: when you want to *observe* values across many hits rather than *interrupt* execution to inspect one. They are the right tool ~70% of the time.
|
|
41
|
+
|
|
42
|
+
Expression syntax inside `{...}` depends on the adapter (debugpy: Python; node: JS). The expression is evaluated in the breakpoint's scope.
|
|
43
|
+
|
|
44
|
+
## Debugging a failing test
|
|
45
|
+
|
|
46
|
+
This is the dominant case. Use the test runner as the program, with the specific test as an argument.
|
|
47
|
+
|
|
48
|
+
### pytest
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
debug_launch({
|
|
52
|
+
adapter: "python",
|
|
53
|
+
program: "/abs/path/.venv/bin/pytest",
|
|
54
|
+
args: ["tests/test_foo.py::test_bar", "-x", "--no-header"],
|
|
55
|
+
cwd: "/abs/path",
|
|
56
|
+
breakpoints: [{ file: "/abs/path/src/foo.py", line: 42 }],
|
|
57
|
+
stopOnEntry: false,
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For pytest, also consider setting `exceptionBreakpoints: ["raised"]` — pytest swallows exceptions before you see them, but the debugger will stop at the raise site.
|
|
62
|
+
|
|
63
|
+
### vitest / jest (Node.js)
|
|
64
|
+
|
|
65
|
+
Requires the `node` adapter configured (see "Node.js setup" below). Use the runner binary from `node_modules/.bin`:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
debug_launch({
|
|
69
|
+
adapter: "node",
|
|
70
|
+
program: "${cwd}/node_modules/.bin/vitest",
|
|
71
|
+
args: ["run", "tests/foo.test.ts", "-t", "the failing test name"],
|
|
72
|
+
cwd: "/abs/path",
|
|
73
|
+
breakpoints: [{ file: "/abs/path/src/foo.ts", line: 42 }],
|
|
74
|
+
stopOnEntry: false,
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### go test
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
debug_launch({
|
|
82
|
+
adapter: "go",
|
|
83
|
+
program: "${cwd}", // delve takes a package dir, not a binary
|
|
84
|
+
args: ["-test.run", "TestFoo", "-test.v"],
|
|
85
|
+
cwd: "/abs/path",
|
|
86
|
+
breakpoints: [{ file: "/abs/path/foo.go", line: 42 }],
|
|
87
|
+
stopOnEntry: false,
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Delve uses `dlv test` semantics under the hood when the program is a package directory containing test files.
|
|
92
|
+
|
|
93
|
+
### Node.js setup
|
|
94
|
+
|
|
95
|
+
If `list_adapters` shows no `node` entry, register it once (path depends on installed extension):
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
configure_adapter({
|
|
99
|
+
type: "node",
|
|
100
|
+
runtime: "node",
|
|
101
|
+
program: "/abs/path/to/js-debug/src/dapDebugServer.js",
|
|
102
|
+
args: [],
|
|
103
|
+
scope: "global",
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`js-debug-dap` ships with the VS Code Node debugger extension. Alternatively use `@vscode/js-debug` from npm.
|
|
108
|
+
|
|
109
|
+
## Quick Start (single-file program)
|
|
110
|
+
|
|
111
|
+
1. `list_adapters` — see what's installed.
|
|
112
|
+
2. Launch with breakpoints in one call:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
debug_launch({
|
|
116
|
+
adapter: "python",
|
|
117
|
+
program: "/abs/path/file.py",
|
|
118
|
+
stopOnEntry: false,
|
|
119
|
+
breakpoints: [{ file: "/abs/path/file.py", line: 42 }],
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
3. The response already contains the full state (threads, stack, scopes, variables) when the breakpoint is hit. No follow-up `get_state` needed.
|
|
124
|
+
4. Step with `step({ action: "next" })` — response includes the new state.
|
|
125
|
+
5. `evaluate({ expression: "len(items)" })` for ad-hoc inspection.
|
|
126
|
+
6. `debug_disconnect` when done.
|
|
127
|
+
|
|
128
|
+
## Stepping strategy
|
|
129
|
+
|
|
130
|
+
- **`next`** (step over) is the default choice. Use it unless you have a specific reason not to.
|
|
131
|
+
- **`stepIn`** only when you suspect the bug is *inside* the function being called — not at the call site. Stepping into library code will get you lost fast.
|
|
132
|
+
- **`stepOut`** to bail out of a function you stepped into by mistake.
|
|
133
|
+
- **`continue`** to run to the next breakpoint. With logpoints set, this is how you collect runtime traces.
|
|
134
|
+
|
|
135
|
+
If you find yourself stepping line-by-line for more than ~10 steps, you're probably doing it wrong. Set a breakpoint at the next interesting location and continue to it.
|
|
136
|
+
|
|
137
|
+
## Worked example
|
|
138
|
+
|
|
139
|
+
Bug: `compute_total(items)` returns `0` when items contain a tax-exempt entry.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
# Launch under pytest with a breakpoint at the suspect line
|
|
143
|
+
debug_launch({
|
|
144
|
+
adapter: "python",
|
|
145
|
+
program: "/proj/.venv/bin/pytest",
|
|
146
|
+
args: ["tests/test_billing.py::test_tax_exempt", "-x"],
|
|
147
|
+
cwd: "/proj",
|
|
148
|
+
breakpoints: [{ file: "/proj/src/billing.py", line: 57 }],
|
|
149
|
+
stopOnEntry: false,
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
# Response (paraphrased):
|
|
153
|
+
# {
|
|
154
|
+
# sessionId: "s-1",
|
|
155
|
+
# status: "stopped",
|
|
156
|
+
# location: { file: ".../billing.py", line: 57, functionName: "compute_total" },
|
|
157
|
+
# scopes: [{ name: "Locals", variables: [
|
|
158
|
+
# { name: "items", value: "[{...}, {...}]", ... },
|
|
159
|
+
# { name: "subtotal", value: "100", ... },
|
|
160
|
+
# { name: "tax", value: "0", ... }
|
|
161
|
+
# ] }]
|
|
162
|
+
# }
|
|
163
|
+
|
|
164
|
+
# Inspect the exempt item more closely
|
|
165
|
+
evaluate({ expression: "[i for i in items if i.get('tax_exempt')]" })
|
|
166
|
+
# → [{name: 'book', price: 100, tax_exempt: True}]
|
|
167
|
+
|
|
168
|
+
# Step over to see what compute_total actually returns
|
|
169
|
+
step({ action: "next" })
|
|
170
|
+
# → see that `total = subtotal + tax` returns 100, not 0. Bug is upstream.
|
|
171
|
+
|
|
172
|
+
# Continue to verify nothing else changes the return
|
|
173
|
+
step({ action: "continue" })
|
|
174
|
+
|
|
175
|
+
debug_disconnect()
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Fix locally, re-run the test, done.
|
|
38
179
|
|
|
39
180
|
## Key Rules
|
|
40
181
|
|
|
41
182
|
- **Do NOT call `get_state` after `step`** — `step` already returns the new stopped state.
|
|
42
|
-
- **Omit `sessionId`** when only one debug session is active
|
|
183
|
+
- **Omit `sessionId`** when only one debug session is active.
|
|
43
184
|
- **Use absolute paths** for `program` and breakpoint `file` parameters.
|
|
44
|
-
- **Prefer `stopOnEntry: false` with breakpoints**
|
|
45
|
-
- **
|
|
185
|
+
- **Prefer `stopOnEntry: false` with breakpoints** — it gets you directly to the interesting code.
|
|
186
|
+
- **Use `get_output`** for program stdout/stderr (including logpoint output).
|
|
46
187
|
|
|
47
188
|
## Debugging Strategies
|
|
48
189
|
|
|
49
190
|
### Narrowing down a bug
|
|
50
|
-
1. Set a breakpoint where
|
|
51
|
-
2. Set another
|
|
52
|
-
3. Use `step` with `
|
|
53
|
-
4. Use `evaluate` to check intermediate values.
|
|
191
|
+
1. Set a breakpoint where state is known good.
|
|
192
|
+
2. Set another where state is wrong.
|
|
193
|
+
3. Use `step` with `next` to walk between them, or set intermediate logpoints.
|
|
54
194
|
|
|
55
195
|
### Understanding a crash
|
|
56
|
-
1. Launch with `exceptionBreakpoints: ["uncaughtExceptions"]
|
|
57
|
-
2. When
|
|
196
|
+
1. Launch with `exceptionBreakpoints: ["uncaughtExceptions"]` (or `"raised"` for any raise).
|
|
197
|
+
2. When stopped at the exception, inspect stack and locals.
|
|
58
198
|
|
|
59
199
|
### Verifying a fix
|
|
60
200
|
1. Set a breakpoint at the fixed code.
|
|
61
|
-
2. Run to it, inspect variables, confirm
|
|
201
|
+
2. Run to it, inspect variables, confirm new behavior.
|
|
62
202
|
3. Continue to verify the program completes successfully.
|
|
203
|
+
|
|
204
|
+
### Observing a hot loop without stopping it
|
|
205
|
+
1. Set logpoints at the relevant lines with `{i}` and any state expression.
|
|
206
|
+
2. `continue`.
|
|
207
|
+
3. Read the trace via `get_output`. For long-running programs, poll incrementally:
|
|
208
|
+
pass the `nextSince` value from each call as the `since` parameter of the next call
|
|
209
|
+
to receive only newly-emitted entries.
|
package/TODO.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# DAP MCP Server — Improvement TODO
|
|
2
|
+
|
|
3
|
+
Findings from a self-review of how usable this MCP is for an AI agent. Ordered by priority (descending). Check items off as completed.
|
|
4
|
+
|
|
5
|
+
## Tier 1 — Documentation (SKILL.md). High leverage, low risk.
|
|
6
|
+
|
|
7
|
+
- [x] **P1 — Logpoints section.** `breakpoints[].logMessage` is already wired through (session.ts:138) but is invisible in SKILL.md. It is the closest thing to a drop-in replacement for `print()` debugging: no code edits, captures every hit, no execution pause. Should have its own headline section with an example.
|
|
8
|
+
- [x] **P2 — "Debug a failing test" section.** Most real bugs surface inside test runners (pytest, vitest, jest, go test, cargo test). Currently zero guidance. Add a per-framework template for launching a single test under the debugger.
|
|
9
|
+
- [x] **P3 — "Switch from print() to debugger" triggers.** Concrete rules an AI agent will actually follow: "if first fix attempt was wrong, stop guessing"; "if about to add 3+ prints, use logpoints"; "if reasoning about iteration N, use `hitCondition`"; "if traceback is non-obvious, launch test under debugger".
|
|
10
|
+
- [x] **P4 — Stepping strategy.** Default to `next`. Use `stepIn` only when you suspect the bug is *inside* the called function. Otherwise agents get lost in library internals.
|
|
11
|
+
- [x] **P5 — Full worked example.** Real bug → real `debug_launch` call → real returned state → identified fix. Replaces all the abstract advice with one concrete walkthrough.
|
|
12
|
+
- [x] **P5b — Node.js adapter recipe.** Builtin was removed; add a ready-to-paste `configure_adapter` snippet for `js-debug-dap`.
|
|
13
|
+
|
|
14
|
+
## Tier 2 — Code changes that materially improve UX.
|
|
15
|
+
|
|
16
|
+
- [x] **P6 — `debug_inspect` macro tool.** One call: launch, run to a breakpoint, evaluate a list of expressions, disconnect. Collapses a 5–7 round-trip workflow into 1. Most likely change to make me reach for the debugger reflexively.
|
|
17
|
+
- [x] **P7 — Flip `stopOnEntry` default to `false` when breakpoints are provided.** Today defaults to `true` regardless (server.ts:206). Doing the right thing automatically is better than relying on the agent reading the SKILL.md.
|
|
18
|
+
- [x] **P8 — Structured deep variables.** `getVariables` with `depth > 1` flattens children into the value string (session.ts:271–278). Hard for the AI to consume. Return nested `children: [...]` instead.
|
|
19
|
+
- [x] **P9 — `list_adapters` summary line + surfaced install hints.** Add `summary: "2/4 installed"` and lift `installHint` for missing adapters to the top level so it's scannable.
|
|
20
|
+
- [x] **P10 — `debug_run` macro tool.** Launch, run to completion, return all stdout/stderr. Zero breakpoints, zero round-trips. For "what does this script actually print/crash with?" cases.
|
|
21
|
+
|
|
22
|
+
## Tier 3 — Polish.
|
|
23
|
+
|
|
24
|
+
- [x] **P11 — Better "session is not stopped" error.** Currently says "use step with action: pause" (server.ts:549) — bad advice (Python `pause` lands in arbitrary library code). Suggest "set a breakpoint where you want to inspect, then continue to it".
|
|
25
|
+
- [x] **P12 — Version drift.** `McpServer` registers as `0.1.0` (server.ts:48); package.json is `0.1.10`. Read from `package.json`.
|
|
26
|
+
- [x] **P13 — `list_breakpoints` tool.** After several `set_breakpoints` calls, no way to introspect what's set. Minor.
|
|
27
|
+
|
|
28
|
+
## Tier 4 — Speculative.
|
|
29
|
+
|
|
30
|
+
- [x] **`get_output({ since })` for incremental polling.** Smaller substitute for streaming subscriptions. Caller passes the `nextSince` value from a prior call to receive only newly-emitted entries. Useful for watching logpoint output during `continue` against long-running programs.
|
|
31
|
+
- [ ] ~~Streaming output via MCP resource subscriptions.~~ AI agents don't watch streams in real time; the request/response pattern doesn't benefit. `since`-based polling covers the practical case.
|
|
32
|
+
- [ ] ~~Auto-detect test runner from program path.~~ Too magic; SKILL.md recipes (P2) make the right call explicit, and silent misfires would be worse than no detection at all.
|
|
@@ -30,14 +30,38 @@ export const BUILTIN_ADAPTERS = [
|
|
|
30
30
|
},
|
|
31
31
|
installHint: "pip install debugpy",
|
|
32
32
|
},
|
|
33
|
-
// node adapter removed — no reliable universal path to js-debug-dap.
|
|
34
|
-
// Configure via configure_adapter if needed.
|
|
35
33
|
{
|
|
36
34
|
type: "go",
|
|
37
35
|
program: "dlv",
|
|
38
|
-
args: ["dap"],
|
|
36
|
+
args: ["dap", "--listen=127.0.0.1:0"],
|
|
37
|
+
transport: "tcp",
|
|
38
|
+
// Matches: "DAP server listening at: 127.0.0.1:38251"
|
|
39
|
+
portMatcher: "DAP server listening at:\\s*\\S+:(\\d+)",
|
|
39
40
|
installHint: "go install github.com/go-delve/delve/cmd/dlv@latest",
|
|
40
41
|
},
|
|
42
|
+
// node adapter: vscode-js-debug's dapDebugServer.js. The user must install
|
|
43
|
+
// it (no universal path); the registry's availability check will mark this
|
|
44
|
+
// unavailable when the program is missing.
|
|
45
|
+
{
|
|
46
|
+
type: "node",
|
|
47
|
+
runtime: "node",
|
|
48
|
+
program: "dapDebugServer.js",
|
|
49
|
+
// Bind to IPv4 explicitly; the default is IPv6 ('::1') which our client
|
|
50
|
+
// (which connects to 127.0.0.1) can't reach on systems without v4↔v6
|
|
51
|
+
// bridging.
|
|
52
|
+
args: ["0", "127.0.0.1"],
|
|
53
|
+
transport: "tcp",
|
|
54
|
+
// Matches: "Debug server listening at 127.0.0.1:38251" (vscode-js-debug)
|
|
55
|
+
portMatcher: "[Ll]istening at\\s*\\S*?:(\\d+)",
|
|
56
|
+
// vscode-js-debug requires these in the launch request; pwa-node is the
|
|
57
|
+
// "production worker agent" Node launcher.
|
|
58
|
+
launchDefaults: {
|
|
59
|
+
type: "pwa-node",
|
|
60
|
+
request: "launch",
|
|
61
|
+
},
|
|
62
|
+
installHint: "Install vscode-js-debug DAP server and set the adapter's `program` to its dapDebugServer.js path " +
|
|
63
|
+
"(e.g. via `configure_adapter`). See https://github.com/microsoft/vscode-js-debug.",
|
|
64
|
+
},
|
|
41
65
|
{
|
|
42
66
|
type: "cppdbg",
|
|
43
67
|
program: "lldb-dap",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/adapters/builtin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,CAAC,iBAAiB,CAAC;QACzB,cAAc,EAAE;YACd,OAAO,EAAE,iBAAiB;SAC3B;QACD,WAAW,EAAE,qBAAqB;KACnC;IACD
|
|
1
|
+
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/adapters/builtin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,CAAC,iBAAiB,CAAC;QACzB,cAAc,EAAE;YACd,OAAO,EAAE,iBAAiB;SAC3B;QACD,WAAW,EAAE,qBAAqB;KACnC;IACD;QACE,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC;QACrC,SAAS,EAAE,KAAK;QAChB,sDAAsD;QACtD,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE,qDAAqD;KACnE;IACD,2EAA2E;IAC3E,2EAA2E;IAC3E,2CAA2C;IAC3C;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,mBAAmB;QAC5B,wEAAwE;QACxE,qEAAqE;QACrE,YAAY;QACZ,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC;QACxB,SAAS,EAAE,KAAK;QAChB,yEAAyE;QACzE,WAAW,EAAE,iCAAiC;QAC9C,wEAAwE;QACxE,2CAA2C;QAC3C,cAAc,EAAE;YACd,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,QAAQ;SAClB;QACD,WAAW,EACT,mGAAmG;YACnG,mFAAmF;KACtF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,+DAA+D;KAC7E;CACF,CAAC"}
|
|
@@ -24,21 +24,88 @@ import { DebugProtocol } from "@vscode/debugprotocol";
|
|
|
24
24
|
export declare class DAPClientError extends Error {
|
|
25
25
|
constructor(message: string);
|
|
26
26
|
}
|
|
27
|
+
export interface DAPClientOptions {
|
|
28
|
+
/** "stdio" (default) or "tcp". */
|
|
29
|
+
transport?: "stdio" | "tcp";
|
|
30
|
+
/**
|
|
31
|
+
* Regex with one capture group that matches the TCP port the adapter is
|
|
32
|
+
* listening on. Required when transport is "tcp". The regex is applied to
|
|
33
|
+
* the cumulative adapter stdout text.
|
|
34
|
+
*/
|
|
35
|
+
portMatcher?: string;
|
|
36
|
+
/** Timeout waiting for the adapter to announce its TCP port, in ms. */
|
|
37
|
+
tcpConnectTimeout?: number;
|
|
38
|
+
}
|
|
27
39
|
export declare class DAPClient extends EventEmitter {
|
|
28
40
|
private runtime;
|
|
29
41
|
private executable;
|
|
30
42
|
private args;
|
|
43
|
+
private transport;
|
|
44
|
+
private portMatcher?;
|
|
45
|
+
private tcpConnectTimeout;
|
|
31
46
|
private process?;
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
private
|
|
47
|
+
private conns;
|
|
48
|
+
/** Index into `conns` of the connection that handles user-sent requests. */
|
|
49
|
+
private activeIdx;
|
|
50
|
+
/** TCP target host (set during spawn for tcp mode). */
|
|
51
|
+
private tcpHost?;
|
|
52
|
+
/** TCP target port (set during spawn for tcp mode). */
|
|
53
|
+
private tcpPort?;
|
|
54
|
+
/**
|
|
55
|
+
* While a startDebugging handler is bootstrapping a new child session
|
|
56
|
+
* (initialize + launch), user-issued `sendRequest` calls await this so they
|
|
57
|
+
* don't race the in-progress handshake.
|
|
58
|
+
*/
|
|
59
|
+
private transitionLock?;
|
|
60
|
+
/**
|
|
61
|
+
* Last setBreakpoints arguments per source path. Replayed onto new child
|
|
62
|
+
* sessions when startDebugging causes the active connection to change —
|
|
63
|
+
* adapters like vscode-js-debug spawn a child for the actual debuggee
|
|
64
|
+
* AFTER the parent has accepted setBreakpoints, so the child wouldn't know
|
|
65
|
+
* about them otherwise.
|
|
66
|
+
*/
|
|
67
|
+
private bpHistory;
|
|
68
|
+
private excBpHistory?;
|
|
69
|
+
private configurationDoneSent;
|
|
35
70
|
private stderrOutput;
|
|
71
|
+
private stdoutPreamble;
|
|
36
72
|
private _exited;
|
|
37
73
|
private _exitCode?;
|
|
38
|
-
constructor(runtime: string, executable: string, args?: string[]);
|
|
74
|
+
constructor(runtime: string, executable: string, args?: string[], options?: DAPClientOptions);
|
|
39
75
|
spawn(): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Record session-shaping requests so we can replay them on child sessions.
|
|
78
|
+
* `setBreakpoints` and `setExceptionBreakpoints` need to be re-sent because
|
|
79
|
+
* each DAP session has its own breakpoint state. `configurationDone` is
|
|
80
|
+
* tracked so we know whether the parent has already finished its
|
|
81
|
+
* configuration phase — if so, child sessions need the same signal.
|
|
82
|
+
*/
|
|
83
|
+
private trackOutgoing;
|
|
84
|
+
/** Build a Conn around a writable/readable stream pair. */
|
|
85
|
+
private makeConn;
|
|
86
|
+
/** Open a fresh TCP connection to the adapter's DAP server. */
|
|
87
|
+
private openTcpConnection;
|
|
88
|
+
private onConnClose;
|
|
40
89
|
sendRequest(command: string, args?: Record<string, unknown>, timeout?: number): Promise<DebugProtocol.Response>;
|
|
90
|
+
/** Internal: send a request on a specific connection. */
|
|
91
|
+
private sendRequestOn;
|
|
41
92
|
private handleMessage;
|
|
93
|
+
/** Reply to a reverse request, on the connection that sent it. */
|
|
94
|
+
private replyToReverseRequest;
|
|
95
|
+
/**
|
|
96
|
+
* Handle a `startDebugging` reverse request from an active session.
|
|
97
|
+
*
|
|
98
|
+
* Per the DAP startDebugging protocol, the client should open a new DAP
|
|
99
|
+
* session for the supplied configuration and run the launch/attach
|
|
100
|
+
* handshake against the SAME adapter. For TCP-server adapters like
|
|
101
|
+
* vscode-js-debug, we open a fresh TCP connection to the same port, run
|
|
102
|
+
* initialize + launch (or attach) using the request's configuration, and
|
|
103
|
+
* make that new connection the active one for subsequent user requests.
|
|
104
|
+
*
|
|
105
|
+
* The `transitionLock` prevents user `sendRequest` calls from racing the
|
|
106
|
+
* handshake.
|
|
107
|
+
*/
|
|
108
|
+
private handleStartDebugging;
|
|
42
109
|
get exited(): boolean;
|
|
43
110
|
get stderr(): string;
|
|
44
111
|
dispose(): Promise<void>;
|