dap-mcp-server 0.1.12 → 0.1.17
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 +50 -10
- package/SKILL.md +39 -184
- package/build/adapters/builtin.js +25 -0
- package/build/adapters/builtin.js.map +1 -1
- package/build/adapters/detect.d.ts +12 -0
- package/build/adapters/detect.js +91 -0
- package/build/adapters/detect.js.map +1 -1
- package/build/adapters/recipes.d.ts +46 -0
- package/build/adapters/recipes.js +128 -0
- package/build/adapters/recipes.js.map +1 -0
- package/build/adapters/registry.js +35 -12
- package/build/adapters/registry.js.map +1 -1
- package/build/dap/types.d.ts +20 -0
- package/build/diagnostics/doctor.d.ts +70 -0
- package/build/diagnostics/doctor.js +268 -0
- package/build/diagnostics/doctor.js.map +1 -0
- package/build/server.js +432 -161
- package/build/server.js.map +1 -1
- package/build/session/inspect.d.ts +12 -2
- package/build/session/inspect.js +33 -20
- package/build/session/inspect.js.map +1 -1
- package/build/session/run.d.ts +2 -0
- package/build/session/run.js +13 -23
- package/build/session/run.js.map +1 -1
- package/build/session/session.d.ts +38 -2
- package/build/session/session.js +158 -12
- package/build/session/session.js.map +1 -1
- package/{src/test-fixtures/crash-adapter.js → build/session/state-format.d.ts} +11 -2
- package/build/session/state-format.js +62 -0
- package/build/session/state-format.js.map +1 -0
- package/integrations/claude/dap-debugging/.claude-plugin/plugin.json +9 -0
- package/integrations/claude/dap-debugging/.mcp.json +8 -0
- package/integrations/claude/dap-debugging/skills/dap-debugging/SKILL.md +51 -0
- package/package.json +8 -3
- package/.forgejo/workflows/publish.yml +0 -63
- package/CLAUDE.md +0 -71
- package/TODO.md +0 -32
- package/docs/plans/2026-03-05-dap-wrapper-mcp-design.md +0 -326
- package/docs/plans/2026-03-05-dap-wrapper-mcp-implementation.md +0 -2815
- package/src/adapters/builtin.ts +0 -75
- package/src/adapters/detect.test.ts +0 -36
- package/src/adapters/detect.ts +0 -36
- package/src/adapters/registry.test.ts +0 -74
- package/src/adapters/registry.ts +0 -86
- package/src/dap/dap-client.test.ts +0 -118
- package/src/dap/dap-client.ts +0 -588
- package/src/dap/protocol.test.ts +0 -82
- package/src/dap/protocol.ts +0 -78
- package/src/dap/ring-buffer.test.ts +0 -82
- package/src/dap/ring-buffer.ts +0 -64
- package/src/dap/types.ts +0 -115
- package/src/index.ts +0 -30
- package/src/integration/debug-lifecycle.test.ts +0 -131
- package/src/server.ts +0 -1096
- package/src/session/inspect.test.ts +0 -126
- package/src/session/inspect.ts +0 -160
- package/src/session/run.test.ts +0 -74
- package/src/session/run.ts +0 -144
- package/src/session/session-manager.test.ts +0 -74
- package/src/session/session-manager.ts +0 -67
- package/src/session/session.test.ts +0 -126
- package/src/session/session.ts +0 -482
- package/src/test-fixtures/mock-adapter.js +0 -164
- package/src/test-fixtures/no-stop-adapter.js +0 -77
- package/src/test-fixtures/silent-adapter.js +0 -24
- package/src/test-fixtures/tcp-mock-adapter.js +0 -87
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,128 @@
|
|
|
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
|
+
import { execFile } from "node:child_process";
|
|
23
|
+
import fs from "node:fs/promises";
|
|
24
|
+
import path from "node:path";
|
|
25
|
+
import { promisify } from "node:util";
|
|
26
|
+
const execFileAsync = promisify(execFile);
|
|
27
|
+
async function exists(filePath) {
|
|
28
|
+
try {
|
|
29
|
+
await fs.access(filePath);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
let rustSysroot;
|
|
37
|
+
function findRustSysroot() {
|
|
38
|
+
rustSysroot ??= execFileAsync("rustc", ["--print", "sysroot"])
|
|
39
|
+
.then(({ stdout }) => stdout.trim() || undefined)
|
|
40
|
+
.catch(() => undefined);
|
|
41
|
+
return rustSysroot;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The LLDB commands `rust-lldb` runs before loading a binary. Without them
|
|
45
|
+
* lldb-dap shows `String`, `&str`, `Vec` and `HashMap` as raw structs.
|
|
46
|
+
*/
|
|
47
|
+
async function rustFormatterCommands(sysroot) {
|
|
48
|
+
if (!sysroot)
|
|
49
|
+
return [];
|
|
50
|
+
const etc = path.join(sysroot, "lib", "rustlib", "etc");
|
|
51
|
+
const lookup = path.join(etc, "lldb_lookup.py");
|
|
52
|
+
if (!(await exists(lookup)))
|
|
53
|
+
return [];
|
|
54
|
+
const commands = [`command script import "${lookup}"`];
|
|
55
|
+
// Older toolchains register the type summaries from a separate command file.
|
|
56
|
+
const legacyCommands = path.join(etc, "lldb_commands");
|
|
57
|
+
if (await exists(legacyCommands))
|
|
58
|
+
commands.push(`command source -s 0 "${legacyCommands}"`);
|
|
59
|
+
return commands;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build the DAP launch arguments shared by debug_launch, debug_inspect/debug_at
|
|
63
|
+
* and debug_run. Merge order: adapter launchDefaults < launchConfig < explicit
|
|
64
|
+
* common fields, then per-adapter recipes that a caller would otherwise have
|
|
65
|
+
* to know by heart.
|
|
66
|
+
*/
|
|
67
|
+
export async function buildLaunchArgs(config, opts, resolveRustSysroot = findRustSysroot) {
|
|
68
|
+
const launchArgs = {
|
|
69
|
+
...config.launchDefaults,
|
|
70
|
+
...opts.launchConfig,
|
|
71
|
+
stopOnEntry: opts.stopOnEntry,
|
|
72
|
+
};
|
|
73
|
+
if (opts.program !== undefined)
|
|
74
|
+
launchArgs.program = opts.program;
|
|
75
|
+
if (opts.args !== undefined)
|
|
76
|
+
launchArgs.args = opts.args;
|
|
77
|
+
if (opts.cwd !== undefined)
|
|
78
|
+
launchArgs.cwd = opts.cwd;
|
|
79
|
+
if (opts.env !== undefined)
|
|
80
|
+
launchArgs.env = opts.env;
|
|
81
|
+
// delve's `cwd` is the debuggee's working directory; the *build* (go build)
|
|
82
|
+
// runs from delve's own process cwd, controlled by `dlvCwd`. Mirror
|
|
83
|
+
// cwd → dlvCwd so a user-supplied cwd is found by `go build` looking for go.mod.
|
|
84
|
+
if (config.type === "go" && opts.cwd !== undefined && launchArgs.dlvCwd === undefined) {
|
|
85
|
+
launchArgs.dlvCwd = opts.cwd;
|
|
86
|
+
}
|
|
87
|
+
const involvesRust = (opts.sourceFiles ?? []).some((file) => path.extname(file).toLowerCase() === ".rs");
|
|
88
|
+
if (config.type === "cppdbg" && involvesRust) {
|
|
89
|
+
const existing = Array.isArray(launchArgs.initCommands)
|
|
90
|
+
? launchArgs.initCommands.map(String)
|
|
91
|
+
: [];
|
|
92
|
+
if (!existing.some((command) => command.includes("lldb_lookup"))) {
|
|
93
|
+
const formatters = await rustFormatterCommands(await resolveRustSysroot());
|
|
94
|
+
if (formatters.length > 0)
|
|
95
|
+
launchArgs.initCommands = [...existing, ...formatters];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return launchArgs;
|
|
99
|
+
}
|
|
100
|
+
/** `target/debug/<package name>` of the Cargo project in cwd, once it has been built. */
|
|
101
|
+
export async function defaultCargoProgram(cwd) {
|
|
102
|
+
const manifest = await fs.readFile(path.join(cwd, "Cargo.toml"), "utf8").catch(() => undefined);
|
|
103
|
+
const name = manifest?.match(/^\s*\[package\][^[]*?^\s*name\s*=\s*"([^"]+)"/ms)?.[1];
|
|
104
|
+
if (!name)
|
|
105
|
+
return undefined;
|
|
106
|
+
const binary = path.join(cwd, "target", "debug", process.platform === "win32" ? `${name}.exe` : name);
|
|
107
|
+
return (await exists(binary)) ? binary : undefined;
|
|
108
|
+
}
|
|
109
|
+
const LAUNCH_FAILURE_HINTS = {
|
|
110
|
+
php: "PHP ran without xdebug connecting to the adapter. Check that xdebug 3 is loaded in the CLI (php -m | grep -i xdebug) " +
|
|
111
|
+
"and that launchConfig.runtimeArgs still enables it (-dxdebug.mode=debug -dxdebug.start_with_request=yes).",
|
|
112
|
+
};
|
|
113
|
+
/** Why a program may have run to completion without the debugger ever binding a breakpoint. */
|
|
114
|
+
export function launchFailureHint(adapterType) {
|
|
115
|
+
return LAUNCH_FAILURE_HINTS[adapterType];
|
|
116
|
+
}
|
|
117
|
+
const ADAPTER_USAGE_NOTES = {
|
|
118
|
+
cppdbg: "Compile with debug info (-g -O0) and pass the executable as program.",
|
|
119
|
+
rust: "Build with `cargo build`; debug_at defaults program to target/debug/<package name> and loads the Rust LLDB formatters.",
|
|
120
|
+
php: "Needs xdebug 3 in the PHP CLI; the xdebug runtimeArgs are supplied by the adapter's launchDefaults.",
|
|
121
|
+
java: "Start the JVM with -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=127.0.0.1:5005, " +
|
|
122
|
+
"then call debug_attach with port and breakpoints so they bind before the VM resumes.",
|
|
123
|
+
};
|
|
124
|
+
/** How to get a first stop with this language/adapter; surfaced by debug_doctor. */
|
|
125
|
+
export function adapterUsageNote(languageOrAdapter) {
|
|
126
|
+
return ADAPTER_USAGE_NOTES[languageOrAdapter];
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/adapters/recipes.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,24 +34,47 @@ export class AdapterRegistry {
|
|
|
34
34
|
this.builtins = new Map(BUILTIN_ADAPTERS.map((a) => [a.type, a]));
|
|
35
35
|
}
|
|
36
36
|
get(type) {
|
|
37
|
-
|
|
37
|
+
const builtin = this.builtins.get(type);
|
|
38
|
+
const global = this.global.get(type);
|
|
39
|
+
const project = this.project.get(type);
|
|
40
|
+
if (!builtin && !global && !project)
|
|
41
|
+
return undefined;
|
|
42
|
+
const merged = {};
|
|
43
|
+
for (const layer of [builtin, global, project]) {
|
|
44
|
+
if (!layer)
|
|
45
|
+
continue;
|
|
46
|
+
for (const [key, value] of Object.entries(layer)) {
|
|
47
|
+
if (value !== undefined && key !== "launchDefaults") {
|
|
48
|
+
merged[key] = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
merged.launchDefaults = {
|
|
53
|
+
...builtin?.launchDefaults,
|
|
54
|
+
...global?.launchDefaults,
|
|
55
|
+
...project?.launchDefaults,
|
|
56
|
+
};
|
|
57
|
+
return merged;
|
|
38
58
|
}
|
|
39
59
|
register(config, scope = "project") {
|
|
40
60
|
const map = scope === "global" ? this.global : this.project;
|
|
41
61
|
map.set(config.type, config);
|
|
42
62
|
}
|
|
43
63
|
listAll() {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
const types = new Set([
|
|
65
|
+
...this.builtins.keys(),
|
|
66
|
+
...this.global.keys(),
|
|
67
|
+
...this.project.keys(),
|
|
68
|
+
]);
|
|
69
|
+
return Array.from(types, (type) => {
|
|
70
|
+
const config = this.get(type);
|
|
71
|
+
const source = this.project.has(type)
|
|
72
|
+
? "project"
|
|
73
|
+
: this.global.has(type)
|
|
74
|
+
? "global"
|
|
75
|
+
: "builtin";
|
|
76
|
+
return { ...config, source };
|
|
77
|
+
});
|
|
55
78
|
}
|
|
56
79
|
async load() {
|
|
57
80
|
this.global = await this.loadFile(path.join(this.globalDir, "adapters.json"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,eAAe;IAClB,QAAQ,CAA6B;IACrC,MAAM,GAA+B,IAAI,GAAG,EAAE,CAAC;IAC/C,OAAO,GAA+B,IAAI,GAAG,EAAE,CAAC;IAChD,SAAS,CAAS;IAClB,UAAU,CAAS;IAE3B,YAAY,SAAiB,EAAE,UAAkB;QAC/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,eAAe;IAClB,QAAQ,CAA6B;IACrC,MAAM,GAA+B,IAAI,GAAG,EAAE,CAAC;IAC/C,OAAO,GAA+B,IAAI,GAAG,EAAE,CAAC;IAChD,SAAS,CAAS;IAClB,UAAU,CAAS;IAE3B,YAAY,SAAiB,EAAE,UAAkB;QAC/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,GAAG,CAAC,IAAY;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAEtD,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;oBACnD,MAAkC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,cAAc,GAAG;YACtB,GAAG,OAAO,EAAE,cAAc;YAC1B,GAAG,MAAM,EAAE,cAAc;YACzB,GAAG,OAAO,EAAE,cAAc;SAC3B,CAAC;QACF,OAAO,MAAuB,CAAC;IACjC,CAAC;IAED,QAAQ,CAAC,MAAqB,EAAE,QAA8B,SAAS;QACrE,MAAM,GAAG,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAC5D,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;YACpB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YACvB,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;YACrB,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;SACvB,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;oBACrB,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,SAAS,CAAC;YAChB,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAA2B;QACpC,MAAM,GAAG,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAClE,MAAM,GAAG,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAC5D,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,QAAgB;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAkC,CAAC;YACjE,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;CACF"}
|
package/build/dap/types.d.ts
CHANGED
|
@@ -54,7 +54,27 @@ export interface StoppedState {
|
|
|
54
54
|
name: string;
|
|
55
55
|
variables: Variable[];
|
|
56
56
|
}>;
|
|
57
|
+
/** Scopes the adapter offers but that were not fetched (e.g. CPU registers). */
|
|
58
|
+
omittedScopes?: string[];
|
|
59
|
+
/** Present when `reason` is "exception". */
|
|
60
|
+
exception?: ExceptionDetails;
|
|
61
|
+
/** Output not yet reported by an earlier state, newest entries last. */
|
|
57
62
|
output?: string[];
|
|
63
|
+
/** Number of older unreported entries dropped from `output`; get_output has them. */
|
|
64
|
+
outputOmitted?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface ExceptionDetails {
|
|
67
|
+
id?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
breakMode?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface CollectStateOptions {
|
|
72
|
+
/** Scope names to fetch (case-insensitive). Default: every scope except CPU registers. */
|
|
73
|
+
scopes?: string[];
|
|
74
|
+
/** Also skip global/static/expensive scopes; used by compact responses. */
|
|
75
|
+
localsOnly?: boolean;
|
|
76
|
+
/** Mark the returned output as reported, so the next state only carries newer output. */
|
|
77
|
+
consumeOutput?: boolean;
|
|
58
78
|
}
|
|
59
79
|
export interface RunningState {
|
|
60
80
|
status: "running";
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
import { AdapterRegistry } from "../adapters/registry.js";
|
|
23
|
+
import { AdapterConfig } from "../dap/types.js";
|
|
24
|
+
export interface ProjectSignals {
|
|
25
|
+
languages: string[];
|
|
26
|
+
testFrameworks: string[];
|
|
27
|
+
packageManager?: string;
|
|
28
|
+
pythonPath?: string;
|
|
29
|
+
launchJson?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface DoctorAdapter {
|
|
32
|
+
type: string;
|
|
33
|
+
source: "builtin" | "global" | "project";
|
|
34
|
+
selected: boolean;
|
|
35
|
+
available: boolean;
|
|
36
|
+
command: string;
|
|
37
|
+
reason?: string;
|
|
38
|
+
installHint?: string;
|
|
39
|
+
runtime?: string;
|
|
40
|
+
program: string;
|
|
41
|
+
transport: "stdio" | "tcp";
|
|
42
|
+
}
|
|
43
|
+
export interface DoctorResult {
|
|
44
|
+
cwd: string;
|
|
45
|
+
ready: boolean;
|
|
46
|
+
recommendedAdapter?: string;
|
|
47
|
+
detected: ProjectSignals;
|
|
48
|
+
/** The selected adapter only, unless the caller asked for a verbose report. */
|
|
49
|
+
adapters: DoctorAdapter[];
|
|
50
|
+
/** Compact roster of the adapters left out of `adapters`, e.g. "go (missing)". */
|
|
51
|
+
otherAdapters?: string[];
|
|
52
|
+
nextSteps: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface ResolvedProjectAdapter {
|
|
55
|
+
result: DoctorResult;
|
|
56
|
+
config?: AdapterConfig;
|
|
57
|
+
}
|
|
58
|
+
export declare function detectProjectSignals(cwd: string, sourceFile?: string): Promise<ProjectSignals>;
|
|
59
|
+
export declare function resolveProjectAdapter(registry: AdapterRegistry, options?: {
|
|
60
|
+
cwd?: string;
|
|
61
|
+
adapter?: string;
|
|
62
|
+
sourceFile?: string;
|
|
63
|
+
}): Promise<ResolvedProjectAdapter>;
|
|
64
|
+
/** Drop the per-adapter detail an agent rarely needs, keeping a one-line roster. */
|
|
65
|
+
export declare function conciseDoctorResult(result: DoctorResult): DoctorResult;
|
|
66
|
+
export declare function runDebugDoctor(registry: AdapterRegistry, options?: {
|
|
67
|
+
cwd?: string;
|
|
68
|
+
adapter?: string;
|
|
69
|
+
verbose?: boolean;
|
|
70
|
+
}): Promise<DoctorResult>;
|
|
@@ -0,0 +1,268 @@
|
|
|
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
|
+
import fs from "node:fs/promises";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
import { inspectAdapterAvailability } from "../adapters/detect.js";
|
|
25
|
+
import { adapterUsageNote } from "../adapters/recipes.js";
|
|
26
|
+
async function exists(filePath) {
|
|
27
|
+
try {
|
|
28
|
+
await fs.access(filePath);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function firstExisting(paths) {
|
|
36
|
+
for (const candidate of paths) {
|
|
37
|
+
if (await exists(candidate))
|
|
38
|
+
return candidate;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
async function readPackageJson(cwd) {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(await fs.readFile(path.join(cwd, "package.json"), "utf8"));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function packageNames(pkg) {
|
|
51
|
+
const names = new Set();
|
|
52
|
+
for (const key of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
53
|
+
const deps = pkg?.[key];
|
|
54
|
+
if (deps && typeof deps === "object") {
|
|
55
|
+
for (const name of Object.keys(deps))
|
|
56
|
+
names.add(name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return names;
|
|
60
|
+
}
|
|
61
|
+
const EXTENSION_LANGUAGES = {
|
|
62
|
+
".py": "python",
|
|
63
|
+
".js": "node",
|
|
64
|
+
".jsx": "node",
|
|
65
|
+
".mjs": "node",
|
|
66
|
+
".cjs": "node",
|
|
67
|
+
".ts": "node",
|
|
68
|
+
".tsx": "node",
|
|
69
|
+
".go": "go",
|
|
70
|
+
".c": "cppdbg",
|
|
71
|
+
".cc": "cppdbg",
|
|
72
|
+
".cpp": "cppdbg",
|
|
73
|
+
".cxx": "cppdbg",
|
|
74
|
+
".h": "cppdbg",
|
|
75
|
+
".hpp": "cppdbg",
|
|
76
|
+
".rs": "rust",
|
|
77
|
+
".php": "php",
|
|
78
|
+
".java": "java",
|
|
79
|
+
};
|
|
80
|
+
const MANIFEST_LANGUAGES = [
|
|
81
|
+
["pyproject.toml", "python"],
|
|
82
|
+
["requirements.txt", "python"],
|
|
83
|
+
["setup.py", "python"],
|
|
84
|
+
["go.mod", "go"],
|
|
85
|
+
["Cargo.toml", "rust"],
|
|
86
|
+
["composer.json", "php"],
|
|
87
|
+
["pom.xml", "java"],
|
|
88
|
+
["build.gradle", "java"],
|
|
89
|
+
["build.gradle.kts", "java"],
|
|
90
|
+
["CMakeLists.txt", "cppdbg"],
|
|
91
|
+
];
|
|
92
|
+
/** Languages debugged through an adapter whose type differs from the language name. */
|
|
93
|
+
const LANGUAGE_ADAPTERS = {
|
|
94
|
+
rust: "cppdbg",
|
|
95
|
+
};
|
|
96
|
+
function languageOf(filePath) {
|
|
97
|
+
return EXTENSION_LANGUAGES[path.extname(filePath).toLowerCase()];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Fallback for manifest-less projects (scripts, pet projects): rank languages
|
|
101
|
+
* by how many source files sit in cwd and cwd/src.
|
|
102
|
+
*/
|
|
103
|
+
async function looseSourceLanguages(cwd) {
|
|
104
|
+
const counts = new Map();
|
|
105
|
+
for (const dir of [cwd, path.join(cwd, "src")]) {
|
|
106
|
+
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
107
|
+
for (const entry of entries) {
|
|
108
|
+
const language = entry.isFile() ? languageOf(entry.name) : undefined;
|
|
109
|
+
if (language)
|
|
110
|
+
counts.set(language, (counts.get(language) ?? 0) + 1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return Array.from(counts.entries())
|
|
114
|
+
.sort((a, b) => b[1] - a[1])
|
|
115
|
+
.map(([language]) => language);
|
|
116
|
+
}
|
|
117
|
+
export async function detectProjectSignals(cwd, sourceFile) {
|
|
118
|
+
const languages = new Set();
|
|
119
|
+
const testFrameworks = new Set();
|
|
120
|
+
const sourceLanguage = sourceFile ? languageOf(sourceFile) : undefined;
|
|
121
|
+
if (sourceLanguage)
|
|
122
|
+
languages.add(sourceLanguage);
|
|
123
|
+
for (const [manifest, language] of MANIFEST_LANGUAGES) {
|
|
124
|
+
if (await exists(path.join(cwd, manifest)))
|
|
125
|
+
languages.add(language);
|
|
126
|
+
}
|
|
127
|
+
const pkg = await readPackageJson(cwd);
|
|
128
|
+
const deps = packageNames(pkg);
|
|
129
|
+
if (pkg)
|
|
130
|
+
languages.add("node");
|
|
131
|
+
if (languages.size === 0) {
|
|
132
|
+
for (const language of await looseSourceLanguages(cwd))
|
|
133
|
+
languages.add(language);
|
|
134
|
+
}
|
|
135
|
+
if (deps.has("vitest"))
|
|
136
|
+
testFrameworks.add("vitest");
|
|
137
|
+
if (deps.has("jest") || deps.has("@jest/core"))
|
|
138
|
+
testFrameworks.add("jest");
|
|
139
|
+
if (deps.has("mocha"))
|
|
140
|
+
testFrameworks.add("mocha");
|
|
141
|
+
if (languages.has("python"))
|
|
142
|
+
testFrameworks.add("pytest-compatible");
|
|
143
|
+
if (languages.has("go"))
|
|
144
|
+
testFrameworks.add("go-test");
|
|
145
|
+
let packageManager;
|
|
146
|
+
if (await exists(path.join(cwd, "pnpm-lock.yaml")))
|
|
147
|
+
packageManager = "pnpm";
|
|
148
|
+
else if (await exists(path.join(cwd, "yarn.lock")))
|
|
149
|
+
packageManager = "yarn";
|
|
150
|
+
else if (await exists(path.join(cwd, "bun.lockb")))
|
|
151
|
+
packageManager = "bun";
|
|
152
|
+
else if (await exists(path.join(cwd, "package-lock.json")))
|
|
153
|
+
packageManager = "npm";
|
|
154
|
+
const pythonPath = await firstExisting(process.platform === "win32"
|
|
155
|
+
? [path.join(cwd, ".venv", "Scripts", "python.exe"), path.join(cwd, "venv", "Scripts", "python.exe")]
|
|
156
|
+
: [path.join(cwd, ".venv", "bin", "python"), path.join(cwd, "venv", "bin", "python")]);
|
|
157
|
+
const launchJsonPath = path.join(cwd, ".vscode", "launch.json");
|
|
158
|
+
const launchJson = (await exists(launchJsonPath)) ? launchJsonPath : undefined;
|
|
159
|
+
return {
|
|
160
|
+
languages: Array.from(languages),
|
|
161
|
+
testFrameworks: Array.from(testFrameworks),
|
|
162
|
+
packageManager,
|
|
163
|
+
pythonPath,
|
|
164
|
+
launchJson,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async function resolveNodeProgram(cwd) {
|
|
168
|
+
return firstExisting([
|
|
169
|
+
path.join(cwd, "node_modules", "@vscode", "js-debug", "src", "dapDebugServer.js"),
|
|
170
|
+
path.join(cwd, "node_modules", "@vscode", "js-debug", "dist", "src", "dapDebugServer.js"),
|
|
171
|
+
path.join(cwd, "node_modules", "vscode-js-debug", "src", "dapDebugServer.js"),
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
function preferredAdapter(signals, sourceFile) {
|
|
175
|
+
const language = (sourceFile ? languageOf(sourceFile) : undefined) ?? signals.languages[0];
|
|
176
|
+
return language ? LANGUAGE_ADAPTERS[language] ?? language : undefined;
|
|
177
|
+
}
|
|
178
|
+
export async function resolveProjectAdapter(registry, options = {}) {
|
|
179
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
180
|
+
const stat = await fs.stat(cwd).catch(() => undefined);
|
|
181
|
+
if (!stat?.isDirectory())
|
|
182
|
+
throw new Error(`Working directory '${cwd}' does not exist.`);
|
|
183
|
+
const detected = await detectProjectSignals(cwd, options.sourceFile);
|
|
184
|
+
const recommendedAdapter = options.adapter ?? preferredAdapter(detected, options.sourceFile);
|
|
185
|
+
const adapters = [];
|
|
186
|
+
const configs = new Map();
|
|
187
|
+
for (const adapter of registry.listAll()) {
|
|
188
|
+
const { source: _source, ...baseConfig } = adapter;
|
|
189
|
+
let config = baseConfig;
|
|
190
|
+
if (adapter.type === "python" && detected.pythonPath) {
|
|
191
|
+
config = { ...config, runtime: detected.pythonPath };
|
|
192
|
+
}
|
|
193
|
+
if (adapter.type === "node") {
|
|
194
|
+
const configured = await inspectAdapterAvailability(config);
|
|
195
|
+
if (!configured.available) {
|
|
196
|
+
const nodeProgram = await resolveNodeProgram(cwd);
|
|
197
|
+
if (nodeProgram)
|
|
198
|
+
config = { ...config, program: nodeProgram };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
configs.set(adapter.type, config);
|
|
202
|
+
const availability = await inspectAdapterAvailability(config);
|
|
203
|
+
adapters.push({
|
|
204
|
+
type: adapter.type,
|
|
205
|
+
source: adapter.source,
|
|
206
|
+
selected: adapter.type === recommendedAdapter,
|
|
207
|
+
available: availability.available,
|
|
208
|
+
command: availability.command,
|
|
209
|
+
reason: availability.reason,
|
|
210
|
+
installHint: adapter.installHint,
|
|
211
|
+
runtime: config.runtime,
|
|
212
|
+
program: config.program,
|
|
213
|
+
transport: config.transport ?? "stdio",
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const selected = adapters.find((adapter) => adapter.selected);
|
|
217
|
+
const nextSteps = [];
|
|
218
|
+
if (!recommendedAdapter) {
|
|
219
|
+
nextSteps.push("Specify an adapter explicitly; no supported project language was detected.");
|
|
220
|
+
}
|
|
221
|
+
else if (!selected) {
|
|
222
|
+
nextSteps.push(`Configure adapter '${recommendedAdapter}' with configure_adapter.`);
|
|
223
|
+
}
|
|
224
|
+
else if (!selected.available) {
|
|
225
|
+
if (selected.reason)
|
|
226
|
+
nextSteps.push(selected.reason);
|
|
227
|
+
if (selected.installHint)
|
|
228
|
+
nextSteps.push(selected.installHint);
|
|
229
|
+
if (recommendedAdapter === "python" && detected.pythonPath) {
|
|
230
|
+
nextSteps.push(`Install debugpy in the project environment: ${detected.pythonPath} -m pip install debugpy`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (selected?.available) {
|
|
234
|
+
// Rust rides on cppdbg, so look the note up by language before adapter.
|
|
235
|
+
const language = detected.languages.find((name) => (LANGUAGE_ADAPTERS[name] ?? name) === selected.type && adapterUsageNote(name));
|
|
236
|
+
const note = adapterUsageNote(language ?? selected.type);
|
|
237
|
+
if (note)
|
|
238
|
+
nextSteps.push(note);
|
|
239
|
+
}
|
|
240
|
+
if (detected.launchJson) {
|
|
241
|
+
nextSteps.push(`A launch configuration is available at ${detected.launchJson}; pass its adapter-specific fields through launchConfig when needed.`);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
result: {
|
|
245
|
+
cwd,
|
|
246
|
+
ready: selected?.available ?? false,
|
|
247
|
+
recommendedAdapter,
|
|
248
|
+
detected,
|
|
249
|
+
adapters,
|
|
250
|
+
nextSteps,
|
|
251
|
+
},
|
|
252
|
+
config: recommendedAdapter ? configs.get(recommendedAdapter) : undefined,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/** Drop the per-adapter detail an agent rarely needs, keeping a one-line roster. */
|
|
256
|
+
export function conciseDoctorResult(result) {
|
|
257
|
+
const others = result.adapters.filter((adapter) => !adapter.selected);
|
|
258
|
+
return {
|
|
259
|
+
...result,
|
|
260
|
+
adapters: result.adapters.filter((adapter) => adapter.selected),
|
|
261
|
+
otherAdapters: others.map((adapter) => adapter.available ? adapter.type : `${adapter.type} (missing)`),
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
export async function runDebugDoctor(registry, options = {}) {
|
|
265
|
+
const { result } = await resolveProjectAdapter(registry, options);
|
|
266
|
+
return options.verbose ? result : conciseDoctorResult(result);
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/diagnostics/doctor.ts"],"names":[],"mappings":"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"}
|