debug-that 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.
Files changed (3) hide show
  1. package/README.md +5 -1
  2. package/dist/main.js +997 -221
  3. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -13,6 +13,9 @@ var __export = (target, all) => {
13
13
  };
14
14
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
15
15
 
16
+ // src/constants.ts
17
+ var REQUEST_TIMEOUT_MS = 30000, INSPECTOR_TIMEOUT_MS = 5000, SPAWN_TIMEOUT_MS = 5000, SPAWN_POLL_INTERVAL_MS = 50, BRK_PAUSE_TIMEOUT_MS = 2000, MAX_INTERNAL_PAUSE_SKIPS = 5, STATE_WAIT_TIMEOUT_MS = 5000, PAUSE_WAITER_TIMEOUT_MS = 30000, MAX_BUFFERED_MESSAGES = 1000, BUFFER_TRIM_BATCH = 100, MAX_SOURCE_LINE_WIDTH = 120, INITIALIZED_TIMEOUT_MS = 1e4, MAX_REQUEST_SIZE = 1048576;
18
+
16
19
  // src/refs/ref-table.ts
17
20
  class RefTable {
18
21
  entries = new Map;
@@ -108,9 +111,6 @@ var init_ref_table = __esm(() => {
108
111
  };
109
112
  });
110
113
 
111
- // src/constants.ts
112
- var REQUEST_TIMEOUT_MS = 30000, INSPECTOR_TIMEOUT_MS = 5000, SPAWN_TIMEOUT_MS = 5000, SPAWN_POLL_INTERVAL_MS = 50, BRK_PAUSE_TIMEOUT_MS = 2000, MAX_INTERNAL_PAUSE_SKIPS = 5, STATE_WAIT_TIMEOUT_MS = 5000, PAUSE_WAITER_TIMEOUT_MS = 30000, MAX_BUFFERED_MESSAGES = 1000, BUFFER_TRIM_BATCH = 100, MAX_SOURCE_LINE_WIDTH = 120, MAX_REQUEST_SIZE = 1048576;
113
-
114
114
  // src/dap/client.ts
