cdp-mcp 0.1.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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -0
  3. package/dist/index.js +345 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/server.js +27 -0
  6. package/dist/server.js.map +1 -0
  7. package/dist/session/browser.js +394 -0
  8. package/dist/session/browser.js.map +1 -0
  9. package/dist/session/buffers.js +43 -0
  10. package/dist/session/buffers.js.map +1 -0
  11. package/dist/session/pause.js +99 -0
  12. package/dist/session/pause.js.map +1 -0
  13. package/dist/session/state.js +93 -0
  14. package/dist/session/state.js.map +1 -0
  15. package/dist/sourcemap/loader.js +138 -0
  16. package/dist/sourcemap/loader.js.map +1 -0
  17. package/dist/sourcemap/normalize.js +59 -0
  18. package/dist/sourcemap/normalize.js.map +1 -0
  19. package/dist/sourcemap/store.js +185 -0
  20. package/dist/sourcemap/store.js.map +1 -0
  21. package/dist/tools/_register.js +30 -0
  22. package/dist/tools/_register.js.map +1 -0
  23. package/dist/tools/breakpoints.js +164 -0
  24. package/dist/tools/breakpoints.js.map +1 -0
  25. package/dist/tools/console.js +48 -0
  26. package/dist/tools/console.js.map +1 -0
  27. package/dist/tools/dom.js +527 -0
  28. package/dist/tools/dom.js.map +1 -0
  29. package/dist/tools/execution.js +89 -0
  30. package/dist/tools/execution.js.map +1 -0
  31. package/dist/tools/inspect.js +178 -0
  32. package/dist/tools/inspect.js.map +1 -0
  33. package/dist/tools/nav.js +136 -0
  34. package/dist/tools/nav.js.map +1 -0
  35. package/dist/tools/network.js +137 -0
  36. package/dist/tools/network.js.map +1 -0
  37. package/dist/tools/session.js +76 -0
  38. package/dist/tools/session.js.map +1 -0
  39. package/dist/tools/source.js +63 -0
  40. package/dist/tools/source.js.map +1 -0
  41. package/dist/util/browser-resolve.js +263 -0
  42. package/dist/util/browser-resolve.js.map +1 -0
  43. package/dist/util/errors.js +12 -0
  44. package/dist/util/errors.js.map +1 -0
  45. package/dist/util/format.js +65 -0
  46. package/dist/util/format.js.map +1 -0
  47. package/dist/util/log.js +34 -0
  48. package/dist/util/log.js.map +1 -0
  49. package/package.json +74 -0
