@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/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
- return { kind: "ipc", path: path2.join(stateDir, "controller.sock") };
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 path16 from "path";
1161
- import { randomBytes as randomBytes5 } from "crypto";
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.end();
1314
- options.socket.destroy();
1315
- return Promise.resolve();
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 fs10 } from "fs";
1469
- import path13 from "path";
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 = createHash("sha256");
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 createHash2 } from "crypto";
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 createHash2("sha256").update(buffer).digest("hex");
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: path13.join(logDir, `js-debug-trace-${Date.now()}.log`)
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 fs10.access(candidate);
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 = path13.join(adaptersDir, "js-debug", "src", "dapDebugServer.js");
2525
- const repoEntrypoint = path13.join(process.cwd(), "node_modules", "vscode-js-debug", "src", "dapDebugServer.js");
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
- this.detachTransportHandlers();
2724
- await this.terminateChildProcesses();
2725
- await this.transport.close();
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.rejectPending(error);
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 randomBytes4 } from "crypto";
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_${randomBytes4(12).toString("base64url")}`;
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 fs11 } from "fs";
3467
+ import { promises as fs12 } from "fs";
3302
3468
  import { randomUUID } from "crypto";
3303
- import path14 from "path";
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 = path14.join(getDapCliStateDir(env), "sessions.json");
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 fs11.readFile(this.storePath, "utf8");
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 fs11.rename(this.storePath, backupPath);
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 fs11.mkdir(path14.dirname(this.storePath), { recursive: true });
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 fs11.writeFile(tempPath, `${JSON.stringify(validated, null, 2)}
3545
+ await fs12.writeFile(tempPath, `${JSON.stringify(validated, null, 2)}
3380
3546
  `, "utf8");
3381
- await fs11.rename(tempPath, this.storePath);
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
- requestPromise.catch(() => void 0);
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 requestPromise;
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 = (path24) => path24.replace(/^file:\/\//, "").replace(/\\/g, "/");
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 fs12 } from "fs";
4893
- import path15 from "path";
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 = path15.dirname(fileURLToPath(import.meta.url));
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 = path15.dirname(pkgPath);
5126
+ pkgDir = path16.dirname(pkgPath);
4911
5127
  try {
4912
- const raw = await fs12.readFile(pkgPath, "utf8");
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 = path15.join(pkgDir, "dist", "index.js");
5136
+ const distPath = path16.join(pkgDir, "dist", "index.js");
4921
5137
  try {
4922
- const stat = await fs12.stat(distPath);
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 = path15.join(dir, "package.json");
5148
+ const candidate = path16.join(dir, "package.json");
4933
5149
  try {
4934
- await fs12.access(candidate);
5150
+ await fs13.access(candidate);
4935
5151
  return candidate;
4936
5152
  } catch {
4937
- const parent = path15.dirname(dir);
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(path16.resolve(source));
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 = path16.resolve(source);
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
- await runtime.lifecycle.disconnect({ terminateDebuggee: opts.terminateDebuggee }).catch(() => void 0);
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_${randomBytes5(12).toString("base64url")}`;
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 path17 from "path";
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: path17.resolve(options.source) },
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 : path17.resolve(options.source)
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 : path17.resolve(options.source)
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 path24 = options.path;
6959
+ const path26 = options.path;
6742
6960
  await sendAliasRequest(output, "source", compactObject({
6743
6961
  sourceReference: parseRequiredIntegerOption(options.sourceReference, "source-reference"),
6744
- source: path24 === void 0 ? void 0 : { path: path24 }
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 = path17.basename(requestedPath);
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(path17.basename(s.path), wantBasename))).map((s) => {
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 path22 from "path";
7263
+ import path24 from "path";
7046
7264
 
7047
7265
  // src/adapters/config.ts
7048
- import { promises as fs13 } from "fs";
7266
+ import { promises as fs14 } from "fs";
7049
7267
  import { randomUUID as randomUUID2 } from "crypto";
7050
- import path18 from "path";
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 fs13.readFile(configPath, "utf8");
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 path18.join(home, "config", "adapters.json");
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 fs14 } from "fs";
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 fs14.access(p);
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 fs15 } from "fs";
7361
+ import { promises as fs16 } from "fs";
7144
7362
  import { spawnSync } from "child_process";
7145
- import path19 from "path";
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 fs15.access(p);
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 path19.join(getDapCliAdaptersDir(env), "delve", process.platform === "win32" ? "dlv.exe" : "dlv");
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 fs16 } from "fs";
7548
+ import { promises as fs17 } from "fs";
7301
7549
  import os from "os";
7302
- import path20 from "path";
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 = path20.resolve(options.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: path20.basename(workspaceFolder),
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 = path20.resolve(cwd);
7363
- const launchJsonPath = path20.join(cwd, ".vscode", "launch.json");
7611
+ const workspaceFolder = path22.resolve(cwd);
7612
+ const launchJsonPath = path22.join(cwd, ".vscode", "launch.json");
7364
7613
  try {
7365
- const stat = await fs16.stat(launchJsonPath);
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 fs16.readFile(launchJsonPath, "utf8");
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(path20.join(options.workspaceFolder, "tsconfig.json"));
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
- path20.join(options.workspaceFolder, "dist", "**", "*.js"),
7488
- path20.join(options.workspaceFolder, "out", "**", "*.js"),
7489
- path20.join(options.workspaceFolder, "build", "**", "*.js")
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" || path20.isAbsolute(config.program)) {
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: path20.resolve(cwd, config.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 fs16.stat(filePath);
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 path21 from "path";
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 = path21.extname(program).toLowerCase();
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 = path21.extname(program).toLowerCase();
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 = path22.resolve(options.workspace ?? process.cwd());
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", path22.join(process.cwd(), "tests", "fixtures", "fake-adapter-entry.ts"), "--script", script, "--mode", mode]
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 path23 from "path";
8036
- import { promises as fs17 } from "fs";
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 path23.join(adaptersDir, "js-debug", "src", "dapDebugServer.js");
8316
+ return path25.join(adaptersDir, "js-debug", "src", "dapDebugServer.js");
8048
8317
  case "debugpy":
8049
- return path23.join(
8318
+ return path25.join(
8050
8319
  adaptersDir,
8051
8320
  "debugpy",
8052
- process.platform === "win32" ? path23.join("venv", "Scripts", "python.exe") : path23.join("venv", "bin", "python")
8321
+ process.platform === "win32" ? path25.join("venv", "Scripts", "python.exe") : path25.join("venv", "bin", "python")
8053
8322
  );
8054
8323
  case "delve":
8055
- return path23.join(adaptersDir, "delve", process.platform === "win32" ? "dlv.exe" : "dlv");
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 fs17.access(p);
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 fs17.mkdir(adaptersDir, { recursive: true });
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 pathExists5(expectedEntrypoint(adaptersDir, id));
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);