@narumitw/pi-chrome-devtools 0.53.2 → 0.53.3

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 (40) hide show
  1. package/README.md +1 -0
  2. package/dist/chunks/{browser-settings-menu-IMB6HXSU.js → browser-settings-menu-SR7KLZT6.js} +16 -42
  3. package/dist/chunks/browser-settings-menu-SR7KLZT6.js.map +7 -0
  4. package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4KMN4SFF.js} +2 -2
  5. package/dist/chunks/chunk-4KMN4SFF.js.map +7 -0
  6. package/dist/chunks/{chunk-SRT3UUIP.js → chunk-F5VG35UI.js} +23 -74
  7. package/dist/chunks/chunk-F5VG35UI.js.map +7 -0
  8. package/dist/chunks/{chunk-LLXOCRNF.js → chunk-MZCGM6D3.js} +12 -33
  9. package/dist/chunks/chunk-MZCGM6D3.js.map +7 -0
  10. package/dist/chunks/{menu-UJETYMSB.js → menu-YR4VRT7D.js} +10 -23
  11. package/dist/chunks/menu-YR4VRT7D.js.map +7 -0
  12. package/dist/chunks/{tools-6P7EUX37.js → tools-6R7Z6HWJ.js} +17 -59
  13. package/dist/chunks/tools-6R7Z6HWJ.js.map +7 -0
  14. package/dist/index.ts +18 -42
  15. package/dist/index.ts.map +2 -2
  16. package/package.json +54 -55
  17. package/src/browser-manager.ts +872 -942
  18. package/src/browser-settings-menu.ts +315 -350
  19. package/src/cdp-client.ts +381 -398
  20. package/src/chrome-devtools.ts +205 -232
  21. package/src/display.ts +26 -29
  22. package/src/lazy-tools.ts +158 -181
  23. package/src/menu.ts +409 -446
  24. package/src/render.ts +72 -81
  25. package/src/runtime.ts +137 -140
  26. package/src/screenshot.ts +170 -186
  27. package/src/settings.ts +472 -523
  28. package/src/tool-names.ts +8 -14
  29. package/src/tool-selector.ts +242 -271
  30. package/src/tools.ts +218 -226
  31. package/src/webmcp/discovery.ts +184 -188
  32. package/src/webmcp/policy.ts +296 -329
  33. package/src/webmcp/protocol.ts +324 -337
  34. package/src/webmcp/tools.ts +136 -147
  35. package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +0 -7
  36. package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
  37. package/dist/chunks/chunk-LLXOCRNF.js.map +0 -7
  38. package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
  39. package/dist/chunks/menu-UJETYMSB.js.map +0 -7
  40. package/dist/chunks/tools-6P7EUX37.js.map +0 -7
package/README.md CHANGED
@@ -96,6 +96,7 @@ Loaded capability tools remain active for the rest of the session unless the use
96
96
  Pi uses native deferred tool references on compatible Anthropic models, native additional-tools or tool-search loading on compatible OpenAI and Codex Responses models, and native Kimi loading on compatible OpenAI Chat Completions models.
97
97
  Kimi-compatible models declare `compat.deferredToolsMode: "kimi"` in Pi's model metadata.
98
98
  `azure-openai-responses` remains eager because Pi's Azure adapter does not implement native deferred tool-search serialization.
99
+ Fireworks Messages models also remain eager because their native protocol requires the canonical `ToolSearch` or `tool_search` loader name, while this independently installable package keeps the collision-safe `chrome_devtools_load` name.
99
100
 
100
101
  When the selected model/provider lacks native deferred support, the extension activates every capability allowed by settings before the next model request instead of using Pi's cache-invalidating lazy-loading fallback.
101
102
  After a session enters eager exposure, it stays eager across later model switches to avoid removing tool definitions within that session.
@@ -5,7 +5,7 @@ import {
5
5
  configuredChromeDevtoolsTools,
6
6
  sanitizeChromeDevtoolsDisplay,
7
7
  setChromeDevtoolsSessionOwner
8
- } from "./chunk-LLXOCRNF.js";
8
+ } from "./chunk-MZCGM6D3.js";
9
9
  import {
10
10
  applyRuntimeBrowserSettings,
11
11
  applyRuntimeWebMcpSetting,
@@ -18,7 +18,7 @@ import {
18
18
  state,
19
19
  syncManagedBrowserSettings,
20
20
  webMcpEnabled
21
- } from "./chunk-SRT3UUIP.js";
21
+ } from "./chunk-F5VG35UI.js";
22
22
 
23
23
  // src/browser-settings-menu.ts
24
24
  import { isAbsolute } from "node:path";
@@ -83,9 +83,7 @@ async function showChromeDevtoolsBrowserSettings(pi, ctx, generation) {
83
83
  kind: "input",
84
84
  title: "DevTools endpoint",
85
85
  lines: [
86
- sanitizeChromeDevtoolsDisplay(
87
- `Current effective endpoint: ${current.load.effectiveBrowser.endpoint}`
88
- ),
86
+ sanitizeChromeDevtoolsDisplay(`Current effective endpoint: ${current.load.effectiveBrowser.endpoint}`),
89
87
  'Enter an HTTP origin with an explicit port, or "default".'
90
88
  ],
91
89
  placeholder: "http://127.0.0.1:9222",
@@ -124,33 +122,18 @@ async function showChromeDevtoolsBrowserSettings(pi, ctx, generation) {
124
122
  notifySaveFailure(ctx, error);
125
123
  return { kind: "rejected" };
126
124
  }
127
- const saved = await saveAndApplyBrowserPatch(
128
- ctx,
129
- generation,
130
- ownerSignal,
131
- signal,
132
- projectTrusted,
133
- { endpoint }
134
- );
125
+ const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {
126
+ endpoint
127
+ });
135
128
  if (!saved) return { kind: "rejected" };
136
- notifyEffectiveSave(
137
- ctx,
138
- "endpoint",
139
- saved.effectiveBrowser.endpoint,
140
- saved.effectiveBrowser.endpointSource
141
- );
129
+ notifyEffectiveSave(ctx, "endpoint", saved.effectiveBrowser.endpoint, saved.effectiveBrowser.endpointSource);
142
130
  return { kind: "back" };
