dap-mcp-server 0.1.5
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/.claude/settings.local.json +31 -0
- package/.forgejo/workflows/publish.yml +63 -0
- package/CLAUDE.md +71 -0
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/SKILL.md +62 -0
- package/build/adapters/builtin.d.ts +24 -0
- package/build/adapters/builtin.js +46 -0
- package/build/adapters/builtin.js.map +1 -0
- package/build/adapters/detect.d.ts +23 -0
- package/build/adapters/detect.js +36 -0
- package/build/adapters/detect.js.map +1 -0
- package/build/adapters/registry.d.ts +39 -0
- package/build/adapters/registry.js +79 -0
- package/build/adapters/registry.js.map +1 -0
- package/build/dap/dap-client.d.ts +46 -0
- package/build/dap/dap-client.js +190 -0
- package/build/dap/dap-client.js.map +1 -0
- package/build/dap/protocol.d.ts +32 -0
- package/build/dap/protocol.js +71 -0
- package/build/dap/protocol.js.map +1 -0
- package/build/dap/ring-buffer.d.ts +35 -0
- package/build/dap/ring-buffer.js +57 -0
- package/build/dap/ring-buffer.js.map +1 -0
- package/build/dap/types.d.ts +87 -0
- package/build/dap/types.js +25 -0
- package/build/dap/types.js.map +1 -0
- package/build/index.d.ts +24 -0
- package/build/index.js +30 -0
- package/build/index.js.map +1 -0
- package/build/server.d.ts +24 -0
- package/build/server.js +735 -0
- package/build/server.js.map +1 -0
- package/build/session/session-manager.d.ts +32 -0
- package/build/session/session-manager.js +60 -0
- package/build/session/session-manager.js.map +1 -0
- package/build/session/session.d.ts +85 -0
- package/build/session/session.js +374 -0
- package/build/session/session.js.map +1 -0
- package/docs/plans/2026-03-05-dap-wrapper-mcp-design.md +326 -0
- package/docs/plans/2026-03-05-dap-wrapper-mcp-implementation.md +2815 -0
- package/package.json +43 -0
- package/src/adapters/builtin.ts +47 -0
- package/src/adapters/detect.test.ts +36 -0
- package/src/adapters/detect.ts +36 -0
- package/src/adapters/registry.test.ts +73 -0
- package/src/adapters/registry.ts +86 -0
- package/src/dap/dap-client.test.ts +87 -0
- package/src/dap/dap-client.ts +216 -0
- package/src/dap/protocol.test.ts +82 -0
- package/src/dap/protocol.ts +78 -0
- package/src/dap/ring-buffer.test.ts +82 -0
- package/src/dap/ring-buffer.ts +64 -0
- package/src/dap/types.ts +92 -0
- package/src/index.ts +30 -0
- package/src/integration/debug-lifecycle.test.ts +107 -0
- package/src/server.ts +866 -0
- package/src/session/session-manager.test.ts +74 -0
- package/src/session/session-manager.ts +67 -0
- package/src/session/session.test.ts +84 -0
- package/src/session/session.ts +435 -0
- package/src/test-fixtures/crash-adapter.js +23 -0
- package/src/test-fixtures/mock-adapter.js +142 -0
- package/src/test-fixtures/silent-adapter.js +24 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"mcp__lsp__lsp_server_status",
|
|
5
|
+
"WebFetch(domain:microsoft.github.io)",
|
|
6
|
+
"WebSearch",
|
|
7
|
+
"WebFetch(domain:www.npmjs.com)",
|
|
8
|
+
"WebFetch(domain:github.com)",
|
|
9
|
+
"WebFetch(domain:registry.npmjs.org)",
|
|
10
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
11
|
+
"WebFetch(domain:deepwiki.com)",
|
|
12
|
+
"Bash(npm install:*)",
|
|
13
|
+
"Bash(npx tsc:*)",
|
|
14
|
+
"mcp__lsp__lsp_start_server",
|
|
15
|
+
"Bash(npx vitest:*)",
|
|
16
|
+
"Bash(git:*)",
|
|
17
|
+
"mcp__lsp__lsp_file_exports",
|
|
18
|
+
"Bash(python3:*)",
|
|
19
|
+
"mcp__lsp__lsp_diagnostics",
|
|
20
|
+
"mcp__lsp__lsp_hover",
|
|
21
|
+
"mcp__lsp__lsp_find_references",
|
|
22
|
+
"mcp__lsp__lsp_goto_definition",
|
|
23
|
+
"Bash(npm run:*)",
|
|
24
|
+
"Bash(npm test:*)"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"enableAllProjectMcpServers": true,
|
|
28
|
+
"enabledMcpjsonServers": [
|
|
29
|
+
"lsp"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: docker
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 0
|
|
16
|
+
token: ${{ secrets.REPO_TOKEN }}
|
|
17
|
+
|
|
18
|
+
- name: Setup Node.js
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: '20'
|
|
22
|
+
registry-url: 'https://registry.npmjs.org'
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: npm ci
|
|
26
|
+
|
|
27
|
+
- name: Run tests
|
|
28
|
+
run: npm test
|
|
29
|
+
|
|
30
|
+
- name: Run typecheck
|
|
31
|
+
run: npm run typecheck
|
|
32
|
+
|
|
33
|
+
- name: Build
|
|
34
|
+
run: npm run build
|
|
35
|
+
|
|
36
|
+
- name: Configure git
|
|
37
|
+
run: |
|
|
38
|
+
git config user.name "Forgejo Actions"
|
|
39
|
+
git config user.email "actions@forgejo.local"
|
|
40
|
+
|
|
41
|
+
- name: Bump version and publish
|
|
42
|
+
env:
|
|
43
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
44
|
+
run: |
|
|
45
|
+
# Get current version
|
|
46
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
47
|
+
echo "Current version: $CURRENT_VERSION"
|
|
48
|
+
|
|
49
|
+
# Bump patch version
|
|
50
|
+
npm version patch --no-git-tag-version
|
|
51
|
+
NEW_VERSION=$(node -p "require('./package.json').version")
|
|
52
|
+
echo "New version: $NEW_VERSION"
|
|
53
|
+
|
|
54
|
+
# Commit version bump
|
|
55
|
+
git add package.json package-lock.json
|
|
56
|
+
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
|
|
57
|
+
git tag "v$NEW_VERSION"
|
|
58
|
+
|
|
59
|
+
# Push changes back to repository
|
|
60
|
+
git push origin main --tags
|
|
61
|
+
|
|
62
|
+
# Publish to npm
|
|
63
|
+
npm publish --access public
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
MCP server wrapping the Debug Adapter Protocol (DAP) for AI agent-driven debugging. TypeScript, Node.js, ESM modules. Published to npm as `dap-mcp-server`.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run build # TypeScript compilation → build/
|
|
13
|
+
npm run typecheck # Type-check without emitting (tsc --noEmit)
|
|
14
|
+
npm test # vitest run (all tests)
|
|
15
|
+
npm run test:watch # vitest in watch mode
|
|
16
|
+
npm run dev # tsc --watch
|
|
17
|
+
npm start # Run the MCP server (stdio transport)
|
|
18
|
+
npx vitest run src/path/to/file.test.ts # Run a single test file
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
Three layers, top to bottom:
|
|
24
|
+
|
|
25
|
+
1. **MCP Layer** (`src/server.ts`, `src/index.ts`) — `McpServer` with 12 tools + 1 resource (`dap://sessions`). All tool handlers return `{ content: [{ type: "text", text: JSON.stringify(...) }] }` with `isError: true` on failure. Entry point connects via `StdioServerTransport`.
|
|
26
|
+
|
|
27
|
+
2. **Session Layer** (`src/session/`) — `DebugSession` wraps a `DAPClient` with state machine (`idle → configuring → running ↔ stopped → terminated`), output buffering (`RingBuffer<OutputEntry>`), and composite state collection (`collectState()` fetches threads + stack + scopes + variables in one call). `SessionManager` handles multi-session tracking with auto-resolution (single active session doesn't need explicit ID).
|
|
28
|
+
|
|
29
|
+
3. **DAP Layer** (`src/dap/`) — `DAPClient` spawns adapter as child process, communicates via stdin/stdout using DAP wire protocol (Content-Length headers + JSON bodies, same framing as LSP). `MessageParser` handles incremental parsing. `DAPClient` extends `EventEmitter`, emitting DAP events and tracking pending request/response correlation by sequence number.
|
|
30
|
+
|
|
31
|
+
4. **Adapters** (`src/adapters/`) — `AdapterRegistry` with three tiers: builtins (`builtin.ts`) < global (`~/.dap-mcp/adapters.json`) < project (`./.dap-mcp/adapters.json`). Higher tiers override lower. `detect.ts` checks adapter binary availability via `which`/`where`.
|
|
32
|
+
|
|
33
|
+
### Request Lifecycle
|
|
34
|
+
|
|
35
|
+
`MCP tool call → server.ts handler → SessionManager.resolve(sessionId) → DebugSession method → DAPClient.sendRequest(command, args) → serialize to DAP wire format → adapter stdin → adapter stdout → MessageParser → response correlation by seq number → resolve Promise`
|
|
36
|
+
|
|
37
|
+
Events flow the reverse direction: adapter emits events → `DAPClient` re-emits → `DebugSession.handleEvent()` updates state machine, resolves waiters, buffers output.
|
|
38
|
+
|
|
39
|
+
## Code Conventions
|
|
40
|
+
|
|
41
|
+
- ESM modules (`"type": "module"` in package.json)
|
|
42
|
+
- Import paths use `.js` extension (e.g., `import { Foo } from "./foo.js"`)
|
|
43
|
+
- Never `console.log()` in server code — stdout is MCP wire protocol; use `console.error()` for diagnostics
|
|
44
|
+
- All tool execution errors use `isError: true` in MCP results, not JSON-RPC protocol errors
|
|
45
|
+
- Types from `@vscode/debugprotocol` for DAP message types
|
|
46
|
+
- Internal/MCP-facing types in `src/dap/types.ts`
|
|
47
|
+
- All source files carry an MIT license header comment — preserve it when creating new files
|
|
48
|
+
|
|
49
|
+
## Testing
|
|
50
|
+
|
|
51
|
+
- Framework: vitest (no config file — uses defaults)
|
|
52
|
+
- Unit tests: co-located with source (`*.test.ts`)
|
|
53
|
+
- Integration tests: `src/integration/` — test full DAP lifecycle against mock adapters
|
|
54
|
+
- Test fixtures: `src/test-fixtures/` — mock DAP adapters written in **plain JS** (not TypeScript), implementing enough of the DAP protocol to test against. `mock-adapter.js` is the full-featured one; `crash-adapter.js` and `silent-adapter.js` test error cases.
|
|
55
|
+
|
|
56
|
+
## Key Design Decisions
|
|
57
|
+
|
|
58
|
+
1. **Coarse-grained tools**: `get_state` returns threads+stack+scopes+variables in one call to minimize AI agent round-trips
|
|
59
|
+
2. **Synchronous stepping**: `step` blocks until stopped, returns new state
|
|
60
|
+
3. **Auto-session resolution**: `sessionId` optional when single session active
|
|
61
|
+
4. **Output ring buffer**: 10K lines max, oldest dropped
|
|
62
|
+
5. **Own DAP client**: Custom implementation (not `@vscode/debugadapter-testsupport`) for full control over event buffering and crash detection
|
|
63
|
+
|
|
64
|
+
## CI/CD
|
|
65
|
+
|
|
66
|
+
Forgejo Actions workflow (`.forgejo/workflows/publish.yml`) runs on push to `main`: tests → typecheck → build → bump patch version → publish to npm. Version bumps are auto-committed with `[skip ci]`.
|
|
67
|
+
|
|
68
|
+
## Design Documents
|
|
69
|
+
|
|
70
|
+
- Design: `docs/plans/2026-03-05-dap-wrapper-mcp-design.md`
|
|
71
|
+
- Implementation plan: `docs/plans/2026-03-05-dap-wrapper-mcp-implementation.md`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# dap-mcp-server
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that wraps the Debug Adapter Protocol (DAP), enabling AI agents to use real debuggers instead of relying on print statements and log analysis.
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
When AI coding agents encounter bugs, they typically resort to adding `console.log` statements or reading stack traces. This MCP server gives them access to actual debuggers — setting breakpoints, stepping through code, inspecting variables, and evaluating expressions — through any debug adapter that implements DAP.
|
|
8
|
+
|
|
9
|
+
The server spawns debug adapters as child processes and exposes a small set of coarse-grained MCP tools optimized for how an AI agent thinks about debugging: "launch this program, stop here, show me what's happening."
|
|
10
|
+
|
|
11
|
+
## Supported Debug Adapters
|
|
12
|
+
|
|
13
|
+
Any DAP-compliant debug adapter works. Built-in defaults for:
|
|
14
|
+
|
|
15
|
+
| Language | Adapter | Install |
|
|
16
|
+
|----------|---------|---------|
|
|
17
|
+
| Python | debugpy | `pip install debugpy` |
|
|
18
|
+
| Go | Delve | `go install github.com/go-delve/delve/cmd/dlv@latest` |
|
|
19
|
+
| C/C++ | lldb-dap | `apt install lldb` / `brew install llvm` |
|
|
20
|
+
|
|
21
|
+
Additional adapters (e.g. Node.js via js-debug) can be registered via the `configure_adapter` tool or config files.
|
|
22
|
+
|
|
23
|
+
## MCP Tools
|
|
24
|
+
|
|
25
|
+
| Tool | Description |
|
|
26
|
+
|------|-------------|
|
|
27
|
+
| `debug_launch` | Start a debug session (launch a program with breakpoints) |
|
|
28
|
+
| `debug_attach` | Attach to a running process |
|
|
29
|
+
| `debug_restart` | Restart with the same configuration |
|
|
30
|
+
| `debug_disconnect` | End a debug session |
|
|
31
|
+
| `set_breakpoints` | Set/replace breakpoints in a file |
|
|
32
|
+
| `set_exception_breakpoints` | Break on exceptions |
|
|
33
|
+
| `get_state` | Get threads, stack trace, scopes, and variables |
|
|
34
|
+
| `evaluate` | Evaluate an expression in the debuggee context |
|
|
35
|
+
| `step` | Continue, next, stepIn, stepOut, or pause |
|
|
36
|
+
| `get_output` | Get buffered stdout/stderr |
|
|
37
|
+
| `configure_adapter` | Register a custom debug adapter |
|
|
38
|
+
| `list_adapters` | List available adapters |
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g dap-mcp-server
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or from source:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone <repo-url>
|
|
50
|
+
cd dap-mcp-server
|
|
51
|
+
npm install
|
|
52
|
+
npm run build
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage with Claude Code
|
|
56
|
+
|
|
57
|
+
Add to your MCP configuration (`~/.claude/mcp.json` or project `.mcp.json`):
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"dap": {
|
|
63
|
+
"command": "npx",
|
|
64
|
+
"args": ["-y", "dap-mcp-server"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or if installed globally:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"dap": {
|
|
76
|
+
"command": "dap-mcp-server"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A `SKILL.md` file is included in the package. Copy it to `.claude/skills/` in your project to teach Claude Code when and how to use the debugger:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
mkdir -p .claude/skills
|
|
86
|
+
cp node_modules/dap-mcp-server/SKILL.md .claude/skills/dap-debugging.md
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Design
|
|
90
|
+
|
|
91
|
+
Tools are deliberately coarse-grained. A single `get_state` call returns threads, stack trace, scopes, and variables — instead of requiring 4 separate calls. The `step` tool blocks synchronously until the debuggee stops again and returns the new state. This minimizes round-trips for AI agents that think in terms of "step forward and show me what happened."
|
|
92
|
+
|
|
93
|
+
Session IDs are optional when only one debug session is active. Breakpoints can be set inline with `debug_launch` for single-call debugging setup.
|
|
94
|
+
|
|
95
|
+
See [docs/plans/2026-03-05-dap-wrapper-mcp-design.md](docs/plans/2026-03-05-dap-wrapper-mcp-design.md) for the full design document.
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
Adapter configurations are stored in:
|
|
100
|
+
- `~/.dap-mcp/adapters.json` — global defaults
|
|
101
|
+
- `./.dap-mcp/adapters.json` — project-local overrides
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dap-debugging
|
|
3
|
+
description: Use when debugging a program — when you need to set breakpoints, step through code, inspect variables, or understand runtime behavior instead of guessing with print statements.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debugging with DAP MCP Server
|
|
7
|
+
|
|
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
|
+
|
|
10
|
+
## When to Use the Debugger
|
|
11
|
+
|
|
12
|
+
- A test fails and the cause is not obvious from the error message or stack trace
|
|
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
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
1. Check available adapters: call `list_adapters` to see what's installed.
|
|
21
|
+
2. Launch with breakpoints in a single call:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
debug_launch({
|
|
25
|
+
adapter: "python", // or "node", "go", "cpp"
|
|
26
|
+
program: "/absolute/path/to/file.py",
|
|
27
|
+
stopOnEntry: false,
|
|
28
|
+
breakpoints: [
|
|
29
|
+
{ file: "/absolute/path/to/file.py", line: 42 }
|
|
30
|
+
]
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
3. When the program stops, the response already contains the full state (threads, stack, scopes, variables). Read it — no extra call needed.
|
|
35
|
+
4. Step through code with `step({ action: "next" })` — the response includes the new state.
|
|
36
|
+
5. Evaluate expressions with `evaluate({ expression: "len(items)" })`.
|
|
37
|
+
6. When done, call `debug_disconnect`.
|
|
38
|
+
|
|
39
|
+
## Key Rules
|
|
40
|
+
|
|
41
|
+
- **Do NOT call `get_state` after `step`** — `step` already returns the new stopped state.
|
|
42
|
+
- **Omit `sessionId`** when only one debug session is active — the server resolves it automatically.
|
|
43
|
+
- **Use absolute paths** for `program` and breakpoint `file` parameters.
|
|
44
|
+
- **Prefer `stopOnEntry: false` with breakpoints** over `stopOnEntry: true` — it gets you directly to the interesting code.
|
|
45
|
+
- **Check `get_output`** for program stdout/stderr if you need to see what the program printed.
|
|
46
|
+
|
|
47
|
+
## Debugging Strategies
|
|
48
|
+
|
|
49
|
+
### Narrowing down a bug
|
|
50
|
+
1. Set a breakpoint where you know the state is still correct.
|
|
51
|
+
2. Set another breakpoint where the state is wrong.
|
|
52
|
+
3. Use `step` with `action: "next"` to walk through the code between them.
|
|
53
|
+
4. Use `evaluate` to check intermediate values.
|
|
54
|
+
|
|
55
|
+
### Understanding a crash
|
|
56
|
+
1. Launch with `exceptionBreakpoints: ["uncaughtExceptions"]`.
|
|
57
|
+
2. When it stops on the exception, inspect the stack and variables.
|
|
58
|
+
|
|
59
|
+
### Verifying a fix
|
|
60
|
+
1. Set a breakpoint at the fixed code.
|
|
61
|
+
2. Run to it, inspect variables, confirm the new behavior.
|
|
62
|
+
3. Continue to verify the program completes successfully.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { AdapterConfig } from "../dap/types.js";
|
|
24
|
+
export declare const BUILTIN_ADAPTERS: AdapterConfig[];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export const BUILTIN_ADAPTERS = [
|
|
24
|
+
{
|
|
25
|
+
type: "python",
|
|
26
|
+
runtime: "python3",
|
|
27
|
+
program: "-m",
|
|
28
|
+
args: ["debugpy.adapter"],
|
|
29
|
+
installHint: "pip install debugpy",
|
|
30
|
+
},
|
|
31
|
+
// node adapter removed — no reliable universal path to js-debug-dap.
|
|
32
|
+
// Configure via configure_adapter if needed.
|
|
33
|
+
{
|
|
34
|
+
type: "go",
|
|
35
|
+
program: "dlv",
|
|
36
|
+
args: ["dap"],
|
|
37
|
+
installHint: "go install github.com/go-delve/delve/cmd/dlv@latest",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: "cppdbg",
|
|
41
|
+
program: "lldb-dap",
|
|
42
|
+
args: [],
|
|
43
|
+
installHint: "apt install lldb (Debian/Ubuntu) or brew install llvm (macOS)",
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
//# sourceMappingURL=builtin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../src/adapters/builtin.ts"],"names":[],"mappings":"AAEA,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,WAAW,EAAE,qBAAqB;KACnC;IACD,qEAAqE;IACrE,6CAA6C;IAC7C;QACE,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,KAAK,CAAC;QACb,WAAW,EAAE,qDAAqD;KACnE;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,EAAE;QACR,WAAW,EAAE,+DAA+D;KAC7E;CACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export declare function checkAdapterAvailable(command: string): Promise<boolean>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { execFile } from "node:child_process";
|
|
24
|
+
import { promisify } from "node:util";
|
|
25
|
+
const execFileAsync = promisify(execFile);
|
|
26
|
+
export async function checkAdapterAvailable(command) {
|
|
27
|
+
try {
|
|
28
|
+
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
29
|
+
await execFileAsync(whichCmd, [command]);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/adapters/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAe;IACzD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAClE,MAAM,aAAa,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { AdapterConfig } from "../dap/types.js";
|
|
24
|
+
export declare class AdapterRegistry {
|
|
25
|
+
private builtins;
|
|
26
|
+
private global;
|
|
27
|
+
private project;
|
|
28
|
+
private globalDir;
|
|
29
|
+
private projectDir;
|
|
30
|
+
constructor(globalDir: string, projectDir: string);
|
|
31
|
+
get(type: string): AdapterConfig | undefined;
|
|
32
|
+
register(config: AdapterConfig, scope?: "global" | "project"): void;
|
|
33
|
+
listAll(): Array<AdapterConfig & {
|
|
34
|
+
source: "builtin" | "global" | "project";
|
|
35
|
+
}>;
|
|
36
|
+
load(): Promise<void>;
|
|
37
|
+
save(scope: "global" | "project"): Promise<void>;
|
|
38
|
+
private loadFile;
|
|
39
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 Ivan Iraci <ivan.iraci@professioneit.com>
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
|
12
|
+
* all copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { BUILTIN_ADAPTERS } from "./builtin.js";
|
|
24
|
+
import fs from "node:fs/promises";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
export class AdapterRegistry {
|
|
27
|
+
builtins;
|
|
28
|
+
global = new Map();
|
|
29
|
+
project = new Map();
|
|
30
|
+
globalDir;
|
|
31
|
+
projectDir;
|
|
32
|
+
constructor(globalDir, projectDir) {
|
|
33
|
+
this.globalDir = globalDir;
|
|
34
|
+
this.projectDir = projectDir;
|
|
35
|
+
this.builtins = new Map(BUILTIN_ADAPTERS.map((a) => [a.type, a]));
|
|
36
|
+
}
|
|
37
|
+
get(type) {
|
|
38
|
+
return this.project.get(type) ?? this.global.get(type) ?? this.builtins.get(type);
|
|
39
|
+
}
|
|
40
|
+
register(config, scope = "project") {
|
|
41
|
+
const map = scope === "global" ? this.global : this.project;
|
|
42
|
+
map.set(config.type, config);
|
|
43
|
+
}
|
|
44
|
+
listAll() {
|
|
45
|
+
const result = new Map();
|
|
46
|
+
for (const [type, config] of this.builtins) {
|
|
47
|
+
result.set(type, { ...config, source: "builtin" });
|
|
48
|
+
}
|
|
49
|
+
for (const [type, config] of this.global) {
|
|
50
|
+
result.set(type, { ...config, source: "global" });
|
|
51
|
+
}
|
|
52
|
+
for (const [type, config] of this.project) {
|
|
53
|
+
result.set(type, { ...config, source: "project" });
|
|
54
|
+
}
|
|
55
|
+
return Array.from(result.values());
|
|
56
|
+
}
|
|
57
|
+
async load() {
|
|
58
|
+
this.global = await this.loadFile(path.join(this.globalDir, "adapters.json"));
|
|
59
|
+
this.project = await this.loadFile(path.join(this.projectDir, "adapters.json"));
|
|
60
|
+
}
|
|
61
|
+
async save(scope) {
|
|
62
|
+
const dir = scope === "global" ? this.globalDir : this.projectDir;
|
|
63
|
+
const map = scope === "global" ? this.global : this.project;
|
|
64
|
+
await fs.mkdir(dir, { recursive: true });
|
|
65
|
+
const data = Object.fromEntries(map);
|
|
66
|
+
await fs.writeFile(path.join(dir, "adapters.json"), JSON.stringify(data, null, 2));
|
|
67
|
+
}
|
|
68
|
+
async loadFile(filePath) {
|
|
69
|
+
try {
|
|
70
|
+
const data = await fs.readFile(filePath, "utf-8");
|
|
71
|
+
const parsed = JSON.parse(data);
|
|
72
|
+
return new Map(Object.entries(parsed));
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return new Map();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"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"}
|