agent-dbg 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -7631,6 +7631,9 @@ class CdpClient {
7631
7631
  ws.addEventListener("error", onError, { once: true });
7632
7632
  });
7633
7633
  }
7634
+ async sendRaw(method, params) {
7635
+ return this.send(method, params);
7636
+ }
7634
7637
  async send(method, ...args) {
7635
7638
  if (!this.isConnected) {
7636
7639
  throw new Error("CDP client is not connected");
@@ -7670,13 +7673,39 @@ class CdpClient {
7670
7673
  }
7671
7674
  }
7672
7675
  }
7676
+ waitFor(event, opts) {
7677
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
7678
+ const filter = opts?.filter;
7679
+ return new Promise((resolve, reject) => {
7680
+ const handler = (params) => {
7681
+ if (filter && !filter(params))
7682
+ return;
7683
+ cleanup();
7684
+ resolve(params);
7685
+ };
7686
+ const timer = setTimeout(() => {
7687
+ cleanup();
7688
+ reject(new Error(`waitFor timed out: ${event} (after ${timeoutMs}ms)`));
7689
+ }, timeoutMs);
7690
+ const cleanup = () => {
7691
+ clearTimeout(timer);
7692
+ this.off(event, handler);
7693
+ };
7694
+ this.on(event, handler);
7695
+ });
7696
+ }
7697
+ enabledDomains = new Set;
7673
7698
  async enableDomains() {
7674
- await Promise.all([
7675
- this.send("Debugger.enable"),
7676
- this.send("Runtime.enable"),
7677
- this.send("Profiler.enable"),
7678
- this.send("HeapProfiler.enable")
7679
- ]);
7699
+ await Promise.all([this.send("Debugger.enable"), this.send("Runtime.enable")]);
7700
+ this.enabledDomains.add("Debugger");
7701
+ this.enabledDomains.add("Runtime");
7702
+ const optional2 = ["Profiler", "HeapProfiler"];
7703
+ await Promise.allSettled(optional2.map(async (domain) => {
7704
+ try {
7705
+ await this.send(`${domain}.enable`);
7706
+ this.enabledDomains.add(domain);
7707
+ } catch {}
7708
+ }));
7680
7709
  }
