agent-dbg 0.1.3 → 0.1.4

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
@@ -12,6 +12,1049 @@ var __export = (target, all) => {
12
12
  };
13
13
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
14
14
 
15
+ // src/refs/ref-table.ts
16
+ class RefTable {
17
+ entries = new Map;
18
+ counters = {
19
+ v: 1,
20
+ f: 0,
21
+ o: 1,
22
+ BP: 1,
23
+ LP: 1,
24
+ HS: 1
25
+ };
26
+ addVar(remoteId, name, meta) {
27
+ return this.add("v", remoteId, name, meta);
28
+ }
29
+ addFrame(remoteId, name, meta) {
30
+ return this.add("f", remoteId, name, meta);
31
+ }
32
+ addObject(remoteId, name, meta) {
33
+ return this.add("o", remoteId, name, meta);
34
+ }
35
+ addBreakpoint(remoteId, meta) {
36
+ return this.add("BP", remoteId, undefined, meta);
37
+ }
38
+ addLogpoint(remoteId, meta) {
39
+ return this.add("LP", remoteId, undefined, meta);
40
+ }
41
+ addHeapSnapshot(remoteId, meta) {
42
+ return this.add("HS", remoteId, undefined, meta);
43
+ }
44
+ resolve(ref) {
45
+ return this.entries.get(ref);
46
+ }
47
+ resolveId(ref) {
48
+ return this.entries.get(ref)?.remoteId;
49
+ }
50
+ clearVolatile() {
51
+ for (const [key, entry] of this.entries) {
52
+ if (entry.type === "v" || entry.type === "f") {
53
+ this.entries.delete(key);
54
+ }
55
+ }
56
+ this.counters.v = 1;
57
+ this.counters.f = 0;
58
+ }
59
+ clearObjects() {
60
+ for (const [key, entry] of this.entries) {
61
+ if (entry.type === "o") {
62
+ this.entries.delete(key);
63
+ }
64
+ }
65
+ this.counters.o = 1;
66
+ }
67
+ clearAll() {
68
+ this.entries.clear();
69
+ this.counters = { v: 1, f: 0, o: 1, BP: 1, LP: 1, HS: 1 };
70
+ }
71
+ list(type) {
72
+ const result = [];
73
+ for (const entry of this.entries.values()) {
74
+ if (entry.type === type) {
75
+ result.push(entry);
76
+ }
77
+ }
78
+ return result;
79
+ }
80
+ remove(ref) {
81
+ return this.entries.delete(ref);
82
+ }
83
+ add(type, remoteId, name, meta) {
84
+ const num = this.counters[type];
85
+ this.counters[type] = num + 1;
86
+ const ref = `${PREFIXES[type]}${num}`;
87
+ const entry = { ref, type, remoteId };
88
+ if (name !== undefined) {
89
+ entry.name = name;
90
+ }
91
+ if (meta !== undefined) {
92
+ entry.meta = meta;
93
+ }
94
+ this.entries.set(ref, entry);
95
+ return ref;
96
+ }
97
+ }
98
+ var PREFIXES;
99
+ var init_ref_table = __esm(() => {
100
+ PREFIXES = {
101
+ v: "@v",
102
+ f: "@f",
103
+ o: "@o",
104
+ BP: "BP#",
105
+ LP: "LP#",
106
+ HS: "HS#"
107
+ };
108
+ });
109
+
110
+ // src/dap/client.ts
111
+ class DapClient {
112
+ proc;
113
+ nextSeq = 1;
114
+ pending = new Map;
115
+ listeners = new Map;
116
+ isConnected = false;
117
+ buffer = "";
118
+ constructor(proc) {
119
+ this.proc = proc;
120
+ this.isConnected = true;
121
+ this.readLoop();
122
+ this.drainStderr();
123
+ }
124
+ static spawn(command) {
125
+ const [cmd, ...args] = command;
126
+ if (!cmd) {
127
+ throw new Error("DapClient.spawn: command array must not be empty");
128
+ }
129
+ const proc = Bun.spawn([cmd, ...args], {
130
+ stdin: "pipe",
131
+ stdout: "pipe",
132
+ stderr: "pipe"
133
+ });
134
+ return new DapClient(proc);
135
+ }
136
+ async send(command, args) {
137
+ if (!this.isConnected) {
138
+ throw new Error("DAP client is not connected");
139
+ }
140
+ const seq = this.nextSeq++;
141
+ const request = {
142
+ seq,
143
+ type: "request",
144
+ command
145
+ };
146
+ if (args !== undefined) {
147
+ request.arguments = args;
148
+ }
149
+ return new Promise((resolve, reject) => {
150
+ const timer = setTimeout(() => {
151
+ this.pending.delete(seq);
152
+ reject(new Error(`DAP request timed out: ${command} (seq=${seq})`));
153
+ }, DEFAULT_TIMEOUT_MS);
154
+ this.pending.set(seq, { resolve, reject, timer });
155
+ this.writeMessage(request);
156
+ });
157
+ }
158
+ on(event, handler) {
159
+ let handlers = this.listeners.get(event);
160
+ if (!handlers) {
161
+ handlers = new Set;
162
+ this.listeners.set(event, handlers);
163
+ }
164
+ handlers.add(handler);
165
+ }
166
+ off(event, handler) {
167
+ const handlers = this.listeners.get(event);
168
+ if (handlers) {
169
+ handlers.delete(handler);
170
+ if (handlers.size === 0) {
171
+ this.listeners.delete(event);
172
+ }
173
+ }
174
+ }
175
+ disconnect() {
176
+ if (!this.isConnected) {
177
+ return;
178
+ }
179
+ this.isConnected = false;
180
+ const error = new Error("DAP client disconnected");
181
+ for (const [id, pending] of this.pending) {
182
+ clearTimeout(pending.timer);
183
+ pending.reject(error);
184
+ this.pending.delete(id);
185
+ }
186
+ this.listeners.clear();
187
+ try {
188
+ this.proc.stdin.end();
189
+ } catch {}
190
+ try {
191
+ this.proc.kill();
192
+ } catch {}
193
+ }
194
+ get connected() {
195
+ return this.isConnected;
196
+ }
197
+ get pid() {
198
+ return this.proc.pid;
199
+ }
200
+ writeMessage(msg) {
201
+ const json = JSON.stringify(msg);
202
+ const header = `Content-Length: ${Buffer.byteLength(json, "utf-8")}\r
203
+ \r
204
+ `;
205
+ try {
206
+ this.proc.stdin.write(header + json);
207
+ } catch {
208
+ this.isConnected = false;
209
+ }
210
+ }
211
+ async readLoop() {
212
+ const reader = this.proc.stdout.getReader();
213
+ const decoder = new TextDecoder;
214
+ try {
215
+ while (this.isConnected) {
216
+ const { done, value } = await reader.read();
217
+ if (done)
218
+ break;
219
+ this.buffer += decoder.decode(value, { stream: true });
220
+ this.processBuffer();
221
+ }
222
+ } catch {} finally {
223
+ this.isConnected = false;
224
+ const error = new Error("DAP adapter process terminated");
225
+ for (const [id, pending] of this.pending) {
226
+ clearTimeout(pending.timer);
227
+ pending.reject(error);
228
+ this.pending.delete(id);
229
+ }
230
+ }
231
+ }
232
+ processBuffer() {
233
+ while (true) {
234
+ const headerEnd = this.buffer.indexOf(`\r
235
+ \r
236
+ `);
237
+ if (headerEnd === -1)
238
+ return;
239
+ const header = this.buffer.slice(0, headerEnd);
240
+ const match = /Content-Length:\s*(\d+)/i.exec(header);
241
+ if (!match?.[1]) {
242
+ this.buffer = this.buffer.slice(headerEnd + 4);
243
+ continue;
244
+ }
245
+ const contentLength = parseInt(match[1], 10);
246
+ const bodyStart = headerEnd + 4;
247
+ const bodyEnd = bodyStart + contentLength;
248
+ if (this.buffer.length < bodyEnd)
249
+ return;
250
+ const body = this.buffer.slice(bodyStart, bodyEnd);
251
+ this.buffer = this.buffer.slice(bodyEnd);
252
+ this.handleMessage(body);
253
+ }
254
+ }
255
+ handleMessage(data) {
256
+ let parsed;
257
+ try {
258
+ parsed = JSON.parse(data);
259
+ } catch {
260
+ return;
261
+ }
262
+ if (parsed.type === "response") {
263
+ const response = parsed;
264
+ const pending = this.pending.get(response.request_seq);
265
+ if (!pending)
266
+ return;
267
+ this.pending.delete(response.request_seq);
268
+ clearTimeout(pending.timer);
269
+ if (!response.success) {
270
+ pending.reject(new Error(`DAP error (${response.command}): ${response.message ?? "unknown error"}`));
271
+ } else {
272
+ pending.resolve(response);
273
+ }
274
+ } else if (parsed.type === "event") {
275
+ const event = parsed;
276
+ const handlers = this.listeners.get(event.event);
277
+ if (handlers) {
278
+ for (const handler of handlers) {
279
+ handler(event.body);
280
+ }
281
+ }
282
+ }
283
+ }
284
+ async drainStderr() {
285
+ const reader = this.proc.stderr.getReader();
286
+ try {
287
+ while (true) {
288
+ const { done } = await reader.read();
289
+ if (done)
290
+ break;
291
+ }
292
+ } catch {}
293
+ }
294
+ }
295
+ var DEFAULT_TIMEOUT_MS = 30000;
296
+
297
+ // src/dap/session.ts
298
+ function resolveAdapterCommand(runtime) {
299
+ switch (runtime) {
300
+ case "lldb":
301
+ case "lldb-dap": {
302
+ const brewPath = "/opt/homebrew/opt/llvm/bin/lldb-dap";
303
+ return [brewPath];
304
+ }
305
+ case "codelldb":
306
+ return ["codelldb", "--port", "0"];
307
+ default:
308
+ return [runtime];
309
+ }
310
+ }
311
+
312
+ class DapSession {
313
+ dap = null;
314
+ refs = new RefTable;
315
+ _state = "idle";
316
+ _pauseInfo = null;
317
+ _session;
318
+ _runtime;
319
+ _startTime = Date.now();
320
+ _threadId = 1;
321
+ _stackFrames = [];
322
+ _consoleMessages = [];
323
+ _exceptionEntries = [];
324
+ capabilities = {};
325
+ breakpoints = new Map;
326
+ allBreakpoints = [];
327
+ functionBreakpoints = [];
328
+ stoppedWaiter = null;
329
+ _stackFetchPromise = null;
330
+ constructor(session, runtime) {
331
+ this._session = session;
332
+ this._runtime = runtime;
333
+ }
334
+ async launch(command, options = {}) {
335
+ if (this._state !== "idle") {
336
+ throw new Error("Session already has an active debug target");
337
+ }
338
+ const adapterCmd = resolveAdapterCommand(this._runtime);
339
+ this.dap = DapClient.spawn(adapterCmd);
340
+ this.setupEventHandlers();
341
+ await this.initializeAdapter();
342
+ const program = options.program ?? command[0];
343
+ const programArgs = options.args ?? command.slice(1);
344
+ const launchArgs = {
345
+ program,
346
+ args: programArgs,
347
+ stopOnEntry: options.brk ?? true,
348
+ cwd: process.cwd()
349
+ };
350
+ await this.dap.send("launch", launchArgs);
351
+ await this.dap.send("configurationDone");
352
+ if (options.brk !== false) {
353
+ await this.waitForStop(5000);
354
+ }
355
+ const result = {
356
+ pid: this.dap.pid,
357
+ wsUrl: `dap://${this._runtime}`,
358
+ paused: this.isPaused()
359
+ };
360
+ if (this._pauseInfo) {
361
+ result.pauseInfo = this._pauseInfo;
362
+ }
363
+ return result;
364
+ }
365
+ async attach(target) {
366
+ if (this._state !== "idle") {
367
+ throw new Error("Session already has an active debug target");
368
+ }
369
+ const adapterCmd = resolveAdapterCommand(this._runtime);
370
+ this.dap = DapClient.spawn(adapterCmd);
371
+ this.setupEventHandlers();
372
+ await this.initializeAdapter();
373
+ const pid = parseInt(target, 10);
374
+ const attachArgs = Number.isNaN(pid) ? { program: target, waitFor: true } : { pid };
375
+ await this.dap.send("attach", attachArgs);
376
+ await this.dap.send("configurationDone");
377
+ await this.waitForStop(5000).catch(() => {});
378
+ if (this._state === "idle") {
379
+ this._state = "running";
380
+ }
381
+ return { wsUrl: `dap://${this._runtime}/${target}` };
382
+ }
383
+ getStatus() {
384
+ return {
385
+ session: this._session,
386
+ state: this._state,
387
+ pid: this.dap?.pid,
388
+ wsUrl: this.dap ? `dap://${this._runtime}` : undefined,
389
+ pauseInfo: this._pauseInfo ?? undefined,
390
+ uptime: Math.floor((Date.now() - this._startTime) / 1000),
391
+ scriptCount: 0
392
+ };
393
+ }
394
+ async stop() {
395
+ if (this.dap) {
396
+ try {
397
+ await this.dap.send("disconnect", { terminateDebuggee: true });
398
+ } catch {}
399
+ this.dap.disconnect();
400
+ this.dap = null;
401
+ }
402
+ this._state = "idle";
403
+ this._pauseInfo = null;
404
+ this._stackFrames = [];
405
+ this.refs.clearAll();
406
+ this.breakpoints.clear();
407
+ this.allBreakpoints = [];
408
+ this.functionBreakpoints = [];
409
+ this._consoleMessages = [];
410
+ this._exceptionEntries = [];
411
+ }
412
+ async continue() {
413
+ this.requireConnected();
414
+ this.requirePaused();
415
+ const waiter = this.createStoppedWaiter(30000);
416
+ await this.getDap().send("continue", { threadId: this._threadId });
417
+ this._state = "running";
418
+ this._pauseInfo = null;
419
+ this._stackFrames = [];
420
+ this.refs.clearVolatile();
421
+ await waiter;
422
+ if (this.isPaused())
423
+ await this.fetchStackTrace();
424
+ }
425
+ async step(mode) {
426
+ this.requireConnected();
427
+ this.requirePaused();
428
+ const waiter = this.createStoppedWaiter(30000);
429
+ const command = mode === "into" ? "stepIn" : mode === "out" ? "stepOut" : "next";
430
+ await this.getDap().send(command, { threadId: this._threadId });
431
+ this._state = "running";
432
+ this._pauseInfo = null;
433
+ this.refs.clearVolatile();
434
+ await waiter;
435
+ if (this.isPaused())
436
+ await this.fetchStackTrace();
437
+ }
438
+ async pause() {
439
+ this.requireConnected();
440
+ if (this._state !== "running") {
441
+ throw new Error("Cannot pause: target is not running");
442
+ }
443
+ const waiter = this.createStoppedWaiter(5000);
444
+ await this.getDap().send("pause", { threadId: this._threadId });
445
+ await waiter;
446
+ if (this.isPaused())
447
+ await this.fetchStackTrace();
448
+ }
449
+ async setBreakpoint(file, line, options) {
450
+ this.requireConnected();
451
+ const entry = {
452
+ ref: "",
453
+ file,
454
+ line,
455
+ condition: options?.condition,
456
+ hitCondition: options?.hitCount ? String(options.hitCount) : undefined,
457
+ verified: false
458
+ };
459
+ let fileBreakpoints = this.breakpoints.get(file);
460
+ if (!fileBreakpoints) {
461
+ fileBreakpoints = [];
462
+ this.breakpoints.set(file, fileBreakpoints);
463
+ }
464
+ fileBreakpoints.push(entry);
465
+ this.allBreakpoints.push(entry);
466
+ const ref = this.refs.addBreakpoint(`dap-bp:${file}:${line}`, {
467
+ file,
468
+ line
469
+ });
470
+ entry.ref = ref;
471
+ await this.syncFileBreakpoints(file);
472
+ return {
473
+ ref,
474
+ location: { url: file, line: entry.actualLine ?? line }
475
+ };
476
+ }
477
+ async removeBreakpoint(ref) {
478
+ this.requireConnected();
479
+ const entry = this.allBreakpoints.find((bp) => bp.ref === ref);
480
+ if (!entry) {
481
+ throw new Error(`Unknown breakpoint ref: ${ref}`);
482
+ }
483
+ const fileBreakpoints = this.breakpoints.get(entry.file);
484
+ if (fileBreakpoints) {
485
+ const idx = fileBreakpoints.indexOf(entry);
486
+ if (idx !== -1)
487
+ fileBreakpoints.splice(idx, 1);
488
+ if (fileBreakpoints.length === 0) {
489
+ this.breakpoints.delete(entry.file);
490
+ }
491
+ }
492
+ const allIdx = this.allBreakpoints.indexOf(entry);
493
+ if (allIdx !== -1)
494
+ this.allBreakpoints.splice(allIdx, 1);
495
+ this.refs.remove(ref);
496
+ await this.syncFileBreakpoints(entry.file);
497
+ }
498
+ async removeAllBreakpoints() {
499
+ this.requireConnected();
500
+ const files = [...this.breakpoints.keys()];
501
+ this.breakpoints.clear();
502
+ this.allBreakpoints = [];
503
+ this.functionBreakpoints = [];
504
+ for (const entry of this.refs.list("BP")) {
505
+ this.refs.remove(entry.ref);
506
+ }
507
+ for (const file of files) {
508
+ await this.getDap().send("setBreakpoints", {
509
+ source: { path: file },
510
+ breakpoints: []
511
+ });
512
+ }
513
+ await this.getDap().send("setFunctionBreakpoints", { breakpoints: [] });
514
+ }
515
+ listBreakpoints() {
516
+ const fileBps = this.allBreakpoints.map((bp) => ({
517
+ ref: bp.ref,
518
+ type: "BP",
519
+ url: bp.file,
520
+ line: bp.actualLine ?? bp.line,
521
+ condition: bp.condition
522
+ }));
523
+ const fnBps = this.functionBreakpoints.map((bp) => ({
524
+ ref: bp.ref,
525
+ type: "BP",
526
+ url: bp.name,
527
+ line: 0,
528
+ condition: bp.condition
529
+ }));
530
+ return [...fileBps, ...fnBps];
531
+ }
532
+ async setFunctionBreakpoint(name, options) {
533
+ this.requireConnected();
534
+ const entry = {
535
+ ref: "",
536
+ name,
537
+ condition: options?.condition,
538
+ hitCondition: options?.hitCount ? String(options.hitCount) : undefined,
539
+ verified: false
540
+ };
541
+ this.functionBreakpoints.push(entry);
542
+ const ref = this.refs.addBreakpoint(`dap-fn:${name}`, {
543
+ file: name,
544
+ line: 0
545
+ });
546
+ entry.ref = ref;
547
+ await this.syncFunctionBreakpoints();
548
+ return { ref };
549
+ }
550
+ async removeFunctionBreakpoint(ref) {
551
+ this.requireConnected();
552
+ const idx = this.functionBreakpoints.findIndex((bp) => bp.ref === ref);
553
+ if (idx === -1) {
554
+ throw new Error(`Unknown function breakpoint ref: ${ref}`);
555
+ }
556
+ this.functionBreakpoints.splice(idx, 1);
557
+ this.refs.remove(ref);
558
+ await this.syncFunctionBreakpoints();
559
+ }
560
+ async syncFunctionBreakpoints() {
561
+ const dapBps = this.functionBreakpoints.map((bp) => ({
562
+ name: bp.name,
563
+ condition: bp.condition,
564
+ hitCondition: bp.hitCondition
565
+ }));
566
+ const response = await this.getDap().send("setFunctionBreakpoints", {
567
+ breakpoints: dapBps
568
+ });
569
+ const body = response.body;
570
+ const resultBps = body?.breakpoints ?? [];
571
+ for (let i = 0;i < this.functionBreakpoints.length; i++) {
572
+ const entry = this.functionBreakpoints[i];
573
+ const result = resultBps[i];
574
+ if (entry && result) {
575
+ entry.verified = result.verified ?? false;
576
+ }
577
+ }
578
+ }
579
+ async eval(expression, options = {}) {
580
+ this.requireConnected();
581
+ this.requirePaused();
582
+ await this.ensureStack();
583
+ const frameId = this.resolveFrameId(options.frame);
584
+ const response = await this.getDap().send("evaluate", {
585
+ expression,
586
+ frameId,
587
+ context: "repl"
588
+ });
589
+ const body = response.body;
590
+ const remoteId = body.variablesReference > 0 ? String(body.variablesReference) : `eval:${Date.now()}`;
591
+ const ref = this.refs.addVar(remoteId, expression);
592
+ return {
593
+ ref,
594
+ type: body.type ?? "unknown",
595
+ value: body.result,
596
+ objectId: body.variablesReference > 0 ? String(body.variablesReference) : undefined
597
+ };
598
+ }
599
+ async getVars(options = {}) {
600
+ this.requireConnected();
601
+ this.requirePaused();
602
+ await this.ensureStack();
603
+ const frameId = this.resolveFrameId(options.frame);
604
+ const scopesResponse = await this.getDap().send("scopes", { frameId });
605
+ const scopes = scopesResponse.body.scopes;
606
+ const result = [];
607
+ const scopesToFetch = options.allScopes ? scopes : scopes.filter((s) => !s.expensive).slice(0, 2);
608
+ for (const scope of scopesToFetch) {
609
+ const varsResponse = await this.getDap().send("variables", {
610
+ variablesReference: scope.variablesReference
611
+ });
612
+ const variables = varsResponse.body.variables;
613
+ for (const v of variables) {
614
+ if (options.names && !options.names.includes(v.name))
615
+ continue;
616
+ const remoteId = v.variablesReference > 0 ? String(v.variablesReference) : `var:${v.name}:${Date.now()}`;
617
+ const ref = this.refs.addVar(remoteId, v.name);
618
+ result.push({
619
+ ref,
620
+ name: v.name,
621
+ type: v.type ?? "unknown",
622
+ value: v.value
623
+ });
624
+ }
625
+ }
626
+ return result;
627
+ }
628
+ async getProps(ref, _options = {}) {
629
+ this.requireConnected();
630
+ const remoteId = this.refs.resolveId(ref);
631
+ if (!remoteId) {
632
+ throw new Error(`Unknown ref: ${ref}`);
633
+ }
634
+ const variablesReference = parseInt(remoteId, 10);
635
+ if (Number.isNaN(variablesReference) || variablesReference <= 0) {
636
+ return [];
637
+ }
638
+ const response = await this.getDap().send("variables", { variablesReference });
639
+ const variables = response.body.variables;
640
+ return variables.map((v) => {
641
+ const childRemoteId = v.variablesReference > 0 ? String(v.variablesReference) : `prop:${v.name}:${Date.now()}`;
642
+ const childRef = v.variablesReference > 0 ? this.refs.addVar(childRemoteId, v.name) : undefined;
643
+ return {
644
+ ref: childRef,
645
+ name: v.name,
646
+ type: v.type ?? "unknown",
647
+ value: v.value,
648
+ isOwn: true
649
+ };
650
+ });
651
+ }
652
+ getStack(_options = {}) {
653
+ return this._stackFrames.map((frame) => {
654
+ const ref = this.refs.addFrame(String(frame.id), frame.name);
655
+ return {
656
+ ref,
657
+ functionName: frame.name,
658
+ file: frame.file ?? "<unknown>",
659
+ line: frame.line,
660
+ column: frame.column > 0 ? frame.column : undefined
661
+ };
662
+ });
663
+ }
664
+ async getSource(options = {}) {
665
+ const file = options.file ?? this._pauseInfo?.url;
666
+ if (!file) {
667
+ throw new Error("No source file available. Specify a file path.");
668
+ }
669
+ let content;
670
+ try {
671
+ content = await Bun.file(file).text();
672
+ } catch {
673
+ throw new Error(`Cannot read source file: ${file}`);
674
+ }
675
+ const allLines = content.split(`
676
+ `);
677
+ const currentLine = this._pauseInfo?.line;
678
+ const windowSize = options.lines ?? 10;
679
+ let startLine;
680
+ let endLine;
681
+ if (options.all) {
682
+ startLine = 1;
683
+ endLine = allLines.length;
684
+ } else if (currentLine !== undefined) {
685
+ startLine = Math.max(1, currentLine - windowSize);
686
+ endLine = Math.min(allLines.length, currentLine + windowSize);
687
+ } else {
688
+ startLine = 1;
689
+ endLine = Math.min(allLines.length, windowSize * 2);
690
+ }
691
+ const lines = [];
692
+ for (let i = startLine;i <= endLine; i++) {
693
+ const lineObj = {
694
+ line: i,
695
+ text: allLines[i - 1] ?? ""
696
+ };
697
+ if (currentLine !== undefined && i === currentLine) {
698
+ lineObj.current = true;
699
+ }
700
+ lines.push(lineObj);
701
+ }
702
+ return { url: file, lines };
703
+ }
704
+ async buildState(options = {}) {
705
+ if (this.isPaused())
706
+ await this.ensureStack();
707
+ const snapshot = {
708
+ status: this._state
709
+ };
710
+ if (this._state === "paused" && this._pauseInfo) {
711
+ snapshot.reason = this._pauseInfo.reason;
712
+ if (this._pauseInfo.url && this._pauseInfo.line !== undefined) {
713
+ snapshot.location = {
714
+ url: this._pauseInfo.url,
715
+ line: this._pauseInfo.line,
716
+ column: this._pauseInfo.column
717
+ };
718
+ }
719
+ }
720
+ if (this._state === "paused" && options.code !== false) {
721
+ try {
722
+ const source = await this.getSource({ lines: options.lines });
723
+ snapshot.source = source;
724
+ } catch {}
725
+ }
726
+ if (this._state === "paused" && (options.vars !== false || !options.compact)) {
727
+ try {
728
+ const vars = await this.getVars({ frame: options.frame, allScopes: options.allScopes });
729
+ snapshot.vars = vars.map((v) => ({
730
+ ref: v.ref,
731
+ name: v.name,
732
+ value: v.value,
733
+ scope: "local"
734
+ }));
735
+ } catch {}
736
+ }
737
+ if (this._state === "paused" && options.stack !== false) {
738
+ try {
739
+ snapshot.stack = this.getStack();
740
+ } catch {}
741
+ }
742
+ if (options.breakpoints !== false) {
743
+ snapshot.breakpointCount = this.allBreakpoints.length;
744
+ }
745
+ return snapshot;
746
+ }
747
+ getConsoleMessages(options = {}) {
748
+ let msgs = this._consoleMessages;
749
+ if (options.level) {
750
+ msgs = msgs.filter((m) => m.level === options.level);
751
+ }
752
+ if (options.since !== undefined) {
753
+ const since = options.since;
754
+ msgs = msgs.filter((m) => m.timestamp >= since);
755
+ }
756
+ if (options.clear) {
757
+ this._consoleMessages = [];
758
+ }
759
+ return msgs;
760
+ }
761
+ getExceptions(options = {}) {
762
+ let entries = this._exceptionEntries;
763
+ if (options.since !== undefined) {
764
+ const since = options.since;
765
+ entries = entries.filter((e) => e.timestamp >= since);
766
+ }
767
+ return entries;
768
+ }
769
+ async setLogpoint(_file, _line, _template, _options) {
770
+ throw new Error("Logpoints are not supported in DAP mode. Use breakpoints with conditions instead.");
771
+ }
772
+ async setExceptionPause(mode) {
773
+ this.requireConnected();
774
+ const available = this.capabilities.exceptionBreakpointFilters ?? [];
775
+ const filterIds = available.map((f) => f.filter);
776
+ let filters;
777
+ if (mode === "none") {
778
+ filters = [];
779
+ } else if (mode === "all") {
780
+ filters = filterIds;
781
+ } else {
782
+ filters = filterIds.filter((id) => id.includes(mode));
783
+ if (filters.length === 0)
784
+ filters = filterIds;
785
+ }
786
+ await this.getDap().send("setExceptionBreakpoints", { filters });
787
+ }
788
+ async toggleBreakpoint(_ref) {
789
+ throw new Error("Breakpoint toggling is not yet supported in DAP mode. Use break-rm and break.");
790
+ }
791
+ async getBreakableLocations(_file, _startLine, _endLine) {
792
+ throw new Error("Breakable locations are not supported in DAP mode.");
793
+ }
794
+ async hotpatch(_file, _source, _options) {
795
+ throw new Error("Hot-patching is not supported in DAP mode.");
796
+ }
797
+ async searchInScripts(_query, _options) {
798
+ throw new Error("Script search is not supported in DAP mode. Use your shell to search source files.");
799
+ }
800
+ async setVariable(varName, value, options = {}) {
801
+ this.requireConnected();
802
+ this.requirePaused();
803
+ await this.ensureStack();
804
+ const frameId = this.resolveFrameId(options.frame);
805
+ const scopesResponse = await this.getDap().send("scopes", { frameId });
806
+ const scopes = scopesResponse.body.scopes;
807
+ for (const scope of scopes) {
808
+ try {
809
+ const response = await this.getDap().send("setVariable", {
810
+ variablesReference: scope.variablesReference,
811
+ name: varName,
812
+ value
813
+ });
814
+ const body = response.body;
815
+ return { name: varName, newValue: body.value, type: body.type ?? "unknown" };
816
+ } catch {}
817
+ }
818
+ throw new Error(`Variable "${varName}" not found in any scope`);
819
+ }
820
+ async setReturnValue(_value) {
821
+ throw new Error("Setting return values is not supported in DAP mode.");
822
+ }
823
+ async restartFrame(_frameRef) {
824
+ throw new Error("Frame restart is not supported in DAP mode.");
825
+ }
826
+ async runTo(_file, _line) {
827
+ throw new Error("Run-to-location is not yet supported in DAP mode. Set a breakpoint and continue.");
828
+ }
829
+ getScripts(_filter) {
830
+ return [];
831
+ }
832
+ async addBlackbox(_patterns) {
833
+ throw new Error("Blackboxing is not supported in DAP mode.");
834
+ }
835
+ listBlackbox() {
836
+ return [];
837
+ }
838
+ async removeBlackbox(_patterns) {
839
+ throw new Error("Blackboxing is not supported in DAP mode.");
840
+ }
841
+ async restart() {
842
+ throw new Error("Restart is not yet supported in DAP mode. Use stop + launch.");
843
+ }
844
+ get sourceMapResolver() {
845
+ return {
846
+ findScriptForSource: () => null,
847
+ getInfo: () => null,
848
+ getAllInfos: () => [],
849
+ setDisabled: () => {}
850
+ };
851
+ }
852
+ isPaused() {
853
+ return this._state === "paused";
854
+ }
855
+ async ensureStack() {
856
+ if (this.isPaused() && this._stackFrames.length === 0) {
857
+ await this.fetchStackTrace();
858
+ }
859
+ }
860
+ getDap() {
861
+ if (!this.dap || !this.dap.connected) {
862
+ throw new Error("Not connected to a debug adapter. Use launch or attach first.");
863
+ }
864
+ return this.dap;
865
+ }
866
+ requireConnected() {
867
+ this.getDap();
868
+ }
869
+ requirePaused() {
870
+ if (!this.isPaused()) {
871
+ throw new Error("Target is not paused. Use pause or wait for a breakpoint.");
872
+ }
873
+ }
874
+ async initializeAdapter() {
875
+ const response = await this.getDap().send("initialize", {
876
+ adapterID: this._runtime,
877
+ clientID: "agent-dbg",
878
+ clientName: "agent-dbg",
879
+ linesStartAt1: true,
880
+ columnsStartAt1: true,
881
+ pathFormat: "path",
882
+ supportsVariableType: true
883
+ });
884
+ this.capabilities = response.body ?? {};
885
+ }
886
+ setupEventHandlers() {
887
+ const dap = this.getDap();
888
+ dap.on("stopped", (body) => {
889
+ const event = body;
890
+ this._state = "paused";
891
+ if (event.threadId !== undefined) {
892
+ this._threadId = event.threadId;
893
+ }
894
+ this._pauseInfo = {
895
+ reason: event.reason
896
+ };
897
+ if (this.stoppedWaiter) {
898
+ this.stoppedWaiter.resolve();
899
+ this.stoppedWaiter = null;
900
+ } else {
901
+ this.fetchStackTrace().catch(() => {});
902
+ }
903
+ });
904
+ dap.on("continued", (_body) => {
905
+ this._state = "running";
906
+ this._pauseInfo = null;
907
+ this._stackFrames = [];
908
+ this.refs.clearVolatile();
909
+ });
910
+ dap.on("terminated", (_body) => {
911
+ this._state = "idle";
912
+ this._pauseInfo = null;
913
+ this._stackFrames = [];
914
+ this.stoppedWaiter?.resolve();
915
+ this.stoppedWaiter = null;
916
+ });
917
+ dap.on("exited", (_body) => {
918
+ this._state = "idle";
919
+ this._pauseInfo = null;
920
+ this.stoppedWaiter?.resolve();
921
+ this.stoppedWaiter = null;
922
+ });
923
+ dap.on("output", (body) => {
924
+ const event = body;
925
+ const category = event.category ?? "console";
926
+ if (category === "stdout" || category === "console") {
927
+ this._consoleMessages.push({
928
+ timestamp: Date.now(),
929
+ level: "log",
930
+ text: event.output.trimEnd(),
931
+ url: event.source?.path,
932
+ line: event.line
933
+ });
934
+ } else if (category === "stderr") {
935
+ this._consoleMessages.push({
936
+ timestamp: Date.now(),
937
+ level: "error",
938
+ text: event.output.trimEnd(),
939
+ url: event.source?.path,
940
+ line: event.line
941
+ });
942
+ }
943
+ if (this._consoleMessages.length > 1000) {
944
+ this._consoleMessages.shift();
945
+ }
946
+ });
947
+ }
948
+ async fetchStackTrace() {
949
+ if (this._stackFetchPromise) {
950
+ await this._stackFetchPromise;
951
+ return;
952
+ }
953
+ this._stackFetchPromise = this._fetchStackTraceImpl();
954
+ try {
955
+ await this._stackFetchPromise;
956
+ } finally {
957
+ this._stackFetchPromise = null;
958
+ }
959
+ }
960
+ async _fetchStackTraceImpl() {
961
+ if (!this.dap || this._state !== "paused")
962
+ return;
963
+ try {
964
+ const response = await this.dap.send("stackTrace", {
965
+ threadId: this._threadId,
966
+ startFrame: 0,
967
+ levels: 50
968
+ });
969
+ const body = response.body;
970
+ this._stackFrames = body.stackFrames.map((f) => ({
971
+ id: f.id,
972
+ name: f.name,
973
+ file: f.source?.path ?? f.source?.name,
974
+ line: f.line,
975
+ column: f.column
976
+ }));
977
+ const topFrame = this._stackFrames[0];
978
+ if (topFrame && this._pauseInfo) {
979
+ this._pauseInfo.url = topFrame.file;
980
+ this._pauseInfo.line = topFrame.line;
981
+ this._pauseInfo.column = topFrame.column > 0 ? topFrame.column : undefined;
982
+ this._pauseInfo.callFrameCount = this._stackFrames.length;
983
+ }
984
+ } catch {}
985
+ }
986
+ resolveFrameId(frameRef) {
987
+ if (!frameRef) {
988
+ const topFrame = this._stackFrames[0];
989
+ if (!topFrame) {
990
+ throw new Error("No stack frames available");
991
+ }
992
+ return topFrame.id;
993
+ }
994
+ const remoteId = this.refs.resolveId(frameRef);
995
+ if (!remoteId) {
996
+ throw new Error(`Unknown frame ref: ${frameRef}`);
997
+ }
998
+ return parseInt(remoteId, 10);
999
+ }
1000
+ async syncFileBreakpoints(file) {
1001
+ const entries = this.breakpoints.get(file) ?? [];
1002
+ const dapBreakpoints = entries.map((bp) => {
1003
+ const sbp = { line: bp.line };
1004
+ if (bp.condition)
1005
+ sbp.condition = bp.condition;
1006
+ if (bp.hitCondition)
1007
+ sbp.hitCondition = bp.hitCondition;
1008
+ return sbp;
1009
+ });
1010
+ const response = await this.getDap().send("setBreakpoints", {
1011
+ source: { path: file },
1012
+ breakpoints: dapBreakpoints
1013
+ });
1014
+ const body = response.body;
1015
+ for (let i = 0;i < entries.length && i < body.breakpoints.length; i++) {
1016
+ const bp = body.breakpoints[i];
1017
+ const entry = entries[i];
1018
+ if (bp && entry) {
1019
+ entry.dapId = bp.id;
1020
+ entry.verified = bp.verified;
1021
+ entry.actualLine = bp.line ?? entry.line;
1022
+ }
1023
+ }
1024
+ }
1025
+ createStoppedWaiter(timeoutMs) {
1026
+ return new Promise((resolve, reject) => {
1027
+ const timer = setTimeout(() => {
1028
+ this.stoppedWaiter = null;
1029
+ resolve();
1030
+ }, timeoutMs);
1031
+ this.stoppedWaiter = {
1032
+ resolve: () => {
1033
+ clearTimeout(timer);
1034
+ this.stoppedWaiter = null;
1035
+ resolve();
1036
+ },
1037
+ reject: (e) => {
1038
+ clearTimeout(timer);
1039
+ this.stoppedWaiter = null;
1040
+ reject(e);
1041
+ }
1042
+ };
1043
+ });
1044
+ }
1045
+ async waitForStop(timeoutMs) {
1046
+ if (!this.isPaused()) {
1047
+ await this.createStoppedWaiter(timeoutMs);
1048
+ }
1049
+ if (this.isPaused() && this._stackFrames.length === 0) {
1050
+ await this.fetchStackTrace();
1051
+ }
1052
+ }
1053
+ }
1054
+ var init_session = __esm(() => {
1055
+ init_ref_table();
1056
+ });
1057
+
15
1058
  // src/daemon/logger.ts
