@narumitw/pi-chrome-devtools 0.53.4 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -11
- package/dist/chunks/{browser-settings-menu-FVMCCUPM.ts → browser-settings-menu-GQAXLWZ7.ts} +25 -3
- package/dist/chunks/browser-settings-menu-GQAXLWZ7.ts.map +7 -0
- package/dist/chunks/{chunk-4B3EQHOH.ts → chunk-5T2WEIYN.ts} +2 -2
- package/dist/chunks/{chunk-LSJSDY2M.ts → chunk-TVVYQ5KM.ts} +55 -7
- package/dist/chunks/chunk-TVVYQ5KM.ts.map +7 -0
- package/dist/chunks/{chunk-V7N3WI5B.ts → chunk-WOFI2A72.ts} +337 -88
- package/dist/chunks/chunk-WOFI2A72.ts.map +7 -0
- package/dist/chunks/{menu-MTPSLDHZ.ts → menu-Z26D6XSI.ts} +7 -7
- package/dist/chunks/{menu-MTPSLDHZ.ts.map → menu-Z26D6XSI.ts.map} +1 -1
- package/dist/chunks/{tools-OVNH45IJ.ts → tools-DSYQPFF3.ts} +3 -3
- package/dist/index.ts +45 -21
- package/dist/index.ts.map +2 -2
- package/package.json +3 -3
- package/src/browser-settings-menu.ts +23 -0
- package/src/chrome-devtools.ts +48 -15
- package/src/lazy-tools.ts +350 -26
- package/src/menu.ts +3 -3
- package/src/settings.ts +65 -1
- package/src/tool-selector.ts +95 -40
- package/dist/chunks/browser-settings-menu-FVMCCUPM.ts.map +0 -7
- package/dist/chunks/chunk-LSJSDY2M.ts.map +0 -7
- package/dist/chunks/chunk-V7N3WI5B.ts.map +0 -7
- /package/dist/chunks/{chunk-4B3EQHOH.ts.map → chunk-5T2WEIYN.ts.map} +0 -0
- /package/dist/chunks/{tools-OVNH45IJ.ts.map → tools-DSYQPFF3.ts.map} +0 -0
package/src/tool-selector.ts
CHANGED
|
@@ -17,9 +17,17 @@ import {
|
|
|
17
17
|
availableChromeDevtoolsTools,
|
|
18
18
|
CHROME_DEVTOOLS_LOAD_TOOL_NAME,
|
|
19
19
|
chromeDevtoolsToolExposureMode,
|
|
20
|
+
chromeDevtoolsToolMode,
|
|
21
|
+
configuredChromeDevtoolsTools,
|
|
20
22
|
} from "./lazy-tools.js";
|
|
21
23
|
import { invalidateWebMcpOperations, state, webMcpEnabled } from "./runtime.js";
|
|
22
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
loadSettings,
|
|
26
|
+
type SettingsLoadResult,
|
|
27
|
+
saveSettings,
|
|
28
|
+
settingsFilePath,
|
|
29
|
+
ToolCatalogApplicationError,
|
|
30
|
+
} from "./settings.js";
|
|
23
31
|
import {
|
|
24
32
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
25
33
|
type ChromeDevToolsToolName,
|
|
@@ -31,10 +39,6 @@ export { sanitizeChromeDevtoolsDisplay };
|
|
|
31
39
|
|
|
32
40
|
type CommandContext = ExtensionCommandContext;
|
|
33
41
|
|
|
34
|
-
function unique<T>(values: T[]) {
|
|
35
|
-
return Array.from(new Set(values));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
42
|
function formatError(error: unknown) {
|
|
39
43
|
return error instanceof Error ? error.message : String(error);
|
|
40
44
|
}
|
|
@@ -85,8 +89,10 @@ function transactSelectedTools(
|
|
|
85
89
|
expectedGeneration: number,
|
|
86
90
|
expectedActiveTools?: readonly ChromeDevToolsToolName[],
|
|
87
91
|
): Promise<ToolSelectionSaveResult> {
|
|
92
|
+
const acceptedTools = [...selectedTools];
|
|
93
|
+
const expectedTools = expectedActiveTools ? [...expectedActiveTools] : undefined;
|
|
88
94
|
const operation = toolTransactionQueue.then(() =>
|
|
89
|
-
transactSelectedToolsNow(pi, ctx,
|
|
95
|
+
transactSelectedToolsNow(pi, ctx, acceptedTools, expectedGeneration, expectedTools),
|
|
90
96
|
);
|
|
91
97
|
toolTransactionQueue = operation.then(
|
|
92
98
|
() => undefined,
|
|
@@ -102,7 +108,31 @@ async function transactSelectedToolsNow(
|
|
|
102
108
|
expectedGeneration: number,
|
|
103
109
|
expectedActiveTools?: readonly ChromeDevToolsToolName[],
|
|
104
110
|
): Promise<ToolSelectionSaveResult> {
|
|
105
|
-
if (expectedGeneration !== state.sessionGeneration)
|
|
111
|
+
if (expectedGeneration !== state.sessionGeneration) {
|
|
112
|
+
// Accepted durable intents outlive their UI/session; never apply to a replacement runtime.
|
|
113
|
+
try {
|
|
114
|
+
if (expectedActiveTools) {
|
|
115
|
+
// Earlier accepted intents can be durable without publishing to this
|
|
116
|
+
// retired API. Compare the policy the replacement will actually load.
|
|
117
|
+
const settings = await loadSettings();
|
|
118
|
+
if (settings.userFile.kind !== "invalid") {
|
|
119
|
+
const catalog = new Set(
|
|
120
|
+
settings.kind === "loaded" && settings.settings.tools
|
|
121
|
+
? settings.settings.tools
|
|
122
|
+
: CHROME_DEVTOOLS_TOOL_NAMES,
|
|
123
|
+
);
|
|
124
|
+
const current = CHROME_DEVTOOLS_TOOL_NAMES.filter(
|
|
125
|
+
(name) => catalog.has(name) && (settings.effectiveWebMcpEnabled || !isWebMcpToolName(name)),
|
|
126
|
+
);
|
|
127
|
+
if (!arraysEqual(current, expectedActiveTools)) return "active-tools-changed";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
await persistSettings(selectedTools);
|
|
131
|
+
} catch {
|
|
132
|
+
// No live owner remains to notify; storage stays unchanged on failure.
|
|
133
|
+
}
|
|
134
|
+
return "failed";
|
|
135
|
+
}
|
|
106
136
|
if (expectedActiveTools && !arraysEqual(availableChromeDevtoolsTools(pi), expectedActiveTools)) {
|
|
107
137
|
ctx.ui.notify(
|
|
108
138
|
"Browser tool selection changed while review was open. Review the current state, then apply again.",
|
|
@@ -110,39 +140,46 @@ async function transactSelectedToolsNow(
|
|
|
110
140
|
);
|
|
111
141
|
return "active-tools-changed";
|
|
112
142
|
}
|
|
113
|
-
const previousActiveTools = pi.getActiveTools();
|
|
114
|
-
const previousAvailableTools = availableChromeDevtoolsTools(pi);
|
|
115
143
|
try {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
144
|
+
await persistSettings(selectedTools, () => {
|
|
145
|
+
if (expectedGeneration !== state.sessionGeneration) return;
|
|
146
|
+
// Capture at publication, not before I/O: host edits during the save are
|
|
147
|
+
// current intent. A persistence failure never touches runtime policy.
|
|
148
|
+
const previousActiveTools = pi.getActiveTools();
|
|
149
|
+
const previousAvailableTools = availableChromeDevtoolsTools(pi);
|
|
150
|
+
const previousConfiguredTools = configuredChromeDevtoolsTools(pi);
|
|
151
|
+
try {
|
|
152
|
+
const previousWebMcpTools = previousAvailableTools.filter(isWebMcpToolName);
|
|
153
|
+
applyChromeDevtoolsTools(pi, selectedTools);
|
|
154
|
+
const publishedWebMcpTools = availableChromeDevtoolsTools(pi).filter(isWebMcpToolName);
|
|
155
|
+
// Abort is irreversible: rejected publication must leave current work
|
|
156
|
+
// alive, and gated configured names are not an effective policy change.
|
|
157
|
+
if (!arraysEqual(previousWebMcpTools, publishedWebMcpTools)) {
|
|
158
|
+
invalidateWebMcpOperations(ctx.sessionManager, "Chrome DevTools WebMCP gateway availability changed");
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (expectedGeneration === state.sessionGeneration) {
|
|
162
|
+
try {
|
|
163
|
+
applyAvailableChromeDevtoolsTools(pi, previousConfiguredTools, previousActiveTools);
|
|
164
|
+
} catch (rollbackError) {
|
|
165
|
+
throw new Error(`${formatError(error)}; active-tool rollback failed: ${formatError(rollbackError)}`, {
|
|
166
|
+
cause: error,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// The storage queue restores only the tool-owned durable fields before
|
|
171
|
+
// it releases dependent settings reads or replacement session starts.
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
123
175
|
return expectedGeneration === state.sessionGeneration ? "saved" : "failed";
|
|
124
176
|
} catch (error) {
|
|
125
|
-
let rollbackError: unknown;
|
|
126
|
-
try {
|
|
127
|
-
applyAvailableChromeDevtoolsTools(pi, previousAvailableTools);
|
|
128
|
-
const currentNonChromeTools = pi
|
|
129
|
-
.getActiveTools()
|
|
130
|
-
.filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));
|
|
131
|
-
const previousLoadedChromeTools = previousActiveTools.filter((name) =>
|
|
132
|
-
CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName),
|
|
133
|
-
);
|
|
134
|
-
const restoredChromeTools =
|
|
135
|
-
chromeDevtoolsToolExposureMode(pi) === "eager" ? previousAvailableTools : previousLoadedChromeTools;
|
|
136
|
-
pi.setActiveTools(unique([...currentNonChromeTools, ...restoredChromeTools]));
|
|
137
|
-
} catch (caught) {
|
|
138
|
-
rollbackError = caught;
|
|
139
|
-
}
|
|
140
177
|
if (expectedGeneration !== state.sessionGeneration) return "failed";
|
|
141
178
|
ctx.ui.notify(
|
|
142
179
|
sanitizeChromeDevtoolsDisplay(
|
|
143
|
-
|
|
144
|
-
? `Chrome DevTools
|
|
145
|
-
: `Chrome DevTools settings save failed; active tools
|
|
180
|
+
error instanceof ToolCatalogApplicationError
|
|
181
|
+
? `Chrome DevTools tool application failed: ${formatError(error)}`
|
|
182
|
+
: `Chrome DevTools settings save failed; active tools unchanged: ${formatError(error)}`,
|
|
146
183
|
),
|
|
147
184
|
"warning",
|
|
148
185
|
);
|
|
@@ -180,12 +217,31 @@ function getToolStatusSummary(pi: ExtensionAPI, owner: object): ToolStatusSummar
|
|
|
180
217
|
}
|
|
181
218
|
|
|
182
219
|
export async function buildToolStatusMessage(pi: ExtensionAPI, owner: object) {
|
|
220
|
+
const generation = state.sessionGeneration;
|
|
221
|
+
await waitForChromeDevtoolsSettings();
|
|
222
|
+
if (generation !== state.sessionGeneration) return "";
|
|
223
|
+
const settings = await loadSettings();
|
|
224
|
+
// Command callers discard replaced-session output; avoid retired API reads.
|
|
225
|
+
if (generation !== state.sessionGeneration) return "";
|
|
226
|
+
// Do not combine a pre-save runtime summary with a post-save document.
|
|
227
|
+
// All saved labels use this one snapshot; no I/O follows the runtime read.
|
|
183
228
|
const summary = getToolStatusSummary(pi, owner);
|
|
184
|
-
const persistedSetting =
|
|
229
|
+
const persistedSetting = persistedSettingLabel(settings);
|
|
230
|
+
const savedMode =
|
|
231
|
+
settings.userFile.kind === "invalid"
|
|
232
|
+
? undefined
|
|
233
|
+
: settings.kind === "loaded"
|
|
234
|
+
? settings.settings.toolMode
|
|
235
|
+
: "codemode";
|
|
185
236
|
return sanitizeChromeDevtoolsDisplay(
|
|
186
237
|
[
|
|
187
238
|
`Chrome DevTools tools available: ${formatRuntimeStatus(summary)}`,
|
|
239
|
+
`Running tool mode: ${chromeDevtoolsToolMode(pi)}`,
|
|
188
240
|
`Tool exposure: ${chromeDevtoolsToolExposureMode(pi)}`,
|
|
241
|
+
`Saved tool mode: ${savedMode ?? "unavailable (invalid user settings)"}`,
|
|
242
|
+
...(savedMode !== undefined && savedMode !== chromeDevtoolsToolMode(pi)
|
|
243
|
+
? ["Tool mode change pending; /reload or session replacement required."]
|
|
244
|
+
: []),
|
|
189
245
|
`Loaded capability tools this session: ${summary.loadedChromeToolCount}/${summary.capabilityCount}`,
|
|
190
246
|
`WebMCP: ${webMcpEnabled(owner) ? "enabled · experimental · confirmation required for every call" : "disabled · experimental"}`,
|
|
191
247
|
`Loader: ${pi.getActiveTools().includes(CHROME_DEVTOOLS_LOAD_TOOL_NAME) ? "active" : "inactive"}`,
|
|
@@ -308,15 +364,14 @@ function formatRuntimeStatus(summary: ToolStatusSummary) {
|
|
|
308
364
|
return `${summary.availabilityStatus} (${summary.availableChromeToolCount}/${summary.capabilityCount} available)`;
|
|
309
365
|
}
|
|
310
366
|
|
|
311
|
-
|
|
312
|
-
const settings = await loadSettings();
|
|
367
|
+
function persistedSettingLabel(settings: SettingsLoadResult) {
|
|
313
368
|
if (settings.kind === "loaded" && settings.settings.tools) {
|
|
314
369
|
return formatPersistedSelection(settings.settings.tools);
|
|
315
370
|
}
|
|
316
371
|
if (settings.kind === "invalid") {
|
|
317
372
|
return `none; current active-tool policy preserved (invalid settings ignored: ${settings.reason})`;
|
|
318
373
|
}
|
|
319
|
-
return "none;
|
|
374
|
+
return "none; default catalog restored on /reload or session replacement";
|
|
320
375
|
}
|
|
321
376
|
|
|
322
377
|
function formatPersistedSelection(tools: readonly ChromeDevToolsToolName[]) {
|
|
@@ -331,6 +386,6 @@ function effectiveCatalog(owner: object): ChromeDevToolsToolName[] {
|
|
|
331
386
|
return webMcpEnabled(owner) ? [...CHROME_DEVTOOLS_TOOL_NAMES] : [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];
|
|
332
387
|
}
|
|
333
388
|
|
|
334
|
-
async function persistSettings(selectedTools: readonly ChromeDevToolsToolName[]) {
|
|
335
|
-
await saveSettings({ tools: [...selectedTools], updatedAt: Date.now() });
|
|
389
|
+
async function persistSettings(selectedTools: readonly ChromeDevToolsToolName[], applyAfterSave?: () => void) {
|
|
390
|
+
await saveSettings({ tools: [...selectedTools], updatedAt: Date.now() }, {}, applyAfterSave);
|
|
336
391
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
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": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAE3B,SAAS,YAAY,eAAe;AAyCpC,eAAsB,kCACpB,IACA,KACA,YACmC;AACnC,gCAA8B,IAAI,IAAI,cAAc;AACpD,QAAM,cAAc,MAAM,kBAAkB;AAC5C,QAAMA,aAAY,MAAM,eAAe,MAAM,qBAAqB,CAAC,YAAY;AAC/E,QAAM,iBAAiB,IAAI,iBAAiB;AAC5C,QAAM,OAAO,WAAmF;AAAA,IAC9F,OAAO;AAAA,IACP,SAAS;AAAA,MACP,UAAU,CAAC,EAAE,OAAO,QAAQ,MAAM;AAChC,YAAI,QAAQ,KAAK,SAAS,SAAS,UAAW,QAAO,sBAAsB,QAAQ,IAAI;AACvF,cAAM,UAAU,QAAQ,KAAK;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO,qBAAqB,QAAQ,IAAI;AAAA,UACxC,OAAO;AAAA,YACL;AAAA,cACE,IAAI;AAAA,cACJ,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc,8BAA8B,QAAQ,QAAQ;AAAA,cAC5D,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,IAAI;AAAA,cACJ,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc,QAAQ,oBAAoB,OAAO;AAAA,cACjD,QAAQ,CAAC,MAAM,KAAK;AAAA,cACpB,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,IAAI;AAAA,cACJ,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc,8BAA8B,QAAQ,kBAAkB,WAAW;AAAA,cACjF,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,IAAI;AAAA,cACJ,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc,QAAQ,KAAK,yBAAyB,OAAO;AAAA,cAC3D,QAAQ,CAAC,MAAM,KAAK;AAAA,cACpB,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,IAAI;AAAA,cACJ,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc,GAAG,QAAQ,eAAe,MAAM;AAAA,cAC9C,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QACjC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,UACL,8BAA8B,+BAA+B,QAAQ,KAAK,iBAAiB,QAAQ,EAAE;AAAA,UACrG;AAAA,QACF;AAAA,QACA,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,YAAY,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QACnC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,UACL;AAAA,YACE,iCAAiC,QAAQ,KAAK,iBAAiB,kBAAkB,qBAAqB;AAAA,UACxG;AAAA,UACA;AAAA,QACF;AAAA,QACA,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,MACA,YAAY,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QACnC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO,qBAAqB,QAAQ,IAAI;AAAA,QACxC,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,iBAAiB,OAAO,EAAE,MAAM,MAAM,QAAQ,WAAW;AAAA,MACzD,iBAAiB,OAAO,EAAE,OAAO,OAAO,MAAM;AAC5C,YAAI,UAAU,OAAW,QAAO,EAAE,MAAM,WAAW;AACnD,YAAI;AACJ,YAAI;AACF,gBAAM,UAAU,MAAM,KAAK;AAC3B,qBAAW,QAAQ,YAAY,MAAM,YAAY,OAAO,qBAAqB,OAAO,EAAE;AAAA,QACxF,SAAS,OAAO;AACd,4BAAkB,KAAK,KAAK;AAC5B,iBAAO,EAAE,MAAM,WAAW;AAAA,QAC5B;AACA,cAAM,QAAQ,MAAM,yBAAyB,KAAK,YAAY,aAAa,QAAQ,gBAAgB;AAAA,UACjG;AAAA,QACF,CAAC;AACD,YAAI,CAAC,MAAO,QAAO,EAAE,MAAM,WAAW;AACtC,4BAAoB,KAAK,YAAY,MAAM,iBAAiB,UAAU,MAAM,iBAAiB,cAAc;AAC3G,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,mBAAmB,OAAO,EAAE,OAAO,OAAO,MAAM;AAC9C,YAAI,UAAU,QAAQ,UAAU,MAAO,QAAO,EAAE,MAAM,WAAW;AACjE,cAAM,QAAQ,MAAM,yBAAyB,KAAK,YAAY,aAAa,QAAQ,gBAAgB;AAAA,UACjG,YAAY,UAAU;AAAA,QACxB,CAAC;AACD,YAAI,CAAC,MAAO,QAAO,EAAE,MAAM,WAAW;AACtC;AAAA,UACE;AAAA,UACA;AAAA,UACA,MAAM,iBAAiB,oBAAoB,OAAO;AAAA,UAClD,MAAM,iBAAiB;AAAA,QACzB;AACA,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,cAAc,OAAO,EAAE,OAAO,OAAO,MAAM;AACzC,YAAI,UAAU,QAAQ,UAAU,MAAO,QAAO,EAAE,MAAM,WAAW;AACjE,cAAM,QAAQ,MAAM;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACZ;AACA,YAAI,CAAC,MAAO,QAAO,EAAE,MAAM,WAAW;AACtC,YAAI,GAAG;AAAA,UACL,MAAM,yBACF,uIACA;AAAA,UACJ;AAAA,QACF;AACA,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,mBAAmB,OAAO,EAAE,MAAM,MAAM,QAAQ,aAAa;AAAA,MAC7D,mBAAmB,OAAO,EAAE,OAAO,OAAO,MAAM;AAC9C,YAAI,UAAU,OAAW,QAAO,EAAE,MAAM,WAAW;AACnD,cAAM,UAAU,MAAM,KAAK;AAC3B,cAAM,QAAQ,CAAC,aAAa,WAAW,MAAM,EAAE,SAAS,QAAQ,YAAY,CAAC;AAC7E,YAAI,CAAC,UAAU,CAAC,WAAW,CAAC,WAAW,OAAO,IAAI;AAChD,4BAAkB,KAAK,IAAI,MAAM,wCAAwC,CAAC;AAC1E,iBAAO,EAAE,MAAM,WAAW;AAAA,QAC5B;AACA,cAAM,iBAAiB,QAAQ,OAAO;AACtC,cAAM,QAAQ,MAAM,yBAAyB,KAAK,YAAY,aAAa,QAAQ,gBAAgB;AAAA,UACjG;AAAA,QACF,CAAC;AACD,YAAI,CAAC,MAAO,QAAO,EAAE,MAAM,WAAW;AACtC;AAAA,UACE;AAAA,UACA;AAAA,UACA,MAAM,iBAAiB,kBAAkB;AAAA,UACzC,MAAM,iBAAiB;AAAA,QACzB;AACA,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,mBAAmB,OAAO,EAAE,MAAM,MAAM,QAAQ,aAAa;AAAA,IAC/D;AAAA,EACF,CAAC;AACD,QAAM,SAAS,MAAM,QAAQ,KAAK,MAAM;AAAA,IACtC,UAAU,OAAO,EAAE,OAAO,MAAM;AAC9B,aAAO,eAAe;AACtB,YAAM,OAAO,MAAM,aAAa,EAAE,KAAK,IAAI,KAAK,eAAe,CAAC;AAChE,aAAO,eAAe;AACtB,aAAO,EAAE,KAAK;AAAA,IAChB;AAAA,IACA,QAAQ;AAAA,IACR,WAAAA;AAAA,IACA,SAAS,CAAC,YAAY,UACpB,WAAW,GAAG;AAAA,MACZ,8BAA8B,4CAA4C,YAAY,KAAK,CAAC,EAAE;AAAA,MAC9F;AAAA,IACF;AAAA,EACJ,CAAC;AACD,SAAO,EAAE,aAAa,OAAO,SAAS,YAAY,OAAO,WAAW,QAAQ;AAC9E;AAEA,eAAe,yBACb,KACA,YACA,aACA,cACA,gBACA,OACA;AACA,MAAI;AACF,UAAM,IAAI,YAAY;AACtB,QAAI,CAAC,UAAU,YAAY,aAAa,YAAY,EAAG,QAAO;AAC9D,UAAM,oBAAoB,KAAK;AAC/B,QAAI,CAAC,UAAU,YAAY,aAAa,YAAY,EAAG,QAAO;AAC9D,+BAA2B,IAAI,gBAAgB,+CAA+C;AAC9F,UAAM,uBAAuB,QAAW,EAAE,OAAO,IAAI,eAAe,CAAC;AACrE,QAAI,CAAC,UAAU,YAAY,aAAa,YAAY,EAAG,QAAO;AAC9D,UAAM,SAAS,MAAM,aAAa,EAAE,KAAK,IAAI,KAAK,eAAe,CAAC;AAClE,QAAI,CAAC,UAAU,YAAY,aAAa,YAAY,EAAG,QAAO;AAC9D,gCAA4B,OAAO,kBAAkB,OAAO,OAAO,cAAc;AACjF,+BAA2B,IAAI,gBAAgB,OAAO,gBAAgB;AACtE,UAAM,iBAAiB,OAAO;AAC9B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,UAAU,YAAY,aAAa,YAAY,EAAG,mBAAkB,KAAK,KAAK;AAClF,WAAO;AAAA,EACT;AACF;AAEA,eAAe,0BACb,IACA,KACA,YACA,aACA,cACA,gBACA,SACA;AACA,QAAM,kBAAkB,cAAc,IAAI,cAAc;AACxD,QAAM,gBAAgB,8BAA8B,EAAE;AACtD,MAAI;AACF,UAAM,IAAI,YAAY;AACtB,QAAI,CAAC,UAAU,YAAY,aAAa,YAAY,EAAG,QAAO;AAC9D,8BAA0B,SAAS,IAAI,cAAc;AACrD,sCAAkC,IAAI,aAAa;AACnD,UAAM,mBAAmB,OAAO;AAChC,QAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO;AACrD,UAAM,SAAS,MAAM,aAAa,EAAE,KAAK,IAAI,KAAK,eAAe,CAAC;AAClE,QAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO;AACrD,UAAM,iBAAiB,OAAO;AAC9B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO;AACrD,QAAI;AACJ,QAAI;AACF,gCAA0B,iBAAiB,IAAI,cAAc;AAC7D,wCAAkC,IAAI,aAAa;AAAA,IACrD,SAAS,QAAQ;AACf,sBAAgB;AAAA,IAClB;AACA,QAAI,UAAU,YAAY,aAAa,YAAY,GAAG;AACpD;AAAA,QACE;AAAA,QACA,gBACI,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,6BAA6B,YAAY,aAAa,CAAC,EAAE,IACxF;AAAA,MACN;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,eAAe,YAAoB,aAA0B;AACpE,SAAO,eAAe,MAAM,qBAAqB,CAAC,YAAY;AAChE;AAEA,SAAS,UAAU,YAAoB,aAA0B,cAA2B;AAC1F,SAAO,eAAe,YAAY,WAAW,KAAK,CAAC,aAAa;AAClE;AAEA,SAAS,sBAAsB,MAA0B;AACvD,QAAM,SAAS,KAAK,SAAS,SAAS,YAAY,KAAK,SAAS,SAAS;AACzE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,MACL;AAAA,QACE,iFAAiF,MAAM;AAAA,MACzF;AAAA,IACF;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,qBAAqB,MAA0B;AACtD,QAAM,UAAU,KAAK;AACrB,SAAO;AAAA,IACL,sBAAmB,KAAK,MAAM,IAAI;AAAA,IAClC,+BAA+B,QAAQ,cAAc,qBAAkB,QAAQ,gBAAgB,oBAAiB,QAAQ,oBAAoB;AAAA,IAC5I,GAAI,KAAK,SAAS,CAAC,YAAY,KAAK,MAAM,EAAE,IAAI,CAAC;AAAA,EACnD,EAAE,IAAI,CAAC,SAAS,8BAA8B,IAAI,CAAC;AACrD;AAEA,SAAS,qBAAqB,MAA0B;AACtD,QAAM,UAAU,KAAK;AACrB,SAAO;AAAA,IACL,qBAAqB,QAAQ,oBAAoB;AAAA,IACjD,GAAI,QAAQ,eAAe,SAAS,IAChC,QAAQ,eAAe,IAAI,CAAC,kBAAkB,KAAK,aAAa,EAAE,IAClE,CAAC,wCAAwC;AAAA,IAC7C;AAAA,IACA;AAAA,EACF,EAAE,IAAI,CAAC,SAAS,8BAA8B,IAAI,CAAC;AACrD;AAEA,SAAS,oBACP,KACA,SACA,gBACA,QACA;AACA,QAAM,iBAAiB,WAAW,gBAAgB,4DAA4D;AAC9G,MAAI,GAAG;AAAA,IACL;AAAA,MACE,mBAAmB,OAAO,qBAAqB,OAAO,KAAK,cAAc,KAAK,MAAM,KAAK,cAAc;AAAA,IACzG;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,KAAqB,OAAgB;AAC9D,MAAI,GAAG;AAAA,IACL;AAAA,MACE,kFAAkF,YAAY,KAAK,CAAC;AAAA,IACtG;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAAgB;AACnC,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;",
|
|
6
|
-
"names": ["isCurrent"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/tool-names.ts", "../../src/settings.ts", "../../src/runtime.ts", "../../src/browser-manager.ts"],
|
|
4
|
-
"sourcesContent": ["export const CORE_CHROME_DEVTOOLS_TOOL_NAMES = [\n \"chrome_devtools_list_pages\",\n \"chrome_devtools_select_page\",\n \"chrome_devtools_navigate\",\n \"chrome_devtools_evaluate\",\n \"chrome_devtools_screenshot\",\n] as const;\n\nexport const WEBMCP_TOOL_NAMES = [\"chrome_devtools_webmcp_list_tools\", \"chrome_devtools_webmcp_call_tool\"] as const;\n\nexport const CHROME_DEVTOOLS_TOOL_NAMES = [...CORE_CHROME_DEVTOOLS_TOOL_NAMES, ...WEBMCP_TOOL_NAMES] as const;\n\nexport type ChromeDevToolsToolName = (typeof CHROME_DEVTOOLS_TOOL_NAMES)[number];\nexport type WebMcpToolName = (typeof WEBMCP_TOOL_NAMES)[number];\n\nexport function isWebMcpToolName(value: string): value is WebMcpToolName {\n return WEBMCP_TOOL_NAMES.includes(value as WebMcpToolName);\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { access, lstat, mkdir, readFile, realpath, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { CONFIG_DIR_NAME, getAgentDir } from \"@earendil-works/pi-coding-agent\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName } from \"./tool-names.js\";\n\nconst NEW_SETTINGS_FILE_NAME = \"pi-chrome-devtools.json\";\nconst LEGACY_SETTINGS_FILE_NAME = \"pi-chrome-devtools-settings.json\";\n\nexport interface ChromeDevToolsSettings {\n tools: ChromeDevToolsToolName[];\n updatedAt: number;\n}\n\nexport const DEFAULT_BROWSER_HOST = \"127.0.0.1\";\nexport const DEFAULT_BROWSER_PORT = 9222;\nexport const DEFAULT_BROWSER_ENDPOINT = `http://${DEFAULT_BROWSER_HOST}:${DEFAULT_BROWSER_PORT}`;\n\nexport type BrowserSettingsSource = \"default\" | \"environment\" | \"project\" | \"user\";\n\nexport interface UserBrowserSettings {\n endpoint?: string;\n autoLaunch?: boolean;\n executablePath?: string;\n extensionPaths?: string[];\n}\n\nexport interface BrowserSettingsPatch {\n endpoint?: string | null;\n autoLaunch?: boolean | null;\n executablePath?: string | null;\n}\n\nexport interface EffectiveBrowserSettings {\n endpoint: string;\n host: string;\n port: number;\n hostConfigured: boolean;\n portConfigured: boolean;\n autoLaunchEnabled: boolean;\n executablePath?: string;\n extensionPaths: string[];\n endpointSource: BrowserSettingsSource;\n autoLaunchSource: BrowserSettingsSource;\n executablePathSource: BrowserSettingsSource;\n extensionPathsSource: BrowserSettingsSource;\n}\n\nexport interface ResolvedChromeDevToolsSettings {\n tools?: ChromeDevToolsToolName[];\n updatedAt?: number;\n browser: EffectiveBrowserSettings;\n webmcp: { enabled: boolean };\n}\n\nexport interface SettingsLoadOptions {\n cwd?: string;\n projectTrusted?: boolean;\n}\n\nexport type UserSettingsFileStatus = { kind: \"missing\" | \"valid\" } | { kind: \"invalid\"; reason: string };\n\ninterface SettingsLoadBase {\n effectiveBrowser: EffectiveBrowserSettings;\n effectiveWebMcpEnabled: boolean;\n paths: { user: string; project?: string };\n userFile: UserSettingsFileStatus;\n warnings: string[];\n notice?: string;\n}\n\nexport type SettingsLoadResult =\n | (SettingsLoadBase & { kind: \"missing\"; settings?: undefined })\n | (SettingsLoadBase & { kind: \"invalid\"; reason: string; settings?: undefined })\n | (SettingsLoadBase & { kind: \"loaded\"; settings: ResolvedChromeDevToolsSettings });\n\nexport interface SettingsFileOperations {\n write(path: string, data: string): Promise<void>;\n rename(source: string, destination: string): Promise<void>;\n}\n\ninterface NormalizedSettingsDocument {\n tools?: ChromeDevToolsToolName[];\n updatedAt?: number;\n browser?: UserBrowserSettings;\n webmcp?: { enabled: boolean };\n}\n\ninterface SettingsDocumentResult {\n kind: \"missing\" | \"invalid\" | \"valid\";\n reason?: string;\n document?: Record<string, unknown>;\n normalized?: NormalizedSettingsDocument;\n warnings: string[];\n}\n\nconst DEFAULT_FILE_OPERATIONS: SettingsFileOperations = {\n write: (path, data) => writeFile(path, data, \"utf8\").then(() => undefined),\n rename,\n};\n\nlet settingsSaveQueue = Promise.resolve();\n\nexport async function waitForSettingsWrites() {\n await settingsSaveQueue;\n}\n\nexport async function loadSettings(options: SettingsLoadOptions = {}): Promise<SettingsLoadResult> {\n await settingsSaveQueue;\n const userPath = settingsFilePath();\n const projectPath = options.cwd ? projectSettingsFilePath(options.cwd) : undefined;\n const paths = { user: userPath, ...(projectPath ? { project: projectPath } : {}) };\n const warnings: string[] = [];\n\n let user = await readSettingsDocument(userPath, \"user\");\n const legacyExists = await fileExists(legacySettingsFilePath());\n if (user.kind !== \"missing\" && legacyExists) {\n warnings.push(\n `Chrome DevTools legacy settings ignored: ${legacySettingsFilePath()} exists, but ${userPath} takes precedence. Delete ${LEGACY_SETTINGS_FILE_NAME} after confirming your settings.`,\n );\n }\n if (user.kind === \"missing\") {\n const legacy = await readSettingsDocument(legacySettingsFilePath(), \"user\");\n const concurrentlyCreated = await readSettingsDocument(userPath, \"user\");\n if (concurrentlyCreated.kind !== \"missing\") {\n user = concurrentlyCreated;\n if (legacy.kind !== \"missing\") {\n warnings.push(\n `Chrome DevTools legacy settings ignored: ${legacySettingsFilePath()} exists, but ${userPath} takes precedence. Delete ${LEGACY_SETTINGS_FILE_NAME} after confirming your settings.`,\n );\n }\n } else if (legacy.kind !== \"missing\") {\n user = legacy;\n if (legacy.kind === \"valid\") {\n warnings.push(\n `Using legacy ${LEGACY_SETTINGS_FILE_NAME}; rename it to ${NEW_SETTINGS_FILE_NAME}. Future saves write ${NEW_SETTINGS_FILE_NAME} without modifying the legacy file.`,\n );\n }\n }\n }\n warnings.push(...user.warnings);\n\n let project: SettingsDocumentResult = { kind: \"missing\", warnings: [] };\n if (projectPath && options.projectTrusted) {\n project = await readSettingsDocument(projectPath, \"project\", options.cwd);\n warnings.push(...project.warnings);\n }\n\n const environmentWarning = deprecatedEnvironmentWarning();\n if (environmentWarning) warnings.push(environmentWarning);\n\n const userBrowser = user.normalized?.browser ?? {};\n const effectiveBrowser = resolveEffectiveBrowser(userBrowser, project.normalized?.browser);\n const settings = resolveSettings(user.normalized, project.normalized, effectiveBrowser);\n const recognized =\n settings.tools !== undefined ||\n user.normalized?.browser !== undefined ||\n project.normalized?.browser !== undefined ||\n user.normalized?.webmcp !== undefined;\n const invalidReasons = [user, project]\n .filter((result) => result.kind === \"invalid\")\n .map((result) => result.reason)\n .filter((reason): reason is string => Boolean(reason));\n const userFile: UserSettingsFileStatus =\n user.kind === \"invalid\"\n ? {\n kind: \"invalid\",\n reason: user.reason ?? `${userPath}: invalid settings`,\n }\n : { kind: user.kind };\n const base = {\n effectiveBrowser,\n effectiveWebMcpEnabled: settings.webmcp.enabled,\n paths,\n userFile,\n warnings,\n ...(warnings.length > 0 ? { notice: warnings.join(\"\\n\") } : {}),\n };\n\n if (recognized) return { ...base, kind: \"loaded\", settings };\n if (invalidReasons.length > 0) {\n return { ...base, kind: \"invalid\", reason: invalidReasons.join(\"; \") };\n }\n return { ...base, kind: \"missing\" };\n}\n\nfunction resolveSettings(\n user: NormalizedSettingsDocument | undefined,\n _project: NormalizedSettingsDocument | undefined,\n browser: EffectiveBrowserSettings,\n): ResolvedChromeDevToolsSettings {\n return {\n ...(user?.tools ? { tools: user.tools, updatedAt: user.updatedAt } : {}),\n browser,\n webmcp: { enabled: user?.webmcp?.enabled ?? false },\n };\n}\n\nfunction resolveEffectiveBrowser(\n user: UserBrowserSettings,\n project: UserBrowserSettings | undefined,\n): EffectiveBrowserSettings {\n const configuredEndpoint = parseBrowserEndpoint(user.endpoint ?? DEFAULT_BROWSER_ENDPOINT);\n const environmentHost = process.env.PI_CHROME_DEVTOOLS_HOST;\n const environmentPortValue = process.env.PI_CHROME_DEVTOOLS_PORT;\n const environmentPort = parseConfiguredPort(environmentPortValue);\n const environmentEndpointConfigured = environmentHost !== undefined || environmentPort !== undefined;\n const host = environmentHost ?? configuredEndpoint.host;\n const port = environmentPort ?? configuredEndpoint.port;\n const environmentAutoLaunch = process.env.PI_CHROME_DEVTOOLS_AUTO_LAUNCH;\n const environmentExecutable = process.env.PI_CHROME_DEVTOOLS_BROWSER;\n const executablePath = environmentExecutable || user.executablePath;\n const extensionPaths = project?.extensionPaths ?? user.extensionPaths ?? [];\n const endpointSource: BrowserSettingsSource = environmentEndpointConfigured\n ? \"environment\"\n : user.endpoint\n ? \"user\"\n : \"default\";\n return {\n endpoint: formatBrowserEndpoint(host, port),\n host,\n port,\n hostConfigured: environmentHost !== undefined || user.endpoint !== undefined,\n portConfigured: environmentPort !== undefined || user.endpoint !== undefined,\n autoLaunchEnabled: environmentAutoLaunch === undefined ? (user.autoLaunch ?? true) : environmentAutoLaunch !== \"0\",\n ...(executablePath ? { executablePath } : {}),\n extensionPaths: [...extensionPaths],\n endpointSource,\n autoLaunchSource:\n environmentAutoLaunch !== undefined ? \"environment\" : user.autoLaunch !== undefined ? \"user\" : \"default\",\n executablePathSource: environmentExecutable ? \"environment\" : user.executablePath ? \"user\" : \"default\",\n extensionPathsSource: project?.extensionPaths ? \"project\" : user.extensionPaths ? \"user\" : \"default\",\n };\n}\n\nfunction deprecatedEnvironmentWarning() {\n const configuredNames = [\n \"PI_CHROME_DEVTOOLS_HOST\",\n \"PI_CHROME_DEVTOOLS_PORT\",\n \"PI_CHROME_DEVTOOLS_AUTO_LAUNCH\",\n \"PI_CHROME_DEVTOOLS_BROWSER\",\n ].filter((name) => process.env[name] !== undefined);\n if (configuredNames.length === 0) return undefined;\n return `Chrome DevTools environment settings are deprecated and will be removed in a future version: ${configuredNames.join(\", \")}. Move them to browser.endpoint, browser.autoLaunch, and browser.executablePath in ${settingsFilePath()}. Environment values remain active overrides during the deprecation period.`;\n}\n\nasync function readSettingsDocument(\n filePath: string,\n scope: \"project\" | \"user\",\n cwd?: string,\n): Promise<SettingsDocumentResult> {\n let text: string;\n try {\n text = await readFile(filePath, \"utf8\");\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") return { kind: \"missing\", warnings: [] };\n const reason = `${filePath}: ${formatError(error)}`;\n return { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n const reason = `${filePath}: invalid JSON`;\n return { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n }\n if (!isRecord(parsed)) {\n const reason = `${filePath}: expected a JSON object`;\n return { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n }\n\n const scopeWarnings = projectOwnedSettingsWarnings(parsed, scope, filePath);\n try {\n const normalized = await normalizeSettingsDocument(parsed, scope, filePath, cwd);\n return { kind: \"valid\", document: { ...parsed }, normalized, warnings: scopeWarnings };\n } catch (error) {\n const reason = `${filePath}: ${formatError(error)}`;\n return {\n kind: \"invalid\",\n reason,\n warnings: [...scopeWarnings, `Chrome DevTools settings ignored: ${reason}`],\n };\n }\n}\n\nfunction projectOwnedSettingsWarnings(document: Record<string, unknown>, scope: \"project\" | \"user\", filePath: string) {\n if (scope !== \"project\") return [];\n const browser = isRecord(document.browser) ? document.browser : undefined;\n const warnings = browser\n ? [\"endpoint\", \"autoLaunch\", \"executablePath\"]\n .filter((field) => browser[field] !== undefined)\n .map(\n (field) =>\n `Chrome DevTools project browser.${field} ignored in ${filePath}; configure this machine-owned setting in ${settingsFilePath()}.`,\n )\n : [];\n if (document.webmcp !== undefined) {\n warnings.push(\n `Chrome DevTools project webmcp settings ignored in ${filePath}; only the user settings file may enable experimental WebMCP.`,\n );\n }\n return warnings;\n}\n\nasync function normalizeSettingsDocument(\n document: Record<string, unknown>,\n scope: \"project\" | \"user\",\n filePath: string,\n cwd?: string,\n): Promise<NormalizedSettingsDocument> {\n const normalized: NormalizedSettingsDocument = {};\n\n if (scope === \"user\" && (document.tools !== undefined || document.updatedAt !== undefined)) {\n const toolSettings = normalizeChromeDevtoolsSettings(document);\n if (!toolSettings) {\n throw new Error(\"expected tools to be an array of Chrome DevTools tool names with numeric updatedAt\");\n }\n normalized.tools = toolSettings.tools;\n normalized.updatedAt = toolSettings.updatedAt;\n }\n\n if (document.browser !== undefined) {\n if (!isRecord(document.browser)) throw new Error(\"expected browser to be an object\");\n normalized.browser = await normalizeBrowserSection(document.browser, scope, filePath, cwd);\n }\n\n if (scope === \"user\" && document.webmcp !== undefined) {\n if (!isRecord(document.webmcp) || typeof document.webmcp.enabled !== \"boolean\") {\n throw new Error(\"expected webmcp.enabled to be a boolean\");\n }\n normalized.webmcp = { enabled: document.webmcp.enabled };\n }\n\n return normalized;\n}\n\nasync function normalizeBrowserSection(\n browser: Record<string, unknown>,\n scope: \"project\" | \"user\",\n _filePath: string,\n cwd?: string,\n): Promise<UserBrowserSettings> {\n const normalized: UserBrowserSettings = {};\n if (scope === \"user\" && browser.endpoint !== undefined) {\n if (typeof browser.endpoint !== \"string\") {\n throw new Error(\"expected browser.endpoint to be an HTTP URL with an explicit port\");\n }\n normalized.endpoint = parseBrowserEndpoint(browser.endpoint).endpoint;\n }\n if (scope === \"user\" && browser.autoLaunch !== undefined) {\n if (typeof browser.autoLaunch !== \"boolean\") {\n throw new Error(\"expected browser.autoLaunch to be a boolean\");\n }\n normalized.autoLaunch = browser.autoLaunch;\n }\n if (scope === \"user\" && browser.executablePath !== undefined) {\n if (typeof browser.executablePath !== \"string\" || browser.executablePath.length === 0) {\n throw new Error(\"expected browser.executablePath to be a non-empty absolute path\");\n }\n if (!isAbsolute(browser.executablePath)) {\n throw new Error(\"browser.executablePath in user settings must be absolute\");\n }\n normalized.executablePath = resolve(browser.executablePath);\n }\n\n if (browser.extensionPaths !== undefined) {\n if (\n !Array.isArray(browser.extensionPaths) ||\n !browser.extensionPaths.every((entry) => typeof entry === \"string\" && entry.length > 0)\n ) {\n throw new Error(`expected ${scope} browser.extensionPaths to be an array of non-empty paths`);\n }\n const resolvedPaths: string[] = [];\n for (const configuredPath of browser.extensionPaths as string[]) {\n if (scope === \"user\" && !isAbsolute(configuredPath)) {\n throw new Error(\"browser.extensionPaths in user settings must contain only absolute paths\");\n }\n const absolutePath = isAbsolute(configuredPath)\n ? resolve(configuredPath)\n : resolve(cwd ?? process.cwd(), configuredPath);\n resolvedPaths.push(await validateUnpackedExtensionPath(absolutePath));\n }\n normalized.extensionPaths = orderedUnique(resolvedPaths);\n }\n return normalized;\n}\n\nasync function validateUnpackedExtensionPath(extensionPath: string) {\n let canonicalPath: string;\n try {\n canonicalPath = await realpath(extensionPath);\n const extensionStat = await stat(canonicalPath);\n if (!extensionStat.isDirectory()) throw new Error(\"not a directory\");\n } catch (error) {\n throw new Error(`unpacked extension path ${extensionPath} is invalid: ${formatError(error)}`);\n }\n\n const manifestPath = join(canonicalPath, \"manifest.json\");\n let manifest: unknown;\n try {\n const manifestStat = await lstat(manifestPath);\n if (!manifestStat.isFile()) throw new Error(\"not a regular file\");\n manifest = JSON.parse(await readFile(manifestPath, \"utf8\")) as unknown;\n } catch (error) {\n throw new Error(`unpacked extension ${canonicalPath} has invalid manifest.json: ${formatError(error)}`);\n }\n if (canonicalPath.includes(\",\")) {\n throw new Error(\n `unpacked extension path ${canonicalPath} cannot contain a comma because Chrome separates multiple --load-extension paths with commas`,\n );\n }\n if (\n !isRecord(manifest) ||\n ![2, 3].includes(manifest.manifest_version as number) ||\n typeof manifest.name !== \"string\" ||\n typeof manifest.version !== \"string\"\n ) {\n throw new Error(\n `unpacked extension ${canonicalPath} has invalid manifest.json: expected manifest_version, name, and version`,\n );\n }\n return canonicalPath;\n}\n\nexport function parseBrowserEndpoint(value: string) {\n const trimmedValue = value.trim();\n const explicitPort = trimmedValue.match(/^http:\\/\\/(?:\\[[^\\]]+\\]|[^/:?#]+):(\\d+)\\/?$/i)?.[1];\n let endpoint: URL;\n try {\n endpoint = new URL(trimmedValue);\n } catch {\n throw new Error(\"browser.endpoint must be a valid HTTP URL with an explicit port\");\n }\n if (\n endpoint.protocol !== \"http:\" ||\n endpoint.username ||\n endpoint.password ||\n !endpoint.hostname ||\n !explicitPort ||\n (endpoint.pathname !== \"/\" && endpoint.pathname !== \"\") ||\n endpoint.search ||\n endpoint.hash\n ) {\n throw new Error(\n \"browser.endpoint must be an HTTP origin with an explicit port and no credentials, path, query, or fragment\",\n );\n }\n const port = parseConfiguredPort(explicitPort);\n if (port === undefined) {\n throw new Error(\"browser.endpoint must use a port from 1 through 65535\");\n }\n const host = endpoint.hostname;\n return { endpoint: formatBrowserEndpoint(host, port), host, port };\n}\n\nexport function parseConfiguredPort(value: string | undefined) {\n if (value === undefined) return undefined;\n const trimmedValue = value.trim();\n if (!/^\\d+$/.test(trimmedValue)) return undefined;\n const port = Number(trimmedValue);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) return undefined;\n return port;\n}\n\nfunction formatBrowserEndpoint(host: string, port: number) {\n const formattedHost = host.startsWith(\"[\") && host.endsWith(\"]\") ? host : host.includes(\":\") ? `[${host}]` : host;\n return `http://${formattedHost}:${port}`;\n}\n\nexport function normalizeChromeDevtoolsSettings(value: unknown): ChromeDevToolsSettings | undefined {\n if (!isRecord(value)) return undefined;\n if (typeof value.updatedAt !== \"number\" || !Number.isFinite(value.updatedAt)) return undefined;\n\n if (value.tools === \"enabled\") {\n return { tools: [...CHROME_DEVTOOLS_TOOL_NAMES], updatedAt: value.updatedAt };\n }\n if (value.tools === \"disabled\") return { tools: [], updatedAt: value.updatedAt };\n if (!Array.isArray(value.tools) || !value.tools.every(isChromeDevtoolsToolName)) return undefined;\n return { tools: orderedUniqueChromeDevtoolsTools(value.tools), updatedAt: value.updatedAt };\n}\n\nfunction isChromeDevtoolsToolName(value: unknown): value is ChromeDevToolsToolName {\n return typeof value === \"string\" && CHROME_DEVTOOLS_TOOL_NAMES.includes(value as never);\n}\n\nfunction orderedUniqueChromeDevtoolsTools(tools: readonly ChromeDevToolsToolName[]) {\n const selectedTools = new Set(tools);\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => selectedTools.has(toolName));\n}\n\nfunction orderedUnique(values: readonly string[]) {\n return [...new Set(values)];\n}\n\nexport function saveSettings(\n settings: ChromeDevToolsSettings,\n operations: Partial<SettingsFileOperations> = {},\n): Promise<void> {\n return queueSettingsMutation(\n (current) => ({\n ...current,\n tools: [...settings.tools],\n updatedAt: settings.updatedAt,\n }),\n operations,\n );\n}\n\nexport function saveWebMcpSettings(enabled: boolean, operations: Partial<SettingsFileOperations> = {}): Promise<void> {\n return queueSettingsMutation(\n (current) => ({\n ...current,\n webmcp: {\n ...(isRecord(current.webmcp) ? current.webmcp : {}),\n enabled,\n },\n }),\n operations,\n );\n}\n\nexport function saveBrowserSettings(\n patch: BrowserSettingsPatch,\n operations: Partial<SettingsFileOperations> = {},\n): Promise<void> {\n return queueSettingsMutation(async (current) => {\n const browser = isRecord(current.browser) ? { ...current.browser } : {};\n for (const field of [\"endpoint\", \"autoLaunch\", \"executablePath\"] as const) {\n const value = patch[field];\n if (value === undefined) continue;\n if (value === null) delete browser[field];\n else browser[field] = value;\n }\n await normalizeBrowserSection(browser, \"user\", settingsFilePath());\n return { ...current, browser };\n }, operations);\n}\n\nfunction queueSettingsMutation(\n mutate: (current: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>,\n operations: Partial<SettingsFileOperations>,\n) {\n const operation = settingsSaveQueue.then(() => saveSettingsMutationNow(mutate, operations));\n settingsSaveQueue = operation.catch(() => undefined);\n return operation;\n}\n\nasync function saveSettingsMutationNow(\n mutate: (current: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>,\n operations: Partial<SettingsFileOperations>,\n): Promise<void> {\n const filePath = settingsFilePath();\n let current = await readSettingsDocument(filePath, \"user\");\n const replaceCanonical = current.kind !== \"missing\";\n if (!replaceCanonical) current = await readSettingsDocument(legacySettingsFilePath(), \"user\");\n if (current.kind === \"invalid\") {\n throw new Error(`Cannot save Chrome DevTools settings until you repair ${current.reason}`);\n }\n const nextDocument = await mutate(current.document ?? {});\n await mkdir(dirname(filePath), { recursive: true });\n const tempFile = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await (operations.write ?? DEFAULT_FILE_OPERATIONS.write)(tempFile, `${JSON.stringify(nextDocument, null, 2)}\\n`);\n if (!replaceCanonical && (await pathEntryExists(filePath))) {\n throw new Error(`${NEW_SETTINGS_FILE_NAME} was created concurrently; reopen settings and retry.`);\n }\n await (operations.rename ?? DEFAULT_FILE_OPERATIONS.rename)(tempFile, filePath);\n } catch (error) {\n await rm(tempFile, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n\nexport function settingsFilePath() {\n return join(getAgentDir(), NEW_SETTINGS_FILE_NAME);\n}\n\nexport function projectSettingsFilePath(cwd: string) {\n return join(cwd, CONFIG_DIR_NAME, NEW_SETTINGS_FILE_NAME);\n}\n\nfunction legacySettingsFilePath() {\n return join(getAgentDir(), LEGACY_SETTINGS_FILE_NAME);\n}\n\nasync function fileExists(filePath: string) {\n try {\n await access(filePath, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function pathEntryExists(filePath: string) {\n try {\n await lstat(filePath);\n return true;\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") return false;\n throw error;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n", "import type { ChildProcess } from \"node:child_process\";\nimport {\n DEFAULT_BROWSER_HOST,\n DEFAULT_BROWSER_PORT,\n type EffectiveBrowserSettings,\n parseConfiguredPort,\n} from \"./settings.js\";\n\nexport const DEFAULT_HOST = DEFAULT_BROWSER_HOST;\nexport const DEFAULT_PORT = DEFAULT_BROWSER_PORT;\nexport const DEFAULT_TIMEOUT_MS = 10_000;\nexport const DEFAULT_HTTP_TIMEOUT_MS = 1_000;\nexport const DEFAULT_ENDPOINT_WAIT_MS = 5_000;\nexport const DEFAULT_ENDPOINT_RETRY_MS = 250;\nexport const MANAGED_BROWSER_PROFILE_PREFIX = \"pi-chrome-devtools-profile-\";\nexport const DEVTOOLS_ACTIVE_PORT_FILE = \"DevToolsActivePort\";\nexport const BROWSER_SHUTDOWN_WAIT_MS = 1_500;\n\nexport interface DevToolsPage {\n id: string;\n type: string;\n title: string;\n url: string;\n webSocketDebuggerUrl?: string;\n}\n\nexport interface ChromeDevToolsState {\n host: string;\n port: number;\n configuredPort: number;\n hostConfigured: boolean;\n portConfigured: boolean;\n autoLaunchEnabled: boolean;\n endpointSource: EffectiveBrowserSettings[\"endpointSource\"];\n autoLaunchSource: EffectiveBrowserSettings[\"autoLaunchSource\"];\n browserExecutable?: string;\n extensionPaths: string[];\n browserExecutableSource: EffectiveBrowserSettings[\"executablePathSource\"];\n extensionPathsSource: EffectiveBrowserSettings[\"extensionPathsSource\"];\n settingsFilePath?: string;\n projectSettingsFilePath?: string;\n projectSettingsTrusted: boolean;\n activePageId?: string;\n managedBrowser?: ManagedBrowser;\n launchPromise?: Promise<void>;\n lastLaunchAttempt?: BrowserLaunchAttempt;\n shuttingDown: boolean;\n sessionGeneration: number;\n sessionController: AbortController;\n settingsNotice?: string;\n}\n\nexport interface ManagedBrowser {\n process: ChildProcess;\n userDataDir: string;\n port?: number;\n exited: boolean;\n ready: boolean;\n ownerGeneration: number;\n sessionOwner?: object;\n cleanupPromise?: Promise<void>;\n}\n\nexport interface BrowserLaunchAttempt {\n candidateLabels: string[];\n mode: \"dynamic-port\" | \"explicit-port\";\n selectedCandidate?: string;\n userDataDir?: string;\n lastError?: string;\n}\n\nexport interface BrowserCandidateDefinition {\n label: string;\n executable: string;\n source: \"env\" | \"path\" | \"wellKnownPath\";\n}\n\nexport interface BrowserCandidate extends BrowserCandidateDefinition {\n resolvedExecutable: string;\n}\n\nexport { parseConfiguredPort };\n\nexport const state: ChromeDevToolsState = {\n host: DEFAULT_HOST,\n port: DEFAULT_PORT,\n configuredPort: DEFAULT_PORT,\n hostConfigured: false,\n portConfigured: false,\n autoLaunchEnabled: true,\n endpointSource: \"default\",\n autoLaunchSource: \"default\",\n extensionPaths: [],\n browserExecutableSource: \"default\",\n extensionPathsSource: \"default\",\n projectSettingsTrusted: false,\n shuttingDown: false,\n sessionGeneration: 0,\n sessionController: new AbortController(),\n};\n\ninterface WebMcpSessionRuntime {\n controller: AbortController;\n enabled: boolean;\n controllers: Set<AbortController>;\n generation: number;\n sessionGeneration: number;\n}\n\nconst webMcpRuntimeByOwner = new WeakMap<object, WebMcpSessionRuntime>();\n\nexport function setWebMcpSessionOwner(owner: object) {\n const runtime = webMcpRuntime(owner);\n runtime.enabled = false;\n runtime.sessionGeneration += 1;\n}\n\nexport function beginWebMcpOperation(owner: object, toolSignal?: AbortSignal) {\n const runtime = webMcpRuntime(owner);\n const controller = new AbortController();\n runtime.controllers.add(controller);\n const signals = [controller.signal, runtime.controller.signal];\n if (toolSignal) signals.push(toolSignal);\n const signal = AbortSignal.any(signals);\n return {\n signal,\n owner,\n sessionGeneration: runtime.sessionGeneration,\n webMcpGeneration: runtime.generation,\n dispose() {\n runtime.controllers.delete(controller);\n },\n };\n}\n\nexport function invalidateWebMcpOperations(owner: object, reason: string) {\n const runtime = webMcpRuntime(owner);\n runtime.generation += 1;\n const controllers = [...runtime.controllers];\n runtime.controllers.clear();\n const error = new DOMException(reason, \"AbortError\");\n runtime.controller.abort(error);\n runtime.controller = new AbortController();\n for (const controller of controllers) controller.abort(error);\n}\n\nexport function currentWebMcpGeneration(owner: object) {\n return webMcpRuntime(owner).generation;\n}\n\nexport function webMcpSessionSignal(owner: object) {\n return webMcpRuntime(owner).controller.signal;\n}\n\nexport function applyRuntimeWebMcpSetting(enabled: boolean, owner: object) {\n const runtime = webMcpRuntime(owner);\n if (runtime.enabled !== enabled) {\n invalidateWebMcpOperations(owner, `WebMCP ${enabled ? \"enabled\" : \"disabled\"}`);\n }\n runtime.enabled = enabled;\n}\n\nexport function webMcpEnabled(owner: object) {\n return webMcpRuntime(owner).enabled;\n}\n\nexport function webMcpOperationIsCurrent(operation: {\n owner: object;\n sessionGeneration: number;\n webMcpGeneration: number;\n}) {\n const runtime = webMcpRuntime(operation.owner);\n return operation.sessionGeneration === runtime.sessionGeneration && operation.webMcpGeneration === runtime.generation;\n}\n\nfunction webMcpRuntime(owner: object) {\n const existing = webMcpRuntimeByOwner.get(owner);\n if (existing) return existing;\n const created: WebMcpSessionRuntime = {\n controller: new AbortController(),\n controllers: new Set(),\n enabled: false,\n generation: 0,\n sessionGeneration: 0,\n };\n webMcpRuntimeByOwner.set(owner, created);\n return created;\n}\n\nexport function applyRuntimeBrowserSettings(\n browser: EffectiveBrowserSettings,\n paths: { user: string; project?: string },\n projectTrusted: boolean,\n) {\n state.host = browser.host;\n state.port = browser.port;\n state.configuredPort = browser.port;\n state.hostConfigured = browser.hostConfigured;\n state.portConfigured = browser.portConfigured;\n state.autoLaunchEnabled = browser.autoLaunchEnabled;\n state.endpointSource = browser.endpointSource;\n state.autoLaunchSource = browser.autoLaunchSource;\n state.browserExecutable = browser.executablePath;\n state.extensionPaths = [...browser.extensionPaths];\n state.browserExecutableSource = browser.executablePathSource;\n state.extensionPathsSource = browser.extensionPathsSource;\n state.settingsFilePath = paths.user;\n state.projectSettingsFilePath = paths.project;\n state.projectSettingsTrusted = projectTrusted;\n}\n", "import { type ChildProcess, execFile, spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { access, mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport { createServer } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { delimiter, isAbsolute, join, resolve } from \"node:path\";\nimport {\n BROWSER_SHUTDOWN_WAIT_MS,\n type BrowserCandidate,\n type BrowserCandidateDefinition,\n type BrowserLaunchAttempt,\n DEFAULT_ENDPOINT_RETRY_MS,\n DEFAULT_ENDPOINT_WAIT_MS,\n DEFAULT_HTTP_TIMEOUT_MS,\n DEVTOOLS_ACTIVE_PORT_FILE,\n type DevToolsPage,\n invalidateWebMcpOperations,\n MANAGED_BROWSER_PROFILE_PREFIX,\n type ManagedBrowser,\n state,\n} from \"./runtime.js\";\nimport type { EffectiveBrowserSettings } from \"./settings.js\";\n\n// Endpoint attachment, managed launch, dynamic-port publication, and shutdown intentionally remain\n// together because they form one ownership state machine behind the testable operations boundary.\ninterface BrowserSpawnOptions {\n shell: false;\n stdio: \"ignore\";\n}\n\nexport interface BrowserManagerOperations {\n access(path: string, mode: number): Promise<void>;\n mkdtemp(prefix: string): Promise<string>;\n readFile(path: string, encoding: \"utf8\"): Promise<string>;\n rm(path: string, options: { recursive: true; force: true }): Promise<void>;\n fetch(input: string, init?: RequestInit): Promise<Response>;\n spawn(executable: string, args: string[], options: BrowserSpawnOptions): ChildProcess;\n inspectBrowserVersion(executable: string, signal: AbortSignal): Promise<string>;\n isPortAvailable(host: string, port: number): Promise<boolean>;\n sleep(ms: number, signal?: AbortSignal): Promise<void>;\n}\n\nconst DEFAULT_BROWSER_MANAGER_OPERATIONS: BrowserManagerOperations = {\n access,\n mkdtemp,\n readFile,\n rm: (path, options) => rm(path, options),\n fetch: (input, init) => fetch(input, init),\n spawn,\n inspectBrowserVersion,\n isPortAvailable,\n sleep: abortableSleep,\n};\n\nlet browserManagerOperations = DEFAULT_BROWSER_MANAGER_OPERATIONS;\n\ninterface ManagedBrowserScope {\n browser: EffectiveBrowserSettings;\n controller: AbortController;\n generation: number;\n launchPromise?: Promise<void>;\n managedBrowser?: ManagedBrowser;\n port: number;\n lastLaunchAttempt?: BrowserLaunchAttempt;\n}\n\nconst managedBrowserScopes = new WeakMap<object, ManagedBrowserScope>();\n\nfunction cloneBrowserSettings(browser: EffectiveBrowserSettings): EffectiveBrowserSettings {\n return { ...browser, extensionPaths: [...browser.extensionPaths] };\n}\n\nfunction runtimeBrowserSettings(): EffectiveBrowserSettings {\n return {\n endpoint: `http://${formatHostForUrl(state.host)}:${state.configuredPort}`,\n host: state.host,\n port: state.configuredPort,\n hostConfigured: state.hostConfigured,\n portConfigured: state.portConfigured,\n autoLaunchEnabled: state.autoLaunchEnabled,\n ...(state.browserExecutable ? { executablePath: state.browserExecutable } : {}),\n extensionPaths: [...state.extensionPaths],\n endpointSource: state.endpointSource,\n autoLaunchSource: state.autoLaunchSource,\n executablePathSource: state.browserExecutableSource,\n extensionPathsSource: state.extensionPathsSource,\n };\n}\n\nfunction managedBrowserScope(owner: object) {\n const existing = managedBrowserScopes.get(owner);\n if (existing) return existing;\n const browser = runtimeBrowserSettings();\n const created: ManagedBrowserScope = {\n browser,\n controller: new AbortController(),\n generation: 0,\n port: browser.port,\n };\n managedBrowserScopes.set(owner, created);\n return created;\n}\n\nexport function startManagedBrowserSession(owner: object) {\n const scope = managedBrowserScope(owner);\n scope.controller.abort(new DOMException(\"Chrome DevTools session replaced\", \"AbortError\"));\n scope.controller = new AbortController();\n scope.generation += 1;\n scope.lastLaunchAttempt = undefined;\n}\n\nexport function syncManagedBrowserSettings(owner: object, browser: EffectiveBrowserSettings) {\n const scope = managedBrowserScope(owner);\n scope.browser = cloneBrowserSettings(browser);\n scope.port = browser.port;\n}\n\nexport function browserSettingsForOwner(owner?: object) {\n return owner ? managedBrowserScope(owner).browser : runtimeBrowserSettings();\n}\n\nexport function managedBrowserExtensionPaths(owner?: object) {\n return browserSettingsForOwner(owner).extensionPaths;\n}\n\nexport function managedBrowserExtensionPathsSource(owner?: object) {\n return browserSettingsForOwner(owner).extensionPathsSource;\n}\n\nexport function managedBrowserForOwner(owner?: object) {\n if (!owner) return state.managedBrowser;\n const scopedBrowser = managedBrowserScope(owner).managedBrowser;\n if (scopedBrowser) return scopedBrowser;\n return state.managedBrowser?.sessionOwner === owner ? state.managedBrowser : undefined;\n}\n\nfunction setManagedBrowser(owner: object | undefined, browser: ManagedBrowser | undefined) {\n if (owner) managedBrowserScope(owner).managedBrowser = browser;\n else state.managedBrowser = browser;\n}\n\nfunction launchPromiseForOwner(owner?: object) {\n return owner ? managedBrowserScope(owner).launchPromise : state.launchPromise;\n}\n\nfunction setLaunchPromise(owner: object | undefined, launchPromise: Promise<void> | undefined) {\n if (owner) managedBrowserScope(owner).launchPromise = launchPromise;\n else state.launchPromise = launchPromise;\n}\n\nfunction managedBrowserPort(owner?: object) {\n return owner ? managedBrowserScope(owner).port : state.port;\n}\n\nfunction managedBrowserConfiguredPort(owner?: object) {\n return browserSettingsForOwner(owner).port;\n}\n\nfunction managedBrowserPortConfigured(owner?: object) {\n return browserSettingsForOwner(owner).portConfigured;\n}\n\nfunction setManagedBrowserPort(owner: object | undefined, port: number) {\n if (owner) managedBrowserScope(owner).port = port;\n else state.port = port;\n}\n\nfunction lastLaunchAttempt(owner?: object) {\n return owner ? managedBrowserScope(owner).lastLaunchAttempt : state.lastLaunchAttempt;\n}\n\nfunction setLastLaunchAttempt(owner: object | undefined, attempt: BrowserLaunchAttempt | undefined) {\n if (owner) managedBrowserScope(owner).lastLaunchAttempt = attempt;\n else state.lastLaunchAttempt = attempt;\n}\n\nexport function setBrowserManagerOperationsForTests(overrides: Partial<BrowserManagerOperations>) {\n const previous = browserManagerOperations;\n browserManagerOperations = { ...DEFAULT_BROWSER_MANAGER_OPERATIONS, ...overrides };\n return () => {\n browserManagerOperations = previous;\n };\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nfunction normalizePathForComparison(value: string) {\n return process.platform === \"win32\" ? value.toLowerCase() : value;\n}\n\nexport async function ensureDevToolsEndpoint(\n waitMs = DEFAULT_ENDPOINT_WAIT_MS,\n callerSignal?: AbortSignal,\n owner?: object,\n) {\n callerSignal?.throwIfAborted();\n if (extensionsConfigured(owner)) {\n validateExtensionLaunchMode(owner);\n await ensureManagedBrowserLaunched(waitMs, callerSignal, owner);\n return;\n }\n if (canAutoLaunchBrowser(owner)) {\n try {\n await withEndpointRetry(\n () => fetchDevToolsJson<unknown>(\"/json/version\", { signal: callerSignal }, owner),\n waitMs,\n callerSignal,\n );\n return;\n } catch (error) {\n if (shouldAutoLaunchAfterEndpointError(error, owner)) {\n await ensureManagedBrowserLaunched(waitMs, callerSignal, owner);\n return;\n }\n throw error;\n }\n }\n\n try {\n await fetchDevToolsJson<unknown>(\"/json/version\", { signal: callerSignal }, owner);\n } catch (error) {\n if (isRetryableEndpointError(error)) return;\n throw error;\n }\n}\n\nfunction validateExtensionLaunchMode(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n if (!isLocalDevToolsHost(browser.host)) {\n throw new DevToolsEndpointError(\n \"Unpacked extensions require a local extension-owned managed browser; remote CDP endpoints cannot be modified.\",\n );\n }\n if (!browser.autoLaunchEnabled) {\n throw new DevToolsEndpointError(\n \"Auto-launch is required for unpacked extensions so Pi can create an isolated managed browser.\",\n );\n }\n if (!browser.executablePath) {\n throw new DevToolsEndpointError(\n \"Unpacked extensions require browser.executablePath for Chrome for Testing or Chromium in pi-chrome-devtools.json.\",\n );\n }\n}\n\nasync function ensureManagedBrowserLaunched(waitMs: number, callerSignal?: AbortSignal, owner?: object) {\n const existingLaunch = launchPromiseForOwner(owner);\n if (existingLaunch) {\n await waitForCaller(existingLaunch, callerSignal);\n return;\n }\n const existingBrowser = managedBrowserForOwner(owner);\n if (existingBrowser && !existingBrowser.exited && existingBrowser.ready) return;\n const generation = owner ? managedBrowserScope(owner).generation : state.sessionGeneration;\n const signal = owner ? managedBrowserScope(owner).controller.signal : state.sessionController.signal;\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n\n const launchPromise = prepareManagedBrowserLaunch(waitMs, generation, signal, owner);\n const wrappedPromise = launchPromise.finally(() => {\n if (launchPromiseForOwner(owner) === wrappedPromise) setLaunchPromise(owner, undefined);\n });\n setLaunchPromise(owner, wrappedPromise);\n await waitForCaller(wrappedPromise, callerSignal);\n}\n\nfunction waitForCaller<T>(operation: Promise<T>, signal?: AbortSignal) {\n if (!signal) return operation;\n signal.throwIfAborted();\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const onAbort = () => settle(() => reject(signal.reason));\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n signal.removeEventListener(\"abort\", onAbort);\n callback();\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n operation.then(\n (value) => settle(() => resolve(value)),\n (error) => settle(() => reject(error)),\n );\n });\n}\n\nasync function prepareManagedBrowserLaunch(waitMs: number, generation: number, signal: AbortSignal, owner?: object) {\n const existingBrowser = managedBrowserForOwner(owner);\n if (existingBrowser) {\n await shutdownManagedBrowser(existingBrowser, { awaitLaunch: false, owner });\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n }\n if (managedBrowserPortConfigured(owner)) {\n const available = await browserManagerOperations.isPortAvailable(\n browserSettingsForOwner(owner).host,\n managedBrowserPort(owner),\n );\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n if (!available) {\n throw new DevToolsEndpointError(\n `Cannot launch the extension-owned browser because explicit port ${managedBrowserPort(owner)} is already in use. Choose a free browser.endpoint port or reset the endpoint to use a dynamic managed port.`,\n );\n }\n }\n return launchManagedBrowser(waitMs, generation, signal, owner);\n}\n\nasync function launchManagedBrowser(waitMs: number, generation: number, signal: AbortSignal, owner?: object) {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const candidateDefinitions = browserCandidateDefinitions(owner);\n const candidates = await resolveBrowserCandidates(candidateDefinitions, generation, signal, owner);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n setLastLaunchAttempt(owner, {\n candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n mode: managedBrowserPortConfigured(owner) ? \"explicit-port\" : \"dynamic-port\",\n });\n\n if (candidates.length === 0) {\n throw new DevToolsEndpointError(noBrowserCandidateMessage(candidateDefinitions, owner));\n }\n\n let lastError: unknown;\n for (const candidate of candidates) {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n try {\n if (extensionsConfigured(owner)) await requireSupportedExtensionBrowser(candidate, generation, signal, owner);\n await launchBrowserCandidate(candidate, waitMs, generation, signal, owner);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n setLastLaunchAttempt(owner, {\n ...lastLaunchAttempt(owner),\n candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n mode: managedBrowserPortConfigured(owner) ? \"explicit-port\" : \"dynamic-port\",\n selectedCandidate: formatBrowserCandidate(candidate),\n userDataDir: managedBrowserForOwner(owner)?.userDataDir,\n });\n return;\n } catch (error) {\n try {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n } catch (cancellation) {\n setLastLaunchAttempt(owner, {\n ...(lastLaunchAttempt(owner) ?? {\n candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n mode: managedBrowserPortConfigured(owner) ? \"explicit-port\" : \"dynamic-port\",\n }),\n lastError: formatError(cancellation),\n });\n throw cancellation;\n }\n lastError = error;\n setLastLaunchAttempt(owner, {\n ...(lastLaunchAttempt(owner) ?? {\n candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n mode: managedBrowserPortConfigured(owner) ? \"explicit-port\" : \"dynamic-port\",\n }),\n lastError: formatError(error),\n });\n }\n }\n\n if (lastError instanceof DevToolsEndpointError && extensionsConfigured(owner)) throw lastError;\n throw new DevToolsEndpointError(\n [\n \"Unable to auto-launch a Chromium-family browser for Chrome DevTools.\",\n `Tried: ${candidates.map(formatBrowserCandidate).join(\", \")}`,\n lastError ? `Last error: ${formatError(lastError)}` : undefined,\n launchHint(owner),\n endpointConfigHint(),\n ]\n .filter(Boolean)\n .join(\"\\n\"),\n );\n}\n\nasync function requireSupportedExtensionBrowser(\n candidate: BrowserCandidate,\n generation: number,\n signal: AbortSignal,\n owner?: object,\n) {\n let version: string;\n try {\n version = (await browserManagerOperations.inspectBrowserVersion(candidate.resolvedExecutable, signal)).trim();\n } catch (error) {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n throw new DevToolsEndpointError(\n `Unable to identify the configured extension browser ${candidate.resolvedExecutable}: ${formatError(error)}. Configure Chrome for Testing or Chromium.`,\n );\n }\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const classification = classifyExtensionBrowserVersion(version);\n if (!classification.supported) {\n throw new DevToolsEndpointError(\n `Unsupported browser for unpacked extensions: ${version || \"unknown product\"}. Configure Chrome for Testing or Chromium; branded Chrome may silently ignore extension startup flags.`,\n );\n }\n}\n\nexport function classifyExtensionBrowserVersion(version: string): {\n supported: boolean;\n product: string;\n} {\n if (/^(?:Google )?Chrome for Testing\\b/i.test(version)) {\n return { supported: true, product: \"Chrome for Testing\" };\n }\n if (/^Chromium\\b/i.test(version)) return { supported: true, product: \"Chromium\" };\n const product = version.trim().replace(/\\s+\\d+(?:\\.\\d+)*.*$/, \"\") || \"Unknown\";\n return { supported: false, product };\n}\n\nasync function launchBrowserCandidate(\n candidate: BrowserCandidate,\n waitMs: number,\n generation: number,\n signal: AbortSignal,\n owner?: object,\n) {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const userDataDir = await browserManagerOperations.mkdtemp(join(tmpdir(), MANAGED_BROWSER_PROFILE_PREFIX));\n let managedBrowser: ManagedBrowser | undefined;\n try {\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const portArgument = managedBrowserPortConfigured(owner) ? String(managedBrowserPort(owner)) : \"0\";\n const args = buildManagedBrowserLaunchArguments(userDataDir, portArgument, managedBrowserExtensionPaths(owner));\n const child = browserManagerOperations.spawn(candidate.resolvedExecutable, args, {\n shell: false,\n stdio: \"ignore\",\n });\n const launchedBrowser: ManagedBrowser = {\n process: child,\n userDataDir,\n exited: false,\n ready: false,\n ownerGeneration: generation,\n ...(owner ? { sessionOwner: owner } : {}),\n };\n managedBrowser = launchedBrowser;\n setManagedBrowser(owner, launchedBrowser);\n\n child.once(\"exit\", () => {\n if (managedBrowserForOwner(owner) === launchedBrowser && owner) {\n invalidateWebMcpOperations(owner, \"Chrome DevTools managed browser exited\");\n }\n launchedBrowser.exited = true;\n launchedBrowser.ready = false;\n if (!managedBrowserPortConfigured(owner) && launchedBrowser.port === managedBrowserPort(owner)) {\n setManagedBrowserPort(owner, managedBrowserConfiguredPort(owner));\n }\n });\n\n await waitForBrowserSpawn(child);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n if (managedBrowserPortConfigured(owner)) {\n launchedBrowser.port = managedBrowserPort(owner);\n } else {\n launchedBrowser.port = await readManagedBrowserPort(\n userDataDir,\n launchedBrowser,\n waitMs,\n generation,\n signal,\n owner,\n );\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n setManagedBrowserPort(owner, launchedBrowser.port);\n }\n await waitForDevToolsEndpoint(waitMs, launchedBrowser, generation, signal, owner);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n launchedBrowser.ready = true;\n } catch (error) {\n if (managedBrowser) await shutdownManagedBrowser(managedBrowser, { awaitLaunch: false, owner });\n else {\n await browserManagerOperations.rm(userDataDir, { recursive: true, force: true }).catch(() => undefined);\n }\n throw error;\n }\n}\n\nexport function buildManagedBrowserLaunchArguments(\n userDataDir: string,\n portArgument: string,\n extensionPaths: readonly string[],\n) {\n const extensionList = extensionPaths.join(\",\");\n return [\n `--remote-debugging-port=${portArgument}`,\n `--user-data-dir=${userDataDir}`,\n ...(extensionPaths.length > 0\n ? [`--disable-extensions-except=${extensionList}`, `--load-extension=${extensionList}`]\n : []),\n // Chrome 138+ de-elevates when launched from an elevated process on Windows: the\n // spawned process relaunches a de-elevated child and exits immediately, which the\n // exit watchdog misreads as a failed launch.\n ...(process.platform === \"win32\" ? [\"--do-not-de-elevate\"] : []),\n \"--no-first-run\",\n \"--no-default-browser-check\",\n \"about:blank\",\n ];\n}\n\nfunction waitForBrowserSpawn(child: ChildProcess) {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n child.off(\"error\", onError);\n child.off(\"spawn\", onSpawn);\n callback();\n };\n const onError = (error: Error) => settle(() => reject(error));\n const onSpawn = () => settle(resolve);\n child.once(\"error\", onError);\n child.once(\"spawn\", onSpawn);\n });\n}\n\nasync function readManagedBrowserPort(\n userDataDir: string,\n managedBrowser: ManagedBrowser,\n waitMs: number,\n generation: number,\n signal: AbortSignal,\n owner?: object,\n) {\n const activePortFile = join(userDataDir, DEVTOOLS_ACTIVE_PORT_FILE);\n const deadline = Date.now() + waitMs;\n while (true) {\n throwIfManagedBrowserExited(managedBrowser);\n const text = await browserManagerOperations.readFile(activePortFile, \"utf8\").catch((error: unknown) => {\n if (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n throw error;\n });\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const portText = text?.split(/\\r?\\n/, 1)[0]?.trim();\n const port = Number(portText);\n if (Number.isInteger(port) && port > 0) return port;\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n throw new DevToolsEndpointError(\n [\n \"Timed out waiting for auto-launched browser DevToolsActivePort.\",\n `Expected file: ${activePortFile}`,\n launchHint(owner),\n ].join(\"\\n\"),\n );\n }\n await browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);\n }\n}\n\nasync function waitForDevToolsEndpoint(\n waitMs: number,\n managedBrowser: ManagedBrowser,\n generation: number,\n signal: AbortSignal,\n owner?: object,\n) {\n const deadline = Date.now() + waitMs;\n while (true) {\n throwIfManagedBrowserExited(managedBrowser);\n try {\n await fetchDevToolsJson<unknown>(\"/json/version\", { signal }, owner);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n return;\n } catch (error) {\n if (!isRetryableEndpointError(error)) throw error;\n }\n\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) {\n throw new DevToolsEndpointError(\n [`Timed out waiting for auto-launched browser at ${devToolsEndpoint(owner)}.`, launchHint(owner)].join(\"\\n\"),\n );\n }\n await browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);\n }\n}\n\nfunction throwIfManagedBrowserExited(managedBrowser: ManagedBrowser) {\n if (!managedBrowser.exited) return;\n throw new DevToolsEndpointError(\"Auto-launched browser exited before DevTools became available.\");\n}\n\nfunction throwIfBrowserLaunchCancelled(generation: number, signal: AbortSignal, owner?: object) {\n const currentGeneration = owner ? managedBrowserScope(owner).generation : state.sessionGeneration;\n const shuttingDown = owner ? signal.aborted : state.shuttingDown;\n if (!shuttingDown && generation === currentGeneration && !signal.aborted) return;\n throw new DevToolsEndpointError(\n generation === currentGeneration\n ? \"Chrome DevTools browser launch cancelled during shutdown.\"\n : \"Chrome DevTools browser launch cancelled because the session was replaced.\",\n );\n}\n\nexport async function shutdownManagedBrowser(\n managedBrowser?: ManagedBrowser,\n options: { awaitLaunch?: boolean; cancelLaunch?: boolean; owner?: object } = {},\n) {\n const owner = options.owner ?? managedBrowser?.sessionOwner;\n if (options.cancelLaunch) {\n if (owner) {\n const scope = managedBrowserScope(owner);\n scope.controller.abort(\n new DOMException(\"Chrome DevTools browser launch cancelled during shutdown\", \"AbortError\"),\n );\n scope.generation += 1;\n } else {\n state.shuttingDown = true;\n }\n }\n managedBrowser ??= managedBrowserForOwner(owner);\n if (options.awaitLaunch !== false) {\n await launchPromiseForOwner(owner)?.catch(() => undefined);\n managedBrowser ??= managedBrowserForOwner(owner);\n }\n if (!managedBrowser) return;\n if (managedBrowser.cleanupPromise) return managedBrowser.cleanupPromise;\n\n const cleanup = cleanupManagedBrowser(managedBrowser, owner);\n managedBrowser.cleanupPromise = cleanup;\n return cleanup;\n}\n\nasync function cleanupManagedBrowser(managedBrowser: ManagedBrowser, owner?: object) {\n if (managedBrowserForOwner(owner) === managedBrowser) {\n if (owner) invalidateWebMcpOperations(owner, \"Chrome DevTools managed browser closed\");\n if (state.managedBrowser === managedBrowser) state.managedBrowser = undefined;\n else setManagedBrowser(owner, undefined);\n }\n if (!managedBrowser.exited) {\n killManagedBrowserProcess(managedBrowser);\n await waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(async () => {\n killManagedBrowserProcess(managedBrowser, \"SIGKILL\");\n await waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(() => undefined);\n });\n }\n await browserManagerOperations\n .rm(managedBrowser.userDataDir, { recursive: true, force: true })\n .catch(() => undefined);\n if (!managedBrowserPortConfigured(owner) && managedBrowser.port === managedBrowserPort(owner)) {\n setManagedBrowserPort(owner, managedBrowserConfiguredPort(owner));\n }\n}\n\nfunction killManagedBrowserProcess(managedBrowser: ManagedBrowser, signal?: NodeJS.Signals) {\n try {\n managedBrowser.process.kill(signal);\n } catch {\n // Best-effort shutdown: the browser may have already exited or failed to spawn.\n }\n}\n\nfunction waitForManagedBrowserExit(managedBrowser: ManagedBrowser, waitMs: number) {\n if (managedBrowser.exited) return Promise.resolve();\n return new Promise<void>((resolve, reject) => {\n const settle = (callback: () => void) => {\n clearTimeout(timeout);\n managedBrowser.process.off(\"exit\", onExitOrClose);\n managedBrowser.process.off(\"close\", onExitOrClose);\n callback();\n };\n const onExitOrClose = () => {\n managedBrowser.exited = true;\n settle(resolve);\n };\n const timeout = setTimeout(\n () => settle(() => reject(new Error(\"Timed out waiting for browser shutdown.\"))),\n waitMs,\n );\n managedBrowser.process.once(\"exit\", onExitOrClose);\n managedBrowser.process.once(\"close\", onExitOrClose);\n });\n}\n\nexport async function fetchDevToolsJson<T>(path: string, init?: RequestInit, owner?: object) {\n const url = `${devToolsEndpoint(owner)}${path}`;\n let response: Response;\n try {\n const timeoutSignal = AbortSignal.timeout(DEFAULT_HTTP_TIMEOUT_MS);\n response = await browserManagerOperations.fetch(url, {\n ...init,\n signal: init?.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal,\n });\n } catch (error) {\n throw new DevToolsEndpointError(endpointConnectionErrorMessage(error, owner), {\n launchable: true,\n retryable: true,\n });\n }\n\n if (!response.ok) {\n const body = (await response.text().catch(() => \"\")).trim();\n const suffix = body ? `: ${body.slice(0, 200)}` : \"\";\n throw new DevToolsEndpointError(\n [\n `Chrome DevTools endpoint ${url} returned ${response.status} ${response.statusText}${suffix}.`,\n endpointConfigHint(),\n ].join(\"\\n\"),\n { retryable: response.status === 429 || response.status >= 500 },\n );\n }\n\n try {\n return (await response.json()) as T;\n } catch (error) {\n throw new DevToolsEndpointError(\n [`Chrome DevTools endpoint ${url} returned invalid JSON: ${formatError(error)}.`, endpointConfigHint()].join(\n \"\\n\",\n ),\n );\n }\n}\n\nexport async function withEndpointRetry<T>(operation: () => Promise<T>, waitMs: number, signal?: AbortSignal) {\n const deadline = Date.now() + waitMs;\n while (true) {\n signal?.throwIfAborted();\n try {\n return await operation();\n } catch (error) {\n if (!isRetryableEndpointError(error)) throw error;\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) throw error;\n\n await browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);\n }\n }\n}\n\nfunction isRetryableEndpointError(error: unknown) {\n return error instanceof DevToolsEndpointError && error.retryable;\n}\n\nfunction isLaunchableEndpointError(error: unknown) {\n return error instanceof DevToolsEndpointError && error.launchable;\n}\n\nfunction shouldAutoLaunchAfterEndpointError(error: unknown, owner?: object) {\n if (!canAutoLaunchBrowser(owner)) return false;\n if (isLaunchableEndpointError(error)) return true;\n\n // After the attach-first attempt (including its retry window, when applicable) fails, treat any\n // DevTools endpoint error on an unpinned port as a conflict we can avoid with a dynamic port.\n return !managedBrowserPortConfigured(owner) && error instanceof DevToolsEndpointError;\n}\n\nfunction canAutoLaunchBrowser(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n return browser.autoLaunchEnabled && isLocalDevToolsHost(browser.host);\n}\n\nfunction extensionsConfigured(owner?: object) {\n return managedBrowserExtensionPaths(owner).length > 0;\n}\n\nfunction endpointConnectionErrorMessage(error: unknown, owner?: object) {\n const reason = isTimeoutError(error) ? \"request timed out\" : \"connection failed\";\n return [\n `Cannot connect to Chrome DevTools endpoint at ${devToolsEndpoint(owner)} (${reason}).`,\n launchHint(owner),\n endpointConfigHint(),\n ].join(\"\\n\");\n}\n\nfunction isTimeoutError(error: unknown) {\n return error instanceof Error && [\"AbortError\", \"TimeoutError\"].includes(error.name);\n}\n\nexport function devToolsEndpoint(owner?: object) {\n return `http://${formatHostForUrl(browserSettingsForOwner(owner).host)}:${managedBrowserPort(owner)}`;\n}\n\nexport function formatHostForUrl(host: string) {\n if (host.startsWith(\"[\") && host.endsWith(\"]\")) return host;\n return host.includes(\":\") ? `[${host}]` : host;\n}\n\nexport function endpointSourceLabel(owner?: object) {\n return browserSettingsForOwner(owner).endpointSource;\n}\n\nexport type BrowserLifecycleState = \"starting\" | \"running\" | \"exited\" | \"failed\" | \"unobserved\";\n\nexport function browserLifecycleState(owner?: object): BrowserLifecycleState {\n if (launchPromiseForOwner(owner)) return \"starting\";\n if (managedBrowserForOwner(owner)?.exited) return \"exited\";\n if (managedBrowserForOwner(owner)?.ready) return \"running\";\n if (lastLaunchAttempt(owner)?.lastError) return \"failed\";\n return \"unobserved\";\n}\n\nexport function launchModeLabel(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n const managedBrowser = managedBrowserForOwner(owner);\n if (extensionsConfigured(owner)) {\n if (!isLocalDevToolsHost(browser.host)) return \"invalid; extensions require a local endpoint\";\n if (!browser.autoLaunchEnabled) return \"invalid; extensions require auto-launch\";\n if (managedBrowser && !managedBrowser.exited) {\n return managedBrowserPortConfigured(owner)\n ? \"extension-owned browser on explicit port\"\n : \"extension-owned browser on dynamic port\";\n }\n return managedBrowserPortConfigured(owner)\n ? \"force extension-owned launch on explicit port\"\n : \"force extension-owned launch on dynamic port\";\n }\n if (!isLocalDevToolsHost(browser.host)) return \"manual remote endpoint\";\n if (!browser.autoLaunchEnabled) return \"manual; auto-launch disabled\";\n if (managedBrowser && !managedBrowser.exited) {\n return managedBrowserPortConfigured(owner) ? \"auto-launched on explicit port\" : \"auto-launched on dynamic port\";\n }\n return managedBrowserPortConfigured(owner)\n ? \"attach first; auto-launch explicit port\"\n : \"attach first; auto-launch dynamic port\";\n}\n\nexport function launchAttemptLines(owner?: object) {\n const attempt = lastLaunchAttempt(owner);\n if (!attempt) return [];\n\n const lines = [`Last launch attempt: ${attempt.mode}`];\n if (attempt.selectedCandidate) {\n lines.push(`Launched browser: ${attempt.selectedCandidate}`);\n } else {\n lines.push(`Tried browser candidates: ${attempt.candidateLabels.join(\", \")}`);\n }\n if (attempt.userDataDir) lines.push(`Managed browser profile: ${attempt.userDataDir}`);\n if (attempt.lastError) lines.push(`Last launch error: ${attempt.lastError}`);\n return lines;\n}\n\nexport function launchHint(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n if (extensionsConfigured(owner)) {\n return \"Configured unpacked extensions force an isolated extension-owned launch; existing CDP browsers are never reused, modified, or closed.\";\n }\n if (!isLocalDevToolsHost(browser.host)) {\n return `Remote/non-local endpoints are not auto-launched. Start a browser with CDP enabled at ${devToolsEndpoint(owner)}.`;\n }\n if (!browser.autoLaunchEnabled) {\n return `Auto-launch is disabled. Start a browser manually: ${chromeLaunchCommand(owner)}`;\n }\n const managedMode = managedBrowserPortConfigured(owner)\n ? `port ${managedBrowserPort(owner)}`\n : \"a dynamic DevTools port\";\n return `If no endpoint is available, Pi will auto-launch a Chromium-family browser with ${managedMode} and an isolated temp profile. Manual command: ${chromeLaunchCommand(owner)}`;\n}\n\nexport function browserCandidateHint(owner?: object) {\n if (extensionsConfigured(owner)) {\n return \"Extension browser requirement: configure Chrome for Testing or Chromium with browser.executablePath; branded Chrome is rejected because it may ignore unpacked-extension flags.\";\n }\n return `Browser candidates: ${browserCandidateDefinitions(owner)\n .map((candidate) => candidate.label)\n .join(\", \")}`;\n}\n\nexport function chromeLaunchCommand(owner?: object) {\n const executable = browserSettingsForOwner(owner).executablePath ?? defaultManualBrowserExecutable();\n const dataDir = process.platform === \"win32\" ? \"%TEMP%\\\\pi-chrome-devtools\" : \"/tmp/pi-chrome-devtools\";\n return `${quoteCommandPart(executable)} --remote-debugging-port=${managedBrowserPort(owner)} --user-data-dir=${dataDir}`;\n}\n\nfunction defaultManualBrowserExecutable() {\n return process.platform === \"darwin\"\n ? \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\"\n : process.platform === \"win32\"\n ? \"chrome.exe\"\n : \"google-chrome\";\n}\n\nexport function quoteCommandPart(value: string) {\n return /\\s/.test(value) ? `\"${value.replaceAll('\"', '\\\\\"')}\"` : value;\n}\n\nexport function endpointConfigHint() {\n return \"Configure browser.endpoint, browser.executablePath, and browser.autoLaunch in pi-chrome-devtools.json or the /chrome-devtools Settings flow.\";\n}\n\nexport function isLocalDevToolsHost(host: string) {\n const normalizedHost = host.toLowerCase().replace(/^\\[(.*)]$/, \"$1\");\n return [\"localhost\", \"127.0.0.1\", \"::1\", \"0:0:0:0:0:0:0:1\"].includes(normalizedHost);\n}\n\nfunction browserCandidateDefinitions(owner?: object): BrowserCandidateDefinition[] {\n const explicitCandidate = explicitBrowserCandidateDefinition(owner);\n if (explicitCandidate.length > 0) return explicitCandidate;\n\n return uniqueBrowserCandidates(platformBrowserCandidateDefinitions());\n}\n\nfunction explicitBrowserCandidateDefinition(owner?: object): BrowserCandidateDefinition[] {\n const browser = browserSettingsForOwner(owner);\n if (!browser.executablePath) return [];\n return [\n {\n label: browser.executablePathSource === \"environment\" ? \"PI_CHROME_DEVTOOLS_BROWSER\" : \"browser.executablePath\",\n executable: browser.executablePath,\n source: \"env\",\n },\n ];\n}\n\nfunction platformBrowserCandidateDefinitions(): BrowserCandidateDefinition[] {\n if (process.platform === \"darwin\") {\n return [\n {\n label: \"Google Chrome\",\n executable: \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\n source: \"wellKnownPath\",\n },\n {\n label: \"Chromium\",\n executable: \"/Applications/Chromium.app/Contents/MacOS/Chromium\",\n source: \"wellKnownPath\",\n },\n {\n label: \"Brave Browser\",\n executable: \"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser\",\n source: \"wellKnownPath\",\n },\n {\n label: \"Microsoft Edge\",\n executable: \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\n source: \"wellKnownPath\",\n },\n ];\n }\n\n if (process.platform === \"win32\") {\n return windowsBrowserCandidateDefinitions();\n }\n\n return [\n { label: \"Google Chrome\", executable: \"google-chrome\", source: \"path\" },\n { label: \"Google Chrome Stable\", executable: \"google-chrome-stable\", source: \"path\" },\n { label: \"Chromium\", executable: \"chromium\", source: \"path\" },\n { label: \"Chromium Browser\", executable: \"chromium-browser\", source: \"path\" },\n { label: \"Brave Browser\", executable: \"brave-browser\", source: \"path\" },\n { label: \"Brave\", executable: \"brave\", source: \"path\" },\n { label: \"Microsoft Edge\", executable: \"microsoft-edge\", source: \"path\" },\n { label: \"Microsoft Edge Stable\", executable: \"microsoft-edge-stable\", source: \"path\" },\n ];\n}\n\nfunction windowsBrowserCandidateDefinitions(): BrowserCandidateDefinition[] {\n const programFiles = [process.env.PROGRAMFILES, process.env[\"PROGRAMFILES(X86)\"], process.env.LOCALAPPDATA].filter(\n (value): value is string => typeof value === \"string\" && value.length > 0,\n );\n const wellKnownPaths = programFiles.flatMap((root) => [\n join(root, \"Google\", \"Chrome\", \"Application\", \"chrome.exe\"),\n join(root, \"Chromium\", \"Application\", \"chrome.exe\"),\n join(root, \"BraveSoftware\", \"Brave-Browser\", \"Application\", \"brave.exe\"),\n join(root, \"Microsoft\", \"Edge\", \"Application\", \"msedge.exe\"),\n ]);\n return [\n ...wellKnownPaths.map((executable) => ({\n label: browserLabelFromExecutable(executable),\n executable,\n source: \"wellKnownPath\" as const,\n })),\n { label: \"Google Chrome\", executable: \"chrome.exe\", source: \"path\" },\n { label: \"Chromium\", executable: \"chromium.exe\", source: \"path\" },\n { label: \"Brave Browser\", executable: \"brave.exe\", source: \"path\" },\n { label: \"Microsoft Edge\", executable: \"msedge.exe\", source: \"path\" },\n ];\n}\n\nfunction browserLabelFromExecutable(executable: string) {\n const normalizedExecutable = normalizePathForComparison(executable);\n if (normalizedExecutable.includes(\"brave\")) return \"Brave Browser\";\n if (normalizedExecutable.includes(\"edge\") || normalizedExecutable.includes(\"msedge\")) {\n return \"Microsoft Edge\";\n }\n if (normalizedExecutable.includes(\"chromium\")) return \"Chromium\";\n return \"Google Chrome\";\n}\n\nfunction uniqueBrowserCandidates(candidates: BrowserCandidateDefinition[]) {\n const seen = new Set<string>();\n return candidates.filter((candidate) => {\n const key = normalizePathForComparison(candidate.executable);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nasync function resolveBrowserCandidates(\n definitions: BrowserCandidateDefinition[],\n generation: number,\n signal: AbortSignal,\n owner?: object,\n) {\n const candidates: BrowserCandidate[] = [];\n for (const definition of definitions) {\n const resolvedExecutable = await resolveBrowserExecutable(definition.executable);\n throwIfBrowserLaunchCancelled(generation, signal, owner);\n if (!resolvedExecutable) continue;\n candidates.push({ ...definition, resolvedExecutable });\n }\n return uniqueBrowserCandidatesByResolvedPath(candidates);\n}\n\nfunction uniqueBrowserCandidatesByResolvedPath(candidates: BrowserCandidate[]) {\n const seen = new Set<string>();\n return candidates.filter((candidate) => {\n const key = normalizePathForComparison(resolve(candidate.resolvedExecutable));\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nasync function resolveBrowserExecutable(executable: string) {\n if (hasPathSeparator(executable) || isAbsolute(executable)) {\n const resolvedExecutable = isAbsolute(executable) ? executable : resolve(executable);\n return (await canAccessExecutable(resolvedExecutable)) ? resolvedExecutable : undefined;\n }\n\n for (const directory of executableSearchPath()) {\n for (const executableName of executableSearchNames(executable)) {\n const candidate = join(directory, executableName);\n if (await canAccessExecutable(candidate)) return candidate;\n }\n }\n return undefined;\n}\n\nfunction hasPathSeparator(path: string) {\n return path.includes(\"/\") || path.includes(\"\\\\\");\n}\n\nfunction executableSearchPath() {\n return (process.env.PATH ?? \"\").split(delimiter).filter((part) => part.length > 0);\n}\n\nfunction executableSearchNames(executable: string) {\n if (process.platform !== \"win32\" || /\\.[a-z0-9]+$/i.test(executable)) return [executable];\n return [executable, `${executable}.exe`, `${executable}.cmd`, `${executable}.bat`];\n}\n\nasync function canAccessExecutable(path: string) {\n try {\n await browserManagerOperations.access(path, process.platform === \"win32\" ? constants.F_OK : constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatBrowserCandidate(candidate: BrowserCandidate) {\n return `${candidate.label} (${candidate.resolvedExecutable})`;\n}\n\nfunction formatBrowserCandidateDefinition(candidate: BrowserCandidateDefinition) {\n return `${candidate.label} (${candidate.executable})`;\n}\n\nfunction noBrowserCandidateMessage(candidateDefinitions: BrowserCandidateDefinition[], owner?: object) {\n if (extensionsConfigured(owner)) {\n return [\n \"Cannot launch unpacked extensions because the configured browser executable was not found or is not executable.\",\n `Tried: ${candidateDefinitions.map(formatBrowserCandidateDefinition).join(\", \")}`,\n \"Set browser.executablePath to an executable Chrome for Testing or Chromium binary.\",\n ].join(\"\\n\");\n }\n return [\n \"Cannot auto-launch Chrome DevTools because no Chromium-family browser executable was found.\",\n `Tried: ${candidateDefinitions.map(formatBrowserCandidateDefinition).join(\", \")}`,\n endpointConfigHint(),\n ].join(\"\\n\");\n}\n\nexport function formatPageListItem(page: DevToolsPage) {\n return `- ${page.id}: ${page.title || \"(untitled)\"} ${page.url}`;\n}\n\nfunction abortableSleep(ms: number, signal?: AbortSignal) {\n return new Promise<void>((resolveSleep, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const timeout = setTimeout(settleResolve, ms);\n const onAbort = () => settleReject(signal?.reason);\n function cleanup() {\n clearTimeout(timeout);\n signal?.removeEventListener(\"abort\", onAbort);\n }\n function settleResolve() {\n cleanup();\n resolveSleep();\n }\n function settleReject(reason: unknown) {\n cleanup();\n reject(reason);\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction inspectBrowserVersion(executable: string, signal: AbortSignal) {\n return new Promise<string>((resolveVersion, reject) => {\n execFile(executable, [\"--version\"], { signal, timeout: 5_000 }, (error, stdout, stderr) => {\n if (error) {\n reject(error);\n return;\n }\n resolveVersion(`${stdout}${stderr}`.trim());\n });\n });\n}\n\nfunction isPortAvailable(host: string, port: number) {\n return new Promise<boolean>((resolveAvailability, reject) => {\n const server = createServer();\n const normalizedHost = host.replace(/^\\[(.*)]$/, \"$1\");\n server.unref();\n server.once(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EADDRINUSE\") resolveAvailability(false);\n else reject(error);\n });\n server.listen(port, normalizedHost, () => {\n server.close((error) => {\n if (error) reject(error);\n else resolveAvailability(true);\n });\n });\n });\n}\n\nclass DevToolsEndpointError extends Error {\n readonly retryable: boolean;\n readonly launchable: boolean;\n\n constructor(message: string, options: { retryable?: boolean; launchable?: boolean } = {}) {\n super(message);\n this.name = \"DevToolsEndpointError\";\n this.retryable = options.retryable ?? false;\n this.launchable = options.launchable ?? false;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["constants", "access", "readFile", "rm", "isAbsolute", "join", "resolve", "access", "readFile", "rm", "formatError", "isNodeError", "resolve", "join", "isAbsolute", "constants"]
|
|
7
|
-
}
|