143
131
  },
144
132
  "set-auto-launch": async ({ value, signal }) => {
145
133
  if (value !== "On" && value !== "Off") return { kind: "rejected" };
146
- const saved = await saveAndApplyBrowserPatch(
147
- ctx,
148
- generation,
149
- ownerSignal,
150
- signal,
151
- projectTrusted,
152
- { autoLaunch: value === "On" }
153
- );
134
+ const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {
135
+ autoLaunch: value === "On"
136
+ });
154
137
  if (!saved) return { kind: "rejected" };
155
138
  notifyEffectiveSave(
156
139
  ctx,
@@ -188,14 +171,9 @@ async function showChromeDevtoolsBrowserSettings(pi, ctx, generation) {
188
171
  return { kind: "rejected" };
189
172
  }
190
173
  const executablePath = reset ? null : trimmed;
191
- const saved = await saveAndApplyBrowserPatch(
192
- ctx,
193
- generation,
194
- ownerSignal,
195
- signal,
196
- projectTrusted,
197
- { executablePath }
198
- );
174
+ const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {
175
+ executablePath
176
+ });
199
177
  if (!saved) return { kind: "rejected" };
200
178
  notifyEffectiveSave(
201
179
  ctx,
@@ -218,9 +196,7 @@ async function showChromeDevtoolsBrowserSettings(pi, ctx, generation) {
218
196
  signal: ownerSignal,
219
197
  isCurrent: isCurrent2,
220
198
  onError: (currentCtx, error) => currentCtx.ui.notify(
221
- sanitizeChromeDevtoolsDisplay(
222
- `Chrome DevTools browser settings failed: ${formatError(error)}`
223
- ),
199
+ sanitizeChromeDevtoolsDisplay(`Chrome DevTools browser settings failed: ${formatError(error)}`),
224
200
  "error"
225
201
  )
226
202
  });