16
1059
  import { appendFileSync, writeFileSync } from "fs";
17
1060
 
@@ -6101,7 +7144,7 @@ var init_esm2 = __esm(() => {
6101
7144
  });
6102
7145
 
6103
7146
  // src/protocol/messages.ts
6104
- var PingRequest, LaunchRequest, AttachRequest, StatusRequest, StateRequest, ContinueRequest, StepRequest, PauseRequest, RunToRequest, BreakRequest, 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;
7147
+ 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;
6105
7148
  var init_messages = __esm(() => {
6106
7149
  init_esm2();
6107
7150
  PingRequest = exports_external.object({ cmd: exports_external.literal("ping") });
@@ -6110,13 +7153,15 @@ var init_messages = __esm(() => {
6110
7153
  args: exports_external.object({
6111
7154
  command: exports_external.array(exports_external.string()),
6112
7155
  brk: exports_external.optional(exports_external.boolean()),
6113
- port: exports_external.optional(exports_external.number())
7156
+ port: exports_external.optional(exports_external.number()),
7157
+ runtime: exports_external.optional(exports_external.string())
6114
7158
  })
6115
7159
  });
6116
7160
  AttachRequest = exports_external.object({
6117
7161
  cmd: exports_external.literal("attach"),
6118
7162
  args: exports_external.object({
6119
- target: exports_external.string()
7163
+ target: exports_external.string(),
7164
+ runtime: exports_external.optional(exports_external.string())
6120
7165
  })
6121
7166
  });
6122
7167
  StatusRequest = exports_external.object({ cmd: exports_external.literal("status") });
@@ -6157,7 +7202,15 @@ var init_messages = __esm(() => {
6157
7202
  line: exports_external.number(),
6158
7203
  condition: exports_external.optional(exports_external.string()),
6159
7204
  hitCount: exports_external.optional(exports_external.number()),
6160
- urlRegex: exports_external.optional(exports_external.string())
7205
+ urlRegex: exports_external.optional(exports_external.string()),
7206
+ column: exports_external.optional(exports_external.number())
7207
+ })
7208
+ });
7209
+ BreakFnRequest = exports_external.object({
7210
+ cmd: exports_external.literal("break-fn"),
7211
+ args: exports_external.object({
7212
+ name: exports_external.string(),
7213
+ condition: exports_external.optional(exports_external.string())
6161
7214
  })
6162
7215
  });