@@ -0,0 +1,394 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import CDP from "chrome-remote-interface";
3
+ import { launch } from "chrome-launcher";
4
+ import { sessionState, ROOT_SESSION_KEY } from "./state.js";
5
+ import { attachScriptListener } from "../sourcemap/loader.js";
6
+ import { mapCdpToOriginal } from "../sourcemap/store.js";
7
+ import { alreadySession } from "../util/errors.js";
8
+ import { previewRemoteObject } from "../util/format.js";
9
+ import { log } from "../util/log.js";
10
+ import { snapUserDataDir } from "../util/browser-resolve.js";
11
+ const DEFAULT_PORT = 9222;
12
+ export async function launchChrome(opts = {}) {
13
+ if (sessionState.client)
14
+ throw alreadySession();
15
+ // chrome-launcher manages --remote-debugging-port itself: it picks an
16
+ // unused port, adds the flag, and polls it. Passing our own
17
+ // --remote-debugging-port=0 in chromeFlags appears AFTER chrome-launcher's,
18
+ // and since Chrome honors the last occurrence, Chrome picks an ephemeral
19
+ // port written to DevToolsActivePort while chrome-launcher polls its own
20
+ // (stale) port → ECONNREFUSED on every connect. Don't pass it; let
21
+ // chrome-launcher own port selection. `runningChrome.port` then reflects
22
+ // the actual port Chrome is listening on. (Codex blocker review on PR #11.)
23
+ const useSandbox = opts.sandbox === true;
24
+ const userArgs = opts.args ?? [];
25
+ const userAlreadyDisabled = userArgs.includes("--no-sandbox");
26
+ // Snap-confinement auto-profile. When the effective Chrome path (explicit
27
+ // chromePath, or CHROME_PATH env that chrome-launcher will pick up) is
28
+ // under /snap/ AND the caller didn't already specify userDataDir, derive
29
+ // the snap-confined profile path so chrome-launcher doesn't hand snap-
30
+ // Chromium a /tmp/... profile that snap confinement rejects (debug port
31
+ // never opens; chrome-launcher's startup-port poll ECONNREFUSEs). Mirrors
32
+ // the L3 globalSetup logic in test/e2e/setup/global.ts so the L4 eval
33
+ // harness (which steers chrome-launcher via CHROME_PATH) and direct
34
+ // launch_chrome callers inherit the same workaround without making the
35
+ // agent responsible for it. (Codex review on PR #24.)
36
+ const effectiveChromePath = opts.chromePath ?? process.env.CHROME_PATH;
37
+ const autoUserDataDir = !opts.userDataDir && effectiveChromePath?.startsWith("/snap/")
38
+ ? snapUserDataDir(effectiveChromePath)
39
+ : undefined;
40
+ if (autoUserDataDir) {
41
+ mkdirSync(autoUserDataDir, { recursive: true });
42
+ }
43
+ const launchOpts = {
44
+ startingUrl: opts.url ?? "about:blank",
45
+ chromeFlags: [
46
+ ...(opts.headless ? ["--headless=new"] : []),
47
+ ...(!useSandbox && !userAlreadyDisabled ? ["--no-sandbox"] : []),
48
+ ...userArgs,
49
+ ],
50
+ ...(opts.userDataDir
51
+ ? { userDataDir: opts.userDataDir }
52
+ : autoUserDataDir
53
+ ? { userDataDir: autoUserDataDir }
54
+ : {}),
55
+ ...(opts.chromePath ? { chromePath: opts.chromePath } : {}),
56
+ };
57
+ const chrome = await launch(launchOpts);
58
+ sessionState.chrome = chrome;
59
+ sessionState.chromePort = chrome.port;
60
+ log.info("launched chrome", { port: chrome.port, pid: chrome.pid });
61
+ // Pick the first page target.
62
+ const targets = await waitForFirstPage(chrome.port);
63
+ const target = targets[0];
64
+ await connectToTarget(chrome.port, target.id);
65
+ return { targetId: target.id, url: target.url };
66
+ }
67
+ export async function attachChrome(opts = {}) {
68
+ if (sessionState.client)
69
+ throw alreadySession();
70
+ const port = opts.port ?? DEFAULT_PORT;
71
+ sessionState.chromePort = port;
72
+ sessionState.attached = true;
73
+ const targets = await CDP.List({ port, host: opts.host });
74
+ const wantType = opts.targetFilter?.type;
75
+ const wantUrl = opts.targetFilter?.urlIncludes;
76
+ const filtered = targets.filter((t) => {
77
+ // When a type filter is supplied, it is authoritative. Otherwise default
78
+ // to "page" targets (the common debugging case).
79
+ if (wantType) {
80
+ if (t.type !== wantType)
81
+ return false;
82
+ }
83
+ else if (t.type !== "page") {
84
+ return false;
85
+ }
86
+ if (wantUrl && !t.url.includes(wantUrl))
87
+ return false;
88
+ return true;
89
+ });
90
+ if (filtered.length === 0) {
91
+ throw new Error(`No matching targets on the running Chrome (filter type=${wantType ?? "page"}, urlIncludes=${wantUrl ?? "*"})`);
92
+ }
93
+ const target = filtered[0];
94
+ await connectToTarget(port, target.id, opts.host);
95
+ log.info("attached to chrome", { port, targetId: target.id, url: target.url });
96
+ return { targetId: target.id, url: target.url };
97
+ }
98
+ async function waitForFirstPage(port) {
99
+ const deadline = Date.now() + 5000;
100
+ while (Date.now() < deadline) {
101
+ try {
102
+ const list = await CDP.List({ port });
103
+ const pages = list.filter((t) => t.type === "page");
104
+ if (pages.length > 0)
105
+ return pages;
106
+ }
107
+ catch {
108
+ // Chrome may not be ready yet
109
+ }
110
+ await new Promise((r) => setTimeout(r, 100));
111
+ }
112
+ throw new Error("Chrome did not expose any page targets within 5s");
113
+ }
114
+ async function connectToTarget(port, targetId, host) {
115
+ const client = await CDP({ port, host, target: targetId });
116
+ sessionState.client = client;
117
+ sessionState.currentTargetId = targetId;
118
+ // Wire root-target handlers and Target.attachedToTarget BEFORE setAutoAttach
119
+ // — Chrome immediately enumerates pre-existing eligible children (workers,
120
+ // OOPIFs, service workers) inline with the setAutoAttach response. If the
121
+ // listener is registered after, those attachedToTarget events are dropped.
122
+ wireDomainHandlers(client, undefined);
123
+ const onAttached = (params) => {
124
+ void onChildAttached(client, params);
125
+ };
126
+ const onDetached = (params) => {
127
+ detachSession(client, params.sessionId);
128
+ };
129
+ client.on("Target.attachedToTarget", onAttached);
130
+ client.on("Target.detachedFromTarget", onDetached);
131
+ client.on("disconnect", () => log.warn("CDP disconnect"));
132
+ await enableDomains(client, undefined);
133
+ try {
134
+ await client.Target.setAutoAttach({
135
+ autoAttach: true,
136
+ waitForDebuggerOnStart: false,
137
+ flatten: true,
138
+ });
139
+ }
140
+ catch (e) {
141
+ log.warn("Target.setAutoAttach failed", { error: String(e) });
142
+ }
143
+ }
144
+ async function onChildAttached(client, params) {
145
+ const sessionId = params.sessionId;
146
+ log.debug("child target attached", { sessionId, type: params.targetInfo.type, url: params.targetInfo.url });
147
+ try {
148
+ wireDomainHandlers(client, sessionId);
149
+ await enableDomains(client, sessionId);
150
+ await client.Target.setAutoAttach({ autoAttach: true, waitForDebuggerOnStart: false, flatten: true }, sessionId);
151
+ // Inherit pause-on-exceptions setting so child sessions honor it from
152
+ // birth, not only if the user re-issues the tool after they attach.
153
+ if (sessionState.pauseOnExceptions !== "none") {
154
+ try {
155
+ await client.Debugger.setPauseOnExceptions({ state: sessionState.pauseOnExceptions }, sessionId);
156
+ }
157
+ catch (e) {
158
+ log.warn("failed to apply pauseOnExceptions to child", { sessionId, error: String(e) });
159
+ }
160
+ }
161
+ }
162
+ catch (e) {
163
+ log.warn("failed to enable child target", { sessionId, error: String(e) });
164
+ }
165
+ }
166
+ function detachSession(client, sessionId) {
167
+ log.debug("child target detached", { sessionId });
168
+ // Remove every event handler we registered for this sub-session and drop
169
+ // its scripts from the store — those scriptIds are now invalid.
170
+ const handlers = sessionState.sessionHandlers.get(sessionId);
171
+ if (handlers) {
172
+ for (const { event, handler } of handlers) {
173
+ client.removeListener(event, handler);
174
+ }
175
+ sessionState.sessionHandlers.delete(sessionId);
176
+ }
177
+ // Drop scripts owned by this session so stale scriptIds don't survive.
178
+ for (const sc of sessionState.scripts.all()) {
179
+ if (sc.sessionId === sessionId)
180
+ sessionState.scripts.remove(sc.scriptId, sc.sessionId);
181
+ }
182
+ }
183
+ async function enableDomains(client, sessionId) {
184
+ // The full debugger surface needs these. Some are no-ops on workers but harmless.
185
+ const swallow = (p) => p.then(() => { }, () => { });
186
+ await swallow(client.Runtime.enable(sessionId));
187
+ await swallow(client.Debugger.enable({}, sessionId));
188
+ await swallow(client.Page.enable(sessionId));
189
+ await swallow(client.DOM.enable({}, sessionId));
190
+ await swallow(client.Network.enable({}, sessionId));
191
+ }
192
+ function wireDomainHandlers(client, sessionId) {
193
+ // The strict gate: only process events from THIS session. The original
194
+ // implementation used `if (sessionId && eventSessionId !== sessionId)`,
195
+ // which is vacuously false when sessionId is undefined (the root) —
196
+ // making the root handler process every child session's events too.
197
+ const own = (eventSessionId) => eventSessionId === sessionId;
198
+ const registered = [];
199
+ const reg = (event, handler) => {
200
+ client.on(event, handler);
201
+ registered.push({ event, handler });
202
+ };
203
+ // Source-map / Debugger.scriptParsed
204
+ const scriptHandler = attachScriptListener(client, sessionState.scripts, sessionId);
205
+ registered.push({ event: "Debugger.scriptParsed", handler: scriptHandler });
206
+ const onPaused = (params, eventSessionId) => {
207
+ if (!own(eventSessionId))
208
+ return;
209
+ sessionState.pause.onPaused({
210
+ reason: params.reason,
211
+ data: params.data,
212
+ hitBreakpoints: params.hitBreakpoints,
213
+ callFrames: params.callFrames,
214
+ asyncStackTrace: params.asyncStackTrace,
215
+ sessionId: eventSessionId,
216
+ pausedAt: Date.now(),
217
+ });
218
+ log.debug("paused", { reason: params.reason, hit: params.hitBreakpoints });
219
+ };
220
+ reg("Debugger.paused", onPaused);
221
+ const onResumed = (_p, eventSessionId) => {
222
+ if (!own(eventSessionId))
223
+ return;
224
+ sessionState.pause.onResumed();
225
+ };
226
+ reg("Debugger.resumed", onResumed);
227
+ const onConsoleApi = (params, eventSessionId) => {
228
+ if (!own(eventSessionId))
229
+ return;
230
+ pushConsoleFromApi(sessionState, params, eventSessionId);
231
+ };
232
+ reg("Runtime.consoleAPICalled", onConsoleApi);
233
+ const onException = (params, eventSessionId) => {
234
+ if (!own(eventSessionId))
235
+ return;
236
+ pushConsoleFromException(sessionState, params, eventSessionId);
237
+ };
238
+ reg("Runtime.exceptionThrown", onException);
239
+ // Predicate that matches an entry by (requestId, sessionId). CDP requestIds
240
+ // are scoped per Network agent — two iframes can both emit requestId="123" —
241
+ // so the predicate must include sessionId to avoid cross-session collisions
242
+ // in RingBuffer.update.
243
+ const matchEntry = (requestId) => (e) => e.requestId === requestId && e.sessionId === sessionId;
244
+ const onRequest = (params, eventSessionId) => {
245
+ if (!own(eventSessionId))
246
+ return;
247
+ sessionState.network.push({
248
+ requestId: params.requestId,
249
+ ts: Date.now(),
250
+ url: params.request.url,
251
+ method: params.request.method,
252
+ resourceType: params.type,
253
+ ...(sessionId ? { sessionId } : {}),
254
+ });
255
+ };
256
+ reg("Network.requestWillBeSent", onRequest);
257
+ const onResponse = (params, eventSessionId) => {
258
+ if (!own(eventSessionId))
259
+ return;
260
+ sessionState.network.update(matchEntry(params.requestId), {
261
+ status: params.response.status,
262
+ statusText: params.response.statusText,
263
+ mimeType: params.response.mimeType,
264
+ fromCache: params.response.fromDiskCache || params.response.fromPrefetchCache,
265
+ });
266
+ };
267
+ reg("Network.responseReceived", onResponse);
268
+ const onLoadingFinished = (params, eventSessionId) => {
269
+ if (!own(eventSessionId))
270
+ return;
271
+ // Use the entry's own ts (set at requestWillBeSent) to compute duration.
272
+ const existing = sessionState.network.query({ filter: matchEntry(params.requestId), limit: 1 }).pop();
273
+ sessionState.network.update(matchEntry(params.requestId), {
274
+ ...(existing ? { durationMs: Date.now() - existing.ts } : {}),
275
+ finished: true,
276
+ });
277
+ };
278
+ reg("Network.loadingFinished", onLoadingFinished);
279
+ const onLoadingFailed = (params, eventSessionId) => {
280
+ if (!own(eventSessionId))
281
+ return;
282
+ // Symmetric with onLoadingFinished: time-to-failure (DNS error, connect
283
+ // refused, RST, abort, …) is useful for latency/anomaly analysis. Without
284
+ // this, duration_ms is `number | undefined` purely as a function of
285
+ // success vs. failure in the same call to get_network_requests.
286
+ const existing = sessionState.network.query({ filter: matchEntry(params.requestId), limit: 1 }).pop();
287
+ sessionState.network.update(matchEntry(params.requestId), {
288
+ ...(existing ? { durationMs: Date.now() - existing.ts } : {}),
289
+ failureReason: params.errorText,
290
+ finished: true,
291
+ });
292
+ };
293
+ reg("Network.loadingFailed", onLoadingFailed);
294
+ sessionState.sessionHandlers.set(sessionId ?? ROOT_SESSION_KEY, registered);
295
+ }
296
+ function pushConsoleFromApi(s, params, sessionId) {
297
+ // Two formatting modes:
298
+ // - String args render as raw text (no surrounding quotes, no \n→\\n
299
+ // escapes) — matches how DevTools / Node / every log shipper renders
300
+ // console.log("Server started"). previewRemoteObject would
301
+ // JSON.stringify them, which is right for REPL/evaluate output but
302
+ // wrong for console buffering.
303
+ // - Everything else (numbers, objects, arrays, functions, …) goes
304
+ // through previewRemoteObject so {foo:1} keeps its shape.
305
+ const renderArg = (a) => a.type === "string" ? (a.value ?? "") : previewRemoteObject(a);
306
+ const text = params.args.length === 0
307
+ ? "(no args)"
308
+ : params.args.map(renderArg).join(" ");
309
+ const top = params.stackTrace?.callFrames?.[0];
310
+ const mapped = top ? mapCdpToOriginal(s.scripts, {
311
+ scriptId: top.scriptId,
312
+ lineNumber: top.lineNumber,
313
+ columnNumber: top.columnNumber,
314
+ }, sessionId) : null;
315
+ s.console.push({
316
+ ts: Date.now(),
317
+ level: mapApiLevel(params.type),
318
+ text,
319
+ source: "console-api",
320
+ ...(top?.url ? { url: top.url } : {}),
321
+ ...(top ? { lineNumber: top.lineNumber, columnNumber: top.columnNumber } : {}),
322
+ ...(mapped ? { mappedFile: mapped.file, mappedLine: mapped.line, mappedColumn: mapped.column } : {}),
323
+ ...(params.stackTrace ? { stack: params.stackTrace } : {}),
324
+ });
325
+ }
326
+ function pushConsoleFromException(s, params, sessionId) {
327
+ const det = params.exceptionDetails;
328
+ const top = det.stackTrace?.callFrames?.[0];
329
+ const mapped = top ? mapCdpToOriginal(s.scripts, {
330
+ scriptId: top.scriptId,
331
+ lineNumber: top.lineNumber,
332
+ columnNumber: top.columnNumber,
333
+ }, sessionId) : null;
334
+ const text = (det.exception?.description ?? det.exception?.value ?? det.text) + "";
335
+ s.console.push({
336
+ ts: Date.now(),
337
+ level: "error",
338
+ text,
339
+ source: "runtime-exception",
340
+ ...(top?.url ? { url: top.url } : { url: det.url }),
341
+ ...(top ? { lineNumber: top.lineNumber, columnNumber: top.columnNumber } : { lineNumber: det.lineNumber, columnNumber: det.columnNumber }),
342
+ ...(mapped ? { mappedFile: mapped.file, mappedLine: mapped.line, mappedColumn: mapped.column } : {}),
343
+ ...(det.stackTrace ? { stack: det.stackTrace } : {}),
344
+ });
345
+ }
346
+ function mapApiLevel(t) {
347
+ switch (t) {
348
+ case "warning":
349
+ return "warn";
350
+ case "error":
351
+ return "error";
352
+ case "debug":
353
+ return "debug";
354
+ case "info":
355
+ return "info";
356
+ case "trace":
357
+ return "trace";
358
+ case "log":
359
+ default:
360
+ return "log";
361
+ }
362
+ }
363
+ export async function closeSession() {
364
+ await sessionState.close();
365
+ }
366
+ // Switch to a different target on the same browser without tearing down the
367
+ // chrome process. Used by select_target.
368
+ export async function switchTarget(targetId) {
369
+ if (!sessionState.client)
370
+ throw new Error("No active session");
371
+ const port = sessionState.chromePort;
372
+ const attached = sessionState.attached;
373
+ const chrome = sessionState.chrome;
374
+ try {
375
+ await sessionState.client.close().catch(() => { });
376
+ }
377
+ catch {
378
+ /* ignore */
379
+ }
380
+ sessionState.client = null;
381
+ sessionState.currentTargetId = null;
382
+ sessionState.pause.reset();
383
+ sessionState.scripts.clear();
384
+ sessionState.breakpoints.clear();
385
+ sessionState.sessionHandlers.clear();
386
+ sessionState.chromePort = port;
387
+ sessionState.attached = attached;
388
+ sessionState.chrome = chrome;
389
+ await connectToTarget(port, targetId);
390
+ const list = await CDP.List({ port });
391
+ const t = list.find((x) => x.id === targetId);
392
+ return { targetId, url: t?.url ?? "" };
393
+ }
394
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/session/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export class RingBuffer {
2
+ capacity;
3
+ items = [];
4
+ nextSeq = 1;
5
+ constructor(capacity) {
6
+ this.capacity = capacity;
7
+ }
8
+ push(item) {
9
+ const full = { ...item, seq: this.nextSeq++ };
10
+ this.items.push(full);
11
+ if (this.items.length > this.capacity) {
12
+ this.items.splice(0, this.items.length - this.capacity);
13
+ }
14
+ return full;
15
+ }
16
+ query(opts = {}) {
17
+ const since = opts.since ?? 0;
18
+ let out = this.items.filter((it) => it.seq > since);
19
+ if (opts.filter)
20
+ out = out.filter(opts.filter);
21
+ if (opts.limit !== undefined)
22
+ out = out.slice(-opts.limit);
23
+ return out;
24
+ }
25
+ clear() {
26
+ this.items = [];
27
+ }
28
+ size() {
29
+ return this.items.length;
30
+ }
31
+ // Mutate-in-place: used by network buffer to update an entry when the response arrives.
32
+ update(predicate, patch) {
33
+ for (let i = this.items.length - 1; i >= 0; i--) {
34
+ const item = this.items[i];
35
+ if (predicate(item)) {
36
+ this.items[i] = { ...item, ...patch };
37
+ return this.items[i];
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ }
43
+ //# sourceMappingURL=buffers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffers.js","sourceRoot":"","sources":["../../src/session/buffers.ts"],"names":[],"mappings":"AA2CA,MAAM,OAAO,UAAU;IAGD;IAFZ,KAAK,GAAQ,EAAE,CAAC;IAChB,OAAO,GAAG,CAAC,CAAC;IACpB,YAAoB,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAExC,IAAI,CAAC,IAAoB;QACvB,MAAM,IAAI,GAAG,EAAE,GAAI,IAAe,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,EAAO,CAAC;QAC/D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAIF,EAAE;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAC9B,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;QACpD,IAAI,IAAI,CAAC,MAAM;YAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3D,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,wFAAwF;IACxF,MAAM,CAAC,SAA+B,EAAE,KAAiB;QACvD,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;YAC5B,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;gBACtC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;YACxB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,99 @@
1
+ // Tracks one pause at a time. Callers wait via waitForPause(); the next
2
+ // Debugger.paused event resolves the pending waiter (or buffers state for a
3
+ // later call).
4
+ export class PauseTracker {
5
+ state = null;
6
+ waiters = [];
7
+ current() {
8
+ return this.state;
9
+ }
10
+ isPaused() {
11
+ return this.state !== null;
12
+ }
13
+ onPaused(state) {
14
+ this.state = state;
15
+ while (this.waiters.length) {
16
+ const w = this.waiters.shift();
17
+ if (w.timer)
18
+ clearTimeout(w.timer);
19
+ w.resolve(state);
20
+ }
21
+ }
22
+ onResumed() {
23
+ this.state = null;
24
+ }
25
+ // Resolves on the next pause, or immediately if already paused.
26
+ waitForPause(timeoutMs) {
27
+ if (this.state)
28
+ return Promise.resolve(this.state);
29
+ return new Promise((resolve, reject) => {
30
+ const w = {
31
+ resolve,
32
+ reject,
33
+ timer: setTimeout(() => {
34
+ const i = this.waiters.indexOf(w);
35
+ if (i >= 0)
36
+ this.waiters.splice(i, 1);
37
+ reject(new Error(`Timed out after ${timeoutMs}ms waiting for pause`));
38
+ }, timeoutMs),
39
+ };
40
+ this.waiters.push(w);
41
+ });
42
+ }
43
+ // Used by step commands: resolve when either paused-again or resumed.
44
+ //
45
+ // Critical: check `this.state` at entry. The step path in tools/execution.ts
46
+ // calls `onResumed()` (clearing state), then awaits `Debugger.stepOver` —
47
+ // and for fast steps Chrome delivers the stepOver response and the
48
+ // subsequent `Debugger.paused` in the same WebSocket batch. CRI emits
49
+ // events synchronously, so `onPaused` runs *before* the awaiter resumes
50
+ // and registers its waiter. Without this entry guard the pause is
51
+ // buffered into nowhere, the waiter sits unresolved for `timeoutMs`,
52
+ // and stepThen returns `{paused:false}` while `isPaused()` is actually
53
+ // true — desync that misleads every subsequent pause-only tool.
54
+ waitForPauseOrResume(timeoutMs) {
55
+ if (this.state)
56
+ return Promise.resolve(this.state);
57
+ return new Promise((resolve, reject) => {
58
+ let settled = false;
59
+ const onPause = (s) => {
60
+ if (settled)
61
+ return;
62
+ settled = true;
63
+ clearTimeout(timer);
64
+ this.waiters = this.waiters.filter((w) => w !== waiter);
65
+ resolve(s);
66
+ };
67
+ const waiter = {
68
+ resolve: onPause,
69
+ reject: (e) => {
70
+ if (settled)
71
+ return;
72
+ settled = true;
73
+ clearTimeout(timer);
74
+ reject(e);
75
+ },
76
+ timer: null,
77
+ };
78
+ this.waiters.push(waiter);
79
+ const timer = setTimeout(() => {
80
+ if (settled)
81
+ return;
82
+ settled = true;
83
+ this.waiters = this.waiters.filter((w) => w !== waiter);
84
+ // Treat timeout as "resumed without pausing" — common for short steps.
85
+ resolve(null);
86
+ }, timeoutMs);
87
+ });
88
+ }
89
+ reset() {
90
+ this.state = null;
91
+ for (const w of this.waiters) {
92
+ if (w.timer)
93
+ clearTimeout(w.timer);
94
+ w.reject(new Error("Session closed"));
95
+ }
96
+ this.waiters = [];
97
+ }
98
+ }
99
+ //# sourceMappingURL=pause.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pause.js","sourceRoot":"","sources":["../../src/session/pause.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { PauseTracker } from "./pause.js";
2
+ import { RingBuffer } from "./buffers.js";
3
+ import { ScriptStore } from "../sourcemap/store.js";
4
+ import { log } from "../util/log.js";
5
+ import { noSession, notPaused } from "../util/errors.js";
6
+ const ROOT_SESSION_KEY = "__root__";
7
+ export { ROOT_SESSION_KEY };
8
+ class SessionState {
9
+ client = null;
10
+ chrome = null;
11
+ chromePort = null;
12
+ attached = false; // true when attached to a pre-existing chrome (don't kill on close)
13
+ currentTargetId = null;
14
+ currentSessionId = undefined; // for flat-session targets
15
+ pause = new PauseTracker();
16
+ console = new RingBuffer(1000);
17
+ network = new RingBuffer(1000);
18
+ scripts = new ScriptStore();
19
+ breakpoints = new Map();
20
+ // Per-session handler refs so we can removeListener on Target.detachedFromTarget.
21
+ // Key is sessionId or ROOT_SESSION_KEY for the top-level target.
22
+ sessionHandlers = new Map();
23
+ // Last set_pause_on_exceptions state. Replayed to every newly-attached
24
+ // child session in onChildAttached, so workers/iframes honor the setting
25
+ // even when they attach after the user configured it.
26
+ pauseOnExceptions = "none";
27
+ // Counter for generating user-friendly breakpoint IDs that survive resolve roundtrips.
28
+ bpCounter = 0;
29
+ nextBpId() {
30
+ this.bpCounter += 1;
31
+ return `bp_${this.bpCounter}`;
32
+ }
33
+ reset() {
34
+ this.client = null;
35
+ this.chrome = null;
36
+ this.chromePort = null;
37
+ this.attached = false;
38
+ this.currentTargetId = null;
39
+ this.currentSessionId = undefined;
40
+ this.pause.reset();
41
+ this.console.clear();
42
+ this.network.clear();
43
+ this.scripts.clear();
44
+ this.breakpoints.clear();
45
+ this.sessionHandlers.clear();
46
+ this.pauseOnExceptions = "none";
47
+ this.bpCounter = 0;
48
+ }
49
+ async close() {
50
+ log.info("closing session");
51
+ try {
52
+ if (this.client) {
53
+ try {
54
+ await this.client.close();
55
+ }
56
+ catch {
57
+ /* ignore */
58
+ }
59
+ }
60
+ }
61
+ finally {
62
+ try {
63
+ if (this.chrome && !this.attached) {
64
+ try {
65
+ this.chrome.kill();
66
+ }
67
+ catch {
68
+ /* ignore */
69
+ }
70
+ }
71
+ }
72
+ finally {
73
+ this.reset();
74
+ }
75
+ }
76
+ }
77
+ }
78
+ export const sessionState = new SessionState();
79
+ export function getSession() {
80
+ return sessionState.client ? sessionState : null;
81
+ }
82
+ export function requireSession() {
83
+ if (!sessionState.client)
84
+ throw noSession();
85
+ return sessionState;
86
+ }
87
+ export function requirePaused() {
88
+ const s = requireSession();
89
+ if (!s.pause.isPaused())
90
+ throw notPaused();
91
+ return s;
92
+ }
93
+ //# sourceMappingURL=state.js.map