@@ -272,9 +248,7 @@ async function saveAndApplyWebMcpSetting(pi, ctx, generation, ownerSignal, actio
272
248
  if (isCurrent(generation, ownerSignal, actionSignal)) {
273
249
  notifySaveFailure(
274
250
  ctx,
275
- rollbackError ? new Error(
276
- `${formatError(error)}; WebMCP rollback failed: ${formatError(rollbackError)}`
277
- ) : error
251
+ rollbackError ? new Error(`${formatError(error)}; WebMCP rollback failed: ${formatError(rollbackError)}`) : error
278
252
  );
279
253
  }
280
254
  return false;
@@ -339,4 +313,4 @@ function formatError(error) {
339
313
  export {
340
314
  showChromeDevtoolsBrowserSettings
341
315
  };
342
- //# sourceMappingURL=browser-settings-menu-IMB6HXSU.js.map
316
+ //# sourceMappingURL=browser-settings-menu-SR7KLZT6.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/browser-settings-menu.ts"],
4
+ "sourcesContent": ["import { isAbsolute } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu } from \"@narumitw/pi-tui-kit\";\nimport { shutdownManagedBrowser, syncManagedBrowserSettings } from \"./browser-manager.js\";\nimport {\n applyAvailableChromeDevtoolsTools,\n configuredChromeDevtoolsTools,\n setChromeDevtoolsSessionOwner,\n} from \"./lazy-tools.js\";\nimport {\n applyRuntimeBrowserSettings,\n applyRuntimeWebMcpSetting,\n invalidateWebMcpOperations,\n state,\n webMcpEnabled,\n} from \"./runtime.js\";\nimport {\n type BrowserSettingsPatch,\n type BrowserSettingsSource,\n loadSettings,\n parseBrowserEndpoint,\n type SettingsLoadResult,\n saveBrowserSettings,\n saveWebMcpSettings,\n} from \"./settings.js\";\nimport { sanitizeChromeDevtoolsDisplay } from \"./tool-selector.js\";\n\ntype BrowserSettingsScreen = \"settings\" | \"endpoint\" | \"executable\" | \"extensions\";\ntype BrowserSettingsAction =\n | \"open-endpoint\"\n | \"save-endpoint\"\n | \"set-auto-launch\"\n | \"set-webmcp\"\n | \"open-executable\"\n | \"save-executable\"\n | \"show-extensions\";\n\ninterface BrowserSettingsMenuState {\n load: SettingsLoadResult;\n}\n\ntype CommandContext = ExtensionCommandContext;\n\nexport async function showChromeDevtoolsBrowserSettings(\n pi: ExtensionAPI,\n ctx: CommandContext,\n generation: number,\n): Promise<{ closeParent: boolean }> {\n setChromeDevtoolsSessionOwner(pi, ctx.sessionManager);\n const ownerSignal = state.sessionController.signal;\n const isCurrent = () => generation === state.sessionGeneration && !ownerSignal.aborted;\n const projectTrusted = ctx.isProjectTrusted();\n const menu = defineMenu<BrowserSettingsMenuState, BrowserSettingsScreen, BrowserSettingsAction>({\n start: \"settings\",\n screens: {\n settings: ({ state: current }) => {\n if (current.load.userFile.kind === \"invalid\") return invalidSettingsScreen(current.load);\n const browser = current.load.effectiveBrowser;\n return {\n kind: \"settings\",\n title: \"Chrome DevTools Browser settings\",\n lines: settingsContextLines(current.load),\n items: [\n {\n id: \"endpoint\",\n label: \"DevTools endpoint\",\n description: 'HTTP origin with an explicit port; enter \"default\" to restore 127.0.0.1:9222.',\n currentValue: sanitizeChromeDevtoolsDisplay(browser.endpoint),\n action: \"open-endpoint\",\n },\n {\n id: \"auto-launch\",\n label: \"Auto-launch\",\n description: \"Launch an isolated managed browser when a local endpoint is unavailable.\",\n currentValue: browser.autoLaunchEnabled ? \"On\" : \"Off\",\n values: [\"On\", \"Off\"],\n action: \"set-auto-launch\",\n },\n {\n id: \"executable\",\n label: \"Browser executable\",\n description: 'Absolute executable path; enter \"automatic\" to restore browser discovery.',\n currentValue: sanitizeChromeDevtoolsDisplay(browser.executablePath ?? \"Automatic\"),\n action: \"open-executable\",\n },\n {\n id: \"webmcp\",\n label: \"WebMCP \u00B7 Experimental\",\n description: \"Allow user-confirmed calls to page-provided WebMCP tools in this browser session.\",\n currentValue: current.load.effectiveWebMcpEnabled ? \"On\" : \"Off\",\n values: [\"On\", \"Off\"],\n action: \"set-webmcp\",\n },\n {\n id: \"extensions\",\n label: \"Unpacked extensions\",\n description: \"Inspect trusted extension paths configured in user or project JSON.\",\n currentValue: `${browser.extensionPaths.length} configured`,\n action: \"show-extensions\",\n },\n ],\n };\n },\n endpoint: ({ state: current }) => ({\n kind: \"input\",\n title: \"DevTools endpoint\",\n lines: [\n sanitizeChromeDevtoolsDisplay(`Current effective endpoint: ${current.load.effectiveBrowser.endpoint}`),\n 'Enter an HTTP origin with an explicit port, or \"default\".',\n ],\n placeholder: \"http://127.0.0.1:9222\",\n action: \"save-endpoint\",\n hint: \"back\",\n }),\n executable: ({ state: current }) => ({\n kind: \"input\",\n title: \"Browser executable\",\n lines: [\n sanitizeChromeDevtoolsDisplay(\n `Current effective executable: ${current.load.effectiveBrowser.executablePath ?? \"automatic discovery\"}`,\n ),\n 'Enter an absolute path, or \"automatic\".',\n ],\n placeholder: \"absolute browser executable path\",\n action: \"save-executable\",\n hint: \"back\",\n }),\n extensions: ({ state: current }) => ({\n kind: \"detail\",\n title: \"Unpacked extensions\",\n lines: extensionDetailLines(current.load),\n hint: \"back\",\n }),\n },\n actions: {\n \"open-endpoint\": () => ({ kind: \"to\", screen: \"endpoint\" }),\n \"save-endpoint\": async ({ value, signal }) => {\n if (value === undefined) return { kind: \"rejected\" };\n let endpoint: string | null;\n try {\n const trimmed = value.trim();\n endpoint = trimmed.toLowerCase() === \"default\" ? null : parseBrowserEndpoint(trimmed).endpoint;\n } catch (error) {\n notifySaveFailure(ctx, error);\n return { kind: \"rejected\" };\n }\n const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {\n endpoint,\n });\n if (!saved) return { kind: \"rejected\" };\n notifyEffectiveSave(ctx, \"endpoint\", saved.effectiveBrowser.endpoint, saved.effectiveBrowser.endpointSource);\n return { kind: \"back\" };\n },\n \"set-auto-launch\": async ({ value, signal }) => {\n if (value !== \"On\" && value !== \"Off\") return { kind: \"rejected\" };\n const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {\n autoLaunch: value === \"On\",\n });\n if (!saved) return { kind: \"rejected\" };\n notifyEffectiveSave(\n ctx,\n \"auto-launch\",\n saved.effectiveBrowser.autoLaunchEnabled ? \"On\" : \"Off\",\n saved.effectiveBrowser.autoLaunchSource,\n );\n return { kind: \"stay\" };\n },\n \"set-webmcp\": async ({ value, signal }) => {\n if (value !== \"On\" && value !== \"Off\") return { kind: \"rejected\" };\n const saved = await saveAndApplyWebMcpSetting(\n pi,\n ctx,\n generation,\n ownerSignal,\n signal,\n projectTrusted,\n value === \"On\",\n );\n if (!saved) return { kind: \"rejected\" };\n ctx.ui.notify(\n saved.effectiveWebMcpEnabled\n ? \"Experimental WebMCP enabled. Every page-provided tool call requires confirmation. Choose gateway availability under Browser tools.\"\n : \"Experimental WebMCP disabled. Active WebMCP work was aborted and both gateway tools are unavailable.\",\n \"warning\",\n );\n return { kind: \"stay\" };\n },\n \"open-executable\": () => ({ kind: \"to\", screen: \"executable\" }),\n \"save-executable\": async ({ value, signal }) => {\n if (value === undefined) return { kind: \"rejected\" };\n const trimmed = value.trim();\n const reset = [\"automatic\", \"default\", \"none\"].includes(trimmed.toLowerCase());\n if (!reset && (!trimmed || !isAbsolute(trimmed))) {\n notifySaveFailure(ctx, new Error('Enter an absolute path or \"automatic\".'));\n return { kind: \"rejected\" };\n }\n const executablePath = reset ? null : trimmed;\n const saved = await saveAndApplyBrowserPatch(ctx, generation, ownerSignal, signal, projectTrusted, {\n executablePath,\n });\n if (!saved) return { kind: \"rejected\" };\n notifyEffectiveSave(\n ctx,\n \"browser executable\",\n saved.effectiveBrowser.executablePath ?? \"automatic discovery\",\n saved.effectiveBrowser.executablePathSource,\n );\n return { kind: \"back\" };\n },\n \"show-extensions\": () => ({ kind: \"to\", screen: \"extensions\" }),\n },\n });\n const result = await runMenu(ctx, menu, {\n getState: async ({ signal }) => {\n signal.throwIfAborted();\n const load = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n signal.throwIfAborted();\n return { load };\n },\n signal: ownerSignal,\n isCurrent,\n onError: (currentCtx, error) =>\n currentCtx.ui.notify(\n sanitizeChromeDevtoolsDisplay(`Chrome DevTools browser settings failed: ${formatError(error)}`),\n \"error\",\n ),\n });\n return { closeParent: result.kind === \"closed\" && result.reason === \"close\" };\n}\n\nasync function saveAndApplyBrowserPatch(\n ctx: CommandContext,\n generation: number,\n ownerSignal: AbortSignal,\n actionSignal: AbortSignal,\n projectTrusted: boolean,\n patch: BrowserSettingsPatch,\n) {\n try {\n await ctx.waitForIdle();\n if (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n await saveBrowserSettings(patch);\n if (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n invalidateWebMcpOperations(ctx.sessionManager, \"Chrome DevTools browser configuration changed\");\n await shutdownManagedBrowser(undefined, { owner: ctx.sessionManager });\n if (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n const loaded = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n if (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n applyRuntimeBrowserSettings(loaded.effectiveBrowser, loaded.paths, projectTrusted);\n syncManagedBrowserSettings(ctx.sessionManager, loaded.effectiveBrowser);\n state.settingsNotice = loaded.notice;\n return loaded;\n } catch (error) {\n if (isCurrent(generation, ownerSignal, actionSignal)) notifySaveFailure(ctx, error);\n return false;\n }\n}\n\nasync function saveAndApplyWebMcpSetting(\n pi: ExtensionAPI,\n ctx: CommandContext,\n generation: number,\n ownerSignal: AbortSignal,\n actionSignal: AbortSignal,\n projectTrusted: boolean,\n enabled: boolean,\n) {\n const previousEnabled = webMcpEnabled(ctx.sessionManager);\n const previousTools = configuredChromeDevtoolsTools(pi);\n try {\n await ctx.waitForIdle();\n if (!isCurrent(generation, ownerSignal, actionSignal)) return false;\n applyRuntimeWebMcpSetting(enabled, ctx.sessionManager);\n applyAvailableChromeDevtoolsTools(pi, previousTools);\n await saveWebMcpSettings(enabled);\n if (!isOwnerCurrent(generation, ownerSignal)) return false;\n const loaded = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n if (!isOwnerCurrent(generation, ownerSignal)) return false;\n state.settingsNotice = loaded.notice;\n return loaded;\n } catch (error) {\n if (!isOwnerCurrent(generation, ownerSignal)) return false;\n let rollbackError: unknown;\n try {\n applyRuntimeWebMcpSetting(previousEnabled, ctx.sessionManager);\n applyAvailableChromeDevtoolsTools(pi, previousTools);\n } catch (caught) {\n rollbackError = caught;\n }\n if (isCurrent(generation, ownerSignal, actionSignal)) {\n notifySaveFailure(\n ctx,\n rollbackError\n ? new Error(`${formatError(error)}; WebMCP rollback failed: ${formatError(rollbackError)}`)\n : error,\n );\n }\n return false;\n }\n}\n\nfunction isOwnerCurrent(generation: number, ownerSignal: AbortSignal) {\n return generation === state.sessionGeneration && !ownerSignal.aborted;\n}\n\nfunction isCurrent(generation: number, ownerSignal: AbortSignal, actionSignal: AbortSignal) {\n return isOwnerCurrent(generation, ownerSignal) && !actionSignal.aborted;\n}\n\nfunction invalidSettingsScreen(load: SettingsLoadResult) {\n const reason = load.userFile.kind === \"invalid\" ? load.userFile.reason : \"The user settings file is unavailable.\";\n return {\n kind: \"detail\" as const,\n title: \"Chrome DevTools Browser settings \u00B7 Read only\",\n lines: [\n sanitizeChromeDevtoolsDisplay(\n `Fix the active user settings before saving; the file will not be overwritten. ${reason}`,\n ),\n ],\n hint: \"back\" as const,\n };\n}\n\nfunction settingsContextLines(load: SettingsLoadResult) {\n const browser = load.effectiveBrowser;\n return [\n `User settings \u00B7 ${load.paths.user}`,\n `Effective sources: endpoint ${browser.endpointSource} \u00B7 auto-launch ${browser.autoLaunchSource} \u00B7 executable ${browser.executablePathSource}`,\n ...(load.notice ? [`Warning: ${load.notice}`] : []),\n ].map((line) => sanitizeChromeDevtoolsDisplay(line));\n}\n\nfunction extensionDetailLines(load: SettingsLoadResult) {\n const browser = load.effectiveBrowser;\n return [\n `Effective source: ${browser.extensionPathsSource}`,\n ...(browser.extensionPaths.length > 0\n ? browser.extensionPaths.map((extensionPath) => `- ${extensionPath}`)\n : [\"No unpacked extensions are configured.\"]),\n \"Edit browser.extensionPaths in the user JSON or a trusted project JSON, then run /reload.\",\n \"Unpacked extensions execute privileged browser code; load only paths you trust.\",\n ].map((line) => sanitizeChromeDevtoolsDisplay(line));\n}\n\nfunction notifyEffectiveSave(\n ctx: CommandContext,\n setting: string,\n effectiveValue: string,\n source: BrowserSettingsSource,\n) {\n const overrideNotice = source === \"environment\" ? \" The deprecated environment override remains effective.\" : \"\";\n ctx.ui.notify(\n sanitizeChromeDevtoolsDisplay(\n `Chrome DevTools ${setting} saved. Effective ${setting}: ${effectiveValue} (${source}).${overrideNotice}`,\n ),\n \"info\",\n );\n}\n\nfunction notifySaveFailure(ctx: CommandContext, error: unknown) {\n ctx.ui.notify(\n sanitizeChromeDevtoolsDisplay(\n `Chrome DevTools browser settings save failed; previous settings remain active: ${formatError(error)}`,\n ),\n \"warning\",\n );\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["isCurrent"]
7
+ }
@@ -10,7 +10,7 @@ import {
10
10
  launchHint,
11
11
  state,
12
12
  withEndpointRetry
13
- } from "./chunk-SRT3UUIP.js";
13
+ } from "./chunk-F5VG35UI.js";
14
14
 
15
15
  // src/cdp-client.ts
16
16
  var MAX_BUFFERED_EVENTS_PER_METHOD = 32;
@@ -381,4 +381,4 @@ export {
381
381
  withCdp,
382
382
  CdpClient
383
383
  };
384
- //# sourceMappingURL=chunk-GTTYS5GT.js.map
384
+ //# sourceMappingURL=chunk-4KMN4SFF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/cdp-client.ts"],
4
+ "sourcesContent": ["import {\n devToolsEndpoint,\n ensureDevToolsEndpoint,\n fetchDevToolsJson,\n formatPageListItem,\n launchHint,\n withEndpointRetry,\n} from \"./browser-manager.js\";\nimport { DEFAULT_ENDPOINT_WAIT_MS, DEFAULT_TIMEOUT_MS, type DevToolsPage, state } from \"./runtime.js\";\n\ninterface CdpResponse<T = unknown> {\n error?: { code: number; data?: unknown; message: string };\n id: number;\n result?: T;\n}\n\ninterface CdpEvent {\n method: string;\n params?: unknown;\n}\n\ninterface PendingRequest {\n cleanup: () => void;\n reject: (reason: unknown) => void;\n resolve: (value: unknown) => void;\n}\n\ninterface EventWaiter<T = unknown> {\n cleanup: () => void;\n method: string;\n predicate: (params: unknown) => params is T;\n reject: (reason: unknown) => void;\n resolve: (params: T) => void;\n}\n\nexport type CdpWebSocketConstructor = new (url: string | URL) => WebSocket;\n\nexport interface CdpOperationOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n}\n\nexport interface CdpConnectOptions extends CdpOperationOptions {\n webSocketConstructor?: CdpWebSocketConstructor;\n}\n\nconst MAX_BUFFERED_EVENTS_PER_METHOD = 32;\nconst MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;\nconst activePageIds = new WeakMap<object, string>();\n\ninterface PageOperationOptions {\n sessionOwner?: object;\n signal?: AbortSignal;\n waitMs?: number;\n}\n\nexport async function listPages(options: PageOperationOptions = {}) {\n const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n return withEndpointRetry(\n async () => {\n const pages = await fetchDevToolsJson<DevToolsPage[]>(\n \"/json/list\",\n { signal: options.signal },\n options.sessionOwner,\n );\n return pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n },\n waitMs,\n options.signal,\n );\n}\n\nexport async function getPage(pageId: string, options: PageOperationOptions = {}) {\n const pages = await listPages(options);\n return requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string, options: PageOperationOptions = {}) {\n const pages = await listPages(options);\n if (pageId) return requirePage(pageId, pages);\n\n const page = resolveDefaultPage(pages, options.sessionOwner);\n if (!page) {\n throw new Error(\n [\n `No Chrome pages found at ${devToolsEndpoint(options.sessionOwner)}.`,\n \"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.\",\n launchHint(options.sessionOwner),\n ].join(\"\\n\"),\n );\n }\n\n return page;\n}\n\nexport async function resolvePageForNavigation(pageId?: string, options: PageOperationOptions = {}) {\n const pages = await listPages(options);\n if (pageId) return { created: false, page: requirePage(pageId, pages) };\n\n const page = resolveDefaultPage(pages, options.sessionOwner);\n if (page) return { created: false, page };\n\n return { created: true, page: await createPage(\"about:blank\", options) };\n}\n\nfunction resolveDefaultPage(pages: DevToolsPage[], owner?: object) {\n const activePageId = owner ? activePageIds.get(owner) : state.activePageId;\n if (!activePageId) return pages[0];\n\n const activePage = pages.find((candidate) => candidate.id === activePageId);\n if (activePage) return activePage;\n\n setActivePageId(owner, undefined);\n return pages[0];\n}\n\nexport function setActivePageId(owner: object | undefined, pageId: string | undefined) {\n if (!owner) {\n state.activePageId = pageId;\n return;\n }\n if (pageId) activePageIds.set(owner, pageId);\n else activePageIds.delete(owner);\n}\n\nfunction requirePage(pageId: string, pages: DevToolsPage[]) {\n const page = pages.find((candidate) => candidate.id === pageId);\n if (page) return page;\n\n const availablePages = pages.map(formatPageListItem).join(\"\\n\");\n throw new Error(\n [\n `Chrome DevTools page not found: ${pageId}.`,\n availablePages ? `Available pages:\\n${availablePages}` : \"No inspectable Chrome pages are currently available.\",\n ].join(\"\\n\"),\n );\n}\n\nexport async function createPage(url: string, options: PageOperationOptions = {}) {\n const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n const page = await withEndpointRetry(\n () =>\n fetchDevToolsJson<DevToolsPage>(\n `/json/new?${encodeURIComponent(url)}`,\n { method: \"PUT\", signal: options.signal },\n options.sessionOwner,\n ),\n waitMs,\n options.signal,\n );\n if (page.type !== \"page\" || !page.webSocketDebuggerUrl) {\n throw new Error(\"Chrome DevTools created a target that is not an inspectable page.\");\n }\n\n return page;\n}\n\nexport function formatPage(page: DevToolsPage) {\n return {\n id: page.id,\n type: page.type,\n title: page.title,\n url: page.url,\n };\n}\n\nexport function textResult<T>(text: string, details: T) {\n return {\n content: [{ type: \"text\" as const, text }],\n details,\n };\n}\n\nexport async function withCdp<T>(\n page: DevToolsPage,\n callback: (client: CdpClient) => Promise<T>,\n options: CdpConnectOptions = {},\n) {\n if (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n const client = await CdpClient.connect(page.webSocketDebuggerUrl, options);\n try {\n return await callback(client);\n } finally {\n client.close();\n }\n}\n\nexport class CdpClient {\n #closed = false;\n #eventBuffers = new Map<string, unknown[]>();\n #eventWaiters = new Set<EventWaiter>();\n #nextId = 1;\n #pending = new Map<number, PendingRequest>();\n readonly #socket: WebSocket;\n\n private constructor(socket: WebSocket) {\n this.#socket = socket;\n socket.addEventListener(\"message\", this.onMessage);\n socket.addEventListener(\"close\", this.onClose);\n socket.addEventListener(\"error\", this.onError);\n }\n\n static connect(url: string, options: CdpConnectOptions = {}) {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const WebSocketImplementation = options.webSocketConstructor ?? WebSocket;\n options.signal?.throwIfAborted();\n return new Promise<CdpClient>((resolve, reject) => {\n const socket = new WebSocketImplementation(url);\n let settled = false;\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", onAbort);\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"error\", onConnectError);\n callback();\n };\n const onOpen = () => settle(() => resolve(new CdpClient(socket)));\n const onConnectError = () =>\n settle(() => {\n socket.close();\n reject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n });\n const onAbort = () =>\n settle(() => {\n socket.close();\n reject(options.signal?.reason ?? abortError(\"Chrome DevTools connection aborted\"));\n });\n const timeout = setTimeout(\n () =>\n settle(() => {\n socket.close();\n reject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n }),\n timeoutMs,\n );\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n socket.addEventListener(\"open\", onOpen, { once: true });\n socket.addEventListener(\"error\", onConnectError, { once: true });\n });\n }\n\n send<T = unknown>(method: string, params: Record<string, unknown> = {}, options: CdpOperationOptions = {}) {\n this.throwIfClosed();\n options.signal?.throwIfAborted();\n const id = this.#nextId;\n this.#nextId += 1;\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n this.#pending.delete(id);\n cleanup();\n reject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));\n };\n const timeout = setTimeout(() => {\n this.#pending.delete(id);\n options.signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(`Timed out waiting for CDP response: ${method}`));\n }, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n const cleanup = () => {\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", onAbort);\n };\n this.#pending.set(id, {\n cleanup,\n reject,\n resolve: resolve as (value: unknown) => void,\n });\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n try {\n this.#socket.send(JSON.stringify({ id, method, params }));\n } catch (error) {\n this.#pending.delete(id);\n cleanup();\n reject(error);\n }\n });\n }\n\n waitForEvent<T>(\n method: string,\n predicate: (params: unknown) => params is T,\n options: CdpOperationOptions = {},\n ): Promise<T> {\n this.throwIfClosed();\n options.signal?.throwIfAborted();\n const buffered = this.#eventBuffers.get(method) ?? [];\n for (const [index, params] of buffered.entries()) {\n if (!predicate(params)) continue;\n buffered.splice(index, 1);\n if (buffered.length === 0) this.#eventBuffers.delete(method);\n return Promise.resolve(params);\n }\n\n return new Promise<T>((resolve, reject) => {\n const waiter = {} as EventWaiter<T>;\n const onAbort = () => {\n this.#eventWaiters.delete(waiter as EventWaiter);\n cleanup();\n reject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));\n };\n const timeout = setTimeout(() => {\n this.#eventWaiters.delete(waiter as EventWaiter);\n options.signal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(`Timed out waiting for CDP event: ${method}`));\n }, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n const cleanup = () => {\n clearTimeout(timeout);\n options.signal?.removeEventListener(\"abort\", onAbort);\n };\n Object.assign(waiter, { cleanup, method, predicate, reject, resolve });\n this.#eventWaiters.add(waiter as EventWaiter);\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n\n close(reason: unknown = new Error(\"Chrome DevTools WebSocket closed\")) {\n if (this.#closed) return;\n this.#closed = true;\n this.#socket.removeEventListener(\"message\", this.onMessage);\n this.#socket.removeEventListener(\"close\", this.onClose);\n this.#socket.removeEventListener(\"error\", this.onError);\n this.rejectAll(reason);\n this.#eventBuffers.clear();\n try {\n this.#socket.close();\n } catch {\n // The transport is already unusable; pending work has still been rejected.\n }\n }\n\n private readonly onClose = () => {\n this.close(new Error(\"Chrome DevTools WebSocket closed\"));\n };\n\n private readonly onError = () => {\n this.close(new Error(\"Chrome DevTools WebSocket error\"));\n };\n\n private readonly onMessage = (event: MessageEvent) => {\n if (typeof event.data !== \"string\") {\n this.close(new Error(\"Chrome DevTools WebSocket sent an unsupported binary message\"));\n return;\n }\n if (event.data.length > MAX_CDP_MESSAGE_BYTES || Buffer.byteLength(event.data, \"utf8\") > MAX_CDP_MESSAGE_BYTES) {\n this.close(new Error(\"Chrome DevTools WebSocket message exceeds the 8 MB limit\"));\n return;\n }\n let payload: unknown;\n try {\n payload = JSON.parse(event.data) as unknown;\n } catch {\n this.close(new Error(\"Chrome DevTools WebSocket sent malformed JSON\"));\n return;\n }\n if (!isRecord(payload)) {\n this.close(new Error(\"Chrome DevTools WebSocket sent a malformed message\"));\n return;\n }\n if (typeof payload.id === \"number\") {\n this.handleResponse(payload as unknown as CdpResponse);\n return;\n }\n if (typeof payload.method !== \"string\") {\n this.close(new Error(\"Chrome DevTools WebSocket sent a malformed event\"));\n return;\n }\n this.handleEvent(payload as unknown as CdpEvent);\n };\n\n private handleResponse(response: CdpResponse) {\n const pending = this.#pending.get(response.id);\n if (!pending) return;\n this.#pending.delete(response.id);\n pending.cleanup();\n if (response.error) {\n pending.reject(\n new Error(\n `CDP error ${response.error.code}: ${response.error.message}${\n response.error.data === undefined ? \"\" : ` (${safeJson(response.error.data)})`\n }`,\n ),\n );\n return;\n }\n pending.resolve(response.result);\n }\n\n private handleEvent(event: CdpEvent) {\n if (event.method === \"Inspector.detached\" || event.method === \"Target.detachedFromTarget\") {\n this.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));\n return;\n }\n for (const waiter of this.#eventWaiters) {\n if (waiter.method !== event.method) continue;\n let matched: boolean;\n try {\n matched = waiter.predicate(event.params);\n } catch (error) {\n this.#eventWaiters.delete(waiter);\n waiter.cleanup();\n waiter.reject(error);\n return;\n }\n if (!matched) continue;\n this.#eventWaiters.delete(waiter);\n waiter.cleanup();\n waiter.resolve(event.params);\n return;\n }\n const buffer = this.#eventBuffers.get(event.method) ?? [];\n buffer.push(event.params);\n if (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {\n this.close(\n new Error(\n `Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`,\n ),\n );\n return;\n }\n this.#eventBuffers.set(event.method, buffer);\n }\n\n private rejectAll(reason: unknown) {\n for (const [id, pending] of this.#pending) {\n this.#pending.delete(id);\n pending.cleanup();\n pending.reject(reason);\n }\n for (const waiter of this.#eventWaiters) {\n this.#eventWaiters.delete(waiter);\n waiter.cleanup();\n waiter.reject(reason);\n }\n }\n\n private throwIfClosed() {\n if (this.#closed) throw new Error(\"Chrome DevTools WebSocket is closed\");\n }\n}\n\nfunction abortError(message: string) {\n return new DOMException(message, \"AbortError\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown) {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -9,14 +9,8 @@ var CORE_CHROME_DEVTOOLS_TOOL_NAMES = [
9
9
  "chrome_devtools_evaluate",
