@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.
- package/README.md +1 -0
- package/dist/chunks/{browser-settings-menu-IMB6HXSU.js → browser-settings-menu-SR7KLZT6.js} +16 -42
- package/dist/chunks/browser-settings-menu-SR7KLZT6.js.map +7 -0
- package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4KMN4SFF.js} +2 -2
- package/dist/chunks/chunk-4KMN4SFF.js.map +7 -0
- package/dist/chunks/{chunk-SRT3UUIP.js → chunk-F5VG35UI.js} +23 -74
- package/dist/chunks/chunk-F5VG35UI.js.map +7 -0
- package/dist/chunks/{chunk-LLXOCRNF.js → chunk-MZCGM6D3.js} +12 -33
- package/dist/chunks/chunk-MZCGM6D3.js.map +7 -0
- package/dist/chunks/{menu-UJETYMSB.js → menu-YR4VRT7D.js} +10 -23
- package/dist/chunks/menu-YR4VRT7D.js.map +7 -0
- package/dist/chunks/{tools-6P7EUX37.js → tools-6R7Z6HWJ.js} +17 -59
- package/dist/chunks/tools-6R7Z6HWJ.js.map +7 -0
- package/dist/index.ts +18 -42
- package/dist/index.ts.map +2 -2
- package/package.json +54 -55
- package/src/browser-manager.ts +872 -942
- package/src/browser-settings-menu.ts +315 -350
- package/src/cdp-client.ts +381 -398
- package/src/chrome-devtools.ts +205 -232
- package/src/display.ts +26 -29
- package/src/lazy-tools.ts +158 -181
- package/src/menu.ts +409 -446
- package/src/render.ts +72 -81
- package/src/runtime.ts +137 -140
- package/src/screenshot.ts +170 -186
- package/src/settings.ts +472 -523
- package/src/tool-names.ts +8 -14
- package/src/tool-selector.ts +242 -271
- package/src/tools.ts +218 -226
- package/src/webmcp/discovery.ts +184 -188
- package/src/webmcp/policy.ts +296 -329
- package/src/webmcp/protocol.ts +324 -337
- package/src/webmcp/tools.ts +136 -147
- package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +0 -7
- package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
- package/dist/chunks/chunk-LLXOCRNF.js.map +0 -7
- package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
- package/dist/chunks/menu-UJETYMSB.js.map +0 -7
- 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-
|
|
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-
|
|
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
|
-
|
|
129
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
193
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1145
|
-
|
|
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
|
-
|
|
1340
|
-
|
|
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-
|
|
1508
|
+
//# sourceMappingURL=chunk-F5VG35UI.js.map
|