6163
7216
  BreakRmRequest = exports_external.object({
@@ -6335,6 +7388,7 @@ var init_messages = __esm(() => {
6335
7388
  PauseRequest,
6336
7389
  RunToRequest,
6337
7390
  BreakRequest,
7391
+ BreakFnRequest,
6338
7392
  BreakRmRequest,
6339
7393
  BreakLsRequest,
6340
7394
  LogpointRequest,
@@ -6414,7 +7468,7 @@ class DaemonServer {
6414
7468
  unix: this.socketPath,
6415
7469
  socket: {
6416
7470
  open(socket) {
6417
- socket.data = { buffer: "" };
7471
+ socket.data = { buffer: "", pendingWrite: null, pendingOffset: 0 };
6418
7472
  server.resetIdleTimer();
6419
7473
  },
6420
7474
  data(socket, data) {
@@ -6427,6 +7481,9 @@ class DaemonServer {
6427
7481
  socket.data.buffer = socket.data.buffer.slice(newlineIdx + 1);
6428
7482
  server.handleMessage(socket, line);
6429
7483
  },
7484
+ drain(socket) {
7485
+ server.flushPending(socket);
7486
+ },
6430
7487
  close() {},
6431
7488
  error(_socket, error3) {
6432
7489
  server.logger?.error("socket.error", error3.message);
@@ -6436,60 +7493,69 @@ class DaemonServer {
6436
7493
  });
6437
7494
  this.resetIdleTimer();
6438
7495
  }
7496
+ flushPending(socket) {
7497
+ const data = socket.data;
7498
+ if (!data.pendingWrite)
7499
+ return;
7500
+ while (data.pendingOffset < data.pendingWrite.length) {
7501
+ const written = socket.write(data.pendingWrite.subarray(data.pendingOffset));
7502
+ if (written === 0) {
7503
+ return;
7504
+ }
7505
+ data.pendingOffset += written;
7506
+ }
7507
+ data.pendingWrite = null;
7508
+ data.pendingOffset = 0;
7509
+ socket.end();
7510
+ }
7511
+ sendResponse(socket, response) {
7512
+ const payload = Buffer.from(`${JSON.stringify(response)}
7513
+ `);
7514
+ const written = socket.write(payload);
7515
+ if (written < payload.length) {
7516
+ socket.data.pendingWrite = payload;
7517
+ socket.data.pendingOffset = written;
7518
+ } else {
7519
+ socket.end();
7520
+ }
7521
+ }
6439
7522
  handleMessage(socket, line) {
6440
7523
  let json2;
6441
7524
  try {
6442
7525
  json2 = JSON.parse(line);
6443
7526
  } catch {
6444
- const errResponse = {
6445
- ok: false,
6446
- error: "Invalid JSON"
6447
- };
6448
- socket.write(`${JSON.stringify(errResponse)}
6449
- `);
6450
- socket.end();
7527
+ this.sendResponse(socket, { ok: false, error: "Invalid JSON" });
6451
7528
  return;
6452
7529
  }
6453
7530
  const parsed = DaemonRequestSchema.safeParse(json2);
6454
7531
  if (!parsed.success) {
6455
7532
  const obj = json2;
6456
7533
  const cmd = obj && typeof obj === "object" && typeof obj.cmd === "string" ? obj.cmd : undefined;
6457
- const errResponse = cmd ? {
7534
+ this.sendResponse(socket, cmd ? {
6458
7535
  ok: false,
6459
7536
  error: `Unknown command: ${cmd}`,
6460
7537
  suggestion: "-> Try: agent-dbg --help"
6461
7538
  } : {
6462
7539
  ok: false,
6463
7540
  error: "Invalid request: must have { cmd: string, args: object }"
6464
- };
6465
- socket.write(`${JSON.stringify(errResponse)}
6466
- `);
6467
- socket.end();
7541
+ });
6468
7542
  return;
6469
7543
  }
6470
7544
  const request = parsed.data;
6471
7545
  if (!this.handler) {
6472
- const errResponse = {
7546
+ this.sendResponse(socket, {
6473
7547
  ok: false,
6474
7548
  error: "No request handler registered"
6475
- };
6476
- socket.write(`${JSON.stringify(errResponse)}
6477
- `);
6478
- socket.end();
7549
+ });
6479
7550
  return;
6480
7551
  }
6481
7552
  this.handler(request).then((response) => {
6482
- socket.write(`${JSON.stringify(response)}
6483
- `);
6484
- socket.end();
7553
+ this.sendResponse(socket, response);
6485
7554
  }).catch((err) => {
6486
- const errResponse = {
7555
+ this.sendResponse(socket, {
6487
7556
  ok: false,
6488
7557
  error: err instanceof Error ? err.message : String(err)
6489
- };
6490
- socket.write(`${JSON.stringify(errResponse)}
6491
- `);
6492
- socket.end();
7558
+ });
6493
7559
  });
6494
7560
  }
6495
7561
  resetIdleTimer() {
@@ -6582,7 +7648,7 @@ class CdpClient {
6582
7648
  this.pending.delete(id);
6583
7649
  this.sentMethods.delete(id);
6584
7650
  reject(new Error(`CDP request timed out: ${method} (id=${id})`));
6585
- }, DEFAULT_TIMEOUT_MS);
7651
+ }, DEFAULT_TIMEOUT_MS2);
6586
7652
  this.pending.set(id, { resolve, reject, timer });
6587
7653
  this.ws.send(JSON.stringify(request));
6588
7654
  });
@@ -6686,7 +7752,7 @@ class CdpClient {
6686
7752
  }
6687
7753
  }
6688
7754
  }