7681
7710
  async runIfWaitingForDebugger() {
7682
7711
  await this.send("Runtime.runIfWaitingForDebugger");
@@ -8765,6 +8794,237 @@ var init_resolver = __esm(() => {
8765
8794
  init_trace_mapping();
8766
8795
  });
8767
8796
 
8797
+ // src/cdp/jsc-client.ts
8798
+ class JscClient {
8799
+ cdp;
8800
+ constructor(cdp) {
8801
+ this.cdp = cdp;
8802
+ }
8803
+ async send(method, ...args) {
8804
+ const params = args[0];
8805
+ return this.cdp.sendRaw(method, params);
8806
+ }
8807
+ on(event, handler) {
8808
+ this.cdp.on(event, handler);
8809
+ }
8810
+ off(event, handler) {
8811
+ this.cdp.off(event, handler);
8812
+ }
8813
+ waitFor(event, opts) {
8814
+ return this.cdp.waitFor(event, opts);
8815
+ }
8816
+ disconnect() {
8817
+ this.cdp.disconnect();
8818
+ }
8819
+ get connected() {
8820
+ return this.cdp.connected;
8821
+ }
8822
+ }
8823
+
8824
+ // src/daemon/adapters/bun-adapter.ts
8825
+ class BunAdapter {
8826
+ name = "bun";
8827
+ internalUrlPrefix = "bun:";
8828
+ jsc = null;
8829
+ async preEnable(cdp) {
8830
+ this.jsc = new JscClient(cdp);
8831
+ await this.jsc.send("Inspector.enable");
8832
+ }
8833
+ async waitForBrkPause(session) {
8834
+ if (!this.jsc)
8835
+ return;
8836
+ await this.jsc.send("Debugger.setBreakpointsActive", { active: true });
8837
+ await this.jsc.send("Debugger.setPauseForInternalScripts", { shouldPause: false });
8838
+ const entryScript = this.resolveEntryScript(session);
8839
+ const tempBpId = await this.setEntryBreakpoint(entryScript);
8840
+ try {
8841
+ const waiter = session.createPauseWaiter(5000);
8842
+ await this.jsc.send("Inspector.initialized");
8843
+ await waiter;
8844
+ } finally {
8845
+ if (tempBpId && this.jsc.connected) {
8846
+ try {
8847
+ await this.jsc.send("Debugger.removeBreakpoint", { breakpointId: tempBpId });
8848
+ } catch {}
8849
+ }
8850
+ }
8851
+ }
8852
+ async setBreakpointByLocation(_cdp, params) {
8853
+ const jsc = this.ensureJsc();
8854
+ const scriptId = params.scriptId ?? this.findScriptId(params.scripts, params.url);
8855
+ if (!scriptId) {
8856
+ throw new Error(`Cannot find script for "${params.file}" \u2014 ensure the script is loaded`);
8857
+ }
8858
+ const r = await jsc.send("Debugger.setBreakpoint", {
8859
+ location: {
8860
+ scriptId,
8861
+ lineNumber: params.line - 1,
8862
+ columnNumber: params.column
8863
+ },
8864
+ options: params.condition ? { condition: params.condition } : undefined
8865
+ });
8866
+ return {
8867
+ breakpointId: r.breakpointId,
8868
+ location: r.actualLocation,
8869
+ url: params.url
8870
+ };
8871
+ }
8872
+ async getBreakableLocations(_cdp, scriptId, startLine, endLine) {
8873
+ const jsc = this.ensureJsc();
8874
+ const r = await jsc.send("Debugger.getBreakpointLocations", {
8875
+ start: { scriptId, lineNumber: startLine - 1 },
8876
+ end: { scriptId, lineNumber: endLine }
8877
+ });
8878
+ return (r.locations ?? []).map((loc) => ({
8879
+ line: loc.lineNumber + 1,
8880
+ column: (loc.columnNumber ?? 0) + 1
8881
+ }));
8882
+ }
8883
+ async getProperties(cdp, params) {
8884
+ const raw = await cdp.sendRaw("Runtime.getProperties", params);
8885
+ if ("properties" in raw && !("result" in raw)) {
8886
+ raw.result = raw.properties;
8887
+ delete raw.properties;
8888
+ }
8889
+ return raw;
8890
+ }
8891
+ async setBlackboxPatterns(_cdp, patterns) {
8892
+ const jsc = this.ensureJsc();
8893
+ for (const pattern of patterns) {
8894
+ await jsc.send("Debugger.setShouldBlackboxURL", {
8895
+ url: pattern,
8896
+ caseSensitive: false,
8897
+ shouldBlackbox: true
8898
+ });
8899
+ }
8900
+ }
8901
+ ensureJsc() {
8902
+ if (!this.jsc)
8903
+ throw new Error("JscClient not initialized \u2014 call preEnable first");
8904
+ return this.jsc;
8905
+ }
8906
+ async setEntryBreakpoint(entryScript) {
8907
+ if (!entryScript || !this.jsc)
8908
+ return null;
8909
+ const parts = entryScript.split("/");
8910
+ const filename = parts[parts.length - 1] ?? entryScript;
8911
+ const urlRegex2 = `${escapeRegex2(filename)}$`;
8912
+ try {
8913
+ const r = await this.jsc.send("Debugger.setBreakpointByUrl", {
8914
+ urlRegex: urlRegex2,
8915
+ lineNumber: 1
8916
+ });
8917
+ return r.breakpointId;
8918
+ } catch {
8919
+ return null;
8920
+ }
8921
+ }
8922
+ findScriptId(scripts, url2) {
8923
+ if (!url2)
8924
+ return;
8925
+ for (const [sid, info] of scripts) {
8926
+ if (info.url === url2)
8927
+ return sid;
8928
+ }
8929
+ return;
8930
+ }
8931
+ resolveEntryScript(session) {
8932
+ if (!session.launchCommand)
8933
+ return null;
8934
+ for (let i = session.launchCommand.length - 1;i >= 0; i--) {
8935
+ const arg = session.launchCommand[i];
8936
+ if (!arg.startsWith("-"))
8937
+ return arg;
8938
+ }
8939
+ return null;
8940
+ }
8941
+ }
8942
+ function escapeRegex2(s) {
8943
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8944
+ }
8945
+ var init_bun_adapter = () => {};
8946
+
8947
+ // src/daemon/adapters/node-adapter.ts
8948
+ class NodeAdapter {
8949
+ name = "node";
8950
+ internalUrlPrefix = "node:";
8951
+ async preEnable(_cdp) {}
8952
+ async waitForBrkPause(session) {
8953
+ if (!session.isPaused()) {
8954
+ await Bun.sleep(100);
8955
+ }
8956
+ if (!session.isPaused() && session.cdp) {
8957
+ await session.cdp.send("Debugger.pause");
8958
+ await session.cdp.send("Runtime.runIfWaitingForDebugger");
8959
+ const deadline = Date.now() + 2000;
8960
+ while (!session.isPaused() && Date.now() < deadline) {
8961
+ await Bun.sleep(50);
8962
+ }
8963
+ }
8964
+ await this.skipInternalPauses(session);
8965
+ }
8966
+ async setBreakpointByLocation(cdp, params) {
8967
+ const bpParams = {
8968
+ lineNumber: params.line - 1
8969
+ };
8970
+ if (params.column !== undefined) {
8971
+ bpParams.columnNumber = params.column;
8972
+ }
8973
+ if (params.urlRegex) {
8974
+ bpParams.urlRegex = params.urlRegex;
8975
+ } else if (params.url) {
8976
+ bpParams.url = params.url;
8977
+ }
8978
+ if (params.condition) {
8979
+ bpParams.condition = params.condition;
8980
+ }
8981
+ const r = await cdp.send("Debugger.setBreakpointByUrl", bpParams);
8982
+ const loc = r.locations[0];
8983
+ return {
8984
+ breakpointId: r.breakpointId,
8985
+ location: loc ? { scriptId: loc.scriptId, lineNumber: loc.lineNumber, columnNumber: loc.columnNumber } : undefined,
8986
+ url: params.url
8987
+ };
8988
+ }
8989
+ async getBreakableLocations(cdp, scriptId, startLine, endLine) {
8990
+ const r = await cdp.send("Debugger.getPossibleBreakpoints", {
8991
+ start: { scriptId, lineNumber: startLine - 1 },
8992
+ end: { scriptId, lineNumber: endLine }
8993
+ });
8994
+ return r.locations.map((loc) => ({
8995
+ line: loc.lineNumber + 1,
8996
+ column: (loc.columnNumber ?? 0) + 1
8997
+ }));
8998
+ }
8999
+ async getProperties(cdp, params) {
9000
+ return cdp.send("Runtime.getProperties", params);
9001
+ }
9002
+ async setBlackboxPatterns(cdp, patterns) {
9003
+ await cdp.send("Debugger.setBlackboxPatterns", { patterns });
9004
+ }
9005
+ async skipInternalPauses(session) {
9006
+ let skips = 0;
9007
+ while (session.isPaused() && session.cdp && session.pauseInfo?.url?.startsWith(this.internalUrlPrefix) && skips < 5) {
9008
+ skips++;
9009
+ const waiter = session.createPauseWaiter(5000);
9010
+ await session.cdp.send("Debugger.resume");
9011
+ await waiter;
9012
+ }
9013
+ }
9014
+ }
9015
+
9016
+ // src/daemon/adapters/index.ts
9017
+ function createAdapter(command) {
9018
+ const bin = command[0]?.split("/").pop();
9019
+ if (bin === "bun" || bin === "bunx")
9020
+ return new BunAdapter;
9021
+ return new NodeAdapter;
9022
+ }
9023
+ var init_adapters = __esm(() => {
9024
+ init_bun_adapter();
9025
+ init_bun_adapter();
9026
+ });
9027
+
8768
9028
  // src/daemon/session-blackbox.ts
8769
9029
  async function addBlackbox(session, patterns) {
8770
9030
  if (!session.cdp) {
@@ -8775,9 +9035,7 @@ async function addBlackbox(session, patterns) {
8775
9035
  session.blackboxPatterns.push(p);
8776
9036
  }
8777
9037
  }
8778
- await session.cdp.send("Debugger.setBlackboxPatterns", {
8779
- patterns: session.blackboxPatterns
8780
- });
9038
+ await session.adapter.setBlackboxPatterns(session.cdp, session.blackboxPatterns);
8781
9039
  return [...session.blackboxPatterns];
8782
9040
  }
8783
9041
  function listBlackbox(session) {
@@ -8792,9 +9050,7 @@ async function removeBlackbox(session, patterns) {
8792
9050
  } else {
8793
9051
  session.blackboxPatterns = session.blackboxPatterns.filter((p) => !patterns.includes(p));
8794
9052
  }
8795
- await session.cdp.send("Debugger.setBlackboxPatterns", {
8796
- patterns: session.blackboxPatterns
8797
- });
9053
+ await session.adapter.setBlackboxPatterns(session.cdp, session.blackboxPatterns);
8798
9054
  return [...session.blackboxPatterns];
8799
9055
  }
8800
9056
 
@@ -8809,6 +9065,7 @@ async function setBreakpoint(session, file2, line, options) {
8809
9065
  let actualLine = line;
8810
9066
  let actualColumn = options?.column !== undefined ? options.column - 1 : undefined;
8811
9067
  let actualFile = file2;
9068
+ let generatedScriptId = null;
8812
9069
  if (!options?.urlRegex) {
8813
9070
  const generated = session.sourceMapResolver.toGenerated(file2, line, actualColumn ?? 0);
8814
9071
  if (generated) {
@@ -8816,34 +9073,37 @@ async function setBreakpoint(session, file2, line, options) {
8816
9073
  originalLine = line;
8817
9074
  actualLine = generated.line;
8818
9075
  actualColumn = generated.column;
9076
+ generatedScriptId = generated.scriptId;
8819
9077
  const scriptInfo = session.scripts.get(generated.scriptId);
8820
9078
  if (scriptInfo) {
8821
9079
  actualFile = scriptInfo.url;
8822
9080
  }
8823
9081
  }
8824
9082
  }
8825
- const params = {
8826
- lineNumber: actualLine - 1
8827
- };
8828
- if (actualColumn !== undefined) {
8829
- params.columnNumber = actualColumn;
8830
- }
8831
9083
  let url2 = null;
9084
+ let urlRegex2;
8832
9085
  if (options?.urlRegex) {
8833
- params.urlRegex = options.urlRegex;
9086
+ urlRegex2 = options.urlRegex;
8834
9087
  } else {
8835
9088
  url2 = session.findScriptUrl(actualFile);
8836
- if (url2) {
8837
- params.url = url2;
8838
- } else {
8839
- params.urlRegex = `${actualFile.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`;
8840
- }
8841
- }
8842
- if (condition) {
8843
- params.condition = condition;
8844
- }
8845
- const r = await session.cdp.send("Debugger.setBreakpointByUrl", params);
8846
- const loc = r.locations[0];
9089
+ if (!url2 && !generatedScriptId) {
9090
+ urlRegex2 = `${actualFile.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`;
9091
+ }
9092
+ }
9093
+ const r = await session.adapter.setBreakpointByLocation(session.cdp, {
9094
+ file: file2,
9095
+ line: actualLine,
9096
+ column: actualColumn,
9097
+ condition,
9098
+ url: url2 ?? undefined,
9099
+ urlRegex: urlRegex2,
9100
+ scriptId: generatedScriptId ?? undefined,
9101
+ scripts: session.scripts
9102
+ });
9103
+ const breakpointId = r.breakpointId;
9104
+ const loc = r.location;
9105
+ if (!url2)
9106
+ url2 = r.url ?? session.findScriptUrl(actualFile);
8847
9107
  const resolvedUrl = originalFile ?? url2 ?? file2;
8848
9108
  const resolvedLine = originalLine ?? (loc ? loc.lineNumber + 1 : line);
8849
9109
  const resolvedColumn = loc?.columnNumber;
@@ -8869,7 +9129,7 @@ async function setBreakpoint(session, file2, line, options) {
8869
9129
  if (options?.urlRegex) {
8870
9130
  meta.urlRegex = options.urlRegex;
8871
9131
  }
8872
- const ref = session.refs.addBreakpoint(r.breakpointId, meta);
9132
+ const ref = session.refs.addBreakpoint(breakpointId, meta);
8873
9133
  const location = {
8874
9134
  url: resolvedUrl,
8875
9135
  line: resolvedLine
@@ -9025,18 +9285,24 @@ async function reEnableBreakpoint(session, ref, entry) {
9025
9285
  const hitCount = meta.hitCount;
9026
9286
  const urlRegex2 = meta.urlRegex;
9027
9287
  const builtCondition = session.buildBreakpointCondition(condition, hitCount);
9028
- const bpParams = {
9029
- lineNumber: line - 1
9030
- };
9031
- if (urlRegex2) {
9032
- bpParams.urlRegex = urlRegex2;
9033
- } else if (url2) {
9034
- bpParams.url = url2;
9035
- }
9036
- if (builtCondition) {
9037
- bpParams.condition = builtCondition;
9288
+ let scriptId;
9289
+ if (url2) {
9290
+ for (const [sid, info] of session.scripts) {
9291
+ if (info.url === url2) {
9292
+ scriptId = sid;
9293
+ break;
9294
+ }
9295
+ }
9038
9296
  }
9039
- const r = await session.cdp.send("Debugger.setBreakpointByUrl", bpParams);
9297
+ const r = await session.adapter.setBreakpointByLocation(session.cdp, {
9298
+ file: url2 ?? urlRegex2 ?? "",
9299
+ line,
9300
+ condition: builtCondition,
9301
+ url: url2,
9302
+ urlRegex: urlRegex2,
9303
+ scriptId,
9304
+ scripts: session.scripts
9305
+ });
9040
9306
  const type = meta.type === "LP" ? "LP" : "BP";
9041
9307
  const newMeta = { ...meta };
9042
9308
  delete newMeta.type;
@@ -9065,14 +9331,7 @@ async function getBreakableLocations(session, file2, startLine, endLine) {
9065
9331
  if (!scriptId) {
9066
9332
  throw new Error(`No scriptId found for "${file2}"`);
9067
9333
  }
9068
- const r = await session.cdp.send("Debugger.getPossibleBreakpoints", {
9069
- start: { scriptId, lineNumber: startLine - 1 },
9070
- end: { scriptId, lineNumber: endLine }
9071
- });
9072
- return r.locations.map((loc) => ({
9073
- line: loc.lineNumber + 1,
9074
- column: (loc.columnNumber ?? 0) + 1
9075
- }));
9334
+ return session.adapter.getBreakableLocations(session.cdp, scriptId, startLine, endLine);
9076
9335
  }
9077
9336
  async function setLogpoint(session, file2, line, template, options) {
9078
9337
  if (!session.cdp) {
@@ -9085,17 +9344,29 @@ async function setLogpoint(session, file2, line, template, options) {
9085
9344
  } else {
9086
9345
  logExpr = `${logExpr}, false`;
9087
9346
  }
9088
- const lpParams = {
9089
- lineNumber: line - 1,
9090
- condition: logExpr
9091
- };
9347
+ let urlRegex2;
9348
+ if (!url2) {
9349
+ urlRegex2 = `${file2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`;
9350
+ }
9351
+ let scriptId;
9092
9352
  if (url2) {
9093
- lpParams.url = url2;
9094
- } else {
9095
- lpParams.urlRegex = `${file2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`;
9353
+ for (const [sid, info] of session.scripts) {
9354
+ if (info.url === url2) {
9355
+ scriptId = sid;
9356
+ break;
9357
+ }
9358
+ }
9096
9359
  }
9097
- const r = await session.cdp.send("Debugger.setBreakpointByUrl", lpParams);
9098
- const loc = r.locations[0];
9360
+ const r = await session.adapter.setBreakpointByLocation(session.cdp, {
9361
+ file: file2,
9362
+ line,
9363
+ condition: logExpr,
9364
+ url: url2 ?? undefined,
9365
+ urlRegex: urlRegex2,
9366
+ scriptId,
9367
+ scripts: session.scripts
9368
+ });
9369
+ const loc = r.location;
9099
9370
  const resolvedUrl = url2 ?? file2;
9100
9371
  const resolvedLine = loc ? loc.lineNumber + 1 : line;
9101
9372
  const resolvedColumn = loc?.columnNumber;
@@ -9364,7 +9635,7 @@ async function getVars(session, options = {}) {
9364
9635
  const objectId = scopeObj.objectId;
9365
9636
  if (!objectId)
9366
9637
  continue;
9367
- const propsResult = await session.cdp.send("Runtime.getProperties", {
9638
+ const propsResult = await session.adapter.getProperties(session.cdp, {
9368
9639
  objectId,
9369
9640
  ownProperties: true,
9370
9641
  generatePreview: true
@@ -9417,7 +9688,7 @@ async function getProps(session, ref, options = {}) {
9417
9688
  if (options.internal) {
9418
9689
  propsParams.accessorPropertiesOnly = false;
9419
9690
  }
9420
- const propsResult = await session.cdp.send("Runtime.getProperties", propsParams);
9691
+ const propsResult = await session.adapter.getProperties(session.cdp, propsParams);
9421
9692
  const properties = propsResult.result ?? [];
9422
9693
  const internalProps = options.internal ? propsResult.internalProperties ?? [] : [];
9423
9694
  const result = [];
@@ -9995,7 +10266,7 @@ async function buildState(session, options = {}) {
9995
10266
  const objectId = scopeObj.objectId;
9996
10267
  if (!objectId)
9997
10268
  continue;
9998
- const propsResult = await session.cdp.send("Runtime.getProperties", {
10269
+ const propsResult = await session.adapter.getProperties(session.cdp, {
9999
10270
  objectId,
10000
10271
  ownProperties: true,
10001
10272
  generatePreview: true
@@ -10053,6 +10324,7 @@ class DebugSession {
10053
10324
  disabledBreakpoints = new Map;
10054
10325
  launchCommand = null;
10055
10326
  launchOptions = null;
10327
+ adapter;
10056
10328
  cdpLogger;
10057
10329
  daemonLogger;
10058
10330
  constructor(session, options) {
@@ -10060,6 +10332,10 @@ class DebugSession {
10060
10332
  ensureSocketDir();
10061
10333
  this.cdpLogger = new CdpLogger(getLogPath(session));
10062
10334
  this.daemonLogger = options?.daemonLogger ?? new DaemonLogger(getDaemonLogPath(session));
10335
+ this.adapter = createAdapter(["node"]);
10336
+ }
10337
+ get runtime() {
10338
+ return this.adapter.name;
10063
10339
  }
10064
10340
  async launch(command, options = {}) {
10065
10341
  if (this.state !== "idle") {
@@ -10070,12 +10346,13 @@ class DebugSession {
10070
10346
  }
10071
10347
  this.launchCommand = command;
10072
10348
  this.launchOptions = options;
10349
+ this.adapter = createAdapter(command);
10073
10350
  const brk = options.brk ?? true;
10074
10351
  const port = options.port ?? 0;
10075
10352
  const inspectFlag = brk ? `--inspect-brk=${port}` : `--inspect=${port}`;
10076
- const runtime = command[0];
10353
+ const runtimeBin = command[0];
10077
10354
  const rest = command.slice(1);
10078
- const spawnArgs = [runtime, inspectFlag, ...rest];
10355
+ const spawnArgs = [runtimeBin, inspectFlag, ...rest];
10079
10356
  const proc = Bun.spawn(spawnArgs, {
10080
10357
  stdin: "ignore",
10081
10358
  stdout: "ignore",
@@ -10102,7 +10379,18 @@ class DebugSession {
10102
10379
  paused: this.sessionState === "paused"
10103
10380
  };
10104
10381
  if (this.pauseInfo) {
10105
- result.pauseInfo = this.pauseInfo;
10382
+ const translated = { ...this.pauseInfo };
10383
+ if (translated.scriptId && translated.line !== undefined) {
10384
+ const resolved = this.resolveOriginalLocation(translated.scriptId, translated.line + 1, translated.column ?? 0);
10385
+ if (resolved) {
10386
+ translated.url = resolved.url;
10387
+ translated.line = resolved.line - 1;
10388
+ if (resolved.column !== undefined) {
10389
+ translated.column = resolved.column - 1;
10390
+ }
10391
+ }
10392
+ }
10393
+ result.pauseInfo = translated;
10106
10394
  }
10107
10395
  return result;
10108
10396
  }
@@ -10338,24 +10626,16 @@ class DebugSession {
10338
10626
  if (settled)
10339
10627
  return;
10340
10628
  settled = true;
10341
- clearTimeout(timer);
10342
10629
  clearInterval(pollTimer);
10343
- this.cdp?.off("Debugger.paused", handler);
10344
10630
  this.onProcessExit = null;
10345
10631
  resolve3();
10346
10632
  };
10347
- const timer = setTimeout(() => {
10348
- settle();
10349
- }, timeoutMs);
10350
- const handler = () => {
10351
- settle();
10352
- };
10633
+ this.cdp?.waitFor("Debugger.paused", { timeoutMs }).then(() => settle()).catch(() => settle());
10353
10634
  const pollTimer = setInterval(() => {
10354
10635
  if (this.isPaused() || this.state === "idle") {
10355
10636
  settle();
10356
10637
  }
10357
10638
  }, 100);
10358
- this.cdp?.on("Debugger.paused", handler);
10359
10639
  this.onProcessExit = settle;
10360
10640
  });
10361
10641
  }
@@ -10385,24 +10665,7 @@ class DebugSession {
10385
10665
  return this.state === "paused";
10386
10666
  }
10387
10667
  async waitForBrkPause() {
10388
- if (!this.isPaused()) {
10389
- await Bun.sleep(100);
10390
- }
10391
- if (!this.isPaused() && this.cdp) {
10392
- await this.cdp.send("Debugger.pause");
10393
- await this.cdp.send("Runtime.runIfWaitingForDebugger");
10394
- const deadline = Date.now() + 2000;
10395
- while (!this.isPaused() && Date.now() < deadline) {
10396
- await Bun.sleep(50);
10397
- }
10398
- }
10399
- let skips = 0;
10400
- while (this.isPaused() && this.cdp && this.pauseInfo?.url?.startsWith("node:") && skips < 5) {
10401
- skips++;
10402
- const waiter = this.createPauseWaiter(5000);
10403
- await this.cdp.send("Debugger.resume");
10404
- await waiter;
10405
- }
10668
+ return this.adapter.waitForBrkPause(this);
10406
10669
  }
10407
10670
  async connectCdp(wsUrl) {
10408
10671
  this.daemonLogger.debug("cdp.connecting", `Connecting to ${wsUrl}`);
@@ -10410,11 +10673,10 @@ class DebugSession {
10410
10673
  this.cdp = cdp;
10411
10674
  this.daemonLogger.info("cdp.connected", `CDP connected to ${wsUrl}`);
10412
10675
  this.setupCdpEventHandlers(cdp);
10676
+ await this.adapter.preEnable(cdp);
10413
10677
  await cdp.enableDomains();
10414
10678
  if (this.blackboxPatterns.length > 0) {
10415
- await cdp.send("Debugger.setBlackboxPatterns", {
10416
- patterns: this.blackboxPatterns
10417
- });
10679
+ await this.adapter.setBlackboxPatterns(cdp, this.blackboxPatterns);
10418
10680
  }
10419
10681
  if (this.state === "idle") {
10420
10682
  this.state = "running";
@@ -10605,12 +10867,13 @@ var init_session2 = __esm(() => {
10605
10867
  init_logger2();
10606
10868
  init_ref_table();
10607
10869
  init_resolver();
10870
+ init_adapters();
10608
10871
  init_logger();
10609
10872
  init_paths();
10610
10873
  init_session_inspection();
10611
10874
  init_session_mutation();
10612
10875
  init_session_state();
10613
- INSPECTOR_URL_REGEX = /Debugger listening on (wss?:\/\/\S+)/;
10876
+ INSPECTOR_URL_REGEX = /(?:Debugger listening on\s+)?(wss?:\/\/\S+)/;
10614
10877
  });
10615
10878
 
10616
10879
  // src/daemon/entry.ts
@@ -11416,8 +11679,9 @@ function formatSource(lines) {
11416
11679
  const trimmed = line.isCurrent ? trimLine(line.content, line.currentColumn) : trimLine(line.content);
11417
11680
  result.push(`${marker} ${num}\u2502${trimmed.text}`);
11418
11681
  if (line.isCurrent && trimmed.caretOffset !== undefined && trimmed.caretOffset >= 0) {
11419
- const gutterWidth = numWidth + 4;
11420
- result.push(`${" ".repeat(gutterWidth)}${" ".repeat(trimmed.caretOffset)}^`);
11682
+ const gutter = " ".repeat(numWidth + 4);
11683
+ const indent = trimmed.text.slice(0, trimmed.caretOffset).replace(/[^\t]/g, " ");
11684
+ result.push(`${gutter}${indent}^`);
11421
11685
  }
11422
11686
  }
11423
11687
  return result.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dbg",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "Node.js Debugger CLI for AI Agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,7 +12,8 @@
12
12
  "test": "bun test",
13
13
  "lint": "biome check .",
14
14
  "format": "biome check --write .",
15
- "typecheck": "tsc --noEmit"
15
+ "typecheck": "tsc --noEmit",
16
+ "update-jsc-protocol": "curl -sL https://raw.githubusercontent.com/oven-sh/bun/main/packages/bun-inspector-protocol/src/protocol/jsc/index.d.ts -o src/cdp/jsc-protocol.d.ts"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@biomejs/biome": "^2.3.14",