@roblourens/dap-cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/index.js +375 -101
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -846,8 +846,10 @@ function breakpointBindingGuidance(options = {}) {
|
|
|
846
846
|
}
|
|
847
847
|
|
|
848
848
|
// src/controller/ipc.ts
|
|
849
|
+
import { createHash } from "crypto";
|
|
849
850
|
import { promises as fs } from "fs";
|
|
850
851
|
import net from "net";
|
|
852
|
+
import { tmpdir } from "os";
|
|
851
853
|
import path2 from "path";
|
|
852
854
|
import { z as z2 } from "zod";
|
|
853
855
|
|
|
@@ -901,6 +903,7 @@ var controllerDiscoverySchema = z2.object({
|
|
|
901
903
|
startedAt: z2.string().min(1),
|
|
902
904
|
lastHeartbeatAt: z2.string().min(1)
|
|
903
905
|
});
|
|
906
|
+
var maximumPortableUnixSocketPathLength = 100;
|
|
904
907
|
function resolveControllerDiscoveryPath(options = {}) {
|
|
905
908
|
return path2.join(resolveStateDir(options), "controller.json");
|
|
906
909
|
}
|
|
@@ -982,7 +985,12 @@ function createControllerEndpoint(stateDir, platform) {
|
|
|
982
985
|
if (platform === "win32") {
|
|
983
986
|
return { kind: "ipc", path: `\\\\.\\pipe\\dap-cli-${Buffer.from(stateDir).toString("hex").slice(0, 24)}` };
|
|
984
987
|
}
|
|
985
|
-
|
|
988
|
+
const endpointPath = path2.join(stateDir, "controller.sock");
|
|
989
|
+
if (Buffer.byteLength(endpointPath, "utf8") <= maximumPortableUnixSocketPathLength) {
|
|
990
|
+
return { kind: "ipc", path: endpointPath };
|
|
991
|
+
}
|
|
992
|
+
const stateHash = createHash("sha256").update(stateDir).digest("hex").slice(0, 24);
|
|
993
|
+
return { kind: "ipc", path: path2.join(tmpdir(), `dap-cli-${stateHash}.sock`) };
|
|
986
994
|
}
|
|
987
995
|
function resolveStateDir(options) {
|
|
988
996
|
return getDapCliStateDir(createEnv(options));
|
|
@@ -1157,8 +1165,8 @@ function isSessionErrorCode(code) {
|
|
|
1157
1165
|
}
|
|
1158
1166
|
|
|
1159
1167
|
// src/controller/server.ts
|
|
1160
|
-
import
|
|
1161
|
-
import { randomBytes as
|
|
1168
|
+
import path17 from "path";
|
|
1169
|
+
import { randomBytes as randomBytes6 } from "crypto";
|
|
1162
1170
|
|
|
1163
1171
|
// src/adapters/descriptor.ts
|
|
1164
1172
|
import { z as z3 } from "zod";
|
|
@@ -1310,9 +1318,16 @@ function createSocketTransport(options) {
|
|
|
1310
1318
|
readable: options.socket,
|
|
1311
1319
|
writable: options.socket,
|
|
1312
1320
|
close() {
|
|
1313
|
-
options.socket.
|
|
1314
|
-
|
|
1315
|
-
|
|
1321
|
+
if (options.socket.closed) {
|
|
1322
|
+
return Promise.resolve();
|
|
1323
|
+
}
|
|
1324
|
+
return new Promise((resolve) => {
|
|
1325
|
+
options.socket.once("close", resolve);
|
|
1326
|
+
if (!options.socket.destroyed) {
|
|
1327
|
+
options.socket.end();
|
|
1328
|
+
options.socket.destroy();
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1316
1331
|
}
|
|
1317
1332
|
};
|
|
1318
1333
|
}
|
|
@@ -1465,8 +1480,8 @@ async function delay(ms) {
|
|
|
1465
1480
|
}
|
|
1466
1481
|
|
|
1467
1482
|
// src/adapters/builtins/jsDebug.ts
|
|
1468
|
-
import { promises as
|
|
1469
|
-
import
|
|
1483
|
+
import { promises as fs11 } from "fs";
|
|
1484
|
+
import path14 from "path";
|
|
1470
1485
|
|
|
1471
1486
|
// src/cli/confirm.ts
|
|
1472
1487
|
import * as readline from "readline/promises";
|
|
@@ -1519,7 +1534,7 @@ function resolveAssumeYes(cliYes, env) {
|
|
|
1519
1534
|
|
|
1520
1535
|
// src/adapters/provision/jsDebug.ts
|
|
1521
1536
|
import path9 from "path";
|
|
1522
|
-
import { createHash, randomBytes as randomBytes2 } from "crypto";
|
|
1537
|
+
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
1523
1538
|
import { promises as fs6, createReadStream as createReadStream2 } from "fs";
|
|
1524
1539
|
|
|
1525
1540
|
// src/adapters/provision/atomicInstall.ts
|
|
@@ -1954,6 +1969,7 @@ async function writeConsentMarker(adaptersDir, adapterId, version) {
|
|
|
1954
1969
|
var JS_DEBUG_VERSION = "1.117.0";
|
|
1955
1970
|
var DEBUGPY_VERSION = "1.8.20";
|
|
1956
1971
|
var DELVE_VERSION = "v1.26.3";
|
|
1972
|
+
var CODELLDB_VERSION = "v1.12.2";
|
|
1957
1973
|
var JS_DEBUG_CHECKSUMS = {
|
|
1958
1974
|
"1.117.0": "ad8d04ede9d4b75cc290fd5438a65047a06f786d04f604b6112485b36f090772"
|
|
1959
1975
|
};
|
|
@@ -1966,6 +1982,11 @@ var DELVE_CHECKSUMS = {
|
|
|
1966
1982
|
windows_amd64: "f9e15b8f3628e4c7bfe481011bea458df754d0e75c6ff4ab01c71294165950fd"
|
|
1967
1983
|
}
|
|
1968
1984
|
};
|
|
1985
|
+
var CODELLDB_CHECKSUMS = {
|
|
1986
|
+
"v1.12.2": {
|
|
1987
|
+
darwin_arm64: "c836b81c6f2da467b5920a376a7bfc849dc4b4d81b19779dedf1c685cb4aa1a0"
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1969
1990
|
|
|
1970
1991
|
// src/adapters/provision/jsDebug.ts
|
|
1971
1992
|
var ADAPTER_ID = "js-debug";
|
|
@@ -1980,7 +2001,7 @@ function downloadUrl(env) {
|
|
|
1980
2001
|
}
|
|
1981
2002
|
async function fileSha256(filePath) {
|
|
1982
2003
|
return await new Promise((resolve, reject) => {
|
|
1983
|
-
const hash =
|
|
2004
|
+
const hash = createHash2("sha256");
|
|
1984
2005
|
const stream = createReadStream2(filePath);
|
|
1985
2006
|
stream.on("error", reject);
|
|
1986
2007
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
@@ -2219,7 +2240,7 @@ async function provisionDebugpy(ctx) {
|
|
|
2219
2240
|
// src/adapters/provision/delve.ts
|
|
2220
2241
|
import path12 from "path";
|
|
2221
2242
|
import { promises as fs9 } from "fs";
|
|
2222
|
-
import { createHash as
|
|
2243
|
+
import { createHash as createHash3 } from "crypto";
|
|
2223
2244
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
2224
2245
|
|
|
2225
2246
|
// src/adapters/provision/extractZip.ts
|
|
@@ -2365,7 +2386,7 @@ async function exists2(p) {
|
|
|
2365
2386
|
}
|
|
2366
2387
|
async function computeSha256(filePath) {
|
|
2367
2388
|
const buffer = await fs9.readFile(filePath);
|
|
2368
|
-
return
|
|
2389
|
+
return createHash3("sha256").update(buffer).digest("hex");
|
|
2369
2390
|
}
|
|
2370
2391
|
async function provisionDelve(ctx) {
|
|
2371
2392
|
const { env, assumeYes, adaptersDir, stdin, stderr } = ctx;
|
|
@@ -2468,6 +2489,139 @@ async function provisionDelve(ctx) {
|
|
|
2468
2489
|
};
|
|
2469
2490
|
}
|
|
2470
2491
|
|
|
2492
|
+
// src/adapters/provision/codelldb.ts
|
|
2493
|
+
import path13 from "path";
|
|
2494
|
+
import { promises as fs10 } from "fs";
|
|
2495
|
+
import { createHash as createHash4, randomBytes as randomBytes4 } from "crypto";
|
|
2496
|
+
var ADAPTER_ID2 = "codelldb";
|
|
2497
|
+
var DEFAULT_RELEASE_BASE_URL2 = "https://github.com";
|
|
2498
|
+
var ENTRYPOINT = "extension/adapter/codelldb";
|
|
2499
|
+
var REQUIRED_RUNTIME_PATHS = [
|
|
2500
|
+
ENTRYPOINT,
|
|
2501
|
+
"extension/adapter/scripts/codelldb/__init__.py",
|
|
2502
|
+
"extension/lldb/bin/lldb",
|
|
2503
|
+
"extension/lldb/bin/lldb-argdumper",
|
|
2504
|
+
"extension/lldb/bin/lldb-server",
|
|
2505
|
+
"extension/lldb/lib/liblldb.dylib",
|
|
2506
|
+
"extension/lldb/lib/libpython312.dylib",
|
|
2507
|
+
"extension/lldb/lib/python3.12/os.py",
|
|
2508
|
+
"extension/lang_support/rust.py",
|
|
2509
|
+
"extension/package.json"
|
|
2510
|
+
];
|
|
2511
|
+
var EXECUTABLE_PATHS = [
|
|
2512
|
+
ENTRYPOINT,
|
|
2513
|
+
"extension/lldb/bin/lldb",
|
|
2514
|
+
"extension/lldb/bin/lldb-argdumper",
|
|
2515
|
+
"extension/lldb/bin/lldb-server"
|
|
2516
|
+
];
|
|
2517
|
+
function resolveCodeLldbAsset(env) {
|
|
2518
|
+
const override = env.DAP_CLI_PROVISION_CODELLDB_PLATFORM_OVERRIDE;
|
|
2519
|
+
const detected = override !== void 0 && override.length > 0 ? override : `${process.platform}_${process.arch}`;
|
|
2520
|
+
if (detected !== "darwin_arm64") {
|
|
2521
|
+
throw usageError(`CodeLLDB provisioning does not support platform '${detected}'.`, {
|
|
2522
|
+
code: "provision_arch_unsupported",
|
|
2523
|
+
diagnostics: [
|
|
2524
|
+
`Detected platform: ${detected}`,
|
|
2525
|
+
"Supported platforms: darwin_arm64.",
|
|
2526
|
+
"Only the official CodeLLDB darwin-arm64 artifact has passed verification."
|
|
2527
|
+
],
|
|
2528
|
+
data: {
|
|
2529
|
+
adapterId: ADAPTER_ID2,
|
|
2530
|
+
detected,
|
|
2531
|
+
supported: ["darwin_arm64"]
|
|
2532
|
+
}
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
return {
|
|
2536
|
+
platformKey: "darwin_arm64",
|
|
2537
|
+
archiveName: "codelldb-darwin-arm64.vsix"
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
async function isCodeLldbRuntimeReady(installRoot) {
|
|
2541
|
+
for (const relativePath of REQUIRED_RUNTIME_PATHS) {
|
|
2542
|
+
try {
|
|
2543
|
+
await fs10.access(path13.join(installRoot, relativePath));
|
|
2544
|
+
} catch {
|
|
2545
|
+
return false;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
return true;
|
|
2549
|
+
}
|
|
2550
|
+
async function computeSha2562(filePath) {
|
|
2551
|
+
const buffer = await fs10.readFile(filePath);
|
|
2552
|
+
return createHash4("sha256").update(buffer).digest("hex");
|
|
2553
|
+
}
|
|
2554
|
+
async function provisionCodeLldb(ctx) {
|
|
2555
|
+
const asset = resolveCodeLldbAsset(ctx.env);
|
|
2556
|
+
const installRoot = path13.join(ctx.adaptersDir, ADAPTER_ID2);
|
|
2557
|
+
const entrypoint = path13.join(installRoot, ENTRYPOINT);
|
|
2558
|
+
const expectedSha = CODELLDB_CHECKSUMS[CODELLDB_VERSION]?.[asset.platformKey];
|
|
2559
|
+
if (expectedSha === void 0) {
|
|
2560
|
+
throw usageError(`No pinned SHA-256 for CodeLLDB ${CODELLDB_VERSION} on ${asset.platformKey}.`, {
|
|
2561
|
+
code: "provision_checksum_mismatch",
|
|
2562
|
+
diagnostics: [
|
|
2563
|
+
`Adapter: ${ADAPTER_ID2} ${CODELLDB_VERSION} (${asset.platformKey})`,
|
|
2564
|
+
"src/adapters/provision/checksums.ts must list a verified checksum for every supported platform.",
|
|
2565
|
+
"Re-run setup or report at https://github.com/roblourens/dap-cli/issues if persistent."
|
|
2566
|
+
],
|
|
2567
|
+
data: { adapterId: ADAPTER_ID2, version: CODELLDB_VERSION, platform: asset.platformKey }
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
if (await hasConsentMarker(ctx.adaptersDir, ADAPTER_ID2, CODELLDB_VERSION) && await isCodeLldbRuntimeReady(installRoot)) {
|
|
2571
|
+
return { adapterId: ADAPTER_ID2, version: CODELLDB_VERSION, installRoot, entrypoint, fromCache: true };
|
|
2572
|
+
}
|
|
2573
|
+
await confirm({
|
|
2574
|
+
assumeYes: ctx.assumeYes,
|
|
2575
|
+
question: `Install CodeLLDB ${CODELLDB_VERSION} into ${installRoot}/ (~44MB download)?`,
|
|
2576
|
+
details: [
|
|
2577
|
+
`Downloads the official release asset ${asset.archiveName} from github.com/vadimcn/codelldb.`,
|
|
2578
|
+
"The full VSIX runtime tree is cached locally after SHA-256 verification."
|
|
2579
|
+
],
|
|
2580
|
+
...ctx.stdin === void 0 ? {} : { stdin: ctx.stdin },
|
|
2581
|
+
...ctx.stderr === void 0 ? {} : { stderr: ctx.stderr }
|
|
2582
|
+
});
|
|
2583
|
+
await withAdapterLock(ctx.adaptersDir, ADAPTER_ID2, async () => {
|
|
2584
|
+
if (await hasConsentMarker(ctx.adaptersDir, ADAPTER_ID2, CODELLDB_VERSION) && await isCodeLldbRuntimeReady(installRoot)) {
|
|
2585
|
+
return;
|
|
2586
|
+
}
|
|
2587
|
+
const releaseBase = ctx.env.DAP_CLI_PROVISION_RELEASE_BASE_URL ?? DEFAULT_RELEASE_BASE_URL2;
|
|
2588
|
+
const url = `${releaseBase}/vadimcn/codelldb/releases/download/${CODELLDB_VERSION}/${asset.archiveName}`;
|
|
2589
|
+
const archivePath = path13.join(ctx.adaptersDir, `.${ADAPTER_ID2}.archive.${process.pid}.${randomBytes4(4).toString("hex")}.vsix`);
|
|
2590
|
+
try {
|
|
2591
|
+
await fs10.mkdir(ctx.adaptersDir, { recursive: true });
|
|
2592
|
+
await downloadToFile({ url, destPath: archivePath, env: ctx.env });
|
|
2593
|
+
const actualSha = await computeSha2562(archivePath);
|
|
2594
|
+
if (actualSha !== expectedSha) {
|
|
2595
|
+
throw usageError("CodeLLDB archive failed SHA-256 verification.", {
|
|
2596
|
+
code: "provision_checksum_mismatch",
|
|
2597
|
+
diagnostics: [
|
|
2598
|
+
`URL: ${url}`,
|
|
2599
|
+
`Expected: ${expectedSha}`,
|
|
2600
|
+
`Actual: ${actualSha}`,
|
|
2601
|
+
"Re-run setup or report at https://github.com/roblourens/dap-cli/issues if persistent."
|
|
2602
|
+
],
|
|
2603
|
+
data: { adapterId: ADAPTER_ID2, version: CODELLDB_VERSION, url, expectedSha, actualSha }
|
|
2604
|
+
});
|
|
2605
|
+
}
|
|
2606
|
+
await atomicInstall({
|
|
2607
|
+
adaptersDir: ctx.adaptersDir,
|
|
2608
|
+
adapterId: ADAPTER_ID2,
|
|
2609
|
+
expectedEntrypoints: REQUIRED_RUNTIME_PATHS,
|
|
2610
|
+
populate: async (stagingDir) => {
|
|
2611
|
+
await extractZip(archivePath, stagingDir);
|
|
2612
|
+
for (const executablePath of EXECUTABLE_PATHS) {
|
|
2613
|
+
await fs10.chmod(path13.join(stagingDir, executablePath), 493);
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
});
|
|
2617
|
+
await writeConsentMarker(ctx.adaptersDir, ADAPTER_ID2, CODELLDB_VERSION);
|
|
2618
|
+
} finally {
|
|
2619
|
+
await fs10.rm(archivePath, { force: true }).catch(() => void 0);
|
|
2620
|
+
}
|
|
2621
|
+
});
|
|
2622
|
+
return { adapterId: ADAPTER_ID2, version: CODELLDB_VERSION, installRoot, entrypoint, fromCache: false };
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2471
2625
|
// src/adapters/provision/index.ts
|
|
2472
2626
|
async function provisionAdapter(id, ctx) {
|
|
2473
2627
|
switch (id) {
|
|
@@ -2477,6 +2631,8 @@ async function provisionAdapter(id, ctx) {
|
|
|
2477
2631
|
return provisionDebugpy(ctx);
|
|
2478
2632
|
case "delve":
|
|
2479
2633
|
return provisionDelve(ctx);
|
|
2634
|
+
case "codelldb":
|
|
2635
|
+
return provisionCodeLldb(ctx);
|
|
2480
2636
|
}
|
|
2481
2637
|
}
|
|
2482
2638
|
|
|
@@ -2506,13 +2662,13 @@ function applyJsDebugTraceDefaults(config, logDir) {
|
|
|
2506
2662
|
...record,
|
|
2507
2663
|
trace: {
|
|
2508
2664
|
stdio: false,
|
|
2509
|
-
logFile:
|
|
2665
|
+
logFile: path14.join(logDir, `js-debug-trace-${Date.now()}.log`)
|
|
2510
2666
|
}
|
|
2511
2667
|
};
|
|
2512
2668
|
}
|
|
2513
2669
|
async function pathExists(candidate) {
|
|
2514
2670
|
try {
|
|
2515
|
-
await
|
|
2671
|
+
await fs11.access(candidate);
|
|
2516
2672
|
return true;
|
|
2517
2673
|
} catch {
|
|
2518
2674
|
return false;
|
|
@@ -2521,8 +2677,8 @@ async function pathExists(candidate) {
|
|
|
2521
2677
|
async function resolveDefaultJsDebugPath() {
|
|
2522
2678
|
const env = process.env;
|
|
2523
2679
|
const adaptersDir = getDapCliAdaptersDir(env);
|
|
2524
|
-
const provisionedEntrypoint =
|
|
2525
|
-
const repoEntrypoint =
|
|
2680
|
+
const provisionedEntrypoint = path14.join(adaptersDir, "js-debug", "src", "dapDebugServer.js");
|
|
2681
|
+
const repoEntrypoint = path14.join(process.cwd(), "node_modules", "vscode-js-debug", "src", "dapDebugServer.js");
|
|
2526
2682
|
if (await pathExists(provisionedEntrypoint)) {
|
|
2527
2683
|
return provisionedEntrypoint;
|
|
2528
2684
|
}
|
|
@@ -2658,6 +2814,9 @@ var DapClient = class {
|
|
|
2658
2814
|
transport.readable.on("close", this.handleClosed);
|
|
2659
2815
|
transport.readable.on("end", this.handleClosed);
|
|
2660
2816
|
transport.readable.on("error", this.handleTransportError);
|
|
2817
|
+
if (!Object.is(transport.writable, transport.readable)) {
|
|
2818
|
+
transport.writable.on("error", this.handleTransportError);
|
|
2819
|
+
}
|
|
2661
2820
|
}
|
|
2662
2821
|
transport;
|
|
2663
2822
|
options;
|
|
@@ -2720,9 +2879,12 @@ var DapClient = class {
|
|
|
2720
2879
|
}
|
|
2721
2880
|
async close() {
|
|
2722
2881
|
this.handleClosed();
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2882
|
+
try {
|
|
2883
|
+
await this.terminateChildProcesses();
|
|
2884
|
+
await this.transport.close();
|
|
2885
|
+
} finally {
|
|
2886
|
+
this.detachTransportHandlers();
|
|
2887
|
+
}
|
|
2726
2888
|
}
|
|
2727
2889
|
handleData = (chunk) => {
|
|
2728
2890
|
try {
|
|
@@ -2742,7 +2904,8 @@ var DapClient = class {
|
|
|
2742
2904
|
this.rejectPending(new DapTransportClosedError());
|
|
2743
2905
|
};
|
|
2744
2906
|
handleTransportError = (error) => {
|
|
2745
|
-
this.
|
|
2907
|
+
this.closed = true;
|
|
2908
|
+
this.rejectPending(error instanceof DapTransportClosedError ? error : new DapTransportClosedError(error.message));
|
|
2746
2909
|
};
|
|
2747
2910
|
handleMessage(message) {
|
|
2748
2911
|
if (message.type === "event") {
|
|
@@ -2847,6 +3010,9 @@ var DapClient = class {
|
|
|
2847
3010
|
this.transport.readable.removeListener("close", this.handleClosed);
|
|
2848
3011
|
this.transport.readable.removeListener("end", this.handleClosed);
|
|
2849
3012
|
this.transport.readable.removeListener("error", this.handleTransportError);
|
|
3013
|
+
if (!Object.is(this.transport.writable, this.transport.readable)) {
|
|
3014
|
+
this.transport.writable.removeListener("error", this.handleTransportError);
|
|
3015
|
+
}
|
|
2850
3016
|
}
|
|
2851
3017
|
handleRunInTerminal(argumentsValue) {
|
|
2852
3018
|
const parsed = runInTerminalArgumentsSchema.safeParse(argumentsValue);
|
|
@@ -3178,14 +3344,14 @@ function getDapGeneratedCommand(command) {
|
|
|
3178
3344
|
}
|
|
3179
3345
|
|
|
3180
3346
|
// src/sessions/session.ts
|
|
3181
|
-
import { randomBytes as
|
|
3347
|
+
import { randomBytes as randomBytes5 } from "crypto";
|
|
3182
3348
|
var REMOVABLE_LIFECYCLES = /* @__PURE__ */ new Set([
|
|
3183
3349
|
"terminated",
|
|
3184
3350
|
"disconnected",
|
|
3185
3351
|
"failed"
|
|
3186
3352
|
]);
|
|
3187
3353
|
function createSessionId() {
|
|
3188
|
-
return `sess_${
|
|
3354
|
+
return `sess_${randomBytes5(12).toString("base64url")}`;
|
|
3189
3355
|
}
|
|
3190
3356
|
function projectSessionSummary(session) {
|
|
3191
3357
|
const summary = {
|
|
@@ -3298,9 +3464,9 @@ function createAmbiguousSessionDiagnostics(targetId, matches) {
|
|
|
3298
3464
|
}
|
|
3299
3465
|
|
|
3300
3466
|
// src/sessions/sessionStore.ts
|
|
3301
|
-
import { promises as
|
|
3467
|
+
import { promises as fs12 } from "fs";
|
|
3302
3468
|
import { randomUUID } from "crypto";
|
|
3303
|
-
import
|
|
3469
|
+
import path15 from "path";
|
|
3304
3470
|
import { z as z5 } from "zod";
|
|
3305
3471
|
var ownedAdapterSchema = z5.object({
|
|
3306
3472
|
pid: z5.number().int().positive().optional(),
|
|
@@ -3342,14 +3508,14 @@ var SessionStore = class {
|
|
|
3342
3508
|
storePath;
|
|
3343
3509
|
constructor(options = {}) {
|
|
3344
3510
|
const env = options.dapCliHome === void 0 ? process.env : { ...process.env, DAP_CLI_HOME: options.dapCliHome };
|
|
3345
|
-
this.storePath =
|
|
3511
|
+
this.storePath = path15.join(getDapCliStateDir(env), "sessions.json");
|
|
3346
3512
|
}
|
|
3347
3513
|
get path() {
|
|
3348
3514
|
return this.storePath;
|
|
3349
3515
|
}
|
|
3350
3516
|
async read() {
|
|
3351
3517
|
try {
|
|
3352
|
-
const raw = await
|
|
3518
|
+
const raw = await fs12.readFile(this.storePath, "utf8");
|
|
3353
3519
|
const parsed = sessionStoreSchema.parse(JSON.parse(raw));
|
|
3354
3520
|
return {
|
|
3355
3521
|
...parsed.activeSessionId !== void 0 ? { activeSessionId: parsed.activeSessionId } : {},
|
|
@@ -3362,7 +3528,7 @@ var SessionStore = class {
|
|
|
3362
3528
|
if (error instanceof SyntaxError || error instanceof z5.ZodError) {
|
|
3363
3529
|
const backupPath = `${this.storePath}.corrupt.${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.bak`;
|
|
3364
3530
|
try {
|
|
3365
|
-
await
|
|
3531
|
+
await fs12.rename(this.storePath, backupPath);
|
|
3366
3532
|
process.stderr.write(`dap-cli: sessions.json was unparseable; moved to ${backupPath} and continuing with empty state.
|
|
3367
3533
|
`);
|
|
3368
3534
|
} catch {
|
|
@@ -3373,12 +3539,12 @@ var SessionStore = class {
|
|
|
3373
3539
|
}
|
|
3374
3540
|
}
|
|
3375
3541
|
async write(data) {
|
|
3376
|
-
await
|
|
3542
|
+
await fs12.mkdir(path15.dirname(this.storePath), { recursive: true });
|
|
3377
3543
|
const validated = sessionStoreSchema.parse(data);
|
|
3378
3544
|
const tempPath = `${this.storePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
3379
|
-
await
|
|
3545
|
+
await fs12.writeFile(tempPath, `${JSON.stringify(validated, null, 2)}
|
|
3380
3546
|
`, "utf8");
|
|
3381
|
-
await
|
|
3547
|
+
await fs12.rename(tempPath, this.storePath);
|
|
3382
3548
|
}
|
|
3383
3549
|
};
|
|
3384
3550
|
function isNodeError2(error) {
|
|
@@ -4111,22 +4277,72 @@ var ChildSessionCoordinator = class {
|
|
|
4111
4277
|
try {
|
|
4112
4278
|
await this.options.sessionManager.updateLifecycle(childId, command === "launch" ? "launching" : "attaching").catch(() => void 0);
|
|
4113
4279
|
const requestPromise = client.request(command, config);
|
|
4114
|
-
|
|
4280
|
+
let launchAttachOutcome = "pending";
|
|
4281
|
+
requestPromise.then(
|
|
4282
|
+
() => {
|
|
4283
|
+
launchAttachOutcome = "fulfilled";
|
|
4284
|
+
},
|
|
4285
|
+
(error) => {
|
|
4286
|
+
launchAttachOutcome = { error };
|
|
4287
|
+
}
|
|
4288
|
+
);
|
|
4115
4289
|
await runtime.initializedPromise;
|
|
4116
4290
|
for (const breakpointArgs of this.pendingSetBreakpoints) {
|
|
4117
4291
|
await client.request("setBreakpoints", breakpointArgs);
|
|
4118
4292
|
}
|
|
4119
4293
|
await client.request("configurationDone");
|
|
4120
|
-
await
|
|
4294
|
+
await Promise.resolve();
|
|
4295
|
+
const getLaunchAttachOutcome = () => launchAttachOutcome;
|
|
4296
|
+
const outcomeAfterConfiguration = getLaunchAttachOutcome();
|
|
4297
|
+
if (typeof outcomeAfterConfiguration === "object") {
|
|
4298
|
+
throw outcomeAfterConfiguration.error;
|
|
4299
|
+
}
|
|
4121
4300
|
await this.options.sessionManager.updateLifecycle(childId, "running").catch(() => void 0);
|
|
4122
4301
|
if (!runtime.readySeen) {
|
|
4123
4302
|
runtime.readySeen = true;
|
|
4124
4303
|
runtime.resolveReady();
|
|
4125
4304
|
}
|
|
4305
|
+
if (outcomeAfterConfiguration === "pending") {
|
|
4306
|
+
this.observeTrailingLaunchAttachResponse(childId, command, requestPromise);
|
|
4307
|
+
}
|
|
4126
4308
|
} catch (error) {
|
|
4127
4309
|
await this.markChildFailed(childId, error);
|
|
4128
4310
|
}
|
|
4129
4311
|
}
|
|
4312
|
+
/**
|
|
4313
|
+
* Observe a launch/attach response that arrives — or times out — AFTER the
|
|
4314
|
+
* child has already been marked `running` off the back of `configurationDone`.
|
|
4315
|
+
*
|
|
4316
|
+
* A trailing rejection no longer fails the child: the session is configured
|
|
4317
|
+
* and usable, and gating readiness on this response wedged js-debug page
|
|
4318
|
+
* sessions (see {@link runChildLifecycle}). Instead it is surfaced as a
|
|
4319
|
+
* non-fatal `output` warning on the parent so the condition stays debuggable
|
|
4320
|
+
* from the agent side. Transport-closed rejections during normal teardown are
|
|
4321
|
+
* ignored — they are not an attach anomaly.
|
|
4322
|
+
*/
|
|
4323
|
+
observeTrailingLaunchAttachResponse(childId, command, requestPromise) {
|
|
4324
|
+
void requestPromise.then(
|
|
4325
|
+
() => void 0,
|
|
4326
|
+
(error) => {
|
|
4327
|
+
if (error instanceof DapTransportClosedError) {
|
|
4328
|
+
return;
|
|
4329
|
+
}
|
|
4330
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4331
|
+
const synthetic = {
|
|
4332
|
+
seq: 0,
|
|
4333
|
+
type: "event",
|
|
4334
|
+
event: "output",
|
|
4335
|
+
body: {
|
|
4336
|
+
category: "stderr",
|
|
4337
|
+
output: `child session ${childId} ${command} response not received: ${message}
|
|
4338
|
+
`,
|
|
4339
|
+
child_session_id: childId
|
|
4340
|
+
}
|
|
4341
|
+
};
|
|
4342
|
+
this.options.parentEventCache.append(this.options.parentSessionId, synthetic);
|
|
4343
|
+
}
|
|
4344
|
+
);
|
|
4345
|
+
}
|
|
4130
4346
|
async markChildFailed(childId, error) {
|
|
4131
4347
|
await this.options.sessionManager.updateLifecycle(childId, "failed").catch(() => void 0);
|
|
4132
4348
|
const runtime = this.children.get(childId);
|
|
@@ -4784,7 +5000,7 @@ function sourceMatches(eventPath, requestPath) {
|
|
|
4784
5000
|
if (eventPath === requestPath) {
|
|
4785
5001
|
return true;
|
|
4786
5002
|
}
|
|
4787
|
-
const normalize = (
|
|
5003
|
+
const normalize = (path26) => path26.replace(/^file:\/\//, "").replace(/\\/g, "/");
|
|
4788
5004
|
return normalize(eventPath) === normalize(requestPath);
|
|
4789
5005
|
}
|
|
4790
5006
|
|
|
@@ -4889,8 +5105,8 @@ function defaultLookupPpid(pid) {
|
|
|
4889
5105
|
}
|
|
4890
5106
|
|
|
4891
5107
|
// src/controller/buildId.ts
|
|
4892
|
-
import { promises as
|
|
4893
|
-
import
|
|
5108
|
+
import { promises as fs13 } from "fs";
|
|
5109
|
+
import path16 from "path";
|
|
4894
5110
|
import { fileURLToPath } from "url";
|
|
4895
5111
|
var cachedBuildId;
|
|
4896
5112
|
async function computeBuildId() {
|
|
@@ -4902,14 +5118,14 @@ async function computeBuildId() {
|
|
|
4902
5118
|
cachedBuildId = envOverride;
|
|
4903
5119
|
return cachedBuildId;
|
|
4904
5120
|
}
|
|
4905
|
-
const here =
|
|
5121
|
+
const here = path16.dirname(fileURLToPath(import.meta.url));
|
|
4906
5122
|
const pkgPath = await findPackageJson(here);
|
|
4907
5123
|
let version = "0.0.0";
|
|
4908
5124
|
let pkgDir = here;
|
|
4909
5125
|
if (pkgPath !== void 0) {
|
|
4910
|
-
pkgDir =
|
|
5126
|
+
pkgDir = path16.dirname(pkgPath);
|
|
4911
5127
|
try {
|
|
4912
|
-
const raw = await
|
|
5128
|
+
const raw = await fs13.readFile(pkgPath, "utf8");
|
|
4913
5129
|
const parsed = JSON.parse(raw);
|
|
4914
5130
|
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
4915
5131
|
version = parsed.version;
|
|
@@ -4917,9 +5133,9 @@ async function computeBuildId() {
|
|
|
4917
5133
|
} catch {
|
|
4918
5134
|
}
|
|
4919
5135
|
}
|
|
4920
|
-
const distPath =
|
|
5136
|
+
const distPath = path16.join(pkgDir, "dist", "index.js");
|
|
4921
5137
|
try {
|
|
4922
|
-
const stat = await
|
|
5138
|
+
const stat = await fs13.stat(distPath);
|
|
4923
5139
|
cachedBuildId = `${version}:dist:${stat.mtimeMs}:${stat.size}`;
|
|
4924
5140
|
} catch {
|
|
4925
5141
|
cachedBuildId = `${version}:src`;
|
|
@@ -4929,12 +5145,12 @@ async function computeBuildId() {
|
|
|
4929
5145
|
async function findPackageJson(startDir) {
|
|
4930
5146
|
let dir = startDir;
|
|
4931
5147
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
4932
|
-
const candidate =
|
|
5148
|
+
const candidate = path16.join(dir, "package.json");
|
|
4933
5149
|
try {
|
|
4934
|
-
await
|
|
5150
|
+
await fs13.access(candidate);
|
|
4935
5151
|
return candidate;
|
|
4936
5152
|
} catch {
|
|
4937
|
-
const parent =
|
|
5153
|
+
const parent = path16.dirname(dir);
|
|
4938
5154
|
if (parent === dir) {
|
|
4939
5155
|
return void 0;
|
|
4940
5156
|
}
|
|
@@ -5687,7 +5903,7 @@ var ControllerServer = class {
|
|
|
5687
5903
|
return { sources: [] };
|
|
5688
5904
|
}
|
|
5689
5905
|
if (source !== void 0) {
|
|
5690
|
-
const entry = map.get(
|
|
5906
|
+
const entry = map.get(path17.resolve(source));
|
|
5691
5907
|
return entry === void 0 ? { sources: [] } : { sources: [{ source: entry.source, breakpoints: entry.response, requested: entry.requested }] };
|
|
5692
5908
|
}
|
|
5693
5909
|
return {
|
|
@@ -5712,7 +5928,7 @@ var ControllerServer = class {
|
|
|
5712
5928
|
};
|
|
5713
5929
|
const cleared = [];
|
|
5714
5930
|
if (source !== void 0) {
|
|
5715
|
-
const key =
|
|
5931
|
+
const key = path17.resolve(source);
|
|
5716
5932
|
const entry = map.get(key);
|
|
5717
5933
|
if (entry === void 0) {
|
|
5718
5934
|
return { cleared: [] };
|
|
@@ -5878,7 +6094,9 @@ var ControllerServer = class {
|
|
|
5878
6094
|
if (runtime.children !== void 0) {
|
|
5879
6095
|
await runtime.children.dispose().catch(() => void 0);
|
|
5880
6096
|
}
|
|
5881
|
-
|
|
6097
|
+
const disconnect = runtime.lifecycle.disconnect({ terminateDebuggee: opts.terminateDebuggee });
|
|
6098
|
+
disconnect.catch(() => void 0);
|
|
6099
|
+
await this.waitForDisconnect(disconnect, controllerDisconnectTimeoutMs);
|
|
5882
6100
|
await runtime.client.close().catch(() => void 0);
|
|
5883
6101
|
await runtime.adapter.close().catch(() => void 0);
|
|
5884
6102
|
this.runtimes.delete(status.id);
|
|
@@ -6075,7 +6293,7 @@ function parseDapStartCompoundMemberParams(value) {
|
|
|
6075
6293
|
return parsed;
|
|
6076
6294
|
}
|
|
6077
6295
|
function createCompoundId() {
|
|
6078
|
-
return `compound_${
|
|
6296
|
+
return `compound_${randomBytes6(12).toString("base64url")}`;
|
|
6079
6297
|
}
|
|
6080
6298
|
function findFailedCompoundMemberName(error, members, startedMemberNames) {
|
|
6081
6299
|
const failed = members.find((member) => !startedMemberNames.includes(member.memberName));
|
|
@@ -6536,7 +6754,7 @@ async function delay2(ms) {
|
|
|
6536
6754
|
}
|
|
6537
6755
|
|
|
6538
6756
|
// src/cli/commands/dapAliases.ts
|
|
6539
|
-
import
|
|
6757
|
+
import path18 from "path";
|
|
6540
6758
|
|
|
6541
6759
|
// src/cli/commands/jsonOptions.ts
|
|
6542
6760
|
function parseJsonOption(value) {
|
|
@@ -6664,7 +6882,7 @@ function registerDapAliasCommands(program, output) {
|
|
|
6664
6882
|
breakpoints.command("set").requiredOption("--source <path>", "source path").requiredOption("--line <number...>", "breakpoint line").option("--name <name>", "session name or id").option("--condition <expr>", "breakpoint condition").option("--hit-condition <expr>", "breakpoint hit condition").option("--log-message <text>", "breakpoint log message").description("Set breakpoints at source file line numbers").action(async (options) => {
|
|
6665
6883
|
const lines = parseIntegerValues(options.line, "line");
|
|
6666
6884
|
const args = {
|
|
6667
|
-
source: { path:
|
|
6885
|
+
source: { path: path18.resolve(options.source) },
|
|
6668
6886
|
breakpoints: lines.map((line) => compactObject({
|
|
6669
6887
|
line,
|
|
6670
6888
|
condition: options.condition,
|
|
@@ -6697,7 +6915,7 @@ function registerDapAliasCommands(program, output) {
|
|
|
6697
6915
|
breakpoints.command("list").option("--source <path>", "filter to a single source path").option("--name <name>", "session name or id").description("List breakpoints currently tracked for a session (per source, with verified state)").action(async (options) => {
|
|
6698
6916
|
const params = compactObject({
|
|
6699
6917
|
name: options.name,
|
|
6700
|
-
source: options.source === void 0 ? void 0 :
|
|
6918
|
+
source: options.source === void 0 ? void 0 : path18.resolve(options.source)
|
|
6701
6919
|
});
|
|
6702
6920
|
const client = await createControllerClient({ dapCliHome: process.env.DAP_CLI_HOME });
|
|
6703
6921
|
try {
|
|
@@ -6710,7 +6928,7 @@ function registerDapAliasCommands(program, output) {
|
|
|
6710
6928
|
breakpoints.command("clear").option("--source <path>", "clear only the named source (otherwise: clear all tracked sources)").option("--name <name>", "session name or id").description("Clear breakpoints in a source (DAP setBreakpoints empty-list semantics)").action(async (options) => {
|
|
6711
6929
|
const params = compactObject({
|
|
6712
6930
|
name: options.name,
|
|
6713
|
-
source: options.source === void 0 ? void 0 :
|
|
6931
|
+
source: options.source === void 0 ? void 0 : path18.resolve(options.source)
|
|
6714
6932
|
});
|
|
6715
6933
|
const client = await createControllerClient({ dapCliHome: process.env.DAP_CLI_HOME });
|
|
6716
6934
|
try {
|
|
@@ -6738,10 +6956,10 @@ function registerDapAliasCommands(program, output) {
|
|
|
6738
6956
|
await sendAliasRequest(output, "variables", { variablesReference: parseRequiredIntegerOption(options.variablesReference, "variables-reference") }, options.name, "variables");
|
|
6739
6957
|
});
|
|
6740
6958
|
program.command("source").helpGroup("Paused-state inspection").requiredOption("--source-reference <number>", "source reference").option("--path <path>", "source path").option("--name <name>", "session name or id").description("Return source content").action(async (options) => {
|
|
6741
|
-
const
|
|
6959
|
+
const path26 = options.path;
|
|
6742
6960
|
await sendAliasRequest(output, "source", compactObject({
|
|
6743
6961
|
sourceReference: parseRequiredIntegerOption(options.sourceReference, "source-reference"),
|
|
6744
|
-
source:
|
|
6962
|
+
source: path26 === void 0 ? void 0 : { path: path26 }
|
|
6745
6963
|
}), options.name, "source");
|
|
6746
6964
|
});
|
|
6747
6965
|
program.command("evaluate").helpGroup("Paused-state inspection").requiredOption("--expression <expr>", "expression").option("--frame-id <number>", "frame id (auto-resolved to topmost paused frame when omitted)").option("--context <context>", "evaluation context").option("--name <name>", "session name or id").description("Evaluate an expression (auto-uses topmost frame of most-recently-stopped thread when paused)").action(async (options) => {
|
|
@@ -6998,9 +7216,9 @@ async function buildVerificationDiagnostic(client, requestedPath, breakpointsRes
|
|
|
6998
7216
|
}
|
|
6999
7217
|
const sources = loaded.sources ?? [];
|
|
7000
7218
|
const loadedSourcesCount = sources.length;
|
|
7001
|
-
const wantBasename =
|
|
7219
|
+
const wantBasename = path18.basename(requestedPath);
|
|
7002
7220
|
const cmp = process.platform === "win32" ? (a, b) => a.toLowerCase() === b.toLowerCase() : (a, b) => a === b;
|
|
7003
|
-
const matchingLoadedSources = sources.filter((s) => typeof s.path === "string" && (cmp(s.path, requestedPath) || cmp(
|
|
7221
|
+
const matchingLoadedSources = sources.filter((s) => typeof s.path === "string" && (cmp(s.path, requestedPath) || cmp(path18.basename(s.path), wantBasename))).map((s) => {
|
|
7004
7222
|
const sourcePath = s.path;
|
|
7005
7223
|
return typeof s.name === "string" ? { path: sourcePath, name: s.name } : { path: sourcePath };
|
|
7006
7224
|
});
|
|
@@ -7042,12 +7260,12 @@ async function countChildSessions(client, parentName) {
|
|
|
7042
7260
|
}
|
|
7043
7261
|
|
|
7044
7262
|
// src/cli/commands/dapCore.ts
|
|
7045
|
-
import
|
|
7263
|
+
import path24 from "path";
|
|
7046
7264
|
|
|
7047
7265
|
// src/adapters/config.ts
|
|
7048
|
-
import { promises as
|
|
7266
|
+
import { promises as fs14 } from "fs";
|
|
7049
7267
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7050
|
-
import
|
|
7268
|
+
import path19 from "path";
|
|
7051
7269
|
import { z as z6 } from "zod";
|
|
7052
7270
|
var configuredAdapterDescriptorSchema = adapterDescriptorSchema.and(z6.object({
|
|
7053
7271
|
launchDefaults: z6.record(z6.string(), z6.unknown()).optional(),
|
|
@@ -7060,7 +7278,7 @@ var adapterConfigSchema = z6.object({
|
|
|
7060
7278
|
async function loadAdapterConfig(dapCliHome) {
|
|
7061
7279
|
const configPath = getAdapterConfigPath(dapCliHome);
|
|
7062
7280
|
try {
|
|
7063
|
-
const raw = await
|
|
7281
|
+
const raw = await fs14.readFile(configPath, "utf8");
|
|
7064
7282
|
return parseAdapterConfig(raw);
|
|
7065
7283
|
} catch (error) {
|
|
7066
7284
|
if (isNodeError4(error) && error.code === "ENOENT") {
|
|
@@ -7074,7 +7292,7 @@ async function loadAdapterConfig(dapCliHome) {
|
|
|
7074
7292
|
}
|
|
7075
7293
|
function getAdapterConfigPath(dapCliHome) {
|
|
7076
7294
|
const home = dapCliHome === void 0 ? getDapCliHome() : getDapCliHome({ ...process.env, DAP_CLI_HOME: dapCliHome });
|
|
7077
|
-
return
|
|
7295
|
+
return path19.join(home, "config", "adapters.json");
|
|
7078
7296
|
}
|
|
7079
7297
|
function parseAdapterConfig(raw) {
|
|
7080
7298
|
return adapterConfigSchema.parse(JSON.parse(raw));
|
|
@@ -7090,7 +7308,7 @@ function isNodeError4(error) {
|
|
|
7090
7308
|
}
|
|
7091
7309
|
|
|
7092
7310
|
// src/adapters/builtins/debugpy.ts
|
|
7093
|
-
import { promises as
|
|
7311
|
+
import { promises as fs15 } from "fs";
|
|
7094
7312
|
import { execFile as execFile3 } from "child_process";
|
|
7095
7313
|
import { promisify as promisify2 } from "util";
|
|
7096
7314
|
var execFileAsync2 = promisify2(execFile3);
|
|
@@ -7108,7 +7326,7 @@ async function createDebugpyDescriptor(pythonPath) {
|
|
|
7108
7326
|
}
|
|
7109
7327
|
async function pathExists2(p) {
|
|
7110
7328
|
try {
|
|
7111
|
-
await
|
|
7329
|
+
await fs15.access(p);
|
|
7112
7330
|
return true;
|
|
7113
7331
|
} catch {
|
|
7114
7332
|
return false;
|
|
@@ -7140,9 +7358,9 @@ async function resolveDefaultDebugpyPythonPath(env = process.env) {
|
|
|
7140
7358
|
}
|
|
7141
7359
|
|
|
7142
7360
|
// src/adapters/builtins/delve.ts
|
|
7143
|
-
import { promises as
|
|
7361
|
+
import { promises as fs16 } from "fs";
|
|
7144
7362
|
import { spawnSync } from "child_process";
|
|
7145
|
-
import
|
|
7363
|
+
import path20 from "path";
|
|
7146
7364
|
async function createDelveDescriptor(delvePath) {
|
|
7147
7365
|
const resolvedDelvePath = delvePath ?? await resolveDefaultDelvePath();
|
|
7148
7366
|
assertSupportedProvisionedDelveToolchain(resolvedDelvePath);
|
|
@@ -7165,7 +7383,7 @@ function createGoToolchainEnvironment() {
|
|
|
7165
7383
|
}
|
|
7166
7384
|
async function pathExists3(p) {
|
|
7167
7385
|
try {
|
|
7168
|
-
await
|
|
7386
|
+
await fs16.access(p);
|
|
7169
7387
|
return true;
|
|
7170
7388
|
} catch {
|
|
7171
7389
|
return false;
|
|
@@ -7188,7 +7406,7 @@ async function resolveDefaultDelvePath(env = process.env) {
|
|
|
7188
7406
|
return result.entrypoint;
|
|
7189
7407
|
}
|
|
7190
7408
|
function getProvisionedDelvePath(env = process.env) {
|
|
7191
|
-
return
|
|
7409
|
+
return path20.join(getDapCliAdaptersDir(env), "delve", process.platform === "win32" ? "dlv.exe" : "dlv");
|
|
7192
7410
|
}
|
|
7193
7411
|
function delveIsUsable(command) {
|
|
7194
7412
|
const result = spawnSync(command, ["version"], { encoding: "utf8" });
|
|
@@ -7235,6 +7453,31 @@ function compareNumericVersions(left, right) {
|
|
|
7235
7453
|
return 0;
|
|
7236
7454
|
}
|
|
7237
7455
|
|
|
7456
|
+
// src/adapters/builtins/codelldb.ts
|
|
7457
|
+
import path21 from "path";
|
|
7458
|
+
async function createCodeLldbDescriptor(codelldbPath) {
|
|
7459
|
+
const entrypoint = codelldbPath ?? await resolveDefaultCodeLldbPath();
|
|
7460
|
+
const libLldbPath = path21.join(path21.dirname(entrypoint), "..", "lldb", "lib", "liblldb.dylib");
|
|
7461
|
+
return {
|
|
7462
|
+
id: "codelldb",
|
|
7463
|
+
label: "Rust Debug Adapter (CodeLLDB)",
|
|
7464
|
+
transport: {
|
|
7465
|
+
kind: "server",
|
|
7466
|
+
command: entrypoint,
|
|
7467
|
+
args: ["--liblldb", libLldbPath, "--port", "${port}"],
|
|
7468
|
+
host: "127.0.0.1"
|
|
7469
|
+
}
|
|
7470
|
+
};
|
|
7471
|
+
}
|
|
7472
|
+
async function resolveDefaultCodeLldbPath(env = process.env) {
|
|
7473
|
+
const result = await provisionAdapter("codelldb", {
|
|
7474
|
+
env,
|
|
7475
|
+
assumeYes: resolveAssumeYes(void 0, env),
|
|
7476
|
+
adaptersDir: getDapCliAdaptersDir(env)
|
|
7477
|
+
});
|
|
7478
|
+
return result.entrypoint;
|
|
7479
|
+
}
|
|
7480
|
+
|
|
7238
7481
|
// src/adapters/registry.ts
|
|
7239
7482
|
var AdapterRegistry = class {
|
|
7240
7483
|
builtInAdapters = /* @__PURE__ */ new Map();
|
|
@@ -7256,6 +7499,11 @@ var AdapterRegistry = class {
|
|
|
7256
7499
|
label: "Go Debug Adapter (Delve)",
|
|
7257
7500
|
create: () => createDelveDescriptor()
|
|
7258
7501
|
});
|
|
7502
|
+
this.builtInAdapters.set("codelldb", {
|
|
7503
|
+
id: "codelldb",
|
|
7504
|
+
label: "Rust Debug Adapter (CodeLLDB)",
|
|
7505
|
+
create: () => createCodeLldbDescriptor()
|
|
7506
|
+
});
|
|
7259
7507
|
}
|
|
7260
7508
|
for (const descriptor of options.builtInAdapters ?? []) {
|
|
7261
7509
|
this.builtInAdapters.set(descriptor.id, {
|
|
@@ -7297,9 +7545,9 @@ var AdapterRegistry = class {
|
|
|
7297
7545
|
};
|
|
7298
7546
|
|
|
7299
7547
|
// src/config/launchConfig.ts
|
|
7300
|
-
import { promises as
|
|
7548
|
+
import { promises as fs17 } from "fs";
|
|
7301
7549
|
import os from "os";
|
|
7302
|
-
import
|
|
7550
|
+
import path22 from "path";
|
|
7303
7551
|
import { parse } from "jsonc-parser";
|
|
7304
7552
|
import { z as z7 } from "zod";
|
|
7305
7553
|
var launchConfigTypeMap = {
|
|
@@ -7309,7 +7557,8 @@ var launchConfigTypeMap = {
|
|
|
7309
7557
|
"pwa-chrome": "js-debug",
|
|
7310
7558
|
python: "debugpy",
|
|
7311
7559
|
debugpy: "debugpy",
|
|
7312
|
-
go: "delve"
|
|
7560
|
+
go: "delve",
|
|
7561
|
+
lldb: "codelldb"
|
|
7313
7562
|
};
|
|
7314
7563
|
var maxLaunchJsonBytes = 256 * 1024;
|
|
7315
7564
|
var platformKeys = /* @__PURE__ */ new Set(["osx", "mac", "linux", "windows"]);
|
|
@@ -7336,12 +7585,12 @@ function resolveLaunchConfig(sources) {
|
|
|
7336
7585
|
};
|
|
7337
7586
|
}
|
|
7338
7587
|
function resolveLaunchConfigurationConfig(config, options) {
|
|
7339
|
-
const workspaceFolder =
|
|
7588
|
+
const workspaceFolder = path22.resolve(options.workspaceFolder);
|
|
7340
7589
|
const platform = options.platform ?? process.platform;
|
|
7341
7590
|
const merged = applyPlatformOverlay(config, platform);
|
|
7342
7591
|
const context = {
|
|
7343
7592
|
workspaceFolder,
|
|
7344
|
-
workspaceFolderBasename:
|
|
7593
|
+
workspaceFolderBasename: path22.basename(workspaceFolder),
|
|
7345
7594
|
userHome: options.userHome ?? os.homedir(),
|
|
7346
7595
|
execPath: options.execPath ?? process.execPath,
|
|
7347
7596
|
env: options.env ?? process.env
|
|
@@ -7359,17 +7608,17 @@ function resolveLaunchConfigurationConfig(config, options) {
|
|
|
7359
7608
|
return normalizeGoLaunchConfigProgram(resolved, workspaceFolder);
|
|
7360
7609
|
}
|
|
7361
7610
|
async function loadVSCodeLaunchJson(cwd) {
|
|
7362
|
-
const workspaceFolder =
|
|
7363
|
-
const launchJsonPath =
|
|
7611
|
+
const workspaceFolder = path22.resolve(cwd);
|
|
7612
|
+
const launchJsonPath = path22.join(cwd, ".vscode", "launch.json");
|
|
7364
7613
|
try {
|
|
7365
|
-
const stat = await
|
|
7614
|
+
const stat = await fs17.stat(launchJsonPath);
|
|
7366
7615
|
if (stat.size > maxLaunchJsonBytes) {
|
|
7367
7616
|
throw usageError("Invalid launch.json.", {
|
|
7368
7617
|
code: "invalid_launch_json",
|
|
7369
7618
|
diagnostics: [".vscode/launch.json is larger than 256KB."]
|
|
7370
7619
|
});
|
|
7371
7620
|
}
|
|
7372
|
-
const raw = await
|
|
7621
|
+
const raw = await fs17.readFile(launchJsonPath, "utf8");
|
|
7373
7622
|
const normalized = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
|
|
7374
7623
|
const parsed = launchJsonSchema.parse(parseJsonc(normalized));
|
|
7375
7624
|
return {
|
|
@@ -7474,7 +7723,7 @@ async function applyJsDebugSourceMapDefaults(config, options) {
|
|
|
7474
7723
|
if (!isJsDebugLaunchType(config.type)) {
|
|
7475
7724
|
return config;
|
|
7476
7725
|
}
|
|
7477
|
-
const hasTsConfig = await pathExists4(
|
|
7726
|
+
const hasTsConfig = await pathExists4(path22.join(options.workspaceFolder, "tsconfig.json"));
|
|
7478
7727
|
if (!hasTsConfig) {
|
|
7479
7728
|
return config;
|
|
7480
7729
|
}
|
|
@@ -7484,9 +7733,9 @@ async function applyJsDebugSourceMapDefaults(config, options) {
|
|
|
7484
7733
|
}
|
|
7485
7734
|
if (mapped.outFiles === void 0) {
|
|
7486
7735
|
mapped.outFiles = [
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7736
|
+
path22.join(options.workspaceFolder, "dist", "**", "*.js"),
|
|
7737
|
+
path22.join(options.workspaceFolder, "out", "**", "*.js"),
|
|
7738
|
+
path22.join(options.workspaceFolder, "build", "**", "*.js")
|
|
7490
7739
|
];
|
|
7491
7740
|
}
|
|
7492
7741
|
return mapped;
|
|
@@ -7499,14 +7748,27 @@ function mapDebugpyFlags(flags) {
|
|
|
7499
7748
|
}
|
|
7500
7749
|
return mapped;
|
|
7501
7750
|
}
|
|
7751
|
+
function validateCodeLldbNativeConfig(config) {
|
|
7752
|
+
if (Object.prototype.hasOwnProperty.call(config, "cargo")) {
|
|
7753
|
+
throw usageError("CodeLLDB Cargo launch configurations are not supported by dap-cli.", {
|
|
7754
|
+
code: "codelldb_cargo_config_unsupported",
|
|
7755
|
+
diagnostics: [
|
|
7756
|
+
"The `cargo` property is resolved by the VS Code CodeLLDB extension and cannot be forwarded to the standalone adapter.",
|
|
7757
|
+
"Build an explicitly built Rust binary and pass its executable path with `program`."
|
|
7758
|
+
],
|
|
7759
|
+
data: { adapterId: "codelldb", unsupportedField: "cargo", requiredField: "program" }
|
|
7760
|
+
});
|
|
7761
|
+
}
|
|
7762
|
+
return config;
|
|
7763
|
+
}
|
|
7502
7764
|
function normalizeGoLaunchConfigProgram(config, workspaceFolder) {
|
|
7503
|
-
if (config.type !== "go" || config.request === "attach" || typeof config.program !== "string" ||
|
|
7765
|
+
if (config.type !== "go" || config.request === "attach" || typeof config.program !== "string" || path22.isAbsolute(config.program)) {
|
|
7504
7766
|
return config;
|
|
7505
7767
|
}
|
|
7506
7768
|
const cwd = typeof config.cwd === "string" ? config.cwd : workspaceFolder;
|
|
7507
7769
|
return {
|
|
7508
7770
|
...config,
|
|
7509
|
-
program:
|
|
7771
|
+
program: path22.resolve(cwd, config.program)
|
|
7510
7772
|
};
|
|
7511
7773
|
}
|
|
7512
7774
|
function applyPlatformOverlay(config, platform) {
|
|
@@ -7593,7 +7855,7 @@ function resolveLaunchString(value, jsonPath, context) {
|
|
|
7593
7855
|
}
|
|
7594
7856
|
async function pathExists4(filePath) {
|
|
7595
7857
|
try {
|
|
7596
|
-
await
|
|
7858
|
+
await fs17.stat(filePath);
|
|
7597
7859
|
return true;
|
|
7598
7860
|
} catch (error) {
|
|
7599
7861
|
if (isNodeError5(error) && error.code === "ENOENT") {
|
|
@@ -7635,7 +7897,7 @@ function isNodeError5(error) {
|
|
|
7635
7897
|
}
|
|
7636
7898
|
|
|
7637
7899
|
// src/config/programInference.ts
|
|
7638
|
-
import
|
|
7900
|
+
import path23 from "path";
|
|
7639
7901
|
var extensionTable = {
|
|
7640
7902
|
".py": { adapterId: "debugpy", type: "python" },
|
|
7641
7903
|
".go": { adapterId: "delve", type: "go" },
|
|
@@ -7666,7 +7928,7 @@ function inferAdapterAndType(args) {
|
|
|
7666
7928
|
return { adapterId, type, inferred: { adapter: true, type: false } };
|
|
7667
7929
|
}
|
|
7668
7930
|
if (program !== void 0) {
|
|
7669
|
-
const extension =
|
|
7931
|
+
const extension = path23.extname(program).toLowerCase();
|
|
7670
7932
|
const match = extensionTable[extension];
|
|
7671
7933
|
if (match === void 0) {
|
|
7672
7934
|
throw usageError(`Cannot infer adapter from program extension '${extension}'. Pass --adapter or --type explicitly.`, {
|
|
@@ -7682,7 +7944,7 @@ function inferAdapterAndType(args) {
|
|
|
7682
7944
|
function defaultTypeForAdapter(adapterId, program) {
|
|
7683
7945
|
if (adapterId === "js-debug") {
|
|
7684
7946
|
if (program !== void 0) {
|
|
7685
|
-
const ext =
|
|
7947
|
+
const ext = path23.extname(program).toLowerCase();
|
|
7686
7948
|
if (ext === ".html" || ext === ".htm") {
|
|
7687
7949
|
return "pwa-chrome";
|
|
7688
7950
|
}
|
|
@@ -7695,6 +7957,9 @@ function defaultTypeForAdapter(adapterId, program) {
|
|
|
7695
7957
|
if (adapterId === "delve") {
|
|
7696
7958
|
return "go";
|
|
7697
7959
|
}
|
|
7960
|
+
if (adapterId === "codelldb") {
|
|
7961
|
+
return "lldb";
|
|
7962
|
+
}
|
|
7698
7963
|
return void 0;
|
|
7699
7964
|
}
|
|
7700
7965
|
|
|
@@ -7736,7 +8001,7 @@ function createNameParams(name) {
|
|
|
7736
8001
|
return name === void 0 ? {} : { name };
|
|
7737
8002
|
}
|
|
7738
8003
|
async function startDap(output, mode, options) {
|
|
7739
|
-
const workspace =
|
|
8004
|
+
const workspace = path24.resolve(options.workspace ?? process.cwd());
|
|
7740
8005
|
if (options.listConfigs === true) {
|
|
7741
8006
|
output.success(listLaunchConfigEntries(await loadVSCodeLaunchJson(workspace)), { command: "launch configs" });
|
|
7742
8007
|
return;
|
|
@@ -7892,6 +8157,9 @@ async function mapConfigForAdapter(adapterId, config, workspaceFolder) {
|
|
|
7892
8157
|
if (adapterId === "delve") {
|
|
7893
8158
|
return normalizeGoLaunchConfigProgram(config, workspaceFolder);
|
|
7894
8159
|
}
|
|
8160
|
+
if (adapterId === "codelldb") {
|
|
8161
|
+
return validateCodeLldbNativeConfig(config);
|
|
8162
|
+
}
|
|
7895
8163
|
return config;
|
|
7896
8164
|
}
|
|
7897
8165
|
function setIfDefined(target, key, value) {
|
|
@@ -7915,7 +8183,7 @@ function createFakeDescriptor(script, mode) {
|
|
|
7915
8183
|
transport: {
|
|
7916
8184
|
kind: "stdio",
|
|
7917
8185
|
command: process.execPath,
|
|
7918
|
-
args: ["--experimental-strip-types",
|
|
8186
|
+
args: ["--experimental-strip-types", path24.join(process.cwd(), "tests", "fixtures", "fake-adapter-entry.ts"), "--script", script, "--mode", mode]
|
|
7919
8187
|
}
|
|
7920
8188
|
};
|
|
7921
8189
|
}
|
|
@@ -8032,48 +8300,54 @@ function createNameParams2(name) {
|
|
|
8032
8300
|
}
|
|
8033
8301
|
|
|
8034
8302
|
// src/cli/commands/setupAdapters.ts
|
|
8035
|
-
import
|
|
8036
|
-
import { promises as
|
|
8303
|
+
import path25 from "path";
|
|
8304
|
+
import { promises as fs18 } from "fs";
|
|
8037
8305
|
import { Option } from "commander";
|
|
8038
|
-
var ALL_ADAPTERS = ["js-debug", "debugpy", "delve"];
|
|
8306
|
+
var ALL_ADAPTERS = ["js-debug", "debugpy", "delve", "codelldb"];
|
|
8039
8307
|
var ADAPTER_VERSIONS = {
|
|
8040
8308
|
"js-debug": JS_DEBUG_VERSION,
|
|
8041
8309
|
"debugpy": DEBUGPY_VERSION,
|
|
8042
|
-
"delve": DELVE_VERSION
|
|
8310
|
+
"delve": DELVE_VERSION,
|
|
8311
|
+
"codelldb": CODELLDB_VERSION
|
|
8043
8312
|
};
|
|
8044
8313
|
function expectedEntrypoint(adaptersDir, id) {
|
|
8045
8314
|
switch (id) {
|
|
8046
8315
|
case "js-debug":
|
|
8047
|
-
return
|
|
8316
|
+
return path25.join(adaptersDir, "js-debug", "src", "dapDebugServer.js");
|
|
8048
8317
|
case "debugpy":
|
|
8049
|
-
return
|
|
8318
|
+
return path25.join(
|
|
8050
8319
|
adaptersDir,
|
|
8051
8320
|
"debugpy",
|
|
8052
|
-
process.platform === "win32" ?
|
|
8321
|
+
process.platform === "win32" ? path25.join("venv", "Scripts", "python.exe") : path25.join("venv", "bin", "python")
|
|
8053
8322
|
);
|
|
8054
8323
|
case "delve":
|
|
8055
|
-
return
|
|
8324
|
+
return path25.join(adaptersDir, "delve", process.platform === "win32" ? "dlv.exe" : "dlv");
|
|
8325
|
+
case "codelldb":
|
|
8326
|
+
return path25.join(adaptersDir, "codelldb", "extension", "adapter", "codelldb");
|
|
8056
8327
|
}
|
|
8057
8328
|
}
|
|
8058
8329
|
async function pathExists5(p) {
|
|
8059
8330
|
try {
|
|
8060
|
-
await
|
|
8331
|
+
await fs18.access(p);
|
|
8061
8332
|
return true;
|
|
8062
8333
|
} catch {
|
|
8063
8334
|
return false;
|
|
8064
8335
|
}
|
|
8065
8336
|
}
|
|
8066
8337
|
function isAdapterId(value) {
|
|
8067
|
-
return value === "js-debug" || value === "debugpy" || value === "delve";
|
|
8338
|
+
return value === "js-debug" || value === "debugpy" || value === "delve" || value === "codelldb";
|
|
8339
|
+
}
|
|
8340
|
+
async function isRuntimeReady(adaptersDir, id) {
|
|
8341
|
+
return id === "codelldb" ? isCodeLldbRuntimeReady(path25.join(adaptersDir, id)) : pathExists5(expectedEntrypoint(adaptersDir, id));
|
|
8068
8342
|
}
|
|
8069
8343
|
async function runSetupAdaptersAction(opts) {
|
|
8070
8344
|
const targets = opts.adapter !== void 0 ? [opts.adapter] : ALL_ADAPTERS;
|
|
8071
8345
|
const adaptersDir = getDapCliAdaptersDir(opts.env);
|
|
8072
|
-
await
|
|
8346
|
+
await fs18.mkdir(adaptersDir, { recursive: true });
|
|
8073
8347
|
const pending = [];
|
|
8074
8348
|
for (const id of targets) {
|
|
8075
8349
|
const version = ADAPTER_VERSIONS[id];
|
|
8076
|
-
const cached = await hasConsentMarker(adaptersDir, id, version) && await
|
|
8350
|
+
const cached = await hasConsentMarker(adaptersDir, id, version) && await isRuntimeReady(adaptersDir, id);
|
|
8077
8351
|
if (!cached) {
|
|
8078
8352
|
pending.push(id);
|
|
8079
8353
|
}
|
|
@@ -8131,8 +8405,8 @@ async function runSetupAdaptersAction(opts) {
|
|
|
8131
8405
|
return { adapters: entries };
|
|
8132
8406
|
}
|
|
8133
8407
|
function registerSetupAdaptersCommand(program, output) {
|
|
8134
|
-
program.command("setup-adapters").helpGroup("Adapters").description("Install or update built-in debug adapters (js-debug, debugpy, delve) into ~/.dap-cli/adapters/").addOption(
|
|
8135
|
-
new Option("--adapter <id>", "install only the named adapter").choices(["js-debug", "debugpy", "delve"])
|
|
8408
|
+
program.command("setup-adapters").helpGroup("Adapters").description("Install or update built-in debug adapters (js-debug, debugpy, delve, codelldb) into ~/.dap-cli/adapters/").addOption(
|
|
8409
|
+
new Option("--adapter <id>", "install only the named adapter").choices(["js-debug", "debugpy", "delve", "codelldb"])
|
|
8136
8410
|
).action(async (cmdOpts) => {
|
|
8137
8411
|
const adapterId = cmdOpts.adapter !== void 0 && isAdapterId(cmdOpts.adapter) ? cmdOpts.adapter : void 0;
|
|
8138
8412
|
const assumeYes = resolveAssumeYes(void 0, process.env);
|