6689
- var DEFAULT_TIMEOUT_MS = 30000;
7755
+ var DEFAULT_TIMEOUT_MS2 = 30000;
6690
7756
 
6691
7757
  // src/cdp/logger.ts
6692
7758
  import { appendFileSync as appendFileSync2, writeFileSync as writeFileSync3 } from "fs";
@@ -6943,101 +8009,6 @@ function formatValue(obj, maxLen = 80) {
6943
8009
  return truncate(obj.description ?? String(obj.value ?? obj.type), maxLen);
6944
8010
  }
6945
8011
 
6946
- // src/refs/ref-table.ts
6947
- class RefTable {
6948
- entries = new Map;
6949
- counters = {
6950
- v: 1,
6951
- f: 0,
6952
- o: 1,
6953
- BP: 1,
6954
- LP: 1,
6955
- HS: 1
6956
- };
6957
- addVar(remoteId, name, meta) {
6958
- return this.add("v", remoteId, name, meta);
6959
- }
6960
- addFrame(remoteId, name, meta) {
6961
- return this.add("f", remoteId, name, meta);
6962
- }
6963
- addObject(remoteId, name, meta) {
6964
- return this.add("o", remoteId, name, meta);
6965
- }
6966
- addBreakpoint(remoteId, meta) {
6967
- return this.add("BP", remoteId, undefined, meta);
6968
- }
6969
- addLogpoint(remoteId, meta) {
6970
- return this.add("LP", remoteId, undefined, meta);
6971
- }
6972
- addHeapSnapshot(remoteId, meta) {
6973
- return this.add("HS", remoteId, undefined, meta);
6974
- }
6975
- resolve(ref) {
6976
- return this.entries.get(ref);
6977
- }
6978
- resolveId(ref) {
6979
- return this.entries.get(ref)?.remoteId;
6980
- }
6981
- clearVolatile() {
6982
- for (const [key, entry] of this.entries) {
6983
- if (entry.type === "v" || entry.type === "f") {
6984
- this.entries.delete(key);
6985
- }
6986
- }
6987
- this.counters.v = 1;
6988
- this.counters.f = 0;
6989
- }
6990
- clearObjects() {
6991
- for (const [key, entry] of this.entries) {
6992
- if (entry.type === "o") {
6993
- this.entries.delete(key);
6994
- }
6995
- }
6996
- this.counters.o = 1;
6997
- }
6998
- clearAll() {
6999
- this.entries.clear();
7000
- this.counters = { v: 1, f: 0, o: 1, BP: 1, LP: 1, HS: 1 };
7001
- }
7002
- list(type) {
7003
- const result = [];
7004
- for (const entry of this.entries.values()) {
7005
- if (entry.type === type) {
7006
- result.push(entry);
7007
- }
7008
- }
7009
- return result;
7010
- }
7011
- remove(ref) {
7012
- return this.entries.delete(ref);
7013
- }
7014
- add(type, remoteId, name, meta) {
7015
- const num = this.counters[type];
7016
- this.counters[type] = num + 1;
7017
- const ref = `${PREFIXES[type]}${num}`;
7018
- const entry = { ref, type, remoteId };
7019
- if (name !== undefined) {
7020
- entry.name = name;
7021
- }
7022
- if (meta !== undefined) {
7023
- entry.meta = meta;
7024
- }
7025
- this.entries.set(ref, entry);
7026
- return ref;
7027
- }
7028
- }
7029
- var PREFIXES;
7030
- var init_ref_table = __esm(() => {
7031
- PREFIXES = {
7032
- v: "@v",
7033
- f: "@f",
7034
- o: "@o",
7035
- BP: "BP#",
7036
- LP: "LP#",
7037
- HS: "HS#"
7038
- };
7039
- });
7040
-
7041
8012
  // node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