115
115
  class DapClient {
116
116
  proc;
@@ -299,15 +299,38 @@ class DapClient {
299
299
  var init_client = () => {};
300
300
 
301
301
  // src/dap/session.ts
302
+ import { existsSync } from "fs";
303
+ import { join } from "path";
304
+ function getManagedAdaptersDir() {
305
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
306
+ return join(home, ".debug-that", "adapters");
307
+ }
302
308
  function resolveAdapterCommand(runtime) {
303
309
  switch (runtime) {
304
310
  case "lldb":
305
311
  case "lldb-dap": {
312
+ const managedPath = join(getManagedAdaptersDir(), "lldb-dap");
313
+ if (existsSync(managedPath)) {
314
+ return [managedPath];
315
+ }
316
+ const whichResult = Bun.spawnSync(["which", "lldb-dap"]);
317
+ if (whichResult.exitCode === 0) {
318
+ return ["lldb-dap"];
319
+ }
306
320
  const brewPath = "/opt/homebrew/opt/llvm/bin/lldb-dap";
307
- return [brewPath];
321
+ if (existsSync(brewPath)) {
322
+ return [brewPath];
323
+ }
324
+ return ["lldb-dap"];
308
325
  }
309
326
  case "codelldb":
310
327
  return ["codelldb", "--port", "0"];
328
+ case "python":
329
+ case "debugpy": {
330
+ const py3 = Bun.spawnSync(["which", "python3"]);
331
+ const pyBin = py3.exitCode === 0 ? "python3" : "python";
332
+ return [pyBin, "-m", "debugpy.adapter"];
333
+ }
311
334
  default:
312
335
  return [runtime];
313
336
  }
@@ -351,8 +374,14 @@ class DapSession {
351
374
  stopOnEntry: options.brk ?? true,
352
375
  cwd: process.cwd()
353
376
  };
354
- await this.dap.send("launch", launchArgs);
377
+ if (this._runtime === "python" || this._runtime === "debugpy") {
378
+ launchArgs.console = "internalConsole";
379
+ launchArgs.justMyCode = false;
380
+ }
381
+ const launchPromise = this.dap.send("launch", launchArgs);
382
+ await this.waitForInitialized();
355
383
  await this.dap.send("configurationDone");
384
+ await launchPromise;
356
385
  if (options.brk !== false) {
357
386
  await this.waitForStop(5000);
358
387
  }
@@ -376,8 +405,10 @@ class DapSession {
376
405
  await this.initializeAdapter();
377
406
  const pid = parseInt(target, 10);
378
407
  const attachArgs = Number.isNaN(pid) ? { program: target, waitFor: true } : { pid };
379
- await this.dap.send("attach", attachArgs);
408
+ const attachPromise = this.dap.send("attach", attachArgs);
409
+ await this.waitForInitialized();
380
410
  await this.dap.send("configurationDone");
411
+ await attachPromise;
381
412
  await this.waitForStop(5000).catch(() => {});
382
413
  if (this._state === "idle") {
383
414
  this._state = "running";
@@ -416,12 +447,12 @@ class DapSession {
416
447
  async continue() {
417
448
  this.requireConnected();
418
449
  this.requirePaused();
419
- const waiter = this.createStoppedWaiter(30000);
420
- await this.getDap().send("continue", { threadId: this._threadId });
421
450
  this._state = "running";
422
451
  this._pauseInfo = null;
423
452
  this._stackFrames = [];
424
453
  this.refs.clearVolatile();
454
+ const waiter = this.createStoppedWaiter(30000);
455
+ await this.getDap().send("continue", { threadId: this._threadId });
425
456
  await waiter;
426
457
  if (this.isPaused())
427
458
  await this.fetchStackTrace();
@@ -429,12 +460,12 @@ class DapSession {
429
460
  async step(mode) {
430
461
  this.requireConnected();
431
462
  this.requirePaused();
432
- const waiter = this.createStoppedWaiter(30000);
433
- const command = mode === "into" ? "stepIn" : mode === "out" ? "stepOut" : "next";
434
- await this.getDap().send(command, { threadId: this._threadId });
435
463
  this._state = "running";
436
464
  this._pauseInfo = null;
437
465
  this.refs.clearVolatile();
466
+ const waiter = this.createStoppedWaiter(30000);
467
+ const command = mode === "into" ? "stepIn" : mode === "out" ? "stepOut" : "next";
468
+ await this.getDap().send(command, { threadId: this._threadId });
438
469
  await waiter;
439
470
  if (this.isPaused())
440
471
  await this.fetchStackTrace();
@@ -653,8 +684,8 @@ class DapSession {
653
684
  };
654
685
  });
655
686
  }
656
- getStack(_options = {}) {
657
- return this._stackFrames.map((frame) => {
687
+ getStack(options = {}) {
688
+ const frames = this._stackFrames.map((frame) => {
658
689
  const ref = this.refs.addFrame(String(frame.id), frame.name);
659
690
  return {
660
691
  ref,
@@ -664,6 +695,11 @@ class DapSession {
664
695
  column: frame.column > 0 ? frame.column : undefined
665
696
  };
666
697
  });
698
+ if (options.filter) {
699
+ const filterLower = options.filter.toLowerCase();
700
+ return frames.filter((f) => f.functionName.toLowerCase().includes(filterLower) || f.file.toLowerCase().includes(filterLower));
701
+ }
702
+ return frames;
667
703
  }
668
704
  async getSource(options = {}) {
669
705
  const file = options.file ?? this._pauseInfo?.url;
@@ -827,12 +863,41 @@ class DapSession {
827
863
  async restartFrame(_frameRef) {
828
864
  throw new Error("Frame restart is not supported in DAP mode.");
829
865
  }
830
- async runTo(_file, _line) {
831
- throw new Error("Run-to-location is not yet supported in DAP mode. Set a breakpoint and continue.");
866
+ async runTo(file, line) {
867
+ this.requireConnected();
868
+ this.requirePaused();
869
+ const tempBp = await this.setBreakpoint(file, line);
870
+ try {
871
+ await this.continue();
872
+ } finally {
873
+ try {
874
+ await this.removeBreakpoint(tempBp.ref);
875
+ } catch {}
876
+ }
832
877
  }
833
878
  getScripts(_filter) {
834
879
  return [];
835
880
  }
881
+ async getModules(filter) {
882
+ this.requireConnected();
883
+ if (!this.capabilities.supportsModulesRequest) {
884
+ throw new Error(`This debug adapter does not support the modules request.
885
+ -> The adapter may not report module/symbol information.`);
886
+ }
887
+ const response = await this.getDap().send("modules", { startModule: 0, moduleCount: 0 });
888
+ const body = response.body;
889
+ let modules = body.modules ?? [];
890
+ if (filter) {
891
+ const filterLower = filter.toLowerCase();
892
+ modules = modules.filter((m) => m.name.toLowerCase().includes(filterLower) || (m.path?.toLowerCase().includes(filterLower) ?? false));
893
+ }
894
+ return modules.map((m) => ({
895
+ id: String(m.id),
896
+ name: m.name,
897
+ path: m.path,
898
+ symbolStatus: m.symbolStatus
899
+ }));
900
+ }
836
901
  async addBlackbox(_patterns) {
837
902
  throw new Error("Blackboxing is not supported in DAP mode.");
838
903
  }
@@ -878,8 +943,8 @@ class DapSession {
878
943
  async initializeAdapter() {
879
944
  const response = await this.getDap().send("initialize", {
880
945
  adapterID: this._runtime,
881
- clientID: "agent-dbg",
882
- clientName: "agent-dbg",
946
+ clientID: "debug-that",
947
+ clientName: "debug-that",
883
948
  linesStartAt1: true,
884
949
  columnsStartAt1: true,
885
950
  pathFormat: "path",
@@ -1046,6 +1111,21 @@ class DapSession {
1046
1111
  };
1047
1112
  });
1048
1113
  }
1114
+ async waitForInitialized() {
1115
+ const dap = this.getDap();
1116
+ return new Promise((resolve, reject) => {
1117
+ const timer = setTimeout(() => {
1118
+ dap.off("initialized", handler);
1119
+ reject(new Error("Timed out waiting for DAP initialized event"));
1120
+ }, INITIALIZED_TIMEOUT_MS);
1121
+ const handler = () => {
1122
+ clearTimeout(timer);
1123
+ dap.off("initialized", handler);
1124
+ resolve();
1125
+ };
1126
+ dap.on("initialized", handler);
1127
+ });
1128
+ }
1049
1129
  async waitForStop(timeoutMs) {
1050
1130
  if (!this.isPaused()) {
1051
1131
  await this.createStoppedWaiter(timeoutMs);
@@ -1060,6 +1140,38 @@ var init_session = __esm(() => {
1060
1140
  init_client();
1061
1141
  });
1062
1142
 
1143
+ // src/daemon/eval-suggestions.ts
1144
+ function suggestEvalFix(errorMsg) {
1145
+ const lower = errorMsg.toLowerCase();
1146
+ if (lower.includes("invalid use of 'this'") || lower.includes("invalid use of this")) {
1147
+ return `This frame may lack debug symbols. Try: debug-that modules
1148
+ Or try a different frame: debug-that eval <expr> --frame @f1`;
1149
+ }
1150
+ if (lower.includes("no member named") || lower.includes("has no member")) {
1151
+ return "Try: debug-that props <@ref> to list available members";
1152
+ }
1153
+ if (lower.includes("undeclared identifier") || lower.includes("use of undeclared") || lower.includes("is not defined")) {
1154
+ return "Try: debug-that vars to see variables in scope";
1155
+ }
1156
+ if (lower.includes("not paused")) {
1157
+ return "Try: debug-that pause";
1158
+ }
1159
+ if (lower.includes("timed out")) {
1160
+ return `The expression may be blocking. Try: debug-that eval <expr> --timeout 30000
1161
+ Or use --side-effect-free to safely inspect without side effects`;
1162
+ }
1163
+ if (lower.includes("side effect")) {
1164
+ return "Expression has side effects. Remove --side-effect-free flag to allow mutation";
1165
+ }
1166
+ if (lower.includes("syntaxerror") || lower.includes("unexpected token")) {
1167
+ return "Check expression syntax. Wrap multi-line expressions in parentheses";
1168
+ }
1169
+ if (lower.includes("cannot read propert") || lower.includes("undefined is not")) {
1170
+ return "The value may be null/undefined. Try: debug-that vars to inspect available values";
1171
+ }
1172
+ return;
1173
+ }
1174
+
1063
1175
  // src/daemon/logger.ts
1064
1176
  import { appendFileSync, writeFileSync } from "fs";
1065
1177
 
@@ -1096,31 +1208,31 @@ class DaemonLogger {
1096
1208
  var init_logger = () => {};
1097
1209
 
1098
1210
  // src/daemon/paths.ts
1099
- import { existsSync, mkdirSync } from "fs";
1100
- import { join } from "path";
1211
+ import { existsSync as existsSync2, mkdirSync } from "fs";
1212
+ import { join as join2 } from "path";
1101
1213
  function getSocketDir() {
1102
1214
  const xdgRuntime = process.env.XDG_RUNTIME_DIR;
1103
1215
  if (xdgRuntime) {
1104
- return join(xdgRuntime, "agent-dbg");
1216
+ return join2(xdgRuntime, "debug-that");
1105
1217
  }
1106
1218
  const tmpdir = process.env.TMPDIR || "/tmp";
1107
- return join(tmpdir, `agent-dbg-${process.getuid?.() ?? 0}`);
1219
+ return join2(tmpdir, `debug-that-${process.getuid?.() ?? 0}`);
1108
1220
  }
1109
1221
  function getSocketPath(session) {
1110
- return join(getSocketDir(), `${session}.sock`);
1222
+ return join2(getSocketDir(), `${session}.sock`);
1111
1223
  }
1112
1224
  function getLockPath(session) {
1113
- return join(getSocketDir(), `${session}.lock`);
1225
+ return join2(getSocketDir(), `${session}.lock`);
1114
1226
  }
1115
1227
  function getLogPath(session) {
1116
- return join(getSocketDir(), `${session}.cdp.log`);
1228
+ return join2(getSocketDir(), `${session}.cdp.log`);
1117
1229
  }
1118
1230
  function getDaemonLogPath(session) {
1119
- return join(getSocketDir(), `${session}.daemon.log`);
1231
+ return join2(getSocketDir(), `${session}.daemon.log`);
1120
1232
  }
1121
1233
  function ensureSocketDir() {
1122
1234
  const dir = getSocketDir();
1123
- if (!existsSync(dir)) {
1235
+ if (!existsSync2(dir)) {
1124
1236
  mkdirSync(dir, { recursive: true });
1125
1237
  }
1126
1238
  }
@@ -7149,7 +7261,7 @@ var init_esm2 = __esm(() => {
7149
7261
  });
7150
7262
 
7151
7263
  // src/protocol/messages.ts
7152
- var PingRequest, LaunchRequest, AttachRequest, StatusRequest, StateRequest, ContinueRequest, StepRequest, PauseRequest, RunToRequest, BreakRequest, BreakFnRequest, BreakRmRequest, BreakLsRequest, LogpointRequest, CatchRequest, SourceRequest, ScriptsRequest, StackRequest, SearchRequest, ConsoleRequest, ExceptionsRequest, EvalRequest, VarsRequest, PropsRequest, BlackboxRequest, BlackboxLsRequest, BlackboxRmRequest, SetRequest, SetReturnRequest, HotpatchRequest, BreakToggleRequest, BreakableRequest, RestartFrameRequest, SourcemapRequest, SourcemapDisableRequest, RestartRequest, StopRequest, DaemonRequestSchema, SuccessResponse, ErrorResponse, DaemonResponseSchema;
7264
+ var PingRequest, LaunchRequest, AttachRequest, StatusRequest, StateRequest, ContinueRequest, StepRequest, PauseRequest, RunToRequest, BreakRequest, BreakFnRequest, BreakRmRequest, BreakLsRequest, LogpointRequest, CatchRequest, SourceRequest, ScriptsRequest, StackRequest, SearchRequest, ConsoleRequest, ExceptionsRequest, EvalRequest, VarsRequest, PropsRequest, BlackboxRequest, BlackboxLsRequest, BlackboxRmRequest, SetRequest, SetReturnRequest, HotpatchRequest, BreakToggleRequest, BreakableRequest, RestartFrameRequest, SourcemapRequest, SourcemapDisableRequest, RestartRequest, StopRequest, ModulesRequest, DaemonRequestSchema, SuccessResponse, ErrorResponse, DaemonResponseSchema;
7153
7265
  var init_messages = __esm(() => {
7154
7266
  init_esm2();
7155
7267
  PingRequest = exports_external.object({ cmd: exports_external.literal("ping") });
@@ -7265,7 +7377,8 @@ var init_messages = __esm(() => {
7265
7377
  cmd: exports_external.literal("stack"),
7266
7378
  args: exports_external.object({
7267
7379
  asyncDepth: exports_external.optional(exports_external.number()),
7268
- generated: exports_external.optional(exports_external.boolean())
7380
+ generated: exports_external.optional(exports_external.boolean()),
7381
+ filter: exports_external.optional(exports_external.string())
7269
7382
  })
7270
7383
  });
7271
7384
  SearchRequest = exports_external.object({
@@ -7382,6 +7495,12 @@ var init_messages = __esm(() => {
7382
7495
  SourcemapDisableRequest = exports_external.object({ cmd: exports_external.literal("sourcemap-disable") });
7383
7496
  RestartRequest = exports_external.object({ cmd: exports_external.literal("restart") });
7384
7497
  StopRequest = exports_external.object({ cmd: exports_external.literal("stop") });
7498
+ ModulesRequest = exports_external.object({
7499
+ cmd: exports_external.literal("modules"),
7500
+ args: exports_external.object({
7501
+ filter: exports_external.optional(exports_external.string())
7502
+ })
7503
+ });
7385
7504
  DaemonRequestSchema = exports_external.union([
7386
7505
  PingRequest,
7387
7506
  LaunchRequest,
@@ -7419,7 +7538,8 @@ var init_messages = __esm(() => {
7419
7538
  RestartRequest,
7420
7539
  SourcemapRequest,
7421
7540
  SourcemapDisableRequest,
7422
- StopRequest
7541
+ StopRequest,
7542
+ ModulesRequest
7423
7543
  ]);
7424
7544
  SuccessResponse = exports_external.object({
7425
7545
  ok: exports_external.literal(true),
@@ -7434,7 +7554,7 @@ var init_messages = __esm(() => {
7434
7554
  });
7435
7555
 
7436
7556
  // src/daemon/server.ts
7437
- import { existsSync as existsSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
7557
+ import { existsSync as existsSync3, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
7438
7558
 
7439
7559
  class DaemonServer {
7440
7560
  session;
@@ -7457,14 +7577,14 @@ class DaemonServer {
7457
7577
  }
7458
7578
  async start() {
7459
7579
  ensureSocketDir();
7460
- if (existsSync2(this.lockPath)) {
7580
+ if (existsSync3(this.lockPath)) {
7461
7581
  const existingPid = parseInt(await Bun.file(this.lockPath).text(), 10);
7462
7582
  if (!Number.isNaN(existingPid) && isProcessRunning(existingPid)) {
7463
7583
  throw new Error(`Daemon already running for session "${this.session}" (pid ${existingPid})`);
7464
7584
  }
7465
7585
  unlinkSync(this.lockPath);
7466
7586
  }
7467
- if (existsSync2(this.socketPath)) {
7587
+ if (existsSync3(this.socketPath)) {
7468
7588
  unlinkSync(this.socketPath);
7469
7589
  }
7470
7590
  writeFileSync2(this.lockPath, String(process.pid));
@@ -7547,7 +7667,7 @@ class DaemonServer {
7547
7667
  this.sendResponse(socket, cmd ? {
7548
7668
  ok: false,
7549
7669
  error: `Unknown command: ${cmd}`,
7550
- suggestion: "-> Try: agent-dbg --help"
7670
+ suggestion: "-> Try: debug-that --help"
7551
7671
  } : {
7552
7672
  ok: false,
7553
7673
  error: "Invalid request: must have { cmd: string, args: object }"
@@ -7591,10 +7711,10 @@ class DaemonServer {
7591
7711
  this.listener.stop(true);
7592
7712
  this.listener = null;
7593
7713
  }
7594
- if (existsSync2(this.socketPath)) {
7714
+ if (existsSync3(this.socketPath)) {
7595
7715
  unlinkSync(this.socketPath);
7596
7716
  }
7597
- if (existsSync2(this.lockPath)) {
7717
+ if (existsSync3(this.lockPath)) {
7598
7718
  unlinkSync(this.lockPath);
7599
7719
  }
7600
7720
  }
@@ -9458,7 +9578,7 @@ async function continueExecution(session) {
9458
9578
  if (!session.cdp) {
9459
9579
  throw new Error("Cannot continue: no CDP connection");
9460
9580
  }
9461
- const waiter = session.createPauseWaiter();
9581
+ const waiter = session.createPauseWaiter(CONTINUE_GRACE_MS);
9462
9582
  await session.cdp.send("Debugger.resume");
9463
9583
  await waiter;
9464
9584
  }
@@ -9479,8 +9599,8 @@ async function stepExecution(session, mode) {
9479
9599
  await waiter;
9480
9600
  }
9481
9601
  async function pauseExecution(session) {
9482
- if (session.sessionState !== "running") {
9483
- throw new Error("Cannot pause: process is not running");
9602
+ if (session.isPaused()) {
9603
+ throw new Error("Cannot pause: process is already paused");
9484
9604
  }
9485
9605
  if (!session.cdp) {
9486
9606
  throw new Error("Cannot pause: no CDP connection");
@@ -9540,6 +9660,7 @@ async function restartFrameExecution(session, frameRef) {
9540
9660
  await waiter;
9541
9661
  return { status: "restarted" };
9542
9662
  }
9663
+ var CONTINUE_GRACE_MS = 500;
9543
9664
  var init_session_execution = () => {};
9544
9665
 
9545
9666
  // src/daemon/session-inspection.ts
@@ -9715,6 +9836,10 @@ async function getProps(session, ref, options = {}) {
9715
9836
  if (objectId.startsWith("primitive:") || objectId.startsWith("eval:")) {
9716
9837
  throw new Error(`Ref ${ref} is a primitive and has no properties`);
9717
9838
  }
9839
+ const depth = Math.min(options.depth ?? 1, MAX_DEPTH);
9840
+ return fetchPropsRecursive(session, objectId, options, depth);
9841
+ }
9842
+ async function fetchPropsRecursive(session, objectId, options, remainingDepth) {
9718
9843
  const propsParams = {
9719
9844
  objectId,
9720
9845
  ownProperties: options.own ?? true,
@@ -9723,7 +9848,10 @@ async function getProps(session, ref, options = {}) {
9723
9848
  if (options.internal) {
9724
9849
  propsParams.accessorPropertiesOnly = false;
9725
9850
  }
9726
- const propsResult = await session.adapter.getProperties(session.cdp, propsParams);
9851
+ const cdp = session.cdp;
9852
+ if (!cdp)
9853
+ throw new Error("No active debug session");
9854
+ const propsResult = await session.adapter.getProperties(cdp, propsParams);
9727
9855
  const properties = propsResult.result ?? [];
9728
9856
  const internalProps = options.internal ? propsResult.internalProperties ?? [] : [];
9729
9857
  const result = [];
@@ -9758,6 +9886,9 @@ async function getProps(session, ref, options = {}) {
9758
9886
  if (isAccessor) {
9759
9887
  item.isAccessor = true;
9760
9888
  }
9889
+ if (propValue?.objectId && remainingDepth > 1) {
9890
+ item.children = await fetchPropsRecursive(session, propValue.objectId, options, remainingDepth - 1);
9891
+ }
9761
9892
  result.push(item);
9762
9893
  }
9763
9894
  for (const prop of internalProps) {
@@ -9777,6 +9908,9 @@ async function getProps(session, ref, options = {}) {
9777
9908
  if (propRef) {
9778
9909
  item.ref = propRef;
9779
9910
  }
9911
+ if (propValue.objectId && remainingDepth > 1) {
9912
+ item.children = await fetchPropsRecursive(session, propValue.objectId, options, remainingDepth - 1);
9913
+ }
9780
9914
  result.push(item);
9781
9915
  }
9782
9916
  return result;
@@ -9945,6 +10079,10 @@ function getStack(session, options = {}) {
9945
10079
  }
9946
10080
  stackFrames.push(stackEntry);
9947
10081
  }
10082
+ if (options.filter) {
10083
+ const filterLower = options.filter.toLowerCase();
10084
+ return stackFrames.filter((f) => f.functionName.toLowerCase().includes(filterLower) || f.file.toLowerCase().includes(filterLower));
10085
+ }
9948
10086
  return stackFrames;
9949
10087
  }
9950
10088
  async function searchInScripts(session, query, options = {}) {
@@ -10011,6 +10149,7 @@ function getExceptions(session, options = {}) {
10011
10149
  function clearConsole(session) {
10012
10150
  session.consoleMessages = [];
10013
10151
  }
10152
+ var MAX_DEPTH = 5;
10014
10153
  var init_session_inspection = () => {};
10015
10154
 
10016
10155
  // src/daemon/session-mutation.ts
@@ -10161,7 +10300,12 @@ var init_session_mutation = () => {};
10161
10300
  // src/daemon/session-state.ts
10162
10301
  async function buildState(session, options = {}) {
10163
10302
  if (session.sessionState !== "paused" || !session.cdp || !session.pauseInfo) {
10164
- return { status: session.sessionState };
10303
+ const snapshot2 = { status: session.sessionState };
10304
+ if (session.sessionState === "idle" && session.exceptionEntries.length > 0) {
10305
+ const last = session.exceptionEntries[session.exceptionEntries.length - 1];
10306
+ snapshot2.lastException = { text: last.text, description: last.description };
10307
+ }
10308
+ return snapshot2;
10165
10309
  }
10166
10310
  session.refs.clearVolatile();
10167
10311
  const showAll = !options.vars && !options.stack && !options.breakpoints && !options.code;
@@ -10475,6 +10619,10 @@ class DebugSession {
10475
10619
  }
10476
10620
  status.pauseInfo = translated;
10477
10621
  }
10622
+ if (this.state === "idle" && this.exceptionEntries.length > 0) {
10623
+ const last = this.exceptionEntries[this.exceptionEntries.length - 1];
10624
+ status.lastException = { text: last.text, description: last.description };
10625
+ }
10478
10626
  return status;
10479
10627
  }
10480
10628
  async stop() {
@@ -10701,7 +10849,7 @@ class DebugSession {
10701
10849
  };
10702
10850
  this.cdp?.waitFor("Debugger.paused", { timeoutMs }).then(() => settle()).catch(() => settle());
10703
10851
  const pollTimer = setInterval(() => {
10704
- if (this.isPaused() || this.state === "idle") {
10852
+ if (this.isPaused() || this.state === "idle" || !this.cdp) {
10705
10853
  settle();
10706
10854
  }
10707
10855
  }, 100);
@@ -10898,7 +11046,7 @@ class DebugSession {
10898
11046
  if (match?.[1]) {
10899
11047
  clearTimeout(timeout);
10900
11048
  this.drainReader(reader);
10901
- return match[1];
11049
+ return match[1].replace(ANSI_RE, "");
10902
11050
  }
10903
11051
  }
10904
11052
  } catch {}
@@ -10943,7 +11091,7 @@ class DebugSession {
10943
11091
  pump();
10944
11092
  }
10945
11093
  }
10946
- var INSPECTOR_URL_REGEX;
11094
+ var INSPECTOR_URL_REGEX, ESC, ANSI_RE;
10947
11095
  var init_session2 = __esm(() => {
10948
11096
  init_client2();
10949
11097
  init_logger2();
@@ -10958,6 +11106,8 @@ var init_session2 = __esm(() => {
10958
11106
  init_session_mutation();
10959
11107
  init_session_state();
10960
11108
  INSPECTOR_URL_REGEX = /(?:Debugger listening on\s+)?(wss?:\/\/\S+)/;
11109
+ ESC = String.fromCharCode(27);
11110
+ ANSI_RE = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
10961
11111
  });
10962
11112
 
10963
11113
  // src/daemon/entry.ts
@@ -10978,7 +11128,7 @@ var init_entry = __esm(async () => {
10978
11128
  daemonIdx = process.argv.indexOf("--daemon");
10979
11129
  session = daemonIdx !== -1 ? process.argv[daemonIdx + 1] : process.argv[2];
10980
11130
  if (!session) {
10981
- console.error("Usage: agent-dbg --daemon <session> [--timeout <seconds>]");
11131
+ console.error("Usage: debug-that --daemon <session> [--timeout <seconds>]");
10982
11132
  process.exit(1);
10983
11133
  }
10984
11134
  timeoutIdx = process.argv.indexOf("--timeout");
@@ -11129,8 +11279,13 @@ var init_entry = __esm(async () => {
11129
11279
  }
11130
11280
  case "eval": {
11131
11281
  const { expression, ...evalOptions } = req.args;
11132
- const evalResult = await activeSession().eval(expression, evalOptions);
11133
- return { ok: true, data: evalResult };
11282
+ try {
11283
+ const evalResult = await activeSession().eval(expression, evalOptions);
11284
+ return { ok: true, data: evalResult };
11285
+ } catch (err) {
11286
+ const msg = err instanceof Error ? err.message : String(err);
11287
+ return { ok: false, error: msg, suggestion: suggestEvalFix(msg) };
11288
+ }
11134
11289
  }
11135
11290
  case "vars": {
11136
11291
  const varsResult = await activeSession().getVars(req.args);
@@ -11204,6 +11359,18 @@ var init_entry = __esm(async () => {
11204
11359
  const result = await activeSession().restart();
11205
11360
  return { ok: true, data: result };
11206
11361
  }
11362
+ case "modules": {
11363
+ const session2 = activeSession();
11364
+ if (!("getModules" in session2)) {
11365
+ return {
11366
+ ok: false,
11367
+ error: "Modules are only available in DAP mode (e.g. --runtime lldb)",
11368
+ suggestion: "For CDP sessions, use: debug-that scripts"
11369
+ };
11370
+ }
11371
+ const modulesResult = await session2.getModules(req.args.filter);
11372
+ return { ok: true, data: modulesResult };
11373
+ }
11207
11374
  case "stop":
11208
11375
  await activeSession().stop();
11209
11376
  dapSession = null;
@@ -11236,7 +11403,7 @@ var init_registry = __esm(() => {
11236
11403
  });
11237
11404
 
11238
11405
  // src/daemon/client.ts
11239
- import { existsSync as existsSync3, readdirSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
11406
+ import { existsSync as existsSync4, readdirSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
11240
11407
 
11241
11408
  class DaemonClient {
11242
11409
  session;
@@ -11333,11 +11500,11 @@ class DaemonClient {
11333
11500
  }
11334
11501
  static isRunning(session2) {
11335
11502
  const socketPath = getSocketPath(session2);
11336
- if (!existsSync3(socketPath)) {
11503
+ if (!existsSync4(socketPath)) {
11337
11504
  return false;
11338
11505
  }
11339
11506
  const lockPath = getLockPath(session2);
11340
- if (!existsSync3(lockPath)) {
11507
+ if (!existsSync4(lockPath)) {
11341
11508
  return false;
11342
11509
  }
11343
11510
  try {
@@ -11353,14 +11520,14 @@ class DaemonClient {
11353
11520
  static cleanStaleFiles(session2) {
11354
11521
  const socketPath = getSocketPath(session2);
11355
11522
  const lockPath = getLockPath(session2);
11356
- if (existsSync3(socketPath))
11523
+ if (existsSync4(socketPath))
11357
11524
  unlinkSync2(socketPath);
11358
- if (existsSync3(lockPath))
11525
+ if (existsSync4(lockPath))
11359
11526
  unlinkSync2(lockPath);
11360
11527
  }
11361
11528
  static async isAlive(session2) {
11362
11529
  const socketPath = getSocketPath(session2);
11363
- if (!existsSync3(socketPath)) {
11530
+ if (!existsSync4(socketPath)) {
11364
11531
  return false;
11365
11532
  }
11366
11533
  try {
@@ -11373,7 +11540,7 @@ class DaemonClient {
11373
11540
  }
11374
11541
  static listSessions() {
11375
11542
  const dir = getSocketDir();
11376
- if (!existsSync3(dir)) {
11543
+ if (!existsSync4(dir)) {
11377
11544
  return [];
11378
11545
  }
11379
11546
  const files = readdirSync(dir);
@@ -11386,7 +11553,7 @@ var init_client3 = __esm(() => {
11386
11553
  });
11387
11554
 
11388
11555
  // src/daemon/spawn.ts
11389
- import { closeSync, existsSync as existsSync4, openSync, readFileSync as readFileSync2 } from "fs";
11556
+ import { closeSync, existsSync as existsSync5, openSync, readFileSync as readFileSync2 } from "fs";
11390
11557
  async function spawnDaemon(session2, options = {}) {
11391
11558
  const socketPath = getSocketPath(session2);
11392
11559
  const spawnArgs = [];
@@ -11413,7 +11580,7 @@ async function spawnDaemon(session2, options = {}) {
11413
11580
  proc.unref();
11414
11581
  const deadline = Date.now() + SPAWN_TIMEOUT_MS;
11415
11582
  while (Date.now() < deadline) {
11416
- if (existsSync4(socketPath)) {
11583
+ if (existsSync5(socketPath)) {
11417
11584
  return;
11418
11585
  }
11419
11586
  await Bun.sleep(SPAWN_POLL_INTERVAL_MS);
@@ -11486,7 +11653,7 @@ var init_launch = __esm(() => {
11486
11653
  const command = args.subcommand ? [args.subcommand, ...args.positionals] : [...args.positionals];
11487
11654
  if (command.length === 0) {
11488
11655
  console.error("No command specified");
11489
- console.error(" -> Try: agent-dbg launch --brk node app.js");
11656
+ console.error(" -> Try: dbg launch --brk node app.js");
11490
11657
  return 1;
11491
11658
  }
11492
11659
  await ensureDaemon(session2, { timeout: timeout2 });
@@ -11527,12 +11694,12 @@ var init_attach = __esm(() => {
11527
11694
  const runtime = typeof args.flags.runtime === "string" ? args.flags.runtime : undefined;
11528
11695
  if (!target) {
11529
11696
  console.error("No target specified");
11530
- console.error(" -> Try: agent-dbg attach <ws-url | port>");
11697
+ console.error(" -> Try: dbg attach <ws-url | port>");
11531
11698
  return 1;
11532
11699
  }
11533
11700
  if (DaemonClient.isRunning(session2)) {
11534
11701
  console.error(`Session "${session2}" is already active`);
11535
- console.error(` -> Try: agent-dbg stop --session ${session2}`);
11702
+ console.error(` -> Try: dbg stop --session ${session2}`);
11536
11703
  return 1;
11537
11704
  }
11538
11705
  const timeout2 = parseIntFlag(args.flags, "timeout");
@@ -11594,7 +11761,7 @@ var init_restart = __esm(() => {
11594
11761
  const session2 = args.global.session;
11595
11762
  if (!DaemonClient.isRunning(session2)) {
11596
11763
  console.error(`No active session "${session2}"`);
11597
- console.error(" -> Try: agent-dbg launch --brk node app.js");
11764
+ console.error(" -> Try: dbg launch --brk node app.js");
11598
11765
  return 1;
11599
11766
  }
11600
11767
  const client = new DaemonClient(session2);
@@ -11697,7 +11864,7 @@ var init_status = __esm(() => {
11697
11864
  const session2 = args.global.session;
11698
11865
  if (!DaemonClient.isRunning(session2)) {
11699
11866
  console.error(`No active session "${session2}"`);
11700
- console.error(" -> Try: agent-dbg launch --brk node app.js");
11867
+ console.error(" -> Try: dbg launch --brk node app.js");
11701
11868
  return 1;
11702
11869
  }
11703
11870
  const client = new DaemonClient(session2);
@@ -11724,11 +11891,317 @@ var init_status = __esm(() => {
11724
11891
  const loc = data.pauseInfo.url ? `${shortPath(data.pauseInfo.url)}:${data.pauseInfo.line}${data.pauseInfo.column !== undefined ? `:${data.pauseInfo.column}` : ""}` : "unknown";
11725
11892
  console.log(` Paused: ${data.pauseInfo.reason} at ${loc}`);
11726
11893
  }
11894
+ if (data.lastException) {
11895
+ const desc = data.lastException.description ?? data.lastException.text;
11896
+ const firstLine = desc.split(`
11897
+ `)[0] ?? desc;
11898
+ console.log(` Last exception: ${firstLine}`);
11899
+ }
11727
11900
  }
11728
11901
  return 0;
11729
11902
  });
11730
11903
  });
11731
11904
 
11905
+ // src/formatter/color.ts
11906
+ function c(color, text) {
11907
+ return `${color}${text}${RESET}`;
11908
+ }
11909
+ function shouldEnableColor(explicitFlag) {
11910
+ if (explicitFlag)
11911
+ return true;
11912
+ if (process.env.NO_COLOR !== undefined)
11913
+ return false;
11914
+ if (process.env.FORCE_COLOR !== undefined)
11915
+ return true;
11916
+ if (process.env.DBG_COLOR === "1" || process.env.DBG_COLOR === "true")
11917
+ return true;
11918
+ return false;
11919
+ }
11920
+ function detectLanguage(url2) {
11921
+ const dot = url2.lastIndexOf(".");
11922
+ if (dot === -1)
11923
+ return "unknown";
11924
+ return EXT_MAP[url2.slice(dot)] ?? "unknown";
11925
+ }
11926
+ function getKeywords(lang) {
11927
+ switch (lang) {
11928
+ case "js":
11929
+ return { keywords: JS_KEYWORDS, constants: JS_CONSTANTS };
11930
+ case "py":
11931
+ return { keywords: PY_KEYWORDS, constants: PY_CONSTANTS };
11932
+ case "c":
11933
+ return { keywords: C_KEYWORDS, constants: C_CONSTANTS };
11934
+ default:
11935
+ return { keywords: new Set, constants: new Set };
11936
+ }
11937
+ }
11938
+ function getRegex(lang) {
11939
+ switch (lang) {
11940
+ case "js":
11941
+ return new RegExp(JS_LINE_RE.source, JS_LINE_RE.flags);
11942
+ case "py":
11943
+ return new RegExp(PY_LINE_RE.source, PY_LINE_RE.flags);
11944
+ case "c":
11945
+ return new RegExp(C_LINE_RE.source, C_LINE_RE.flags);
11946
+ default:
11947
+ return new RegExp(JS_LINE_RE.source, JS_LINE_RE.flags);
11948
+ }
11949
+ }
11950
+ function tokenizeLine(line, lang) {
11951
+ if (lang === "unknown")
11952
+ return [{ text: line }];
11953
+ const { keywords, constants } = getKeywords(lang);
11954
+ const re = getRegex(lang);
11955
+ const tokens = [];
11956
+ for (let match = re.exec(line);match !== null; match = re.exec(line)) {
11957
+ const [full, comment, str, num, word] = match;
11958
+ if (comment) {
11959
+ tokens.push({ text: comment, color: ansi.gray });
11960
+ } else if (str) {
11961
+ tokens.push({ text: str, color: ansi.green });
11962
+ } else if (num) {
11963
+ tokens.push({ text: num, color: ansi.yellow });
11964
+ } else if (word) {
11965
+ if (keywords.has(word)) {
11966
+ tokens.push({ text: word, color: ansi.blue });
11967
+ } else if (constants.has(word)) {
11968
+ tokens.push({ text: word, color: ansi.yellow });
11969
+ } else if (word[0] === word[0]?.toUpperCase() && /^[A-Z]/.test(word)) {
11970
+ tokens.push({ text: word, color: ansi.cyan });
11971
+ } else {
11972
+ tokens.push({ text: word });
11973
+ }
11974
+ } else {
11975
+ tokens.push({ text: full });
11976
+ }
11977
+ }
11978
+ return tokens;
11979
+ }
11980
+ function highlightLine(line, lang) {
11981
+ const tokens = tokenizeLine(line, lang);
11982
+ return tokens.map((t) => t.color ? c(t.color, t.text) : t.text).join("");
11983
+ }
11984
+ var ESC2 = "\x1B[", RESET, ansi, EXT_MAP, JS_KEYWORDS, JS_CONSTANTS, PY_KEYWORDS, PY_CONSTANTS, C_KEYWORDS, C_CONSTANTS, JS_LINE_RE, PY_LINE_RE, C_LINE_RE;
11985
+ var init_color = __esm(() => {
11986
+ RESET = `${ESC2}0m`;
11987
+ ansi = {
11988
+ reset: RESET,
11989
+ bold: `${ESC2}1m`,
11990
+ dim: `${ESC2}2m`,
11991
+ italic: `${ESC2}3m`,
11992
+ underline: `${ESC2}4m`,
11993
+ red: `${ESC2}31m`,
11994
+ green: `${ESC2}32m`,
11995
+ yellow: `${ESC2}33m`,
11996
+ blue: `${ESC2}34m`,
11997
+ magenta: `${ESC2}35m`,
11998
+ cyan: `${ESC2}36m`,
11999
+ white: `${ESC2}37m`,
12000
+ gray: `${ESC2}90m`,
12001
+ brightRed: `${ESC2}91m`,
12002
+ brightGreen: `${ESC2}92m`,
12003
+ brightYellow: `${ESC2}93m`,
12004
+ brightBlue: `${ESC2}94m`,
12005
+ brightMagenta: `${ESC2}95m`,
12006
+ brightCyan: `${ESC2}96m`
12007
+ };
12008
+ EXT_MAP = {
12009
+ ".js": "js",
12010
+ ".mjs": "js",
12011
+ ".cjs": "js",
12012
+ ".ts": "js",
12013
+ ".mts": "js",
12014
+ ".cts": "js",
12015
+ ".tsx": "js",
12016
+ ".jsx": "js",
12017
+ ".py": "py",
12018
+ ".pyw": "py",
12019
+ ".c": "c",
12020
+ ".cpp": "c",
12021
+ ".cc": "c",
12022
+ ".cxx": "c",
12023
+ ".h": "c",
12024
+ ".hpp": "c",
12025
+ ".rs": "c",
12026
+ ".go": "c",
12027
+ ".java": "c",
12028
+ ".swift": "c",
12029
+ ".m": "c"
12030
+ };
12031
+ JS_KEYWORDS = new Set([
12032
+ "async",
12033
+ "await",
12034
+ "break",
12035
+ "case",
12036
+ "catch",
12037
+ "class",
12038
+ "const",
12039
+ "continue",
12040
+ "debugger",
12041
+ "default",
12042
+ "delete",
12043
+ "do",
12044
+ "else",
12045
+ "export",
12046
+ "extends",
12047
+ "finally",
12048
+ "for",
12049
+ "from",
12050
+ "function",
12051
+ "if",
12052
+ "import",
12053
+ "in",
12054
+ "instanceof",
12055
+ "let",
12056
+ "new",
12057
+ "of",
12058
+ "return",
12059
+ "static",
12060
+ "super",
12061
+ "switch",
12062
+ "this",
12063
+ "throw",
12064
+ "try",
12065
+ "typeof",
12066
+ "var",
12067
+ "void",
12068
+ "while",
12069
+ "with",
12070
+ "yield",
12071
+ "type",
12072
+ "interface",
12073
+ "enum",
12074
+ "as",
12075
+ "implements",
12076
+ "declare",
12077
+ "readonly",
12078
+ "abstract",
12079
+ "override"
12080
+ ]);
12081
+ JS_CONSTANTS = new Set(["true", "false", "null", "undefined", "NaN", "Infinity"]);
12082
+ PY_KEYWORDS = new Set([
12083
+ "and",
12084
+ "as",
12085
+ "assert",
12086
+ "async",
12087
+ "await",
12088
+ "break",
12089
+ "class",
12090
+ "continue",
12091
+ "def",
12092
+ "del",
12093
+ "elif",
12094
+ "else",
12095
+ "except",
12096
+ "finally",
12097
+ "for",
12098
+ "from",
12099
+ "global",
12100
+ "if",
12101
+ "import",
12102
+ "in",
12103
+ "is",
12104
+ "lambda",
12105
+ "nonlocal",
12106
+ "not",
12107
+ "or",
12108
+ "pass",
12109
+ "raise",
12110
+ "return",
12111
+ "try",
12112
+ "while",
12113
+ "with",
12114
+ "yield"
12115
+ ]);
12116
+ PY_CONSTANTS = new Set(["True", "False", "None"]);
12117
+ C_KEYWORDS = new Set([
12118
+ "auto",
12119
+ "break",
12120
+ "case",
12121
+ "char",
12122
+ "const",
12123
+ "continue",
12124
+ "default",
12125
+ "do",
12126
+ "double",
12127
+ "else",
12128
+ "enum",
12129
+ "extern",
12130
+ "float",
12131
+ "for",
12132
+ "goto",
12133
+ "if",
12134
+ "inline",
12135
+ "int",
12136
+ "long",
12137
+ "register",
12138
+ "return",
12139
+ "short",
12140
+ "signed",
12141
+ "sizeof",
12142
+ "static",
12143
+ "struct",
12144
+ "switch",
12145
+ "typedef",
12146
+ "union",
12147
+ "unsigned",
12148
+ "void",
12149
+ "volatile",
12150
+ "while",
12151
+ "class",
12152
+ "namespace",
12153
+ "template",
12154
+ "typename",
12155
+ "public",
12156
+ "private",
12157
+ "protected",
12158
+ "virtual",
12159
+ "override",
12160
+ "final",
12161
+ "new",
12162
+ "delete",
12163
+ "throw",
12164
+ "try",
12165
+ "catch",
12166
+ "using",
12167
+ "nullptr",
12168
+ "fn",
12169
+ "let",
12170
+ "mut",
12171
+ "pub",
12172
+ "impl",
12173
+ "trait",
12174
+ "self",
12175
+ "Self",
12176
+ "match",
12177
+ "mod",
12178
+ "use",
12179
+ "crate",
12180
+ "where",
12181
+ "async",
12182
+ "await",
12183
+ "move",
12184
+ "ref",
12185
+ "unsafe",
12186
+ "func",
12187
+ "package",
12188
+ "import",
12189
+ "var",
12190
+ "type",
12191
+ "range",
12192
+ "defer",
12193
+ "chan",
12194
+ "select",
12195
+ "go",
12196
+ "map",
12197
+ "interface"
12198
+ ]);
12199
+ C_CONSTANTS = new Set(["true", "false", "NULL", "nullptr", "nil"]);
12200
+ JS_LINE_RE = /(\/\/.*$|\/\*.*?\*\/)|("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`)|((?<!\w)(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?n?)(?!\w))|([a-zA-Z_$][\w$]*)|(.)/g;
12201
+ PY_LINE_RE = /(#.*$)|("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|"""[\s\S]*?"""|'''[\s\S]*?''')|((?<!\w)(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?)(?!\w))|([a-zA-Z_][\w]*)|(.)/g;
12202
+ C_LINE_RE = /(\/\/.*$|\/\*.*?\*\/)|("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)')|((?<!\w)(?:0[xXoObB][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?\d+)?[fFlLuU]*)(?!\w))|([a-zA-Z_][\w]*)|(.)/g;
12203
+ });
12204
+
11732
12205
  // src/formatter/source.ts
11733
12206
  function trimLine(content, column) {
11734
12207
  const col = column !== undefined ? column - 1 : undefined;
@@ -11756,9 +12229,11 @@ function trimLine(content, column) {
11756
12229
  const adjustedCaret = col !== undefined ? col - start + (hasPrefix ? 1 : 0) : undefined;
11757
12230
  return { text: `${prefix}${content.slice(start, end)}${suffix}`, caretOffset: adjustedCaret };
11758
12231
  }
11759
- function formatSource(lines) {
12232
+ function formatSource(lines, opts) {
11760
12233
  if (lines.length === 0)
11761
12234
  return "";
12235
+ const color = opts?.color ?? false;
12236
+ const lang = opts?.language ?? "unknown";
11762
12237
  const maxLineNum = Math.max(...lines.map((l) => l.lineNumber));
11763
12238
  const numWidth = String(maxLineNum).length;
11764
12239
  const result = [];
@@ -11773,20 +12248,36 @@ function formatSource(lines) {
11773
12248
  marker = " \u25CF";
11774
12249
  }
11775
12250
  const trimmed = line.isCurrent ? trimLine(line.content, line.currentColumn) : trimLine(line.content);
11776
- result.push(`${marker} ${num}\u2502${trimmed.text}`);
12251
+ let coloredMarker = marker;
12252
+ let coloredNum = num;
12253
+ let coloredContent = trimmed.text;
12254
+ if (color) {
12255
+ if (line.isCurrent) {
12256
+ coloredMarker = c(ansi.brightYellow, marker);
12257
+ } else if (line.hasBreakpoint) {
12258
+ coloredMarker = c(ansi.red, marker);
12259
+ }
12260
+ coloredNum = c(ansi.gray, num);
12261
+ coloredContent = highlightLine(trimmed.text, lang);
12262
+ }
12263
+ result.push(`${coloredMarker} ${coloredNum}\u2502${coloredContent}`);
11777
12264
  if (line.isCurrent && trimmed.caretOffset !== undefined && trimmed.caretOffset >= 0) {
11778
12265
  const gutter = " ".repeat(numWidth + 4);
11779
12266
  const indent = trimmed.text.slice(0, trimmed.caretOffset).replace(/[^\t]/g, " ");
11780
- result.push(`${gutter}${indent}^`);
12267
+ const caret = color ? c(ansi.brightYellow, "^") : "^";
12268
+ result.push(`${gutter}${indent}${caret}`);
11781
12269
  }
11782
12270
  }
11783
12271
  return result.join(`
11784
12272
  `);
11785
12273
  }
11786
- var init_source = () => {};
12274
+ var init_source = __esm(() => {
12275
+ init_color();
12276
+ });
11787
12277
 
11788
12278
  // src/formatter/stack.ts
11789
- function formatStack(frames) {
12279
+ function formatStack(frames, opts) {
12280
+ const color = opts?.color ?? false;
11790
12281
  const outputLines = [];
11791
12282
  const segments = [];
11792
12283
  let i = 0;
@@ -11817,28 +12308,34 @@ function formatStack(frames) {
11817
12308
  for (const seg of segments) {
11818
12309
  if ("blackboxedCount" in seg) {
11819
12310
  const label = seg.blackboxedCount === 1 ? "\u250A ... 1 framework frame (blackboxed)" : `\u250A ... ${seg.blackboxedCount} framework frames (blackboxed)`;
11820
- outputLines.push(label);
12311
+ outputLines.push(color ? c(ansi.gray, label) : label);
11821
12312
  continue;
11822
12313
  }
11823
12314
  const frame = seg;
11824
12315
  if (frame.isAsync) {
11825
- outputLines.push("\u250A async gap");
12316
+ const gap = "\u250A async gap";
12317
+ outputLines.push(color ? c(ansi.gray, gap) : gap);
11826
12318
  }
11827
12319
  const ref = frame.ref.padEnd(maxRefLen);
11828
12320
  const name = frame.functionName.padEnd(maxNameLen);
11829
12321
  const file2 = shortPath(frame.file);
11830
12322
  const loc = frame.column !== undefined ? `${file2}:${frame.line}:${frame.column}` : `${file2}:${frame.line}`;
11831
- outputLines.push(`${ref} ${name} ${loc}`);
12323
+ if (color) {
12324
+ outputLines.push(`${c(ansi.gray, ref)} ${c(ansi.yellow, name)} ${c(ansi.gray, loc)}`);
12325
+ } else {
12326
+ outputLines.push(`${ref} ${name} ${loc}`);
12327
+ }
11832
12328
  }
11833
12329
  return outputLines.join(`
11834
12330
  `);
11835
12331
  }
11836
12332
  var init_stack = __esm(() => {
12333
+ init_color();
11837
12334
  init_path();
11838
12335
  });
11839
12336
 
11840
12337
  // src/formatter/variables.ts
11841
- function formatGroup(vars) {
12338
+ function formatGroup(vars, color) {
11842
12339
  if (vars.length === 0)
11843
12340
  return "";
11844
12341
  const maxRefLen = Math.max(...vars.map((v) => v.ref.length));
@@ -11846,13 +12343,17 @@ function formatGroup(vars) {
11846
12343
  return vars.map((v) => {
11847
12344
  const ref = v.ref.padEnd(maxRefLen);
11848
12345
  const name = v.name.padEnd(maxNameLen);
12346
+ if (color) {
12347
+ return `${c(ansi.gray, ref)} ${c(ansi.cyan, name)} ${v.value}`;
12348
+ }
11849
12349
  return `${ref} ${name} ${v.value}`;
11850
12350
  }).join(`
11851
12351
  `);
11852
12352
  }
11853
- function formatVariables(vars) {
12353
+ function formatVariables(vars, opts) {
11854
12354
  if (vars.length === 0)
11855
12355
  return "";
12356
+ const color = opts?.color ?? false;
11856
12357
  const scopeOrder = [];
11857
12358
  const groups = new Map;
11858
12359
  for (const v of vars) {
@@ -11866,7 +12367,7 @@ function formatVariables(vars) {
11866
12367
  group.push(v);
11867
12368
  }
11868
12369
  if (scopeOrder.length === 1) {
11869
- return formatGroup(vars);
12370
+ return formatGroup(vars, color);
11870
12371
  }
11871
12372
  const sections = [];
11872
12373
  for (const scope of scopeOrder) {
@@ -11874,8 +12375,9 @@ function formatVariables(vars) {
11874
12375
  if (!group || group.length === 0)
11875
12376
  continue;
11876
12377
  const label = SCOPE_LABELS[scope] ?? scope;
11877
- sections.push(`${label}:
11878
- ${formatGroup(group)}`);
12378
+ const header = color ? c(ansi.bold, `${label}:`) : `${label}:`;
12379
+ sections.push(`${header}
12380
+ ${formatGroup(group, color)}`);
11879
12381
  }
11880
12382
  return sections.join(`
11881
12383
 
@@ -11883,6 +12385,7 @@ ${formatGroup(group)}`);
11883
12385
  }
11884
12386
  var SCOPE_LABELS;
11885
12387
  var init_variables = __esm(() => {
12388
+ init_color();
11886
12389
  SCOPE_LABELS = {
11887
12390
  local: "Locals",
11888
12391
  module: "Module",
@@ -11897,25 +12400,52 @@ var init_variables = __esm(() => {
11897
12400
  });
11898
12401
 
11899
12402
  // src/commands/print-state.ts
11900
- function printState(data) {
12403
+ function printState(data, opts) {
12404
+ const color = opts?.color ?? false;
11901
12405
  if (data.status !== "paused") {
11902
12406
  const icon = data.status === "running" ? "\u25B6" : "\u25CB";
11903
- console.log(`${icon} ${data.status === "running" ? "Running" : "Idle"}`);
12407
+ const label = data.status === "running" ? "Running" : "Idle";
12408
+ if (data.lastException) {
12409
+ const desc = data.lastException.description ?? data.lastException.text;
12410
+ const firstLine = desc.split(`
12411
+ `)[0] ?? desc;
12412
+ if (color) {
12413
+ console.log(`${c(ansi.yellow, icon)} ${label} ${c(ansi.red, "(crashed)")}`);
12414
+ console.log(` ${c(ansi.red, firstLine)}`);
12415
+ console.log(` ${c(ansi.cyan, "-> Try:")} dbg exceptions`);
12416
+ } else {
12417
+ console.log(`${icon} ${label} (crashed)`);
12418
+ console.log(` ${firstLine}`);
12419
+ console.log(" -> Try: dbg exceptions");
12420
+ }
12421
+ } else {
12422
+ if (color) {
12423
+ const coloredIcon = data.status === "running" ? c(ansi.green, icon) : c(ansi.gray, icon);
12424
+ console.log(`${coloredIcon} ${label}`);
12425
+ } else {
12426
+ console.log(`${icon} ${label}`);
12427
+ }
12428
+ }
11904
12429
  return;
11905
12430
  }
11906
12431
  const loc = data.location ? `${shortPath(data.location.url)}:${data.location.line}${data.location.column !== undefined ? `:${data.location.column}` : ""}` : "unknown";
11907
12432
  const reason = data.reason ?? "unknown";
11908
- console.log(`\u23F8 Paused at ${loc} (${reason})`);
12433
+ if (color) {
12434
+ console.log(`${c(ansi.brightYellow, "\u23F8")} Paused at ${c(ansi.cyan, loc)} ${c(ansi.gray, `(${reason})`)}`);
12435
+ } else {
12436
+ console.log(`\u23F8 Paused at ${loc} (${reason})`);
12437
+ }
12438
+ const lang = data.location?.url ? detectLanguage(data.location.url) : "unknown";
11909
12439
  if (data.source?.lines) {
11910
12440
  console.log("");
11911
- console.log("Source:");
12441
+ console.log(color ? c(ansi.bold, "Source:") : "Source:");
11912
12442
  const sourceLines = data.source.lines.map((l) => ({
11913
12443
  lineNumber: l.line,
11914
12444
  content: l.text,
11915
12445
  isCurrent: l.current,
11916
12446
  currentColumn: l.current ? data.location?.column : undefined
11917
12447
  }));
11918
- console.log(formatSource(sourceLines));
12448
+ console.log(formatSource(sourceLines, { color, language: lang }));
11919
12449
  }
11920
12450
  if (data.vars) {
11921
12451
  console.log("");
@@ -11925,21 +12455,21 @@ function printState(data) {
11925
12455
  value: v.value,
11926
12456
  scope: v.scope
11927
12457
  }));
11928
- const formatted = formatVariables(vars);
12458
+ const formatted = formatVariables(vars, { color });
11929
12459
  if (formatted) {
11930
12460
  const scopes = new Set(vars.map((v) => v.scope ?? "local"));
11931
12461
  if (scopes.size <= 1) {
11932
- console.log("Locals:");
12462
+ console.log(color ? c(ansi.bold, "Locals:") : "Locals:");
11933
12463
  }
11934
12464
  console.log(formatted);
11935
12465
  } else {
11936
- console.log("Locals:");
12466
+ console.log(color ? c(ansi.bold, "Locals:") : "Locals:");
11937
12467
  console.log(" (none)");
11938
12468
  }
11939
12469
  }
11940
12470
  if (data.stack) {
11941
12471
  console.log("");
11942
- console.log("Stack:");
12472
+ console.log(color ? c(ansi.bold, "Stack:") : "Stack:");
11943
12473
  const frames = data.stack.map((f) => ({
11944
12474
  ref: f.ref,
11945
12475
  functionName: f.functionName,
@@ -11948,14 +12478,19 @@ function printState(data) {
11948
12478
  column: f.column,
11949
12479
  isAsync: f.isAsync
11950
12480
  }));
11951
- console.log(formatStack(frames));
12481
+ console.log(formatStack(frames, { color }));
11952
12482
  }
11953
12483
  if (data.breakpointCount !== undefined) {
11954
12484
  console.log("");
11955
- console.log(`Breakpoints: ${data.breakpointCount} active`);
12485
+ if (color) {
12486
+ console.log(`Breakpoints: ${c(ansi.yellow, String(data.breakpointCount))} active`);
12487
+ } else {
12488
+ console.log(`Breakpoints: ${data.breakpointCount} active`);
12489
+ }
11956
12490
  }
11957
12491
  }
11958
12492
  var init_print_state = __esm(() => {
12493
+ init_color();
11959
12494
  init_path();
11960
12495
  init_source();
11961
12496
  init_stack();
@@ -11967,12 +12502,13 @@ var exports_state = {};
11967
12502
  var init_state = __esm(() => {
11968
12503
  init_registry();
11969
12504
  init_client3();
12505
+ init_color();
11970
12506
  init_print_state();
11971
12507
  registerCommand("state", async (args) => {
11972
12508
  const session2 = args.global.session;
11973
12509
  if (!DaemonClient.isRunning(session2)) {
11974
12510
  console.error(`No active session "${session2}"`);
11975
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12511
+ console.error(" -> Try: dbg launch --brk node app.js");
11976
12512
  return 1;
11977
12513
  }
11978
12514
  const client = new DaemonClient(session2);
@@ -12012,7 +12548,7 @@ var init_state = __esm(() => {
12012
12548
  console.log(JSON.stringify(data, null, 2));
12013
12549
  return 0;
12014
12550
  }
12015
- printState(data);
12551
+ printState(data, { color: shouldEnableColor(args.global.color) });
12016
12552
  return 0;
12017
12553
  });
12018
12554
  });
@@ -12022,12 +12558,13 @@ var exports_continue = {};
12022
12558
  var init_continue = __esm(() => {
12023
12559
  init_registry();
12024
12560
  init_client3();
12561
+ init_color();
12025
12562
  init_print_state();
12026
12563
  registerCommand("continue", async (args) => {
12027
12564
  const session2 = args.global.session;
12028
12565
  if (!DaemonClient.isRunning(session2)) {
12029
12566
  console.error(`No active session "${session2}"`);
12030
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12567
+ console.error(" -> Try: dbg launch --brk node app.js");
12031
12568
  return 1;
12032
12569
  }
12033
12570
  const client = new DaemonClient(session2);
@@ -12042,7 +12579,7 @@ var init_continue = __esm(() => {
12042
12579
  if (args.global.json) {
12043
12580
  console.log(JSON.stringify(data, null, 2));
12044
12581
  } else {
12045
- printState(data);
12582
+ printState(data, { color: shouldEnableColor(args.global.color) });
12046
12583
  }
12047
12584
  return 0;
12048
12585
  });
@@ -12053,12 +12590,13 @@ var exports_step = {};
12053
12590
  var init_step = __esm(() => {
12054
12591
  init_registry();
12055
12592
  init_client3();
12593
+ init_color();
12056
12594
  init_print_state();
12057
12595
  registerCommand("step", async (args) => {
12058
12596
  const session2 = args.global.session;
12059
12597
  if (!DaemonClient.isRunning(session2)) {
12060
12598
  console.error(`No active session "${session2}"`);
12061
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12599
+ console.error(" -> Try: dbg launch --brk node app.js");
12062
12600
  return 1;
12063
12601
  }
12064
12602
  const validModes = new Set(["over", "into", "out"]);
@@ -12075,7 +12613,7 @@ var init_step = __esm(() => {
12075
12613
  if (args.global.json) {
12076
12614
  console.log(JSON.stringify(data, null, 2));
12077
12615
  } else {
12078
- printState(data);
12616
+ printState(data, { color: shouldEnableColor(args.global.color) });
12079
12617
  }
12080
12618
  return 0;
12081
12619
  });
@@ -12086,12 +12624,13 @@ var exports_pause = {};
12086
12624
  var init_pause = __esm(() => {
12087
12625
  init_registry();
12088
12626
  init_client3();
12627
+ init_color();
12089
12628
  init_print_state();
12090
12629
  registerCommand("pause", async (args) => {
12091
12630
  const session2 = args.global.session;
12092
12631
  if (!DaemonClient.isRunning(session2)) {
12093
12632
  console.error(`No active session "${session2}"`);
12094
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12633
+ console.error(" -> Try: dbg launch --brk node app.js");
12095
12634
  return 1;
12096
12635
  }
12097
12636
  const client = new DaemonClient(session2);
@@ -12106,7 +12645,7 @@ var init_pause = __esm(() => {
12106
12645
  if (args.global.json) {
12107
12646
  console.log(JSON.stringify(data, null, 2));
12108
12647
  } else {
12109
- printState(data);
12648
+ printState(data, { color: shouldEnableColor(args.global.color) });
12110
12649
  }
12111
12650
  return 0;
12112
12651
  });
@@ -12152,18 +12691,19 @@ var exports_run_to = {};
12152
12691
  var init_run_to = __esm(() => {
12153
12692
  init_registry();
12154
12693
  init_client3();
12694
+ init_color();
12155
12695
  init_print_state();
12156
12696
  registerCommand("run-to", async (args) => {
12157
12697
  const session2 = args.global.session;
12158
12698
  if (!DaemonClient.isRunning(session2)) {
12159
12699
  console.error(`No active session "${session2}"`);
12160
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12700
+ console.error(" -> Try: dbg launch --brk node app.js");
12161
12701
  return 1;
12162
12702
  }
12163
12703
  const target = args.subcommand ?? args.positionals[0];
12164
12704
  if (!target) {
12165
12705
  console.error("No target specified");
12166
- console.error(" -> Try: agent-dbg run-to src/file.ts:42");
12706
+ console.error(" -> Try: dbg run-to src/file.ts:42");
12167
12707
  return 1;
12168
12708
  }
12169
12709
  const parsed = parseFileLine(target);
@@ -12185,7 +12725,7 @@ var init_run_to = __esm(() => {
12185
12725
  if (args.global.json) {
12186
12726
  console.log(JSON.stringify(data, null, 2));
12187
12727
  } else {
12188
- printState(data);
12728
+ printState(data, { color: shouldEnableColor(args.global.color) });
12189
12729
  }
12190
12730
  return 0;
12191
12731
  });
@@ -12196,12 +12736,13 @@ var exports_break = {};
12196
12736
  var init_break = __esm(() => {
12197
12737
  init_registry();
12198
12738
  init_client3();
12739
+ init_color();
12199
12740
  init_path();
12200
12741
  registerCommand("break", async (args) => {
12201
12742
  const session2 = args.global.session;
12202
12743
  if (!DaemonClient.isRunning(session2)) {
12203
12744
  console.error(`No active session "${session2}"`);
12204
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12745
+ console.error(" -> Try: dbg launch --brk node app.js");
12205
12746
  return 1;
12206
12747
  }
12207
12748
  const patternFlag = typeof args.flags.pattern === "string" ? args.flags.pattern : undefined;
@@ -12213,7 +12754,7 @@ var init_break = __esm(() => {
12213
12754
  const lastColon = patternFlag.lastIndexOf(":");
12214
12755
  if (lastColon === -1 || lastColon === 0) {
12215
12756
  console.error(`Invalid --pattern target: "${patternFlag}"`);
12216
- console.error(" -> Try: agent-dbg break --pattern 'app\\.js':42");
12757
+ console.error(" -> Try: dbg break --pattern 'app\\.js':42");
12217
12758
  return 1;
12218
12759
  }
12219
12760
  file2 = patternFlag.slice(0, lastColon);
@@ -12226,13 +12767,13 @@ var init_break = __esm(() => {
12226
12767
  const target = args.subcommand;
12227
12768
  if (!target) {
12228
12769
  console.error("No target specified");
12229
- console.error(" -> Try: agent-dbg break src/app.ts:42");
12770
+ console.error(" -> Try: dbg break src/app.ts:42");
12230
12771
  return 1;
12231
12772
  }
12232
12773
  const parsed = parseFileLineColumn(target);
12233
12774
  if (!parsed) {
12234
12775
  console.error(`Invalid breakpoint target: "${target}"`);
12235
- console.error(" -> Try: agent-dbg break src/app.ts:42 or src/app.ts:42:5");
12776
+ console.error(" -> Try: dbg break src/app.ts:42 or src/app.ts:42:5");
12236
12777
  return 1;
12237
12778
  }
12238
12779
  file2 = parsed.file;
@@ -12260,8 +12801,13 @@ var init_break = __esm(() => {
12260
12801
  if (args.global.json) {
12261
12802
  console.log(JSON.stringify(data2, null, 2));
12262
12803
  } else {
12804
+ const color = shouldEnableColor(args.global.color);
12263
12805
  const loc = `${shortPath(data2.location.url)}:${data2.location.line}`;
12264
- console.log(`${data2.ref} set at ${loc} (log: ${logTemplate})`);
12806
+ if (color) {
12807
+ console.log(`${c(ansi.magenta, data2.ref)} set at ${c(ansi.cyan, loc)} (log: ${logTemplate})`);
12808
+ } else {
12809
+ console.log(`${data2.ref} set at ${loc} (log: ${logTemplate})`);
12810
+ }
12265
12811
  }
12266
12812
  return 0;
12267
12813
  }
@@ -12286,15 +12832,27 @@ var init_break = __esm(() => {
12286
12832
  if (args.global.json) {
12287
12833
  console.log(JSON.stringify(data, null, 2));
12288
12834
  } else {
12835
+ const color = shouldEnableColor(args.global.color);
12289
12836
  const loc = `${shortPath(data.location.url)}:${data.location.line}`;
12290
- let msg = `${data.ref} set at ${loc}`;
12291
- if (condition) {
12292
- msg += ` (condition: ${condition})`;
12293
- }
12294
- if (hitCount) {
12295
- msg += ` (hit-count: ${hitCount})`;
12837
+ if (color) {
12838
+ let msg = `${c(ansi.magenta, data.ref)} set at ${c(ansi.cyan, loc)}`;
12839
+ if (condition) {
12840
+ msg += ` ${c(ansi.gray, `(condition: ${condition})`)}`;
12841
+ }
12842
+ if (hitCount) {
12843
+ msg += ` ${c(ansi.gray, `(hit-count: ${hitCount})`)}`;
12844
+ }
12845
+ console.log(msg);
12846
+ } else {
12847
+ let msg = `${data.ref} set at ${loc}`;
12848
+ if (condition) {
12849
+ msg += ` (condition: ${condition})`;
12850
+ }
12851
+ if (hitCount) {
12852
+ msg += ` (hit-count: ${hitCount})`;
12853
+ }
12854
+ console.log(msg);
12296
12855
  }
12297
- console.log(msg);
12298
12856
  }
12299
12857
  if (shouldContinue) {
12300
12858
  const contResponse = await client.request("continue");
@@ -12319,14 +12877,14 @@ var init_break_fn = __esm(() => {
12319
12877
  const session2 = args.global.session;
12320
12878
  if (!DaemonClient.isRunning(session2)) {
12321
12879
  console.error(`No active session "${session2}"`);
12322
- console.error(" -> Try: agent-dbg launch --brk --runtime lldb ./program");
12880
+ console.error(" -> Try: dbg launch --brk --runtime lldb ./program");
12323
12881
  return 1;
12324
12882
  }
12325
12883
  const name = args.subcommand;
12326
12884
  if (!name) {
12327
- console.error("Usage: agent-dbg break-fn <function-name>");
12328
- console.error(" Example: agent-dbg break-fn __assert_rtn");
12329
- console.error(" Example: agent-dbg break-fn 'yoga::Style::operator=='");
12885
+ console.error("Usage: dbg break-fn <function-name>");
12886
+ console.error(" Example: dbg break-fn __assert_rtn");
12887
+ console.error(" Example: dbg break-fn 'yoga::Style::operator=='");
12330
12888
  return 1;
12331
12889
  }
12332
12890
  const condition = typeof args.flags.condition === "string" ? args.flags.condition : undefined;
@@ -12357,13 +12915,13 @@ var init_break_rm = __esm(() => {
12357
12915
  const session2 = args.global.session;
12358
12916
  if (!DaemonClient.isRunning(session2)) {
12359
12917
  console.error(`No active session "${session2}"`);
12360
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12918
+ console.error(" -> Try: dbg launch --brk node app.js");
12361
12919
  return 1;
12362
12920
  }
12363
12921
  const ref = args.subcommand;
12364
12922
  if (!ref) {
12365
12923
  console.error("No breakpoint ref specified");
12366
- console.error(" -> Try: agent-dbg break-rm BP#1");
12924
+ console.error(" -> Try: dbg break-rm BP#1");
12367
12925
  return 1;
12368
12926
  }
12369
12927
  const client = new DaemonClient(session2);
@@ -12392,12 +12950,13 @@ var exports_break_ls = {};
12392
12950
  var init_break_ls = __esm(() => {
12393
12951
  init_registry();
12394
12952
  init_client3();
12953
+ init_color();
12395
12954
  init_path();
12396
12955
  registerCommand("break-ls", async (args) => {
12397
12956
  const session2 = args.global.session;
12398
12957
  if (!DaemonClient.isRunning(session2)) {
12399
12958
  console.error(`No active session "${session2}"`);
12400
- console.error(" -> Try: agent-dbg launch --brk node app.js");
12959
+ console.error(" -> Try: dbg launch --brk node app.js");
12401
12960
  return 1;
12402
12961
  }
12403
12962
  const client = new DaemonClient(session2);
@@ -12412,22 +12971,37 @@ var init_break_ls = __esm(() => {
12412
12971
  if (args.global.json) {
12413
12972
  console.log(JSON.stringify(data, null, 2));
12414
12973
  } else {
12974
+ const color = shouldEnableColor(args.global.color);
12415
12975
  if (data.length === 0) {
12416
12976
  console.log("No breakpoints or logpoints set");
12417
12977
  } else {
12418
12978
  for (const bp of data) {
12419
12979
  const loc = `${shortPath(bp.url)}:${bp.line}`;
12420
- let line = `${bp.ref} ${loc}`;
12421
- if (bp.type === "LP" && bp.template) {
12422
- line += ` (log: ${bp.template})`;
12423
- }
12424
- if (bp.condition) {
12425
- line += ` [condition: ${bp.condition}]`;
12426
- }
12427
- if (bp.hitCount) {
12428
- line += ` [hit-count: ${bp.hitCount}]`;
12980
+ if (color) {
12981
+ let line = `${c(ansi.magenta, bp.ref)} ${c(ansi.cyan, loc)}`;
12982
+ if (bp.type === "LP" && bp.template) {
12983
+ line += ` ${c(ansi.green, `(log: ${bp.template})`)}`;
12984
+ }
12985
+ if (bp.condition) {
12986
+ line += ` ${c(ansi.gray, `[condition: ${bp.condition}]`)}`;
12987
+ }
12988
+ if (bp.hitCount) {
12989
+ line += ` ${c(ansi.gray, `[hit-count: ${bp.hitCount}]`)}`;
12990
+ }
12991
+ console.log(line);
12992
+ } else {
12993
+ let line = `${bp.ref} ${loc}`;
12994
+ if (bp.type === "LP" && bp.template) {
12995
+ line += ` (log: ${bp.template})`;
12996
+ }
12997
+ if (bp.condition) {
12998
+ line += ` [condition: ${bp.condition}]`;
12999
+ }
13000
+ if (bp.hitCount) {
13001
+ line += ` [hit-count: ${bp.hitCount}]`;
13002
+ }
13003
+ console.log(line);
12429
13004
  }
12430
- console.log(line);
12431
13005
  }
12432
13006
  }
12433
13007
  }
@@ -12445,26 +13019,26 @@ var init_logpoint = __esm(() => {
12445
13019
  const session2 = args.global.session;
12446
13020
  if (!DaemonClient.isRunning(session2)) {
12447
13021
  console.error(`No active session "${session2}"`);
12448
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13022
+ console.error(" -> Try: dbg launch --brk node app.js");
12449
13023
  return 1;
12450
13024
  }
12451
13025
  const target = args.subcommand;
12452
13026
  if (!target) {
12453
13027
  console.error("No target specified");
12454
- console.error(' -> Try: agent-dbg logpoint src/app.ts:42 "x =", x');
13028
+ console.error(' -> Try: dbg logpoint src/app.ts:42 "x =", x');
12455
13029
  return 1;
12456
13030
  }
12457
13031
  const parsed = parseFileLine(target);
12458
13032
  if (!parsed) {
12459
13033
  console.error(`Invalid logpoint target: "${target}"`);
12460
- console.error(' -> Try: agent-dbg logpoint src/app.ts:42 "x =", x');
13034
+ console.error(' -> Try: dbg logpoint src/app.ts:42 "x =", x');
12461
13035
  return 1;
12462
13036
  }
12463
13037
  const { file: file2, line } = parsed;
12464
13038
  const template = args.positionals[0];
12465
13039
  if (!template) {
12466
13040
  console.error("No log template specified");
12467
- console.error(' -> Try: agent-dbg logpoint src/app.ts:42 "x =", x');
13041
+ console.error(' -> Try: dbg logpoint src/app.ts:42 "x =", x');
12468
13042
  return 1;
12469
13043
  }
12470
13044
  const condition = typeof args.flags.condition === "string" ? args.flags.condition : undefined;
@@ -12505,13 +13079,13 @@ var init_catch = __esm(() => {
12505
13079
  const session2 = args.global.session;
12506
13080
  if (!DaemonClient.isRunning(session2)) {
12507
13081
  console.error(`No active session "${session2}"`);
12508
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13082
+ console.error(" -> Try: dbg launch --brk node app.js");
12509
13083
  return 1;
12510
13084
  }
12511
13085
  const mode = args.subcommand ?? "all";
12512
13086
  if (!VALID_MODES.has(mode)) {
12513
13087
  console.error(`Invalid catch mode: "${mode}"`);
12514
- console.error(" -> Try: agent-dbg catch [all | uncaught | caught | none]");
13088
+ console.error(" -> Try: dbg catch [all | uncaught | caught | none]");
12515
13089
  return 1;
12516
13090
  }
12517
13091
  const client = new DaemonClient(session2);
@@ -12536,13 +13110,14 @@ var exports_source = {};
12536
13110
  var init_source2 = __esm(() => {
12537
13111
  init_registry();
12538
13112
  init_client3();
13113
+ init_color();
12539
13114
  init_path();
12540
13115
  init_source();
12541
13116
  registerCommand("source", async (args) => {
12542
13117
  const session2 = args.global.session;
12543
13118
  if (!DaemonClient.isRunning(session2)) {
12544
13119
  console.error(`No active session "${session2}"`);
12545
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13120
+ console.error(" -> Try: dbg launch --brk node app.js");
12546
13121
  return 1;
12547
13122
  }
12548
13123
  const client = new DaemonClient(session2);
@@ -12571,13 +13146,14 @@ var init_source2 = __esm(() => {
12571
13146
  console.log(JSON.stringify(data, null, 2));
12572
13147
  return 0;
12573
13148
  }
13149
+ const color = shouldEnableColor(args.global.color);
12574
13150
  console.log(`Source: ${shortPath(data.url)}`);
12575
13151
  const sourceLines = data.lines.map((l) => ({
12576
13152
  lineNumber: l.line,
12577
13153
  content: l.text,
12578
13154
  isCurrent: l.current
12579
13155
  }));
12580
- console.log(formatSource(sourceLines));
13156
+ console.log(formatSource(sourceLines, { color, language: detectLanguage(data.url) }));
12581
13157
  return 0;
12582
13158
  });
12583
13159
  });
@@ -12591,7 +13167,7 @@ var init_scripts = __esm(() => {
12591
13167
  const session2 = args.global.session;
12592
13168
  if (!DaemonClient.isRunning(session2)) {
12593
13169
  console.error(`No active session "${session2}"`);
12594
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13170
+ console.error(" -> Try: dbg launch --brk node app.js");
12595
13171
  return 1;
12596
13172
  }
12597
13173
  const client = new DaemonClient(session2);
@@ -12628,6 +13204,52 @@ var init_scripts = __esm(() => {
12628
13204
  });
12629
13205
  });
12630
13206
 
13207
+ // src/commands/modules.ts
13208
+ var exports_modules = {};
13209
+ var init_modules = __esm(() => {
13210
+ init_registry();
13211
+ init_client3();
13212
+ registerCommand("modules", async (args) => {
13213
+ const session2 = args.global.session;
13214
+ if (!DaemonClient.isRunning(session2)) {
13215
+ console.error(`No active session "${session2}"`);
13216
+ console.error(" -> Try: dbg launch --brk node app.js");
13217
+ return 1;
13218
+ }
13219
+ const client = new DaemonClient(session2);
13220
+ const modulesArgs = {};
13221
+ const filter = args.subcommand ?? (typeof args.flags.filter === "string" ? args.flags.filter : undefined);
13222
+ if (filter) {
13223
+ modulesArgs.filter = filter;
13224
+ }
13225
+ const response = await client.request("modules", modulesArgs);
13226
+ if (!response.ok) {
13227
+ console.error(`${response.error}`);
13228
+ if (response.suggestion)
13229
+ console.error(` ${response.suggestion}`);
13230
+ return 1;
13231
+ }
13232
+ const data = response.data;
13233
+ if (args.global.json) {
13234
+ console.log(JSON.stringify(data, null, 2));
13235
+ return 0;
13236
+ }
13237
+ if (data.length === 0) {
13238
+ console.log("No modules loaded");
13239
+ return 0;
13240
+ }
13241
+ const nameWidth = Math.max(...data.map((m) => m.name.length), 4);
13242
+ const statusWidth = Math.max(...data.map((m) => (m.symbolStatus ?? "").length), 7);
13243
+ for (const mod of data) {
13244
+ const name = mod.name.padEnd(nameWidth);
13245
+ const status = (mod.symbolStatus ?? "unknown").padEnd(statusWidth);
13246
+ const path = mod.path ?? "";
13247
+ console.log(` ${name} ${status} ${path}`);
13248
+ }
13249
+ return 0;
13250
+ });
13251
+ });
13252
+
12631
13253
  // src/commands/stack.ts
12632
13254
  var exports_stack = {};
12633
13255
  var init_stack2 = __esm(() => {
@@ -12638,7 +13260,7 @@ var init_stack2 = __esm(() => {
12638
13260
  const session2 = args.global.session;
12639
13261
  if (!DaemonClient.isRunning(session2)) {
12640
13262
  console.error(`No active session "${session2}"`);
12641
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13263
+ console.error(" -> Try: dbg launch --brk node app.js");
12642
13264
  return 1;
12643
13265
  }
12644
13266
  const client = new DaemonClient(session2);
@@ -12649,6 +13271,9 @@ var init_stack2 = __esm(() => {
12649
13271
  if (args.flags.generated === true) {
12650
13272
  stackArgs.generated = true;
12651
13273
  }
13274
+ if (typeof args.flags.filter === "string") {
13275
+ stackArgs.filter = args.flags.filter;
13276
+ }
12652
13277
  const response = await client.request("stack", stackArgs);
12653
13278
  if (!response.ok) {
12654
13279
  console.error(`${response.error}`);
@@ -12688,7 +13313,7 @@ var init_search = __esm(() => {
12688
13313
  const session2 = args.global.session;
12689
13314
  if (!DaemonClient.isRunning(session2)) {
12690
13315
  console.error(`No active session "${session2}"`);
12691
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13316
+ console.error(" -> Try: dbg launch --brk node app.js");
12692
13317
  return 1;
12693
13318
  }
12694
13319
  const parts = [];
@@ -12701,7 +13326,7 @@ var init_search = __esm(() => {
12701
13326
  const query = parts.join(" ");
12702
13327
  if (!query) {
12703
13328
  console.error("No search query specified");
12704
- console.error(" -> Try: agent-dbg search <query> [--regex] [--case-sensitive]");
13329
+ console.error(" -> Try: dbg search <query> [--regex] [--case-sensitive]");
12705
13330
  return 1;
12706
13331
  }
12707
13332
  const client = new DaemonClient(session2);
@@ -12756,7 +13381,7 @@ var init_console = __esm(() => {
12756
13381
  const session2 = args.global.session;
12757
13382
  if (!DaemonClient.isRunning(session2)) {
12758
13383
  console.error(`No active session "${session2}"`);
12759
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13384
+ console.error(" -> Try: dbg launch --brk node app.js");
12760
13385
  return 1;
12761
13386
  }
12762
13387
  const client = new DaemonClient(session2);
@@ -12803,7 +13428,7 @@ var init_exceptions = __esm(() => {
12803
13428
  const session2 = args.global.session;
12804
13429
  if (!DaemonClient.isRunning(session2)) {
12805
13430
  console.error(`No active session "${session2}"`);
12806
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13431
+ console.error(" -> Try: dbg launch --brk node app.js");
12807
13432
  return 1;
12808
13433
  }
12809
13434
  const client = new DaemonClient(session2);
@@ -12850,7 +13475,7 @@ var init_eval = __esm(() => {
12850
13475
  const session2 = args.global.session;
12851
13476
  if (!DaemonClient.isRunning(session2)) {
12852
13477
  console.error(`No active session "${session2}"`);
12853
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13478
+ console.error(" -> Try: dbg launch --brk node app.js");
12854
13479
  return 1;
12855
13480
  }
12856
13481
  const parts = [];
@@ -12861,7 +13486,7 @@ var init_eval = __esm(() => {
12861
13486
  const expression = parts.join(" ");
12862
13487
  if (!expression) {
12863
13488
  console.error("No expression specified");
12864
- console.error(" -> Try: agent-dbg eval 1 + 2");
13489
+ console.error(" -> Try: dbg eval 1 + 2");
12865
13490
  return 1;
12866
13491
  }
12867
13492
  const evalArgs = {
@@ -12910,7 +13535,7 @@ var init_vars = __esm(() => {
12910
13535
  const session2 = args.global.session;
12911
13536
  if (!DaemonClient.isRunning(session2)) {
12912
13537
  console.error(`No active session "${session2}"`);
12913
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13538
+ console.error(" -> Try: dbg launch --brk node app.js");
12914
13539
  return 1;
12915
13540
  }
12916
13541
  const names = [];
@@ -12968,13 +13593,13 @@ var init_props = __esm(() => {
12968
13593
  const session2 = args.global.session;
12969
13594
  if (!DaemonClient.isRunning(session2)) {
12970
13595
  console.error(`No active session "${session2}"`);
12971
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13596
+ console.error(" -> Try: dbg launch --brk node app.js");
12972
13597
  return 1;
12973
13598
  }
12974
13599
  const ref = args.subcommand;
12975
13600
  if (!ref) {
12976
13601
  console.error("No ref specified");
12977
- console.error(" -> Try: agent-dbg props @v1");
13602
+ console.error(" -> Try: dbg props @v1");
12978
13603
  return 1;
12979
13604
  }
12980
13605
  const propsArgs = {
@@ -13030,7 +13655,7 @@ var init_blackbox = __esm(() => {
13030
13655
  const session2 = args.global.session;
13031
13656
  if (!DaemonClient.isRunning(session2)) {
13032
13657
  console.error(`No active session "${session2}"`);
13033
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13658
+ console.error(" -> Try: dbg launch --brk node app.js");
13034
13659
  return 1;
13035
13660
  }
13036
13661
  const patterns = [];
@@ -13042,7 +13667,7 @@ var init_blackbox = __esm(() => {
13042
13667
  }
13043
13668
  if (patterns.length === 0) {
13044
13669
  console.error("No patterns specified");
13045
- console.error(" -> Try: agent-dbg blackbox node_modules");
13670
+ console.error(" -> Try: dbg blackbox node_modules");
13046
13671
  return 1;
13047
13672
  }
13048
13673
  const client = new DaemonClient(session2);
@@ -13075,7 +13700,7 @@ var init_blackbox_ls = __esm(() => {
13075
13700
  const session2 = args.global.session;
13076
13701
  if (!DaemonClient.isRunning(session2)) {
13077
13702
  console.error(`No active session "${session2}"`);
13078
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13703
+ console.error(" -> Try: dbg launch --brk node app.js");
13079
13704
  return 1;
13080
13705
  }
13081
13706
  const client = new DaemonClient(session2);
@@ -13112,7 +13737,7 @@ var init_blackbox_rm = __esm(() => {
13112
13737
  const session2 = args.global.session;
13113
13738
  if (!DaemonClient.isRunning(session2)) {
13114
13739
  console.error(`No active session "${session2}"`);
13115
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13740
+ console.error(" -> Try: dbg launch --brk node app.js");
13116
13741
  return 1;
13117
13742
  }
13118
13743
  const patterns = [];
@@ -13128,8 +13753,8 @@ var init_blackbox_rm = __esm(() => {
13128
13753
  }
13129
13754
  if (patterns.length === 0) {
13130
13755
  console.error("No patterns specified");
13131
- console.error(" -> Try: agent-dbg blackbox-rm node_modules");
13132
- console.error(" -> Try: agent-dbg blackbox-rm all");
13756
+ console.error(" -> Try: dbg blackbox-rm node_modules");
13757
+ console.error(" -> Try: dbg blackbox-rm all");
13133
13758
  return 1;
13134
13759
  }
13135
13760
  const client = new DaemonClient(session2);
@@ -13166,19 +13791,19 @@ var init_set = __esm(() => {
13166
13791
  const session2 = args.global.session;
13167
13792
  if (!DaemonClient.isRunning(session2)) {
13168
13793
  console.error(`No active session "${session2}"`);
13169
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13794
+ console.error(" -> Try: dbg launch --brk node app.js");
13170
13795
  return 1;
13171
13796
  }
13172
13797
  const varName = args.subcommand;
13173
13798
  if (!varName) {
13174
13799
  console.error("No variable name specified");
13175
- console.error(" -> Try: agent-dbg set counter 42");
13800
+ console.error(" -> Try: dbg set counter 42");
13176
13801
  return 1;
13177
13802
  }
13178
13803
  const valueParts = args.positionals;
13179
13804
  if (valueParts.length === 0) {
13180
13805
  console.error("No value specified");
13181
- console.error(" -> Try: agent-dbg set counter 42");
13806
+ console.error(" -> Try: dbg set counter 42");
13182
13807
  return 1;
13183
13808
  }
13184
13809
  const value = valueParts.join(" ");
@@ -13216,7 +13841,7 @@ var init_set_return = __esm(() => {
13216
13841
  const session2 = args.global.session;
13217
13842
  if (!DaemonClient.isRunning(session2)) {
13218
13843
  console.error(`No active session "${session2}"`);
13219
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13844
+ console.error(" -> Try: dbg launch --brk node app.js");
13220
13845
  return 1;
13221
13846
  }
13222
13847
  const parts = [];
@@ -13227,7 +13852,7 @@ var init_set_return = __esm(() => {
13227
13852
  const value = parts.join(" ");
13228
13853
  if (!value) {
13229
13854
  console.error("No value specified");
13230
- console.error(" -> Try: agent-dbg set-return 42");
13855
+ console.error(" -> Try: dbg set-return 42");
13231
13856
  return 1;
13232
13857
  }
13233
13858
  const client = new DaemonClient(session2);
@@ -13257,13 +13882,13 @@ var init_hotpatch = __esm(() => {
13257
13882
  const session2 = args.global.session;
13258
13883
  if (!DaemonClient.isRunning(session2)) {
13259
13884
  console.error(`No active session "${session2}"`);
13260
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13885
+ console.error(" -> Try: dbg launch --brk node app.js");
13261
13886
  return 1;
13262
13887
  }
13263
13888
  const file2 = args.subcommand;
13264
13889
  if (!file2) {
13265
13890
  console.error("No file specified");
13266
- console.error(" -> Try: agent-dbg hotpatch app.js");
13891
+ console.error(" -> Try: dbg hotpatch app.js");
13267
13892
  return 1;
13268
13893
  }
13269
13894
  let source;
@@ -13312,13 +13937,13 @@ var init_break_toggle = __esm(() => {
13312
13937
  const session2 = args.global.session;
13313
13938
  if (!DaemonClient.isRunning(session2)) {
13314
13939
  console.error(`No active session "${session2}"`);
13315
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13940
+ console.error(" -> Try: dbg launch --brk node app.js");
13316
13941
  return 1;
13317
13942
  }
13318
13943
  const ref = args.subcommand;
13319
13944
  if (!ref) {
13320
13945
  console.error("No breakpoint ref specified");
13321
- console.error(" -> Try: agent-dbg break-toggle BP#1");
13946
+ console.error(" -> Try: dbg break-toggle BP#1");
13322
13947
  return 1;
13323
13948
  }
13324
13949
  const client = new DaemonClient(session2);
@@ -13352,13 +13977,13 @@ var init_breakable = __esm(() => {
13352
13977
  const session2 = args.global.session;
13353
13978
  if (!DaemonClient.isRunning(session2)) {
13354
13979
  console.error(`No active session "${session2}"`);
13355
- console.error(" -> Try: agent-dbg launch --brk node app.js");
13980
+ console.error(" -> Try: dbg launch --brk node app.js");
13356
13981
  return 1;
13357
13982
  }
13358
13983
  const target = args.subcommand;
13359
13984
  if (!target) {
13360
13985
  console.error("No target specified");
13361
- console.error(" -> Try: agent-dbg breakable src/app.ts:10-20");
13986
+ console.error(" -> Try: dbg breakable src/app.ts:10-20");
13362
13987
  return 1;
13363
13988
  }
13364
13989
  const lastColon = target.lastIndexOf(":");
@@ -13415,7 +14040,7 @@ var init_restart_frame = __esm(() => {
13415
14040
  const session2 = args.global.session;
13416
14041
  if (!DaemonClient.isRunning(session2)) {
13417
14042
  console.error(`No active session "${session2}"`);
13418
- console.error(" -> Try: agent-dbg launch --brk node app.js");
14043
+ console.error(" -> Try: dbg launch --brk node app.js");
13419
14044
  return 1;
13420
14045
  }
13421
14046
  const frameRef = args.subcommand ?? undefined;
@@ -13448,7 +14073,7 @@ var init_sourcemap = __esm(() => {
13448
14073
  const session2 = args.global.session;
13449
14074
  if (!DaemonClient.isRunning(session2)) {
13450
14075
  console.error(`No active session "${session2}"`);
13451
- console.error(" -> Try: agent-dbg launch --brk node app.js");
14076
+ console.error(" -> Try: dbg launch --brk node app.js");
13452
14077
  return 1;
13453
14078
  }
13454
14079
  const client = new DaemonClient(session2);
@@ -13491,6 +14116,148 @@ var init_sourcemap = __esm(() => {
13491
14116
  });
13492
14117
  });
13493
14118
 
14119
+ // src/commands/install.ts
14120
+ var exports_install = {};
14121
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
14122
+ import { join as join3 } from "path";
14123
+ function getPlatformArch() {
14124
+ const os = process.platform;
14125
+ const arch = process.arch;
14126
+ return { os, arch };
14127
+ }
14128
+ function getLlvmDownloadUrl(version, os, arch) {
14129
+ if (os === "darwin") {
14130
+ if (arch === "arm64") {
14131
+ return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/LLVM-${version}-macOS-ARM64.tar.xz`;
14132
+ }
14133
+ if (arch === "x64") {
14134
+ return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/LLVM-${version}-macOS-X64.tar.xz`;
14135
+ }
14136
+ }
14137
+ if (os === "linux") {
14138
+ if (arch === "x64") {
14139
+ return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/LLVM-${version}-Linux-X64.tar.xz`;
14140
+ }
14141
+ if (arch === "arm64") {
14142
+ return `https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/LLVM-${version}-Linux-AArch64.tar.xz`;
14143
+ }
14144
+ }
14145
+ return null;
14146
+ }
14147
+ var LLVM_VERSION = "19.1.7";
14148
+ var init_install = __esm(() => {
14149
+ init_registry();
14150
+ init_session();
14151
+ registerCommand("install", async (args) => {
14152
+ const adapter = args.subcommand;
14153
+ if (args.flags.list === true) {
14154
+ const dir = getManagedAdaptersDir();
14155
+ console.log(`Managed adapters directory: ${dir}`);
14156
+ if (!existsSync6(dir)) {
14157
+ console.log(" (empty \u2014 no adapters installed)");
14158
+ return 0;
14159
+ }
14160
+ const entries = Array.from(new Bun.Glob("*").scanSync(dir));
14161
+ if (entries.length === 0) {
14162
+ console.log(" (empty \u2014 no adapters installed)");
14163
+ } else {
14164
+ for (const entry of entries) {
14165
+ console.log(` ${entry}`);
14166
+ }
14167
+ }
14168
+ return 0;
14169
+ }
14170
+ if (!adapter) {
14171
+ console.error("Usage: dbg install <adapter>");
14172
+ console.error(" Supported adapters: lldb");
14173
+ console.error(" Options: --list (show installed adapters)");
14174
+ return 1;
14175
+ }
14176
+ if (adapter !== "lldb") {
14177
+ console.error(`Unknown adapter: ${adapter}`);
14178
+ console.error(" Supported adapters: lldb");
14179
+ return 1;
14180
+ }
14181
+ const { os, arch } = getPlatformArch();
14182
+ const url2 = getLlvmDownloadUrl(LLVM_VERSION, os, arch);
14183
+ if (!url2) {
14184
+ console.error(`Unsupported platform: ${os}-${arch}`);
14185
+ console.error(" Supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64");
14186
+ return 1;
14187
+ }
14188
+ const adaptersDir = getManagedAdaptersDir();
14189
+ const targetPath = join3(adaptersDir, "lldb-dap");
14190
+ if (existsSync6(targetPath)) {
14191
+ console.log(`lldb-dap already installed at ${targetPath}`);
14192
+ console.log(` To reinstall, remove it first: rm ${targetPath}`);
14193
+ return 0;
14194
+ }
14195
+ console.log(`Downloading LLVM ${LLVM_VERSION} for ${os}-${arch}...`);
14196
+ console.log(` From: ${url2}`);
14197
+ const response = await fetch(url2, { redirect: "follow" });
14198
+ if (!response.ok) {
14199
+ console.error(`Download failed: HTTP ${response.status}`);
14200
+ console.error(" -> Check your internet connection or try again later");
14201
+ return 1;
14202
+ }
14203
+ const tarball = await response.arrayBuffer();
14204
+ console.log(`Downloaded ${(tarball.byteLength / 1024 / 1024).toFixed(1)} MB`);
14205
+ mkdirSync2(adaptersDir, { recursive: true });
14206
+ const tmpTar = join3(adaptersDir, "llvm-download.tar.xz");
14207
+ await Bun.write(tmpTar, tarball);
14208
+ console.log("Extracting lldb-dap...");
14209
+ const listResult = Bun.spawnSync(["tar", "-tf", tmpTar], {
14210
+ stdout: "pipe"
14211
+ });
14212
+ const files = listResult.stdout.toString().split(`
14213
+ `);
14214
+ const lldbDapEntry = files.find((f) => f.endsWith("/bin/lldb-dap") || f === "bin/lldb-dap");
14215
+ if (!lldbDapEntry) {
14216
+ Bun.spawnSync(["rm", tmpTar]);
14217
+ console.error("Could not find lldb-dap in the LLVM archive");
14218
+ console.error(` Archive entries searched: ${files.length}`);
14219
+ console.error(" -> Try installing manually: brew install llvm");
14220
+ return 1;
14221
+ }
14222
+ const extractResult = Bun.spawnSync([
14223
+ "tar",
14224
+ "-xf",
14225
+ tmpTar,
14226
+ "-C",
14227
+ adaptersDir,
14228
+ "--strip-components",
14229
+ String(lldbDapEntry.split("/").length - 1),
14230
+ lldbDapEntry
14231
+ ], { stdout: "pipe", stderr: "pipe" });
14232
+ Bun.spawnSync(["rm", tmpTar]);
14233
+ if (extractResult.exitCode !== 0) {
14234
+ console.error(`Extraction failed: ${extractResult.stderr.toString()}`);
14235
+ return 1;
14236
+ }
14237
+ const liblldbEntries = files.filter((f) => f.includes("liblldb") && (f.endsWith(".so") || f.endsWith(".dylib")));
14238
+ for (const libEntry of liblldbEntries) {
14239
+ Bun.spawnSync([
14240
+ "tar",
14241
+ "-xf",
14242
+ tmpTar,
14243
+ "-C",
14244
+ adaptersDir,
14245
+ "--strip-components",
14246
+ String(libEntry.split("/").length - 1),
14247
+ libEntry
14248
+ ], { stdout: "pipe", stderr: "pipe" });
14249
+ }
14250
+ Bun.spawnSync(["chmod", "+x", targetPath]);
14251
+ if (existsSync6(targetPath)) {
14252
+ console.log(`Installed lldb-dap to ${targetPath}`);
14253
+ return 0;
14254
+ }
14255
+ console.error("Installation failed \u2014 lldb-dap not found after extraction");
14256
+ console.error(" -> Try installing manually: brew install llvm");
14257
+ return 1;
14258
+ });
14259
+ });
14260
+
13494
14261
  // src/formatter/logs.ts
13495
14262
  function formatTime(ts) {
13496
14263
  const d = new Date(ts);
@@ -13609,7 +14376,7 @@ var init_logs = __esm(() => {
13609
14376
  var exports_logs = {};
13610
14377
  import {
13611
14378
  closeSync as closeSync2,
13612
- existsSync as existsSync5,
14379
+ existsSync as existsSync7,
13613
14380
  openSync as openSync2,
13614
14381
  readFileSync as readFileSync3,
13615
14382
  readSync,
@@ -13673,7 +14440,7 @@ var init_logs2 = __esm(() => {
13673
14440
  const isDaemon = args.flags.daemon === true;
13674
14441
  const logPath = isDaemon ? getDaemonLogPath(session2) : getLogPath(session2);
13675
14442
  if (args.flags.clear === true) {
13676
- if (existsSync5(logPath)) {
14443
+ if (existsSync7(logPath)) {
13677
14444
  writeFileSync4(logPath, "");
13678
14445
  console.log(`${isDaemon ? "Daemon log" : "Log"} cleared`);
13679
14446
  } else {
@@ -13681,9 +14448,9 @@ var init_logs2 = __esm(() => {
13681
14448
  }
13682
14449
  return 0;
13683
14450
  }
13684
- if (!existsSync5(logPath)) {
14451
+ if (!existsSync7(logPath)) {
13685
14452
  console.error(`No ${isDaemon ? "daemon " : ""}log file for session "${session2}"`);
13686
- console.error(" -> Try: agent-dbg launch --brk node app.js");
14453
+ console.error(" -> Try: dbg launch --brk node app.js");
13687
14454
  return 1;
13688
14455
  }
13689
14456
  const isJson = args.global.json;
@@ -13748,16 +14515,16 @@ var init_logs2 = __esm(() => {
13748
14515
  // package.json
13749
14516
  var require_package = __commonJS((exports, module) => {
13750
14517
  module.exports = {
13751
- name: "agent-dbg",
13752
- version: "0.2.0",
14518
+ name: "debug-that",
14519
+ version: "0.2.1",
13753
14520
  description: "Node.js Debugger CLI for AI Agents",
13754
14521
  license: "MIT",
13755
14522
  author: "Theodo Group",
13756
14523
  repository: {
13757
14524
  type: "git",
13758
- url: "https://github.com/theodo-group/agent-dbg.git"
14525
+ url: "https://github.com/theodo-group/debug-that.git"
13759
14526
  },
13760
- homepage: "https://github.com/theodo-group/agent-dbg",
14527
+ homepage: "https://github.com/theodo-group/debug-that",
13761
14528
  keywords: [
13762
14529
  "debugger",
13763
14530
  "cli",
@@ -13771,7 +14538,8 @@ var require_package = __commonJS((exports, module) => {
13771
14538
  ],
13772
14539
  type: "module",
13773
14540
  bin: {
13774
- "agent-dbg": "./dist/main.js"
14541
+ "debug-that": "./dist/main.js",
14542
+ dbg: "./dist/main.js"
13775
14543
  },
13776
14544
  files: [
13777
14545
  "dist",
@@ -13912,9 +14680,9 @@ async function run(args) {
13912
14680
  const suggestion = suggestCommand(args.command);
13913
14681
  console.error(`\u2717 Unknown command: ${args.command}`);
13914
14682
  if (suggestion) {
13915
- console.error(` \u2192 Did you mean: agent-dbg ${suggestion}`);
14683
+ console.error(` \u2192 Did you mean: dbg ${suggestion}`);
13916
14684
  } else {
13917
- console.error(" \u2192 Try: agent-dbg --help");
14685
+ console.error(" \u2192 Try: dbg --help");
13918
14686
  }
13919
14687
  return 1;
13920
14688
  }
@@ -13932,7 +14700,7 @@ async function run(args) {
13932
14700
  }
13933
14701
  function printVersion() {
13934
14702
  const pkg = require_package();
13935
- console.log(`agent-dbg ${pkg.version}`);
14703
+ console.log(`dbg ${pkg.version}`);
13936
14704
  }
13937
14705
  function suggestCommand(input) {
13938
14706
  let bestMatch = null;
@@ -13961,9 +14729,9 @@ function editDistance(a, b) {
13961
14729
  return prev[n] ?? m;
13962
14730
  }
13963
14731
  function printHelp() {
13964
- console.log(`agent-dbg \u2014 Node.js debugger CLI for AI agents
14732
+ console.log(`dbg \u2014 Node.js debugger CLI for AI agents
13965
14733
 
13966
- Usage: agent-dbg <command> [options]
14734
+ Usage: dbg <command> [options]
13967
14735
 
13968
14736
  Session:
13969
14737
  launch [--brk] <command...> Start + attach debugger
@@ -13985,7 +14753,7 @@ Inspection:
13985
14753
  vars [name...] Show local variables
13986
14754
  [--frame @fN] [--all-scopes]
13987
14755
  stack [--async-depth N] Show call stack
13988
- [--generated]
14756
+ [--generated] [--filter <keyword>]
13989
14757
  eval <expression> Evaluate expression
13990
14758
  [--frame @fN] [--silent] [--timeout MS] [--side-effect-free]
13991
14759
  props <@ref> Expand object properties
@@ -13995,6 +14763,7 @@ Inspection:
13995
14763
  search <query> Search loaded scripts
13996
14764
  [--regex] [--case-sensitive] [--file <id>]
13997
14765
  scripts [--filter <pattern>] List loaded scripts
14766
+ modules [--filter <pattern>] List loaded modules/libraries (DAP only)
13998
14767
  console [--since N] [--level] Console output
13999
14768
  [--clear]
14000
14769
  exceptions [--since N] Captured exceptions
@@ -14024,6 +14793,10 @@ Source Maps:
14024
14793
  sourcemap [file] Show source map info
14025
14794
  sourcemap --disable Disable resolution globally
14026
14795
 
14796
+ Setup:
14797
+ install <adapter> Download managed adapter binary
14798
+ install --list Show installed adapters
14799
+
14027
14800
  Diagnostics:
14028
14801
  logs [-f|--follow] Show CDP protocol log
14029
14802
  [--limit N] [--domain <name>] [--clear]
@@ -14037,69 +14810,70 @@ Global flags:
14037
14810
  --version Show version`);
14038
14811
  }
14039
14812
  function printHelpAgent() {
14040
- console.log(`agent-dbg \u2014 Node.js debugger CLI for AI agents
14813
+ console.log(`dbg \u2014 Node.js debugger CLI for AI agents
14041
14814
 
14042
14815
  CORE LOOP:
14043
- 1. agent-dbg launch --brk "node app.js" \u2192 pauses at first line, returns state
14044
- 2. agent-dbg break src/file.ts:42 \u2192 set breakpoint
14045
- 3. agent-dbg continue \u2192 run to breakpoint, returns state
14046
- 4. Inspect: agent-dbg vars, agent-dbg eval, agent-dbg props @v1
14047
- 5. Mutate/fix: agent-dbg set @v1 value, agent-dbg hotpatch src/file.ts
14816
+ 1. dbg launch --brk "node app.js" \u2192 pauses at first line, returns state
14817
+ 2. dbg break src/file.ts:42 \u2192 set breakpoint
14818
+ 3. dbg continue \u2192 run to breakpoint, returns state
14819
+ 4. Inspect: dbg vars, dbg eval, dbg props @v1
14820
+ 5. Mutate/fix: dbg set @v1 value, dbg hotpatch src/file.ts
14048
14821
  6. Repeat from 3
14049
14822
 
14050
14823
  REFS: Every output assigns @refs. Use them everywhere:
14051
- @v1..@vN variables | agent-dbg props @v1, agent-dbg set @v2 true
14052
- @f0..@fN stack frames | agent-dbg eval --frame @f1
14053
- BP#1..N breakpoints | agent-dbg break-rm BP#1, agent-dbg break-toggle BP#1
14824
+ @v1..@vN variables | dbg props @v1, dbg set @v2 true
14825
+ @f0..@fN stack frames | dbg eval --frame @f1
14826
+ BP#1..N breakpoints | dbg break-rm BP#1, dbg break-toggle BP#1
14054
14827
 
14055
14828
  EXECUTION (all return state automatically):
14056
- agent-dbg continue Resume to next breakpoint
14057
- agent-dbg step [over|into|out] Step one statement
14058
- agent-dbg run-to file:line Continue to location
14059
- agent-dbg pause Interrupt running process
14060
- agent-dbg restart-frame [@fN] Re-run frame from beginning
14829
+ dbg continue Resume to next breakpoint
14830
+ dbg step [over|into|out] Step one statement
14831
+ dbg run-to file:line Continue to location
14832
+ dbg pause Interrupt running process
14833
+ dbg restart-frame [@fN] Re-run frame from beginning
14061
14834
 
14062
14835
  BREAKPOINTS:
14063
- agent-dbg break file:line [--condition expr] [--hit-count N] [--continue]
14064
- agent-dbg break --pattern "regex":line
14065
- agent-dbg break-rm <BP#|all> Remove breakpoints
14066
- agent-dbg break-ls List breakpoints
14067
- agent-dbg break-toggle <BP#|all> Enable/disable breakpoints
14068
- agent-dbg breakable file:start-end Valid breakpoint locations
14069
- agent-dbg logpoint file:line "template \${var}" [--condition expr]
14070
- agent-dbg catch [all|uncaught|caught|none]
14836
+ dbg break file:line [--condition expr] [--hit-count N] [--continue]
14837
+ dbg break --pattern "regex":line
14838
+ dbg break-rm <BP#|all> Remove breakpoints
14839
+ dbg break-ls List breakpoints
14840
+ dbg break-toggle <BP#|all> Enable/disable breakpoints
14841
+ dbg breakable file:start-end Valid breakpoint locations
14842
+ dbg logpoint file:line "template \${var}" [--condition expr]
14843
+ dbg catch [all|uncaught|caught|none]
14071
14844
 
14072
14845
  INSPECTION:
14073
- agent-dbg state [-v|-s|-b|-c] [--depth N] [--lines N] [--frame @fN] [--all-scopes] [--compact] [--generated]
14074
- agent-dbg vars [name...] [--frame @fN] [--all-scopes]
14075
- agent-dbg stack [--async-depth N] [--generated]
14076
- agent-dbg eval <expr> [--frame @fN] [--silent] [--timeout MS] [--side-effect-free]
14077
- agent-dbg props @ref [--own] [--depth N] [--private] [--internal]
14078
- agent-dbg source [--lines N] [--file path] [--all] [--generated]
14079
- agent-dbg search "query" [--regex] [--case-sensitive] [--file id]
14080
- agent-dbg scripts [--filter pattern]
14081
- agent-dbg console [--since N] [--level type] [--clear]
14082
- agent-dbg exceptions [--since N]
14846
+ dbg state [-v|-s|-b|-c] [--depth N] [--lines N] [--frame @fN] [--all-scopes] [--compact] [--generated]
14847
+ dbg vars [name...] [--frame @fN] [--all-scopes]
14848
+ dbg stack [--async-depth N] [--generated] [--filter <keyword>]
14849
+ dbg eval <expr> [--frame @fN] [--silent] [--timeout MS] [--side-effect-free]
14850
+ dbg props @ref [--own] [--depth N] [--private] [--internal]
14851
+ dbg modules [--filter <pattern>] (DAP only: list loaded libraries with symbol status)
14852
+ dbg source [--lines N] [--file path] [--all] [--generated]
14853
+ dbg search "query" [--regex] [--case-sensitive] [--file id]
14854
+ dbg scripts [--filter pattern]
14855
+ dbg console [--since N] [--level type] [--clear]
14856
+ dbg exceptions [--since N]
14083
14857
 
14084
14858
  MUTATION:
14085
- agent-dbg set <@ref|name> <value> Change variable
14086
- agent-dbg set-return <value> Change return value (at return point)
14087
- agent-dbg hotpatch <file> [--dry-run] Live-edit code (no restart!)
14859
+ dbg set <@ref|name> <value> Change variable
14860
+ dbg set-return <value> Change return value (at return point)
14861
+ dbg hotpatch <file> [--dry-run] Live-edit code (no restart!)
14088
14862
 
14089
14863
  BLACKBOXING:
14090
- agent-dbg blackbox <pattern...> Skip stepping into matching scripts
14091
- agent-dbg blackbox-ls List current patterns
14092
- agent-dbg blackbox-rm <pattern|all> Remove patterns
14864
+ dbg blackbox <pattern...> Skip stepping into matching scripts
14865
+ dbg blackbox-ls List current patterns
14866
+ dbg blackbox-rm <pattern|all> Remove patterns
14093
14867
 
14094
14868
  SOURCE MAPS:
14095
- agent-dbg sourcemap [file] Show source map info
14096
- agent-dbg sourcemap --disable Disable resolution globally
14869
+ dbg sourcemap [file] Show source map info
14870
+ dbg sourcemap --disable Disable resolution globally
14097
14871
 
14098
14872
  DIAGNOSTICS:
14099
- agent-dbg logs [-f|--follow] Show CDP protocol log
14100
- agent-dbg logs --limit 100 Show last N entries (default: 50)
14101
- agent-dbg logs --domain Debugger Filter by CDP domain
14102
- agent-dbg logs --clear Clear the log file`);
14873
+ dbg logs [-f|--follow] Show CDP protocol log
14874
+ dbg logs --limit 100 Show last N entries (default: 50)
14875
+ dbg logs --domain Debugger Filter by CDP domain
14876
+ dbg logs --clear Clear the log file`);
14103
14877
  }
14104
14878
  var GLOBAL_FLAGS, BOOLEAN_FLAGS;
14105
14879
  var init_parser = __esm(() => {
@@ -14163,6 +14937,7 @@ if (process.argv.includes("--daemon")) {
14163
14937
  await Promise.resolve().then(() => (init_catch(), exports_catch));
14164
14938
  await Promise.resolve().then(() => (init_source2(), exports_source));
14165
14939
  await Promise.resolve().then(() => (init_scripts(), exports_scripts));
14940
+ await Promise.resolve().then(() => (init_modules(), exports_modules));
14166
14941
  await Promise.resolve().then(() => (init_stack2(), exports_stack));
14167
14942
  await Promise.resolve().then(() => (init_search(), exports_search));
14168
14943
  await Promise.resolve().then(() => (init_console(), exports_console));
@@ -14180,6 +14955,7 @@ if (process.argv.includes("--daemon")) {
14180
14955
  await Promise.resolve().then(() => (init_breakable(), exports_breakable));
14181
14956
  await Promise.resolve().then(() => (init_restart_frame(), exports_restart_frame));
14182
14957
  await Promise.resolve().then(() => (init_sourcemap(), exports_sourcemap));
14958
+ await Promise.resolve().then(() => (init_install(), exports_install));
14183
14959
  await Promise.resolve().then(() => (init_logs2(), exports_logs));
14184
14960
  const { parseArgs: parseArgs2, run: run2 } = await Promise.resolve().then(() => (init_parser(), exports_parser));
14185
14961
  const args = parseArgs2(process.argv.slice(2));