10
10
  "chrome_devtools_screenshot"
11
11
  ];
12
- var WEBMCP_TOOL_NAMES = [
13
- "chrome_devtools_webmcp_list_tools",
14
- "chrome_devtools_webmcp_call_tool"
15
- ];
16
- var CHROME_DEVTOOLS_TOOL_NAMES = [
17
- ...CORE_CHROME_DEVTOOLS_TOOL_NAMES,
18
- ...WEBMCP_TOOL_NAMES
19
- ];
12
+ var WEBMCP_TOOL_NAMES = ["chrome_devtools_webmcp_list_tools", "chrome_devtools_webmcp_call_tool"];
13
+ var CHROME_DEVTOOLS_TOOL_NAMES = [...CORE_CHROME_DEVTOOLS_TOOL_NAMES, ...WEBMCP_TOOL_NAMES];
20
14
  function isWebMcpToolName(value) {
21
15
  return WEBMCP_TOOL_NAMES.includes(value);
22
16
  }
@@ -24,17 +18,7 @@ function isWebMcpToolName(value) {
24
18
  // src/settings.ts
25
19
  import { randomUUID } from "node:crypto";
26
20
  import { constants } from "node:fs";
27
- import {
28
- access,
29
- lstat,
30
- mkdir,
31
- readFile,
32
- realpath,
33
- rename,
34
- rm,
35
- stat,
36
- writeFile
37
- } from "node:fs/promises";
21
+ import { access, lstat, mkdir, readFile, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
38
22
  import { dirname, isAbsolute, join, resolve } from "node:path";
39
23
  import { CONFIG_DIR_NAME, getAgentDir } from "@earendil-works/pi-coding-agent";
40
24
  var NEW_SETTINGS_FILE_NAME = "pi-chrome-devtools.json";
@@ -209,9 +193,7 @@ async function normalizeSettingsDocument(document, scope, filePath, cwd) {
209
193
  if (scope === "user" && (document.tools !== void 0 || document.updatedAt !== void 0)) {
210
194
  const toolSettings = normalizeChromeDevtoolsSettings(document);
211
195
  if (!toolSettings) {
212
- throw new Error(
213
- "expected tools to be an array of Chrome DevTools tool names with numeric updatedAt"
214
- );
196
+ throw new Error("expected tools to be an array of Chrome DevTools tool names with numeric updatedAt");
215
197
  }
216
198
  normalized.tools = toolSettings.tools;
217
199
  normalized.updatedAt = toolSettings.updatedAt;
@@ -283,9 +265,7 @@ async function validateUnpackedExtensionPath(extensionPath) {
283
265
  if (!manifestStat.isFile()) throw new Error("not a regular file");
284
266
  manifest = JSON.parse(await readFile(manifestPath, "utf8"));
285
267
  } catch (error) {
286
- throw new Error(
287
- `unpacked extension ${canonicalPath} has invalid manifest.json: ${formatError(error)}`
288
- );
268
+ throw new Error(`unpacked extension ${canonicalPath} has invalid manifest.json: ${formatError(error)}`);
289
269
  }
290
270
  if (canonicalPath.includes(",")) {
291
271
  throw new Error(
@@ -404,15 +384,10 @@ async function saveSettingsMutationNow(mutate, operations) {
404
384
  await mkdir(dirname(filePath), { recursive: true });
405
385
  const tempFile = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
406
386
  try {
407
- await (operations.write ?? DEFAULT_FILE_OPERATIONS.write)(
408
- tempFile,
409
- `${JSON.stringify(nextDocument, null, 2)}
410
- `
411
- );
387
+ await (operations.write ?? DEFAULT_FILE_OPERATIONS.write)(tempFile, `${JSON.stringify(nextDocument, null, 2)}
388
+ `);
412
389
  if (!replaceCanonical && await pathEntryExists(filePath)) {
413
- throw new Error(
414
- `${NEW_SETTINGS_FILE_NAME} was created concurrently; reopen settings and retry.`
415
- );
390
+ throw new Error(`${NEW_SETTINGS_FILE_NAME} was created concurrently; reopen settings and retry.`);
416
391
  }
417
392
  await (operations.rename ?? DEFAULT_FILE_OPERATIONS.rename)(tempFile, filePath);
418
393
  } catch (error) {
@@ -791,12 +766,7 @@ async function prepareManagedBrowserLaunch(waitMs, generation, signal, owner) {
791
766
  async function launchManagedBrowser(waitMs, generation, signal, owner) {
792
767
  throwIfBrowserLaunchCancelled(generation, signal, owner);
793
768
  const candidateDefinitions = browserCandidateDefinitions(owner);
794
- const candidates = await resolveBrowserCandidates(
795
- candidateDefinitions,
796
- generation,
797
- signal,
798
- owner
799
- );
769
+ const candidates = await resolveBrowserCandidates(candidateDefinitions, generation, signal, owner);
800
770
  throwIfBrowserLaunchCancelled(generation, signal, owner);
801
771
  setLastLaunchAttempt(owner, {
802
772
  candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),
@@ -809,8 +779,7 @@ async function launchManagedBrowser(waitMs, generation, signal, owner) {
809
779
  for (const candidate of candidates) {
810
780
  throwIfBrowserLaunchCancelled(generation, signal, owner);
811
781
  try {
812
- if (extensionsConfigured(owner))
813
- await requireSupportedExtensionBrowser(candidate, generation, signal, owner);
782
+ if (extensionsConfigured(owner)) await requireSupportedExtensionBrowser(candidate, generation, signal, owner);
814
783
  await launchBrowserCandidate(candidate, waitMs, generation, signal, owner);
815
784
  throwIfBrowserLaunchCancelled(generation, signal, owner);
816
785
  setLastLaunchAttempt(owner, {
@@ -883,18 +852,12 @@ function classifyExtensionBrowserVersion(version) {
883
852
  }
884
853
  async function launchBrowserCandidate(candidate, waitMs, generation, signal, owner) {
885
854
  throwIfBrowserLaunchCancelled(generation, signal, owner);
886
- const userDataDir = await browserManagerOperations.mkdtemp(
887
- join2(tmpdir(), MANAGED_BROWSER_PROFILE_PREFIX)
888
- );
855
+ const userDataDir = await browserManagerOperations.mkdtemp(join2(tmpdir(), MANAGED_BROWSER_PROFILE_PREFIX));
889
856
  let managedBrowser;
890
857
  try {
891
858
  throwIfBrowserLaunchCancelled(generation, signal, owner);
892
859
  const portArgument = managedBrowserPortConfigured(owner) ? String(managedBrowserPort(owner)) : "0";
893
- const args = buildManagedBrowserLaunchArguments(
894
- userDataDir,
895
- portArgument,
896
- managedBrowserExtensionPaths(owner)
897
- );
860
+ const args = buildManagedBrowserLaunchArguments(userDataDir, portArgument, managedBrowserExtensionPaths(owner));
898
861
  const child = browserManagerOperations.spawn(candidate.resolvedExecutable, args, {
899
862
  shell: false,
900
863
  stdio: "ignore"
@@ -1018,10 +981,7 @@ async function waitForDevToolsEndpoint(waitMs, managedBrowser, generation, signa
1018
981
  const remainingMs = deadline - Date.now();
1019
982
  if (remainingMs <= 0) {
1020
983
  throw new DevToolsEndpointError(
1021
- [
1022
- `Timed out waiting for auto-launched browser at ${devToolsEndpoint(owner)}.`,
1023
- launchHint(owner)
1024
- ].join("\n")
984
+ [`Timed out waiting for auto-launched browser at ${devToolsEndpoint(owner)}.`, launchHint(owner)].join("\n")
1025
985
  );
1026
986
  }
1027
987
  await browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);
@@ -1073,9 +1033,7 @@ async function cleanupManagedBrowser(managedBrowser, owner) {
1073
1033
  killManagedBrowserProcess(managedBrowser);
1074
1034
  await waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(async () => {
1075
1035
  killManagedBrowserProcess(managedBrowser, "SIGKILL");
1076
- await waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(
1077
- () => void 0
1078
- );
1036
+ await waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(() => void 0);
1079
1037
  });
1080
1038
  }
1081
1039
  await browserManagerOperations.rm(managedBrowser.userDataDir, { recursive: true, force: true }).catch(() => void 0);
@@ -1140,10 +1098,9 @@ async function fetchDevToolsJson(path, init, owner) {
1140
1098
  return await response.json();
1141
1099
  } catch (error) {
1142
1100
  throw new DevToolsEndpointError(
1143
- [
1144
- `Chrome DevTools endpoint ${url} returned invalid JSON: ${formatError2(error)}.`,
1145
- endpointConfigHint()
1146
- ].join("\n")
1101
+ [`Chrome DevTools endpoint ${url} returned invalid JSON: ${formatError2(error)}.`, endpointConfigHint()].join(
1102
+ "\n"
1103
+ )
1147
1104
  );
1148
1105
  }
1149
1106
  }
@@ -1157,10 +1114,7 @@ async function withEndpointRetry(operation, waitMs, signal) {
1157
1114
  if (!isRetryableEndpointError(error)) throw error;
1158
1115
  const remainingMs = deadline - Date.now();
1159
1116
  if (remainingMs <= 0) throw error;
1160
- await browserManagerOperations.sleep(
1161
- Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs),
1162
- signal
1163
- );
1117
+ await browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);
1164
1118
  }
1165
1119
  }
1166
1120
  }
@@ -1335,11 +1289,9 @@ function platformBrowserCandidateDefinitions() {
1335
1289
  ];
1336
1290
  }
1337
1291
  function windowsBrowserCandidateDefinitions() {
1338
- const programFiles = [
1339
- process.env.PROGRAMFILES,
1340
- process.env["PROGRAMFILES(X86)"],
1341
- process.env.LOCALAPPDATA
1342
- ].filter((value) => typeof value === "string" && value.length > 0);
1292
+ const programFiles = [process.env.PROGRAMFILES, process.env["PROGRAMFILES(X86)"], process.env.LOCALAPPDATA].filter(
1293
+ (value) => typeof value === "string" && value.length > 0
1294
+ );
1343
1295
  const wellKnownPaths = programFiles.flatMap((root) => [
1344
1296
  join2(root, "Google", "Chrome", "Application", "chrome.exe"),
1345
1297
  join2(root, "Chromium", "Application", "chrome.exe"),
@@ -1420,10 +1372,7 @@ function executableSearchNames(executable) {
1420
1372
  }
1421
1373
  async function canAccessExecutable(path) {
1422
1374
  try {
1423
- await browserManagerOperations.access(
1424
- path,
1425
- process.platform === "win32" ? constants2.F_OK : constants2.X_OK
1426
- );
1375
+ await browserManagerOperations.access(path, process.platform === "win32" ? constants2.F_OK : constants2.X_OK);
1427
1376
  return true;
1428
1377
  } catch {
1429
1378
  return false;
@@ -1556,4 +1505,4 @@ export {
1556
1505
  endpointConfigHint,
1557
1506
  formatPageListItem
1558
1507
  };
1559
- //# sourceMappingURL=chunk-SRT3UUIP.js.map
1508
+ //# sourceMappingURL=chunk-F5VG35UI.js.map