7042
8013
  function decodeInteger(reader, relative) {
7043
8014
  let value = 0;
@@ -8861,7 +9832,8 @@ async function hotpatch(session, file2, newSource, options = {}) {
8861
9832
  }
8862
9833
  const setSourceParams = {
8863
9834
  scriptId,
8864
- scriptSource: newSource
9835
+ scriptSource: newSource,
9836
+ allowTopFrameEditing: true
8865
9837
  };
8866
9838
  if (options.dryRun) {
8867
9839
  setSourceParams.dryRun = true;
@@ -9629,7 +10601,7 @@ class DebugSession {
9629
10601
  }
9630
10602
  }
9631
10603
  var INSPECTOR_URL_REGEX, INSPECTOR_TIMEOUT_MS = 5000;
9632
- var init_session = __esm(() => {
10604
+ var init_session2 = __esm(() => {
9633
10605
  init_logger2();
9634
10606
  init_ref_table();
9635
10607
  init_resolver();
@@ -9643,12 +10615,19 @@ var init_session = __esm(() => {
9643
10615
 
9644
10616
  // src/daemon/entry.ts
9645
10617
  var exports_entry = {};
9646
- var daemonIdx, session, timeout = 300, timeoutIdx, daemonLogger, server, debugSession;
10618
+ function isDapRuntime(runtime) {
10619
+ return runtime !== undefined && runtime !== "node";
10620
+ }
10621
+ function activeSession() {
10622
+ return dapSession ?? cdpSession;
10623
+ }
10624
+ var daemonIdx, session, timeout = 300, timeoutIdx, daemonLogger, server, cdpSession, dapSession = null;
9647
10625
  var init_entry = __esm(async () => {
10626
+ init_session();
9648
10627
  init_logger();
9649
10628
  init_paths();
9650
10629
  init_server();
9651
- init_session();
10630
+ init_session2();
9652
10631
  daemonIdx = process.argv.indexOf("--daemon");
9653
10632
  session = daemonIdx !== -1 ? process.argv[daemonIdx + 1] : process.argv[2];
9654
10633
  if (!session) {
@@ -9673,52 +10652,62 @@ var init_entry = __esm(async () => {
9673
10652
  timeout
9674
10653
  });
9675
10654
  server = new DaemonServer(session, { idleTimeout: timeout, logger: daemonLogger });
9676
- debugSession = new DebugSession(session, { daemonLogger });
10655
+ cdpSession = new DebugSession(session, { daemonLogger });
9677
10656
  server.onRequest(async (req) => {
9678
10657
  switch (req.cmd) {
9679
10658
  case "ping":
9680
10659
  return { ok: true, data: "pong" };
9681
10660
  case "launch": {
9682
- const { command, brk = true, port } = req.args;
9683
- const result = await debugSession.launch(command, { brk, port });
10661
+ const { command, brk = true, port, runtime } = req.args;
10662
+ if (isDapRuntime(runtime)) {
10663
+ dapSession = new DapSession(session, runtime);
10664
+ const result2 = await dapSession.launch(command, { brk });
10665
+ return { ok: true, data: result2 };
10666
+ }
10667
+ const result = await cdpSession.launch(command, { brk, port });
9684
10668
  return { ok: true, data: result };
9685
10669
  }
9686
10670
  case "attach": {
9687
- const { target } = req.args;
9688
- const result = await debugSession.attach(target);
10671
+ const { target, runtime } = req.args;
10672
+ if (isDapRuntime(runtime)) {
10673
+ dapSession = new DapSession(session, runtime);
10674
+ const result2 = await dapSession.attach(target);
10675
+ return { ok: true, data: result2 };
10676
+ }
10677
+ const result = await cdpSession.attach(target);
9689
10678
  return { ok: true, data: result };
9690
10679
  }
9691
10680
  case "status":
9692
- return { ok: true, data: debugSession.getStatus() };
10681
+ return { ok: true, data: activeSession().getStatus() };
9693
10682
  case "state": {
9694
- const stateResult = await debugSession.buildState(req.args);
10683
+ const stateResult = await activeSession().buildState(req.args);
9695
10684
  return { ok: true, data: stateResult };
9696
10685
  }
9697
10686
  case "continue": {
9698
- await debugSession.continue();
9699
- const stateAfter = await debugSession.buildState();
10687
+ await activeSession().continue();
10688
+ const stateAfter = await activeSession().buildState();
9700
10689
  return { ok: true, data: stateAfter };
9701
10690
  }
9702
10691
  case "step": {
9703
10692
  const { mode = "over" } = req.args;
9704
- await debugSession.step(mode);
9705
- const stateAfter = await debugSession.buildState();
10693
+ await activeSession().step(mode);
10694
+ const stateAfter = await activeSession().buildState();
9706
10695
  return { ok: true, data: stateAfter };
9707
10696
  }
9708
10697
  case "pause": {
9709
- await debugSession.pause();
9710
- const stateAfter = await debugSession.buildState();
10698
+ await activeSession().pause();
10699
+ const stateAfter = await activeSession().buildState();
9711
10700
  return { ok: true, data: stateAfter };
9712
10701
  }
9713
10702
  case "run-to": {
9714
10703
  const { file: file2, line } = req.args;
9715
- await debugSession.runTo(file2, line);
9716
- const stateAfter = await debugSession.buildState();
10704
+ await activeSession().runTo(file2, line);
10705
+ const stateAfter = await activeSession().buildState();
9717
10706
  return { ok: true, data: stateAfter };
9718
10707
  }
9719
10708
  case "break": {
9720
10709
  const { file: file2, line, condition, hitCount, urlRegex: urlRegex2, column } = req.args;
9721
- const bpResult = await debugSession.setBreakpoint(file2, line, {
10710
+ const bpResult = await activeSession().setBreakpoint(file2, line, {
9722
10711
  condition,
9723
10712
  hitCount,
9724
10713
  urlRegex: urlRegex2,
@@ -9726,20 +10715,35 @@ var init_entry = __esm(async () => {
9726
10715
  });
9727
10716
  return { ok: true, data: bpResult };
9728
10717
  }
10718
+ case "break-fn": {
10719
+ const session2 = activeSession();
10720
+ if (!("setFunctionBreakpoint" in session2)) {
10721
+ return {
10722
+ ok: false,
10723
+ error: "Function breakpoints are only supported with DAP runtimes (e.g. --runtime lldb)",
10724
+ suggestion: "Use 'break <file>:<line>' for CDP sessions"
10725
+ };
10726
+ }
10727
+ const { name, condition } = req.args;
10728
+ const bpResult = await session2.setFunctionBreakpoint(name, {
10729
+ condition
10730
+ });
10731
+ return { ok: true, data: bpResult };
10732
+ }
9729
10733
  case "break-rm": {
9730
10734
  const { ref } = req.args;
9731
10735
  if (ref === "all") {
9732
- await debugSession.removeAllBreakpoints();
10736
+ await activeSession().removeAllBreakpoints();
9733
10737
  return { ok: true, data: "all removed" };
9734
10738
  }
9735
- await debugSession.removeBreakpoint(ref);
10739
+ await activeSession().removeBreakpoint(ref);
9736
10740
  return { ok: true, data: "removed" };
9737
10741
  }
9738
10742
  case "break-ls":
9739
- return { ok: true, data: debugSession.listBreakpoints() };
10743
+ return { ok: true, data: activeSession().listBreakpoints() };
9740
10744
  case "logpoint": {
9741
10745
  const { file: file2, line, template, condition, maxEmissions } = req.args;
9742
- const lpResult = await debugSession.setLogpoint(file2, line, template, {
10746
+ const lpResult = await activeSession().setLogpoint(file2, line, template, {
9743
10747
  condition,
9744
10748
  maxEmissions
9745
10749
  });
@@ -9747,114 +10751,115 @@ var init_entry = __esm(async () => {
9747
10751
  }
9748
10752
  case "catch": {
9749
10753
  const { mode } = req.args;
9750
- await debugSession.setExceptionPause(mode);
10754
+ await activeSession().setExceptionPause(mode);
9751
10755
  return { ok: true, data: mode };
9752
10756
  }
9753
10757
  case "source": {
9754
- const sourceResult = await debugSession.getSource(req.args);
10758
+ const sourceResult = await activeSession().getSource(req.args);
9755
10759
  return { ok: true, data: sourceResult };
9756
10760
  }
9757
10761
  case "scripts": {
9758
10762
  const { filter } = req.args;
9759
- const scriptsResult = debugSession.getScripts(filter);
10763
+ const scriptsResult = activeSession().getScripts(filter);
9760
10764
  return { ok: true, data: scriptsResult };
9761
10765
  }
9762
10766
  case "stack": {
9763
- const stackResult = debugSession.getStack(req.args);
10767
+ const stackResult = activeSession().getStack(req.args);
9764
10768
  return { ok: true, data: stackResult };
9765
10769
  }
9766
10770
  case "search": {
9767
10771
  const { query, ...searchOptions } = req.args;
9768
- const searchResult = await debugSession.searchInScripts(query, searchOptions);
10772
+ const searchResult = await activeSession().searchInScripts(query, searchOptions);
9769
10773
  return { ok: true, data: searchResult };
9770
10774
  }
9771
10775
  case "console": {
9772
- const consoleResult = debugSession.getConsoleMessages(req.args);
10776
+ const consoleResult = activeSession().getConsoleMessages(req.args);
9773
10777
  return { ok: true, data: consoleResult };
9774
10778
  }
9775
10779
  case "exceptions": {
9776
- const exceptionsResult = debugSession.getExceptions(req.args);
10780
+ const exceptionsResult = activeSession().getExceptions(req.args);
9777
10781
  return { ok: true, data: exceptionsResult };
9778
10782
  }
9779
10783
  case "eval": {
9780
10784
  const { expression, ...evalOptions } = req.args;
9781
- const evalResult = await debugSession.eval(expression, evalOptions);
10785
+ const evalResult = await activeSession().eval(expression, evalOptions);
9782
10786
  return { ok: true, data: evalResult };
9783
10787
  }
9784
10788
  case "vars": {
9785
- const varsResult = await debugSession.getVars(req.args);
10789
+ const varsResult = await activeSession().getVars(req.args);
9786
10790
  return { ok: true, data: varsResult };
9787
10791
  }
9788
10792
  case "props": {
9789
10793
  const { ref, ...propsOptions } = req.args;
9790
- const propsResult = await debugSession.getProps(ref, propsOptions);
10794
+ const propsResult = await activeSession().getProps(ref, propsOptions);
9791
10795
  return { ok: true, data: propsResult };
9792
10796
  }
9793
10797
  case "blackbox": {
9794
10798
  const { patterns } = req.args;
9795
- const result = await debugSession.addBlackbox(patterns);
10799
+ const result = await activeSession().addBlackbox(patterns);
9796
10800
  return { ok: true, data: result };
9797
10801
  }
9798
10802
  case "blackbox-ls": {
9799
- return { ok: true, data: debugSession.listBlackbox() };
10803
+ return { ok: true, data: activeSession().listBlackbox() };
9800
10804
  }
9801
10805
  case "blackbox-rm": {
9802
10806
  const { patterns } = req.args;
9803
- const result = await debugSession.removeBlackbox(patterns);
10807
+ const result = await activeSession().removeBlackbox(patterns);
9804
10808
  return { ok: true, data: result };
9805
10809
  }
9806
10810
  case "set": {
9807
10811
  const { name, value, frame } = req.args;
9808
- const result = await debugSession.setVariable(name, value, { frame });
10812
+ const result = await activeSession().setVariable(name, value, { frame });
9809
10813
  return { ok: true, data: result };
9810
10814
  }
9811
10815
  case "set-return": {
9812
10816
  const { value } = req.args;
9813
- const result = await debugSession.setReturnValue(value);
10817
+ const result = await activeSession().setReturnValue(value);
9814
10818
  return { ok: true, data: result };
9815
10819
  }
9816
10820
  case "hotpatch": {
9817
10821
  const { file: file2, source, dryRun } = req.args;
9818
- const result = await debugSession.hotpatch(file2, source, { dryRun });
10822
+ const result = await activeSession().hotpatch(file2, source, { dryRun });
9819
10823
  return { ok: true, data: result };
9820
10824
  }
9821
10825
  case "break-toggle": {
9822
10826
  const { ref } = req.args;
9823
- const toggleResult = await debugSession.toggleBreakpoint(ref);
10827
+ const toggleResult = await activeSession().toggleBreakpoint(ref);
9824
10828
  return { ok: true, data: toggleResult };
9825
10829
  }
9826
10830
  case "breakable": {
9827
10831
  const { file: file2, startLine, endLine } = req.args;
9828
- const breakableResult = await debugSession.getBreakableLocations(file2, startLine, endLine);
10832
+ const breakableResult = await activeSession().getBreakableLocations(file2, startLine, endLine);
9829
10833
  return { ok: true, data: breakableResult };
9830
10834
  }
9831
10835
  case "restart-frame": {
9832
10836
  const { frameRef } = req.args;
9833
- const restartResult = await debugSession.restartFrame(frameRef);
10837
+ const restartResult = await activeSession().restartFrame(frameRef);
9834
10838
  return { ok: true, data: restartResult };
9835
10839
  }
9836
10840
  case "sourcemap": {
9837
10841
  const { file: smFile } = req.args;
9838
10842
  if (smFile) {
9839
- const match = debugSession.sourceMapResolver.findScriptForSource(smFile);
10843
+ const match = activeSession().sourceMapResolver.findScriptForSource(smFile);
9840
10844
  if (match) {
9841
- const info = debugSession.sourceMapResolver.getInfo(match.scriptId);
10845
+ const info = activeSession().sourceMapResolver.getInfo(match.scriptId);
9842
10846
  return { ok: true, data: info ? [info] : [] };
9843
10847
  }
9844
10848
  return { ok: true, data: [] };
9845
10849
  }
9846
- return { ok: true, data: debugSession.sourceMapResolver.getAllInfos() };
10850
+ return { ok: true, data: activeSession().sourceMapResolver.getAllInfos() };
9847
10851
  }
9848
10852
  case "sourcemap-disable": {
9849
- debugSession.sourceMapResolver.setDisabled(true);
10853
+ activeSession().sourceMapResolver.setDisabled(true);
9850
10854
  return { ok: true, data: "disabled" };
9851
10855
  }
9852
10856
  case "restart": {
9853
- const result = await debugSession.restart();
10857
+ const result = await activeSession().restart();
9854
10858
  return { ok: true, data: result };
9855
10859
  }
9856
10860
  case "stop":
9857
- await debugSession.stop();
10861
+ await activeSession().stop();
10862
+ dapSession = null;
9858
10863
  setTimeout(() => {
9859
10864
  server.stop();
9860
10865
  process.exit(0);
@@ -9875,7 +10880,7 @@ var init_registry = __esm(() => {
9875
10880
  });
9876
10881
 
9877
10882
  // src/daemon/client.ts
9878
- import { existsSync as existsSync3, readFileSync, readdirSync, unlinkSync as unlinkSync2 } from "fs";
10883
+ import { existsSync as existsSync3, readdirSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
9879
10884
 
9880
10885
  class DaemonClient {
9881
10886
  session;
@@ -9895,9 +10900,9 @@ class DaemonClient {
9895
10900
  const timer = setTimeout(() => {
9896
10901
  if (!settled) {
9897
10902
  settled = true;
9898
- reject(new Error(`Request timed out after ${DEFAULT_TIMEOUT_MS2}ms`));
10903
+ reject(new Error(`Request timed out after ${DEFAULT_TIMEOUT_MS3}ms`));
9899
10904
  }
9900
- }, DEFAULT_TIMEOUT_MS2);
10905
+ }, DEFAULT_TIMEOUT_MS3);
9901
10906
  Bun.connect({
9902
10907
  unix: socketPath,
9903
10908
  socket: {
@@ -10019,20 +11024,20 @@ class DaemonClient {
10019
11024
  return files.filter((f) => f.endsWith(".sock")).map((f) => f.slice(0, -5));
10020
11025
  }
10021
11026
  }
10022
- var DEFAULT_TIMEOUT_MS2 = 30000;
11027
+ var DEFAULT_TIMEOUT_MS3 = 30000;
10023
11028
  var init_client = __esm(() => {
10024
11029
  init_messages();
10025
11030
  init_paths();
10026
11031
  });
10027
11032
 
10028
11033
  // src/daemon/spawn.ts
10029
- import { existsSync as existsSync4, openSync } from "fs";
11034
+ import { existsSync as existsSync4, openSync, readFileSync as readFileSync2 } from "fs";
10030
11035
  async function spawnDaemon(session2, options = {}) {
10031
11036
  const socketPath = getSocketPath(session2);
10032
11037
  const spawnArgs = [];
10033
11038
  const execPath = process.execPath;
10034
11039
  const scriptPath = process.argv[1];
10035
- if (scriptPath && scriptPath.endsWith(".ts")) {
11040
+ if (scriptPath && (scriptPath.endsWith(".ts") || scriptPath.endsWith(".js"))) {
10036
11041
  spawnArgs.push(execPath, "run", scriptPath);
10037
11042
  } else {
10038
11043
  spawnArgs.push(execPath);
@@ -10057,7 +11062,24 @@ async function spawnDaemon(session2, options = {}) {
10057
11062
  }
10058
11063
  await Bun.sleep(POLL_INTERVAL_MS);
10059
11064
  }
10060
- throw new Error(`Daemon for session "${session2}" failed to start within ${SPAWN_TIMEOUT_MS}ms`);
11065
+ const logPath = getDaemonLogPath(session2);
11066
+ let logTail = "";
11067
+ try {
11068
+ const log = readFileSync2(logPath, "utf-8");
11069
+ const lines = log.trimEnd().split(`
11070
+ `);
11071
+ logTail = lines.slice(-20).join(`
11072
+ `);
11073
+ } catch {}
11074
+ const details = [
11075
+ `Daemon for session "${session2}" failed to start within ${SPAWN_TIMEOUT_MS}ms`,
11076
+ `Spawn command: ${spawnArgs.join(" ")}`,
11077
+ `Socket path: ${socketPath}`,
11078
+ logTail ? `Daemon log (last 20 lines):
11079
+ ${logTail}` : `No daemon log at ${logPath}`
11080
+ ].join(`
11081
+ `);
11082
+ throw new Error(details);
10061
11083
  }
10062
11084
  async function ensureDaemon(session2, options) {
10063
11085
  if (DaemonClient.isRunning(session2))
@@ -10105,6 +11127,7 @@ var init_launch = __esm(() => {
10105
11127
  const brk = args.flags.brk === true;
10106
11128
  const port = typeof args.flags.port === "string" ? parseInt(args.flags.port, 10) : undefined;
10107
11129
  const timeout2 = typeof args.flags.timeout === "string" ? parseInt(args.flags.timeout, 10) : undefined;
11130
+ const runtime = typeof args.flags.runtime === "string" ? args.flags.runtime : undefined;
10108
11131
  const command = args.subcommand ? [args.subcommand, ...args.positionals] : [...args.positionals];
10109
11132
  if (command.length === 0) {
10110
11133
  console.error("No command specified");
@@ -10113,7 +11136,7 @@ var init_launch = __esm(() => {
10113
11136
  }
10114
11137
  await ensureDaemon(session2, { timeout: timeout2 });
10115
11138
  const client = new DaemonClient(session2);
10116
- const response = await client.request("launch", { command, brk, port });
11139
+ const response = await client.request("launch", { command, brk, port, runtime });
10117
11140
  if (!response.ok) {
10118
11141
  console.error(`${response.error}`);
10119
11142
  if (response.suggestion)
@@ -10146,6 +11169,7 @@ var init_attach = __esm(() => {
10146
11169
  registerCommand("attach", async (args) => {
10147
11170
  const session2 = args.global.session;
10148
11171
  const target = args.subcommand ?? args.positionals[0];
11172
+ const runtime = typeof args.flags.runtime === "string" ? args.flags.runtime : undefined;
10149
11173
  if (!target) {
10150
11174
  console.error("No target specified");
10151
11175
  console.error(" -> Try: agent-dbg attach <ws-url | port>");
@@ -10159,7 +11183,7 @@ var init_attach = __esm(() => {
10159
11183
  const timeout2 = typeof args.flags.timeout === "string" ? parseInt(args.flags.timeout, 10) : undefined;
10160
11184
  await ensureDaemon(session2, { timeout: timeout2 });
10161
11185
  const client = new DaemonClient(session2);
10162
- const response = await client.request("attach", { target });
11186
+ const response = await client.request("attach", { target, runtime });
10163
11187
  if (!response.ok) {
10164
11188
  console.error(`${response.error}`);
10165
11189
  if (response.suggestion)
@@ -10919,6 +11943,44 @@ var init_break = __esm(() => {
10919
11943
  });
10920
11944
  });
10921
11945
 
11946
+ // src/commands/break-fn.ts
11947
+ var exports_break_fn = {};
11948
+ var init_break_fn = __esm(() => {
11949
+ init_registry();
11950
+ init_client();
11951
+ registerCommand("break-fn", async (args) => {
11952
+ const session2 = args.global.session;
11953
+ if (!DaemonClient.isRunning(session2)) {
11954
+ console.error(`No active session "${session2}"`);
11955
+ console.error(" -> Try: agent-dbg launch --brk --runtime lldb ./program");
11956
+ return 1;
11957
+ }
11958
+ const name = args.subcommand;
11959
+ if (!name) {
11960
+ console.error("Usage: agent-dbg break-fn <function-name>");
11961
+ console.error(" Example: agent-dbg break-fn __assert_rtn");
11962
+ console.error(" Example: agent-dbg break-fn 'yoga::Style::operator=='");
11963
+ return 1;
11964
+ }
11965
+ const condition = typeof args.flags.condition === "string" ? args.flags.condition : undefined;
11966
+ const client = new DaemonClient(session2);
11967
+ const response = await client.request("break-fn", { name, condition });
11968
+ if (!response.ok) {
11969
+ console.error(`${response.error}`);
11970
+ if (response.suggestion)
11971
+ console.error(` ${response.suggestion}`);
11972
+ return 1;
11973
+ }
11974
+ const data = response.data;
11975
+ if (args.global.json) {
11976
+ console.log(JSON.stringify(data, null, 2));
11977
+ } else {
11978
+ console.log(`${data.ref} fn:${name}`);
11979
+ }
11980
+ return 0;
11981
+ });
11982
+ });
11983
+
10922
11984
  // src/commands/break-rm.ts
10923
11985
  var exports_break_rm = {};
10924
11986
  var init_break_rm = __esm(() => {
@@ -12191,7 +13253,7 @@ import {
12191
13253
  closeSync,
12192
13254
  existsSync as existsSync5,
12193
13255
  openSync as openSync2,
12194
- readFileSync as readFileSync2,
13256
+ readFileSync as readFileSync3,
12195
13257
  readSync,
12196
13258
  watch,
12197
13259
  writeFileSync as writeFileSync4
@@ -12271,7 +13333,7 @@ var init_logs2 = __esm(() => {
12271
13333
  const level = typeof args.flags.level === "string" ? args.flags.level : undefined;
12272
13334
  const limit = typeof args.flags.limit === "string" ? parseInt(args.flags.limit, 10) : 50;
12273
13335
  const follow = args.flags.follow === true;
12274
- const content = readFileSync2(logPath, "utf-8");
13336
+ const content = readFileSync3(logPath, "utf-8");
12275
13337
  if (isDaemon) {
12276
13338
  let entries = parseDaemonEntries(content);
12277
13339
  if (level)
@@ -12630,6 +13692,7 @@ if (process.argv.includes("--daemon")) {
12630
13692
  await Promise.resolve().then(() => (init_pause(), exports_pause));
12631
13693
  await Promise.resolve().then(() => (init_run_to(), exports_run_to));
12632
13694
  await Promise.resolve().then(() => (init_break(), exports_break));
13695
+ await Promise.resolve().then(() => (init_break_fn(), exports_break_fn));
12633
13696
  await Promise.resolve().then(() => (init_break_rm(), exports_break_rm));
12634
13697
  await Promise.resolve().then(() => (init_break_ls(), exports_break_ls));
12635
13698
  await Promise.resolve().then(() => (init_logpoint(), exports_logpoint));