@narumitw/pi-chrome-devtools 0.52.2 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +78 -17
  2. package/dist/chunks/{browser-settings-menu-VI2I3TXI.js → browser-settings-menu-N5O65I7S.js} +81 -7
  3. package/dist/chunks/browser-settings-menu-N5O65I7S.js.map +7 -0
  4. package/dist/chunks/chunk-B7B63PWB.js +465 -0
  5. package/dist/chunks/chunk-B7B63PWB.js.map +7 -0
  6. package/dist/chunks/{chunk-CC37WUUE.js → chunk-GVBXT3FB.js} +369 -461
  7. package/dist/chunks/chunk-GVBXT3FB.js.map +7 -0
  8. package/dist/chunks/chunk-RTECHAEZ.js +373 -0
  9. package/dist/chunks/chunk-RTECHAEZ.js.map +7 -0
  10. package/dist/chunks/{menu-LLR455UX.js → menu-UBHW6UP2.js} +75 -41
  11. package/dist/chunks/menu-UBHW6UP2.js.map +7 -0
  12. package/dist/chunks/tools-V7OR5KJ3.js +945 -0
  13. package/dist/chunks/tools-V7OR5KJ3.js.map +7 -0
  14. package/dist/index.ts +166 -196
  15. package/dist/index.ts.map +4 -4
  16. package/package.json +4 -3
  17. package/src/browser-manager.ts +282 -109
  18. package/src/browser-settings-menu.ts +98 -4
  19. package/src/cdp-client.ts +329 -83
  20. package/src/chrome-devtools.ts +61 -13
  21. package/src/lazy-tools.ts +105 -8
  22. package/src/menu.ts +83 -41
  23. package/src/render.ts +12 -1
  24. package/src/runtime.ts +92 -0
  25. package/src/settings.ts +47 -10
  26. package/src/tool-names.ts +16 -1
  27. package/src/tool-selector.ts +79 -36
  28. package/src/tools.ts +86 -10
  29. package/src/webmcp/discovery.ts +235 -0
  30. package/src/webmcp/policy.ts +402 -0
  31. package/src/webmcp/protocol.ts +414 -0
  32. package/src/webmcp/tools.ts +190 -0
  33. package/dist/chunks/browser-settings-menu-VI2I3TXI.js.map +0 -7
  34. package/dist/chunks/chunk-CC37WUUE.js.map +0 -7
  35. package/dist/chunks/menu-LLR455UX.js.map +0 -7
@@ -0,0 +1,7 @@
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\t\"chrome_devtools_list_pages\",\n\t\"chrome_devtools_select_page\",\n\t\"chrome_devtools_navigate\",\n\t\"chrome_devtools_evaluate\",\n\t\"chrome_devtools_screenshot\",\n] as const;\n\nexport const WEBMCP_TOOL_NAMES = [\n\t\"chrome_devtools_webmcp_list_tools\",\n\t\"chrome_devtools_webmcp_call_tool\",\n] as const;\n\nexport const CHROME_DEVTOOLS_TOOL_NAMES = [\n\t...CORE_CHROME_DEVTOOLS_TOOL_NAMES,\n\t...WEBMCP_TOOL_NAMES,\n] 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\treturn WEBMCP_TOOL_NAMES.includes(value as WebMcpToolName);\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport {\n\taccess,\n\tlstat,\n\tmkdir,\n\treadFile,\n\trealpath,\n\trename,\n\trm,\n\tstat,\n\twriteFile,\n} 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\ttools: ChromeDevToolsToolName[];\n\tupdatedAt: 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\tendpoint?: string;\n\tautoLaunch?: boolean;\n\texecutablePath?: string;\n\textensionPaths?: string[];\n}\n\nexport interface BrowserSettingsPatch {\n\tendpoint?: string | null;\n\tautoLaunch?: boolean | null;\n\texecutablePath?: string | null;\n}\n\nexport interface EffectiveBrowserSettings {\n\tendpoint: string;\n\thost: string;\n\tport: number;\n\thostConfigured: boolean;\n\tportConfigured: boolean;\n\tautoLaunchEnabled: boolean;\n\texecutablePath?: string;\n\textensionPaths: string[];\n\tendpointSource: BrowserSettingsSource;\n\tautoLaunchSource: BrowserSettingsSource;\n\texecutablePathSource: BrowserSettingsSource;\n\textensionPathsSource: BrowserSettingsSource;\n}\n\nexport interface ResolvedChromeDevToolsSettings {\n\ttools?: ChromeDevToolsToolName[];\n\tupdatedAt?: number;\n\tbrowser: EffectiveBrowserSettings;\n\twebmcp: { enabled: boolean };\n}\n\nexport interface SettingsLoadOptions {\n\tcwd?: string;\n\tprojectTrusted?: boolean;\n}\n\nexport type UserSettingsFileStatus =\n\t| { kind: \"missing\" | \"valid\" }\n\t| { kind: \"invalid\"; reason: string };\n\ninterface SettingsLoadBase {\n\teffectiveBrowser: EffectiveBrowserSettings;\n\teffectiveWebMcpEnabled: boolean;\n\tpaths: { user: string; project?: string };\n\tuserFile: UserSettingsFileStatus;\n\twarnings: string[];\n\tnotice?: string;\n}\n\nexport type SettingsLoadResult =\n\t| (SettingsLoadBase & { kind: \"missing\"; settings?: undefined })\n\t| (SettingsLoadBase & { kind: \"invalid\"; reason: string; settings?: undefined })\n\t| (SettingsLoadBase & { kind: \"loaded\"; settings: ResolvedChromeDevToolsSettings });\n\nexport interface SettingsFileOperations {\n\twrite(path: string, data: string): Promise<void>;\n\trename(source: string, destination: string): Promise<void>;\n}\n\ninterface NormalizedSettingsDocument {\n\ttools?: ChromeDevToolsToolName[];\n\tupdatedAt?: number;\n\tbrowser?: UserBrowserSettings;\n\twebmcp?: { enabled: boolean };\n}\n\ninterface SettingsDocumentResult {\n\tkind: \"missing\" | \"invalid\" | \"valid\";\n\treason?: string;\n\tdocument?: Record<string, unknown>;\n\tnormalized?: NormalizedSettingsDocument;\n\twarnings: string[];\n}\n\nconst DEFAULT_FILE_OPERATIONS: SettingsFileOperations = {\n\twrite: (path, data) => writeFile(path, data, \"utf8\").then(() => undefined),\n\trename,\n};\n\nlet settingsSaveQueue = Promise.resolve();\n\nexport async function waitForSettingsWrites() {\n\tawait settingsSaveQueue;\n}\n\nexport async function loadSettings(options: SettingsLoadOptions = {}): Promise<SettingsLoadResult> {\n\tawait settingsSaveQueue;\n\tconst userPath = settingsFilePath();\n\tconst projectPath = options.cwd ? projectSettingsFilePath(options.cwd) : undefined;\n\tconst paths = { user: userPath, ...(projectPath ? { project: projectPath } : {}) };\n\tconst warnings: string[] = [];\n\n\tlet user = await readSettingsDocument(userPath, \"user\");\n\tconst legacyExists = await fileExists(legacySettingsFilePath());\n\tif (user.kind !== \"missing\" && legacyExists) {\n\t\twarnings.push(\n\t\t\t`Chrome DevTools legacy settings ignored: ${legacySettingsFilePath()} exists, but ${userPath} takes precedence. Delete ${LEGACY_SETTINGS_FILE_NAME} after confirming your settings.`,\n\t\t);\n\t}\n\tif (user.kind === \"missing\") {\n\t\tconst legacy = await readSettingsDocument(legacySettingsFilePath(), \"user\");\n\t\tconst concurrentlyCreated = await readSettingsDocument(userPath, \"user\");\n\t\tif (concurrentlyCreated.kind !== \"missing\") {\n\t\t\tuser = concurrentlyCreated;\n\t\t\tif (legacy.kind !== \"missing\") {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`Chrome DevTools legacy settings ignored: ${legacySettingsFilePath()} exists, but ${userPath} takes precedence. Delete ${LEGACY_SETTINGS_FILE_NAME} after confirming your settings.`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (legacy.kind !== \"missing\") {\n\t\t\tuser = legacy;\n\t\t\tif (legacy.kind === \"valid\") {\n\t\t\t\twarnings.push(\n\t\t\t\t\t`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\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\twarnings.push(...user.warnings);\n\n\tlet project: SettingsDocumentResult = { kind: \"missing\", warnings: [] };\n\tif (projectPath && options.projectTrusted) {\n\t\tproject = await readSettingsDocument(projectPath, \"project\", options.cwd);\n\t\twarnings.push(...project.warnings);\n\t}\n\n\tconst environmentWarning = deprecatedEnvironmentWarning();\n\tif (environmentWarning) warnings.push(environmentWarning);\n\n\tconst userBrowser = user.normalized?.browser ?? {};\n\tconst effectiveBrowser = resolveEffectiveBrowser(userBrowser, project.normalized?.browser);\n\tconst settings = resolveSettings(user.normalized, project.normalized, effectiveBrowser);\n\tconst recognized =\n\t\tsettings.tools !== undefined ||\n\t\tuser.normalized?.browser !== undefined ||\n\t\tproject.normalized?.browser !== undefined ||\n\t\tuser.normalized?.webmcp !== undefined;\n\tconst invalidReasons = [user, project]\n\t\t.filter((result) => result.kind === \"invalid\")\n\t\t.map((result) => result.reason)\n\t\t.filter((reason): reason is string => Boolean(reason));\n\tconst userFile: UserSettingsFileStatus =\n\t\tuser.kind === \"invalid\"\n\t\t\t? {\n\t\t\t\t\tkind: \"invalid\",\n\t\t\t\t\treason: user.reason ?? `${userPath}: invalid settings`,\n\t\t\t\t}\n\t\t\t: { kind: user.kind };\n\tconst base = {\n\t\teffectiveBrowser,\n\t\teffectiveWebMcpEnabled: settings.webmcp.enabled,\n\t\tpaths,\n\t\tuserFile,\n\t\twarnings,\n\t\t...(warnings.length > 0 ? { notice: warnings.join(\"\\n\") } : {}),\n\t};\n\n\tif (recognized) return { ...base, kind: \"loaded\", settings };\n\tif (invalidReasons.length > 0) {\n\t\treturn { ...base, kind: \"invalid\", reason: invalidReasons.join(\"; \") };\n\t}\n\treturn { ...base, kind: \"missing\" };\n}\n\nfunction resolveSettings(\n\tuser: NormalizedSettingsDocument | undefined,\n\t_project: NormalizedSettingsDocument | undefined,\n\tbrowser: EffectiveBrowserSettings,\n): ResolvedChromeDevToolsSettings {\n\treturn {\n\t\t...(user?.tools ? { tools: user.tools, updatedAt: user.updatedAt } : {}),\n\t\tbrowser,\n\t\twebmcp: { enabled: user?.webmcp?.enabled ?? false },\n\t};\n}\n\nfunction resolveEffectiveBrowser(\n\tuser: UserBrowserSettings,\n\tproject: UserBrowserSettings | undefined,\n): EffectiveBrowserSettings {\n\tconst configuredEndpoint = parseBrowserEndpoint(user.endpoint ?? DEFAULT_BROWSER_ENDPOINT);\n\tconst environmentHost = process.env.PI_CHROME_DEVTOOLS_HOST;\n\tconst environmentPortValue = process.env.PI_CHROME_DEVTOOLS_PORT;\n\tconst environmentPort = parseConfiguredPort(environmentPortValue);\n\tconst environmentEndpointConfigured =\n\t\tenvironmentHost !== undefined || environmentPort !== undefined;\n\tconst host = environmentHost ?? configuredEndpoint.host;\n\tconst port = environmentPort ?? configuredEndpoint.port;\n\tconst environmentAutoLaunch = process.env.PI_CHROME_DEVTOOLS_AUTO_LAUNCH;\n\tconst environmentExecutable = process.env.PI_CHROME_DEVTOOLS_BROWSER;\n\tconst executablePath = environmentExecutable || user.executablePath;\n\tconst extensionPaths = project?.extensionPaths ?? user.extensionPaths ?? [];\n\tconst endpointSource: BrowserSettingsSource = environmentEndpointConfigured\n\t\t? \"environment\"\n\t\t: user.endpoint\n\t\t\t? \"user\"\n\t\t\t: \"default\";\n\treturn {\n\t\tendpoint: formatBrowserEndpoint(host, port),\n\t\thost,\n\t\tport,\n\t\thostConfigured: environmentHost !== undefined || user.endpoint !== undefined,\n\t\tportConfigured: environmentPort !== undefined || user.endpoint !== undefined,\n\t\tautoLaunchEnabled:\n\t\t\tenvironmentAutoLaunch === undefined\n\t\t\t\t? (user.autoLaunch ?? true)\n\t\t\t\t: environmentAutoLaunch !== \"0\",\n\t\t...(executablePath ? { executablePath } : {}),\n\t\textensionPaths: [...extensionPaths],\n\t\tendpointSource,\n\t\tautoLaunchSource:\n\t\t\tenvironmentAutoLaunch !== undefined\n\t\t\t\t? \"environment\"\n\t\t\t\t: user.autoLaunch !== undefined\n\t\t\t\t\t? \"user\"\n\t\t\t\t\t: \"default\",\n\t\texecutablePathSource: environmentExecutable\n\t\t\t? \"environment\"\n\t\t\t: user.executablePath\n\t\t\t\t? \"user\"\n\t\t\t\t: \"default\",\n\t\textensionPathsSource: project?.extensionPaths\n\t\t\t? \"project\"\n\t\t\t: user.extensionPaths\n\t\t\t\t? \"user\"\n\t\t\t\t: \"default\",\n\t};\n}\n\nfunction deprecatedEnvironmentWarning() {\n\tconst configuredNames = [\n\t\t\"PI_CHROME_DEVTOOLS_HOST\",\n\t\t\"PI_CHROME_DEVTOOLS_PORT\",\n\t\t\"PI_CHROME_DEVTOOLS_AUTO_LAUNCH\",\n\t\t\"PI_CHROME_DEVTOOLS_BROWSER\",\n\t].filter((name) => process.env[name] !== undefined);\n\tif (configuredNames.length === 0) return undefined;\n\treturn `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\tfilePath: string,\n\tscope: \"project\" | \"user\",\n\tcwd?: string,\n): Promise<SettingsDocumentResult> {\n\tlet text: string;\n\ttry {\n\t\ttext = await readFile(filePath, \"utf8\");\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return { kind: \"missing\", warnings: [] };\n\t\tconst reason = `${filePath}: ${formatError(error)}`;\n\t\treturn { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text) as unknown;\n\t} catch {\n\t\tconst reason = `${filePath}: invalid JSON`;\n\t\treturn { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n\t}\n\tif (!isRecord(parsed)) {\n\t\tconst reason = `${filePath}: expected a JSON object`;\n\t\treturn { kind: \"invalid\", reason, warnings: [`Chrome DevTools settings ignored: ${reason}`] };\n\t}\n\n\tconst scopeWarnings = projectOwnedSettingsWarnings(parsed, scope, filePath);\n\ttry {\n\t\tconst normalized = await normalizeSettingsDocument(parsed, scope, filePath, cwd);\n\t\treturn { kind: \"valid\", document: { ...parsed }, normalized, warnings: scopeWarnings };\n\t} catch (error) {\n\t\tconst reason = `${filePath}: ${formatError(error)}`;\n\t\treturn {\n\t\t\tkind: \"invalid\",\n\t\t\treason,\n\t\t\twarnings: [...scopeWarnings, `Chrome DevTools settings ignored: ${reason}`],\n\t\t};\n\t}\n}\n\nfunction projectOwnedSettingsWarnings(\n\tdocument: Record<string, unknown>,\n\tscope: \"project\" | \"user\",\n\tfilePath: string,\n) {\n\tif (scope !== \"project\") return [];\n\tconst browser = isRecord(document.browser) ? document.browser : undefined;\n\tconst warnings = browser\n\t\t? [\"endpoint\", \"autoLaunch\", \"executablePath\"]\n\t\t\t\t.filter((field) => browser[field] !== undefined)\n\t\t\t\t.map(\n\t\t\t\t\t(field) =>\n\t\t\t\t\t\t`Chrome DevTools project browser.${field} ignored in ${filePath}; configure this machine-owned setting in ${settingsFilePath()}.`,\n\t\t\t\t)\n\t\t: [];\n\tif (document.webmcp !== undefined) {\n\t\twarnings.push(\n\t\t\t`Chrome DevTools project webmcp settings ignored in ${filePath}; only the user settings file may enable experimental WebMCP.`,\n\t\t);\n\t}\n\treturn warnings;\n}\n\nasync function normalizeSettingsDocument(\n\tdocument: Record<string, unknown>,\n\tscope: \"project\" | \"user\",\n\tfilePath: string,\n\tcwd?: string,\n): Promise<NormalizedSettingsDocument> {\n\tconst normalized: NormalizedSettingsDocument = {};\n\n\tif (scope === \"user\" && (document.tools !== undefined || document.updatedAt !== undefined)) {\n\t\tconst toolSettings = normalizeChromeDevtoolsSettings(document);\n\t\tif (!toolSettings) {\n\t\t\tthrow new Error(\n\t\t\t\t\"expected tools to be an array of Chrome DevTools tool names with numeric updatedAt\",\n\t\t\t);\n\t\t}\n\t\tnormalized.tools = toolSettings.tools;\n\t\tnormalized.updatedAt = toolSettings.updatedAt;\n\t}\n\n\tif (document.browser !== undefined) {\n\t\tif (!isRecord(document.browser)) throw new Error(\"expected browser to be an object\");\n\t\tnormalized.browser = await normalizeBrowserSection(document.browser, scope, filePath, cwd);\n\t}\n\n\tif (scope === \"user\" && document.webmcp !== undefined) {\n\t\tif (!isRecord(document.webmcp) || typeof document.webmcp.enabled !== \"boolean\") {\n\t\t\tthrow new Error(\"expected webmcp.enabled to be a boolean\");\n\t\t}\n\t\tnormalized.webmcp = { enabled: document.webmcp.enabled };\n\t}\n\n\treturn normalized;\n}\n\nasync function normalizeBrowserSection(\n\tbrowser: Record<string, unknown>,\n\tscope: \"project\" | \"user\",\n\t_filePath: string,\n\tcwd?: string,\n): Promise<UserBrowserSettings> {\n\tconst normalized: UserBrowserSettings = {};\n\tif (scope === \"user\" && browser.endpoint !== undefined) {\n\t\tif (typeof browser.endpoint !== \"string\") {\n\t\t\tthrow new Error(\"expected browser.endpoint to be an HTTP URL with an explicit port\");\n\t\t}\n\t\tnormalized.endpoint = parseBrowserEndpoint(browser.endpoint).endpoint;\n\t}\n\tif (scope === \"user\" && browser.autoLaunch !== undefined) {\n\t\tif (typeof browser.autoLaunch !== \"boolean\") {\n\t\t\tthrow new Error(\"expected browser.autoLaunch to be a boolean\");\n\t\t}\n\t\tnormalized.autoLaunch = browser.autoLaunch;\n\t}\n\tif (scope === \"user\" && browser.executablePath !== undefined) {\n\t\tif (typeof browser.executablePath !== \"string\" || browser.executablePath.length === 0) {\n\t\t\tthrow new Error(\"expected browser.executablePath to be a non-empty absolute path\");\n\t\t}\n\t\tif (!isAbsolute(browser.executablePath)) {\n\t\t\tthrow new Error(\"browser.executablePath in user settings must be absolute\");\n\t\t}\n\t\tnormalized.executablePath = resolve(browser.executablePath);\n\t}\n\n\tif (browser.extensionPaths !== undefined) {\n\t\tif (\n\t\t\t!Array.isArray(browser.extensionPaths) ||\n\t\t\t!browser.extensionPaths.every((entry) => typeof entry === \"string\" && entry.length > 0)\n\t\t) {\n\t\t\tthrow new Error(`expected ${scope} browser.extensionPaths to be an array of non-empty paths`);\n\t\t}\n\t\tconst resolvedPaths: string[] = [];\n\t\tfor (const configuredPath of browser.extensionPaths as string[]) {\n\t\t\tif (scope === \"user\" && !isAbsolute(configuredPath)) {\n\t\t\t\tthrow new Error(\"browser.extensionPaths in user settings must contain only absolute paths\");\n\t\t\t}\n\t\t\tconst absolutePath = isAbsolute(configuredPath)\n\t\t\t\t? resolve(configuredPath)\n\t\t\t\t: resolve(cwd ?? process.cwd(), configuredPath);\n\t\t\tresolvedPaths.push(await validateUnpackedExtensionPath(absolutePath));\n\t\t}\n\t\tnormalized.extensionPaths = orderedUnique(resolvedPaths);\n\t}\n\treturn normalized;\n}\n\nasync function validateUnpackedExtensionPath(extensionPath: string) {\n\tlet canonicalPath: string;\n\ttry {\n\t\tcanonicalPath = await realpath(extensionPath);\n\t\tconst extensionStat = await stat(canonicalPath);\n\t\tif (!extensionStat.isDirectory()) throw new Error(\"not a directory\");\n\t} catch (error) {\n\t\tthrow new Error(`unpacked extension path ${extensionPath} is invalid: ${formatError(error)}`);\n\t}\n\n\tconst manifestPath = join(canonicalPath, \"manifest.json\");\n\tlet manifest: unknown;\n\ttry {\n\t\tconst manifestStat = await lstat(manifestPath);\n\t\tif (!manifestStat.isFile()) throw new Error(\"not a regular file\");\n\t\tmanifest = JSON.parse(await readFile(manifestPath, \"utf8\")) as unknown;\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`unpacked extension ${canonicalPath} has invalid manifest.json: ${formatError(error)}`,\n\t\t);\n\t}\n\tif (canonicalPath.includes(\",\")) {\n\t\tthrow new Error(\n\t\t\t`unpacked extension path ${canonicalPath} cannot contain a comma because Chrome separates multiple --load-extension paths with commas`,\n\t\t);\n\t}\n\tif (\n\t\t!isRecord(manifest) ||\n\t\t![2, 3].includes(manifest.manifest_version as number) ||\n\t\ttypeof manifest.name !== \"string\" ||\n\t\ttypeof manifest.version !== \"string\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`unpacked extension ${canonicalPath} has invalid manifest.json: expected manifest_version, name, and version`,\n\t\t);\n\t}\n\treturn canonicalPath;\n}\n\nexport function parseBrowserEndpoint(value: string) {\n\tconst trimmedValue = value.trim();\n\tconst explicitPort = trimmedValue.match(/^http:\\/\\/(?:\\[[^\\]]+\\]|[^/:?#]+):(\\d+)\\/?$/i)?.[1];\n\tlet endpoint: URL;\n\ttry {\n\t\tendpoint = new URL(trimmedValue);\n\t} catch {\n\t\tthrow new Error(\"browser.endpoint must be a valid HTTP URL with an explicit port\");\n\t}\n\tif (\n\t\tendpoint.protocol !== \"http:\" ||\n\t\tendpoint.username ||\n\t\tendpoint.password ||\n\t\t!endpoint.hostname ||\n\t\t!explicitPort ||\n\t\t(endpoint.pathname !== \"/\" && endpoint.pathname !== \"\") ||\n\t\tendpoint.search ||\n\t\tendpoint.hash\n\t) {\n\t\tthrow new Error(\n\t\t\t\"browser.endpoint must be an HTTP origin with an explicit port and no credentials, path, query, or fragment\",\n\t\t);\n\t}\n\tconst port = parseConfiguredPort(explicitPort);\n\tif (port === undefined) {\n\t\tthrow new Error(\"browser.endpoint must use a port from 1 through 65535\");\n\t}\n\tconst host = endpoint.hostname;\n\treturn { endpoint: formatBrowserEndpoint(host, port), host, port };\n}\n\nexport function parseConfiguredPort(value: string | undefined) {\n\tif (value === undefined) return undefined;\n\tconst trimmedValue = value.trim();\n\tif (!/^\\d+$/.test(trimmedValue)) return undefined;\n\tconst port = Number(trimmedValue);\n\tif (!Number.isInteger(port) || port < 1 || port > 65_535) return undefined;\n\treturn port;\n}\n\nfunction formatBrowserEndpoint(host: string, port: number) {\n\tconst formattedHost =\n\t\thost.startsWith(\"[\") && host.endsWith(\"]\") ? host : host.includes(\":\") ? `[${host}]` : host;\n\treturn `http://${formattedHost}:${port}`;\n}\n\nexport function normalizeChromeDevtoolsSettings(\n\tvalue: unknown,\n): ChromeDevToolsSettings | undefined {\n\tif (!isRecord(value)) return undefined;\n\tif (typeof value.updatedAt !== \"number\" || !Number.isFinite(value.updatedAt)) return undefined;\n\n\tif (value.tools === \"enabled\") {\n\t\treturn { tools: [...CHROME_DEVTOOLS_TOOL_NAMES], updatedAt: value.updatedAt };\n\t}\n\tif (value.tools === \"disabled\") return { tools: [], updatedAt: value.updatedAt };\n\tif (!Array.isArray(value.tools) || !value.tools.every(isChromeDevtoolsToolName)) return undefined;\n\treturn { tools: orderedUniqueChromeDevtoolsTools(value.tools), updatedAt: value.updatedAt };\n}\n\nfunction isChromeDevtoolsToolName(value: unknown): value is ChromeDevToolsToolName {\n\treturn typeof value === \"string\" && CHROME_DEVTOOLS_TOOL_NAMES.includes(value as never);\n}\n\nfunction orderedUniqueChromeDevtoolsTools(tools: readonly ChromeDevToolsToolName[]) {\n\tconst selectedTools = new Set(tools);\n\treturn CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => selectedTools.has(toolName));\n}\n\nfunction orderedUnique(values: readonly string[]) {\n\treturn [...new Set(values)];\n}\n\nexport function saveSettings(\n\tsettings: ChromeDevToolsSettings,\n\toperations: Partial<SettingsFileOperations> = {},\n): Promise<void> {\n\treturn queueSettingsMutation(\n\t\t(current) => ({\n\t\t\t...current,\n\t\t\ttools: [...settings.tools],\n\t\t\tupdatedAt: settings.updatedAt,\n\t\t}),\n\t\toperations,\n\t);\n}\n\nexport function saveWebMcpSettings(\n\tenabled: boolean,\n\toperations: Partial<SettingsFileOperations> = {},\n): Promise<void> {\n\treturn queueSettingsMutation(\n\t\t(current) => ({\n\t\t\t...current,\n\t\t\twebmcp: {\n\t\t\t\t...(isRecord(current.webmcp) ? current.webmcp : {}),\n\t\t\t\tenabled,\n\t\t\t},\n\t\t}),\n\t\toperations,\n\t);\n}\n\nexport function saveBrowserSettings(\n\tpatch: BrowserSettingsPatch,\n\toperations: Partial<SettingsFileOperations> = {},\n): Promise<void> {\n\treturn queueSettingsMutation(async (current) => {\n\t\tconst browser = isRecord(current.browser) ? { ...current.browser } : {};\n\t\tfor (const field of [\"endpoint\", \"autoLaunch\", \"executablePath\"] as const) {\n\t\t\tconst value = patch[field];\n\t\t\tif (value === undefined) continue;\n\t\t\tif (value === null) delete browser[field];\n\t\t\telse browser[field] = value;\n\t\t}\n\t\tawait normalizeBrowserSection(browser, \"user\", settingsFilePath());\n\t\treturn { ...current, browser };\n\t}, operations);\n}\n\nfunction queueSettingsMutation(\n\tmutate: (\n\t\tcurrent: Record<string, unknown>,\n\t) => Record<string, unknown> | Promise<Record<string, unknown>>,\n\toperations: Partial<SettingsFileOperations>,\n) {\n\tconst operation = settingsSaveQueue.then(() => saveSettingsMutationNow(mutate, operations));\n\tsettingsSaveQueue = operation.catch(() => undefined);\n\treturn operation;\n}\n\nasync function saveSettingsMutationNow(\n\tmutate: (\n\t\tcurrent: Record<string, unknown>,\n\t) => Record<string, unknown> | Promise<Record<string, unknown>>,\n\toperations: Partial<SettingsFileOperations>,\n): Promise<void> {\n\tconst filePath = settingsFilePath();\n\tlet current = await readSettingsDocument(filePath, \"user\");\n\tconst replaceCanonical = current.kind !== \"missing\";\n\tif (!replaceCanonical) current = await readSettingsDocument(legacySettingsFilePath(), \"user\");\n\tif (current.kind === \"invalid\") {\n\t\tthrow new Error(`Cannot save Chrome DevTools settings until you repair ${current.reason}`);\n\t}\n\tconst nextDocument = await mutate(current.document ?? {});\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tconst tempFile = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\tawait (operations.write ?? DEFAULT_FILE_OPERATIONS.write)(\n\t\t\ttempFile,\n\t\t\t`${JSON.stringify(nextDocument, null, 2)}\\n`,\n\t\t);\n\t\tif (!replaceCanonical && (await pathEntryExists(filePath))) {\n\t\t\tthrow new Error(\n\t\t\t\t`${NEW_SETTINGS_FILE_NAME} was created concurrently; reopen settings and retry.`,\n\t\t\t);\n\t\t}\n\t\tawait (operations.rename ?? DEFAULT_FILE_OPERATIONS.rename)(tempFile, filePath);\n\t} catch (error) {\n\t\tawait rm(tempFile, { force: true }).catch(() => undefined);\n\t\tthrow error;\n\t}\n}\n\nexport function settingsFilePath() {\n\treturn join(getAgentDir(), NEW_SETTINGS_FILE_NAME);\n}\n\nexport function projectSettingsFilePath(cwd: string) {\n\treturn join(cwd, CONFIG_DIR_NAME, NEW_SETTINGS_FILE_NAME);\n}\n\nfunction legacySettingsFilePath() {\n\treturn join(getAgentDir(), LEGACY_SETTINGS_FILE_NAME);\n}\n\nasync function fileExists(filePath: string) {\n\ttry {\n\t\tawait access(filePath, constants.F_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function pathEntryExists(filePath: string) {\n\ttry {\n\t\tawait lstat(filePath);\n\t\treturn true;\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return false;\n\t\tthrow error;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n", "import type { ChildProcess } from \"node:child_process\";\nimport {\n\tDEFAULT_BROWSER_HOST,\n\tDEFAULT_BROWSER_PORT,\n\ttype EffectiveBrowserSettings,\n\tparseConfiguredPort,\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\tid: string;\n\ttype: string;\n\ttitle: string;\n\turl: string;\n\twebSocketDebuggerUrl?: string;\n}\n\nexport interface ChromeDevToolsState {\n\thost: string;\n\tport: number;\n\tconfiguredPort: number;\n\thostConfigured: boolean;\n\tportConfigured: boolean;\n\tautoLaunchEnabled: boolean;\n\tendpointSource: EffectiveBrowserSettings[\"endpointSource\"];\n\tautoLaunchSource: EffectiveBrowserSettings[\"autoLaunchSource\"];\n\tbrowserExecutable?: string;\n\textensionPaths: string[];\n\tbrowserExecutableSource: EffectiveBrowserSettings[\"executablePathSource\"];\n\textensionPathsSource: EffectiveBrowserSettings[\"extensionPathsSource\"];\n\tsettingsFilePath?: string;\n\tprojectSettingsFilePath?: string;\n\tprojectSettingsTrusted: boolean;\n\tactivePageId?: string;\n\tmanagedBrowser?: ManagedBrowser;\n\tlaunchPromise?: Promise<void>;\n\tlastLaunchAttempt?: BrowserLaunchAttempt;\n\tshuttingDown: boolean;\n\tsessionGeneration: number;\n\tsessionController: AbortController;\n\tsettingsNotice?: string;\n}\n\nexport interface ManagedBrowser {\n\tprocess: ChildProcess;\n\tuserDataDir: string;\n\tport?: number;\n\texited: boolean;\n\tready: boolean;\n\townerGeneration: number;\n\tsessionOwner?: object;\n\tcleanupPromise?: Promise<void>;\n}\n\nexport interface BrowserLaunchAttempt {\n\tcandidateLabels: string[];\n\tmode: \"dynamic-port\" | \"explicit-port\";\n\tselectedCandidate?: string;\n\tuserDataDir?: string;\n\tlastError?: string;\n}\n\nexport interface BrowserCandidateDefinition {\n\tlabel: string;\n\texecutable: string;\n\tsource: \"env\" | \"path\" | \"wellKnownPath\";\n}\n\nexport interface BrowserCandidate extends BrowserCandidateDefinition {\n\tresolvedExecutable: string;\n}\n\nexport { parseConfiguredPort };\n\nexport const state: ChromeDevToolsState = {\n\thost: DEFAULT_HOST,\n\tport: DEFAULT_PORT,\n\tconfiguredPort: DEFAULT_PORT,\n\thostConfigured: false,\n\tportConfigured: false,\n\tautoLaunchEnabled: true,\n\tendpointSource: \"default\",\n\tautoLaunchSource: \"default\",\n\textensionPaths: [],\n\tbrowserExecutableSource: \"default\",\n\textensionPathsSource: \"default\",\n\tprojectSettingsTrusted: false,\n\tshuttingDown: false,\n\tsessionGeneration: 0,\n\tsessionController: new AbortController(),\n};\n\ninterface WebMcpSessionRuntime {\n\tcontroller: AbortController;\n\tenabled: boolean;\n\tcontrollers: Set<AbortController>;\n\tgeneration: number;\n\tsessionGeneration: number;\n}\n\nconst webMcpRuntimeByOwner = new WeakMap<object, WebMcpSessionRuntime>();\n\nexport function setWebMcpSessionOwner(owner: object) {\n\tconst runtime = webMcpRuntime(owner);\n\truntime.enabled = false;\n\truntime.sessionGeneration += 1;\n}\n\nexport function beginWebMcpOperation(owner: object, toolSignal?: AbortSignal) {\n\tconst runtime = webMcpRuntime(owner);\n\tconst controller = new AbortController();\n\truntime.controllers.add(controller);\n\tconst signals = [controller.signal, runtime.controller.signal];\n\tif (toolSignal) signals.push(toolSignal);\n\tconst signal = AbortSignal.any(signals);\n\treturn {\n\t\tsignal,\n\t\towner,\n\t\tsessionGeneration: runtime.sessionGeneration,\n\t\twebMcpGeneration: runtime.generation,\n\t\tdispose() {\n\t\t\truntime.controllers.delete(controller);\n\t\t},\n\t};\n}\n\nexport function invalidateWebMcpOperations(owner: object, reason: string) {\n\tconst runtime = webMcpRuntime(owner);\n\truntime.generation += 1;\n\tconst controllers = [...runtime.controllers];\n\truntime.controllers.clear();\n\tconst error = new DOMException(reason, \"AbortError\");\n\truntime.controller.abort(error);\n\truntime.controller = new AbortController();\n\tfor (const controller of controllers) controller.abort(error);\n}\n\nexport function currentWebMcpGeneration(owner: object) {\n\treturn webMcpRuntime(owner).generation;\n}\n\nexport function webMcpSessionSignal(owner: object) {\n\treturn webMcpRuntime(owner).controller.signal;\n}\n\nexport function applyRuntimeWebMcpSetting(enabled: boolean, owner: object) {\n\tconst runtime = webMcpRuntime(owner);\n\tif (runtime.enabled !== enabled) {\n\t\tinvalidateWebMcpOperations(owner, `WebMCP ${enabled ? \"enabled\" : \"disabled\"}`);\n\t}\n\truntime.enabled = enabled;\n}\n\nexport function webMcpEnabled(owner: object) {\n\treturn webMcpRuntime(owner).enabled;\n}\n\nexport function webMcpOperationIsCurrent(operation: {\n\towner: object;\n\tsessionGeneration: number;\n\twebMcpGeneration: number;\n}) {\n\tconst runtime = webMcpRuntime(operation.owner);\n\treturn (\n\t\toperation.sessionGeneration === runtime.sessionGeneration &&\n\t\toperation.webMcpGeneration === runtime.generation\n\t);\n}\n\nfunction webMcpRuntime(owner: object) {\n\tconst existing = webMcpRuntimeByOwner.get(owner);\n\tif (existing) return existing;\n\tconst created: WebMcpSessionRuntime = {\n\t\tcontroller: new AbortController(),\n\t\tcontrollers: new Set(),\n\t\tenabled: false,\n\t\tgeneration: 0,\n\t\tsessionGeneration: 0,\n\t};\n\twebMcpRuntimeByOwner.set(owner, created);\n\treturn created;\n}\n\nexport function applyRuntimeBrowserSettings(\n\tbrowser: EffectiveBrowserSettings,\n\tpaths: { user: string; project?: string },\n\tprojectTrusted: boolean,\n) {\n\tstate.host = browser.host;\n\tstate.port = browser.port;\n\tstate.configuredPort = browser.port;\n\tstate.hostConfigured = browser.hostConfigured;\n\tstate.portConfigured = browser.portConfigured;\n\tstate.autoLaunchEnabled = browser.autoLaunchEnabled;\n\tstate.endpointSource = browser.endpointSource;\n\tstate.autoLaunchSource = browser.autoLaunchSource;\n\tstate.browserExecutable = browser.executablePath;\n\tstate.extensionPaths = [...browser.extensionPaths];\n\tstate.browserExecutableSource = browser.executablePathSource;\n\tstate.extensionPathsSource = browser.extensionPathsSource;\n\tstate.settingsFilePath = paths.user;\n\tstate.projectSettingsFilePath = paths.project;\n\tstate.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\tBROWSER_SHUTDOWN_WAIT_MS,\n\ttype BrowserCandidate,\n\ttype BrowserCandidateDefinition,\n\ttype BrowserLaunchAttempt,\n\tDEFAULT_ENDPOINT_RETRY_MS,\n\tDEFAULT_ENDPOINT_WAIT_MS,\n\tDEFAULT_HTTP_TIMEOUT_MS,\n\tDEVTOOLS_ACTIVE_PORT_FILE,\n\ttype DevToolsPage,\n\tinvalidateWebMcpOperations,\n\tMANAGED_BROWSER_PROFILE_PREFIX,\n\ttype ManagedBrowser,\n\tstate,\n} from \"./runtime.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\tshell: false;\n\tstdio: \"ignore\";\n}\n\nexport interface BrowserManagerOperations {\n\taccess(path: string, mode: number): Promise<void>;\n\tmkdtemp(prefix: string): Promise<string>;\n\treadFile(path: string, encoding: \"utf8\"): Promise<string>;\n\trm(path: string, options: { recursive: true; force: true }): Promise<void>;\n\tfetch(input: string, init?: RequestInit): Promise<Response>;\n\tspawn(executable: string, args: string[], options: BrowserSpawnOptions): ChildProcess;\n\tinspectBrowserVersion(executable: string, signal: AbortSignal): Promise<string>;\n\tisPortAvailable(host: string, port: number): Promise<boolean>;\n\tsleep(ms: number, signal?: AbortSignal): Promise<void>;\n}\n\nconst DEFAULT_BROWSER_MANAGER_OPERATIONS: BrowserManagerOperations = {\n\taccess,\n\tmkdtemp,\n\treadFile,\n\trm: (path, options) => rm(path, options),\n\tfetch: (input, init) => fetch(input, init),\n\tspawn,\n\tinspectBrowserVersion,\n\tisPortAvailable,\n\tsleep: abortableSleep,\n};\n\nlet browserManagerOperations = DEFAULT_BROWSER_MANAGER_OPERATIONS;\n\ninterface ManagedBrowserScope {\n\tcontroller: AbortController;\n\tgeneration: number;\n\tlaunchPromise?: Promise<void>;\n\tmanagedBrowser?: ManagedBrowser;\n\tport: number;\n\tlastLaunchAttempt?: BrowserLaunchAttempt;\n}\n\nconst managedBrowserScopes = new WeakMap<object, ManagedBrowserScope>();\n\nfunction managedBrowserScope(owner: object) {\n\tconst existing = managedBrowserScopes.get(owner);\n\tif (existing) return existing;\n\tconst created: ManagedBrowserScope = {\n\t\tcontroller: new AbortController(),\n\t\tgeneration: 0,\n\t\tport: state.configuredPort,\n\t};\n\tmanagedBrowserScopes.set(owner, created);\n\treturn created;\n}\n\nexport function startManagedBrowserSession(owner: object) {\n\tconst scope = managedBrowserScope(owner);\n\tscope.controller.abort(new DOMException(\"Chrome DevTools session replaced\", \"AbortError\"));\n\tscope.controller = new AbortController();\n\tscope.generation += 1;\n\tscope.port = state.configuredPort;\n\tscope.lastLaunchAttempt = undefined;\n}\n\nexport function managedBrowserForOwner(owner?: object) {\n\tif (!owner) return state.managedBrowser;\n\tconst scopedBrowser = managedBrowserScope(owner).managedBrowser;\n\tif (scopedBrowser) return scopedBrowser;\n\treturn state.managedBrowser?.sessionOwner === owner ? state.managedBrowser : undefined;\n}\n\nfunction setManagedBrowser(owner: object | undefined, browser: ManagedBrowser | undefined) {\n\tif (owner) managedBrowserScope(owner).managedBrowser = browser;\n\telse state.managedBrowser = browser;\n}\n\nfunction launchPromiseForOwner(owner?: object) {\n\treturn owner ? managedBrowserScope(owner).launchPromise : state.launchPromise;\n}\n\nfunction setLaunchPromise(owner: object | undefined, launchPromise: Promise<void> | undefined) {\n\tif (owner) managedBrowserScope(owner).launchPromise = launchPromise;\n\telse state.launchPromise = launchPromise;\n}\n\nfunction managedBrowserPort(owner?: object) {\n\treturn owner ? managedBrowserScope(owner).port : state.port;\n}\n\nfunction setManagedBrowserPort(owner: object | undefined, port: number) {\n\tif (owner) managedBrowserScope(owner).port = port;\n\telse state.port = port;\n}\n\nfunction lastLaunchAttempt(owner?: object) {\n\treturn owner ? managedBrowserScope(owner).lastLaunchAttempt : state.lastLaunchAttempt;\n}\n\nfunction setLastLaunchAttempt(\n\towner: object | undefined,\n\tattempt: BrowserLaunchAttempt | undefined,\n) {\n\tif (owner) managedBrowserScope(owner).lastLaunchAttempt = attempt;\n\telse state.lastLaunchAttempt = attempt;\n}\n\nexport function setBrowserManagerOperationsForTests(overrides: Partial<BrowserManagerOperations>) {\n\tconst previous = browserManagerOperations;\n\tbrowserManagerOperations = { ...DEFAULT_BROWSER_MANAGER_OPERATIONS, ...overrides };\n\treturn () => {\n\t\tbrowserManagerOperations = previous;\n\t};\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nfunction normalizePathForComparison(value: string) {\n\treturn process.platform === \"win32\" ? value.toLowerCase() : value;\n}\n\nexport async function ensureDevToolsEndpoint(\n\twaitMs = DEFAULT_ENDPOINT_WAIT_MS,\n\tcallerSignal?: AbortSignal,\n\towner?: object,\n) {\n\tcallerSignal?.throwIfAborted();\n\tif (extensionsConfigured()) {\n\t\tvalidateExtensionLaunchMode();\n\t\tawait ensureManagedBrowserLaunched(waitMs, callerSignal, owner);\n\t\treturn;\n\t}\n\tif (canAutoLaunchBrowser()) {\n\t\ttry {\n\t\t\tawait withEndpointRetry(\n\t\t\t\t() => fetchDevToolsJson<unknown>(\"/json/version\", { signal: callerSignal }, owner),\n\t\t\t\twaitMs,\n\t\t\t\tcallerSignal,\n\t\t\t);\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tif (shouldAutoLaunchAfterEndpointError(error)) {\n\t\t\t\tawait ensureManagedBrowserLaunched(waitMs, callerSignal, owner);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\ttry {\n\t\tawait fetchDevToolsJson<unknown>(\"/json/version\", { signal: callerSignal }, owner);\n\t} catch (error) {\n\t\tif (isRetryableEndpointError(error)) return;\n\t\tthrow error;\n\t}\n}\n\nfunction validateExtensionLaunchMode() {\n\tif (!isLocalDevToolsHost(state.host)) {\n\t\tthrow new DevToolsEndpointError(\n\t\t\t\"Unpacked extensions require a local extension-owned managed browser; remote CDP endpoints cannot be modified.\",\n\t\t);\n\t}\n\tif (!state.autoLaunchEnabled) {\n\t\tthrow new DevToolsEndpointError(\n\t\t\t\"Auto-launch is required for unpacked extensions so Pi can create an isolated managed browser.\",\n\t\t);\n\t}\n\tif (!state.browserExecutable) {\n\t\tthrow new DevToolsEndpointError(\n\t\t\t\"Unpacked extensions require browser.executablePath for Chrome for Testing or Chromium in pi-chrome-devtools.json.\",\n\t\t);\n\t}\n}\n\nasync function ensureManagedBrowserLaunched(\n\twaitMs: number,\n\tcallerSignal?: AbortSignal,\n\towner?: object,\n) {\n\tconst existingLaunch = launchPromiseForOwner(owner);\n\tif (existingLaunch) {\n\t\tawait waitForCaller(existingLaunch, callerSignal);\n\t\treturn;\n\t}\n\tconst existingBrowser = managedBrowserForOwner(owner);\n\tif (existingBrowser && !existingBrowser.exited && existingBrowser.ready) return;\n\tconst generation = owner ? managedBrowserScope(owner).generation : state.sessionGeneration;\n\tconst signal = owner\n\t\t? managedBrowserScope(owner).controller.signal\n\t\t: state.sessionController.signal;\n\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\n\tconst launchPromise = prepareManagedBrowserLaunch(waitMs, generation, signal, owner);\n\tconst wrappedPromise = launchPromise.finally(() => {\n\t\tif (launchPromiseForOwner(owner) === wrappedPromise) setLaunchPromise(owner, undefined);\n\t});\n\tsetLaunchPromise(owner, wrappedPromise);\n\tawait waitForCaller(wrappedPromise, callerSignal);\n}\n\nfunction waitForCaller<T>(operation: Promise<T>, signal?: AbortSignal) {\n\tif (!signal) return operation;\n\tsignal.throwIfAborted();\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst onAbort = () => settle(() => reject(signal.reason));\n\t\tconst settle = (callback: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tcallback();\n\t\t};\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\toperation.then(\n\t\t\t(value) => settle(() => resolve(value)),\n\t\t\t(error) => settle(() => reject(error)),\n\t\t);\n\t});\n}\n\nasync function prepareManagedBrowserLaunch(\n\twaitMs: number,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tconst existingBrowser = managedBrowserForOwner(owner);\n\tif (existingBrowser) {\n\t\tawait shutdownManagedBrowser(existingBrowser, { awaitLaunch: false, owner });\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t}\n\tif (state.portConfigured) {\n\t\tconst available = await browserManagerOperations.isPortAvailable(\n\t\t\tstate.host,\n\t\t\tmanagedBrowserPort(owner),\n\t\t);\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tif (!available) {\n\t\t\tthrow new DevToolsEndpointError(\n\t\t\t\t`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\t\t\t);\n\t\t}\n\t}\n\treturn launchManagedBrowser(waitMs, generation, signal, owner);\n}\n\nasync function launchManagedBrowser(\n\twaitMs: number,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\tconst candidateDefinitions = browserCandidateDefinitions();\n\tconst candidates = await resolveBrowserCandidates(\n\t\tcandidateDefinitions,\n\t\tgeneration,\n\t\tsignal,\n\t\towner,\n\t);\n\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\tsetLastLaunchAttempt(owner, {\n\t\tcandidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n\t\tmode: state.portConfigured ? \"explicit-port\" : \"dynamic-port\",\n\t});\n\n\tif (candidates.length === 0) {\n\t\tthrow new DevToolsEndpointError(noBrowserCandidateMessage(candidateDefinitions));\n\t}\n\n\tlet lastError: unknown;\n\tfor (const candidate of candidates) {\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\ttry {\n\t\t\tif (extensionsConfigured())\n\t\t\t\tawait requireSupportedExtensionBrowser(candidate, generation, signal, owner);\n\t\t\tawait launchBrowserCandidate(candidate, waitMs, generation, signal, owner);\n\t\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\t\tsetLastLaunchAttempt(owner, {\n\t\t\t\t...lastLaunchAttempt(owner),\n\t\t\t\tcandidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n\t\t\t\tmode: state.portConfigured ? \"explicit-port\" : \"dynamic-port\",\n\t\t\t\tselectedCandidate: formatBrowserCandidate(candidate),\n\t\t\t\tuserDataDir: managedBrowserForOwner(owner)?.userDataDir,\n\t\t\t});\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\t\t} catch (cancellation) {\n\t\t\t\tsetLastLaunchAttempt(owner, {\n\t\t\t\t\t...(lastLaunchAttempt(owner) ?? {\n\t\t\t\t\t\tcandidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n\t\t\t\t\t\tmode: state.portConfigured ? \"explicit-port\" : \"dynamic-port\",\n\t\t\t\t\t}),\n\t\t\t\t\tlastError: formatError(cancellation),\n\t\t\t\t});\n\t\t\t\tthrow cancellation;\n\t\t\t}\n\t\t\tlastError = error;\n\t\t\tsetLastLaunchAttempt(owner, {\n\t\t\t\t...(lastLaunchAttempt(owner) ?? {\n\t\t\t\t\tcandidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),\n\t\t\t\t\tmode: state.portConfigured ? \"explicit-port\" : \"dynamic-port\",\n\t\t\t\t}),\n\t\t\t\tlastError: formatError(error),\n\t\t\t});\n\t\t}\n\t}\n\n\tif (lastError instanceof DevToolsEndpointError && extensionsConfigured()) throw lastError;\n\tthrow new DevToolsEndpointError(\n\t\t[\n\t\t\t\"Unable to auto-launch a Chromium-family browser for Chrome DevTools.\",\n\t\t\t`Tried: ${candidates.map(formatBrowserCandidate).join(\", \")}`,\n\t\t\tlastError ? `Last error: ${formatError(lastError)}` : undefined,\n\t\t\tlaunchHint(),\n\t\t\tendpointConfigHint(),\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\"\\n\"),\n\t);\n}\n\nasync function requireSupportedExtensionBrowser(\n\tcandidate: BrowserCandidate,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tlet version: string;\n\ttry {\n\t\tversion = (\n\t\t\tawait browserManagerOperations.inspectBrowserVersion(candidate.resolvedExecutable, signal)\n\t\t).trim();\n\t} catch (error) {\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tthrow new DevToolsEndpointError(\n\t\t\t`Unable to identify the configured extension browser ${candidate.resolvedExecutable}: ${formatError(error)}. Configure Chrome for Testing or Chromium.`,\n\t\t);\n\t}\n\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\tconst classification = classifyExtensionBrowserVersion(version);\n\tif (!classification.supported) {\n\t\tthrow new DevToolsEndpointError(\n\t\t\t`Unsupported browser for unpacked extensions: ${version || \"unknown product\"}. Configure Chrome for Testing or Chromium; branded Chrome may silently ignore extension startup flags.`,\n\t\t);\n\t}\n}\n\nexport function classifyExtensionBrowserVersion(version: string): {\n\tsupported: boolean;\n\tproduct: string;\n} {\n\tif (/^(?:Google )?Chrome for Testing\\b/i.test(version)) {\n\t\treturn { supported: true, product: \"Chrome for Testing\" };\n\t}\n\tif (/^Chromium\\b/i.test(version)) return { supported: true, product: \"Chromium\" };\n\tconst product = version.trim().replace(/\\s+\\d+(?:\\.\\d+)*.*$/, \"\") || \"Unknown\";\n\treturn { supported: false, product };\n}\n\nasync function launchBrowserCandidate(\n\tcandidate: BrowserCandidate,\n\twaitMs: number,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\tconst userDataDir = await browserManagerOperations.mkdtemp(\n\t\tjoin(tmpdir(), MANAGED_BROWSER_PROFILE_PREFIX),\n\t);\n\tlet managedBrowser: ManagedBrowser | undefined;\n\ttry {\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tconst portArgument = state.portConfigured ? String(managedBrowserPort(owner)) : \"0\";\n\t\tconst args = buildManagedBrowserLaunchArguments(\n\t\t\tuserDataDir,\n\t\t\tportArgument,\n\t\t\tstate.extensionPaths,\n\t\t);\n\t\tconst child = browserManagerOperations.spawn(candidate.resolvedExecutable, args, {\n\t\t\tshell: false,\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tconst launchedBrowser: ManagedBrowser = {\n\t\t\tprocess: child,\n\t\t\tuserDataDir,\n\t\t\texited: false,\n\t\t\tready: false,\n\t\t\townerGeneration: generation,\n\t\t\t...(owner ? { sessionOwner: owner } : {}),\n\t\t};\n\t\tmanagedBrowser = launchedBrowser;\n\t\tsetManagedBrowser(owner, launchedBrowser);\n\n\t\tchild.once(\"exit\", () => {\n\t\t\tif (managedBrowserForOwner(owner) === launchedBrowser && owner) {\n\t\t\t\tinvalidateWebMcpOperations(owner, \"Chrome DevTools managed browser exited\");\n\t\t\t}\n\t\t\tlaunchedBrowser.exited = true;\n\t\t\tlaunchedBrowser.ready = false;\n\t\t\tif (!state.portConfigured && launchedBrowser.port === managedBrowserPort(owner)) {\n\t\t\t\tsetManagedBrowserPort(owner, state.configuredPort);\n\t\t\t}\n\t\t});\n\n\t\tawait waitForBrowserSpawn(child);\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tif (state.portConfigured) {\n\t\t\tlaunchedBrowser.port = managedBrowserPort(owner);\n\t\t} else {\n\t\t\tlaunchedBrowser.port = await readManagedBrowserPort(\n\t\t\t\tuserDataDir,\n\t\t\t\tlaunchedBrowser,\n\t\t\t\twaitMs,\n\t\t\t\tgeneration,\n\t\t\t\tsignal,\n\t\t\t\towner,\n\t\t\t);\n\t\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\t\tsetManagedBrowserPort(owner, launchedBrowser.port);\n\t\t}\n\t\tawait waitForDevToolsEndpoint(waitMs, launchedBrowser, generation, signal, owner);\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tlaunchedBrowser.ready = true;\n\t} catch (error) {\n\t\tif (managedBrowser) await shutdownManagedBrowser(managedBrowser, { awaitLaunch: false, owner });\n\t\telse {\n\t\t\tawait browserManagerOperations\n\t\t\t\t.rm(userDataDir, { recursive: true, force: true })\n\t\t\t\t.catch(() => undefined);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport function buildManagedBrowserLaunchArguments(\n\tuserDataDir: string,\n\tportArgument: string,\n\textensionPaths: readonly string[],\n) {\n\tconst extensionList = extensionPaths.join(\",\");\n\treturn [\n\t\t`--remote-debugging-port=${portArgument}`,\n\t\t`--user-data-dir=${userDataDir}`,\n\t\t...(extensionPaths.length > 0\n\t\t\t? [`--disable-extensions-except=${extensionList}`, `--load-extension=${extensionList}`]\n\t\t\t: []),\n\t\t// Chrome 138+ de-elevates when launched from an elevated process on Windows: the\n\t\t// spawned process relaunches a de-elevated child and exits immediately, which the\n\t\t// exit watchdog misreads as a failed launch.\n\t\t...(process.platform === \"win32\" ? [\"--do-not-de-elevate\"] : []),\n\t\t\"--no-first-run\",\n\t\t\"--no-default-browser-check\",\n\t\t\"about:blank\",\n\t];\n}\n\nfunction waitForBrowserSpawn(child: ChildProcess) {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst settle = (callback: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tchild.off(\"error\", onError);\n\t\t\tchild.off(\"spawn\", onSpawn);\n\t\t\tcallback();\n\t\t};\n\t\tconst onError = (error: Error) => settle(() => reject(error));\n\t\tconst onSpawn = () => settle(resolve);\n\t\tchild.once(\"error\", onError);\n\t\tchild.once(\"spawn\", onSpawn);\n\t});\n}\n\nasync function readManagedBrowserPort(\n\tuserDataDir: string,\n\tmanagedBrowser: ManagedBrowser,\n\twaitMs: number,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tconst activePortFile = join(userDataDir, DEVTOOLS_ACTIVE_PORT_FILE);\n\tconst deadline = Date.now() + waitMs;\n\twhile (true) {\n\t\tthrowIfManagedBrowserExited(managedBrowser);\n\t\tconst text = await browserManagerOperations\n\t\t\t.readFile(activePortFile, \"utf8\")\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tconst portText = text?.split(/\\r?\\n/, 1)[0]?.trim();\n\t\tconst port = Number(portText);\n\t\tif (Number.isInteger(port) && port > 0) return port;\n\n\t\tconst remainingMs = deadline - Date.now();\n\t\tif (remainingMs <= 0) {\n\t\t\tthrow new DevToolsEndpointError(\n\t\t\t\t[\n\t\t\t\t\t\"Timed out waiting for auto-launched browser DevToolsActivePort.\",\n\t\t\t\t\t`Expected file: ${activePortFile}`,\n\t\t\t\t\tlaunchHint(),\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t}\n\t\tawait browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);\n\t}\n}\n\nasync function waitForDevToolsEndpoint(\n\twaitMs: number,\n\tmanagedBrowser: ManagedBrowser,\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tconst deadline = Date.now() + waitMs;\n\twhile (true) {\n\t\tthrowIfManagedBrowserExited(managedBrowser);\n\t\ttry {\n\t\t\tawait fetchDevToolsJson<unknown>(\"/json/version\", { signal }, owner);\n\t\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tif (!isRetryableEndpointError(error)) throw error;\n\t\t}\n\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tconst remainingMs = deadline - Date.now();\n\t\tif (remainingMs <= 0) {\n\t\t\tthrow new DevToolsEndpointError(\n\t\t\t\t[\n\t\t\t\t\t`Timed out waiting for auto-launched browser at ${devToolsEndpoint(owner)}.`,\n\t\t\t\t\tlaunchHint(),\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t}\n\t\tawait browserManagerOperations.sleep(Math.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs), signal);\n\t}\n}\n\nfunction throwIfManagedBrowserExited(managedBrowser: ManagedBrowser) {\n\tif (!managedBrowser.exited) return;\n\tthrow new DevToolsEndpointError(\"Auto-launched browser exited before DevTools became available.\");\n}\n\nfunction throwIfBrowserLaunchCancelled(generation: number, signal: AbortSignal, owner?: object) {\n\tconst currentGeneration = owner ? managedBrowserScope(owner).generation : state.sessionGeneration;\n\tconst shuttingDown = owner ? signal.aborted : state.shuttingDown;\n\tif (!shuttingDown && generation === currentGeneration && !signal.aborted) return;\n\tthrow new DevToolsEndpointError(\n\t\tgeneration === currentGeneration\n\t\t\t? \"Chrome DevTools browser launch cancelled during shutdown.\"\n\t\t\t: \"Chrome DevTools browser launch cancelled because the session was replaced.\",\n\t);\n}\n\nexport async function shutdownManagedBrowser(\n\tmanagedBrowser?: ManagedBrowser,\n\toptions: { awaitLaunch?: boolean; cancelLaunch?: boolean; owner?: object } = {},\n) {\n\tconst owner = options.owner ?? managedBrowser?.sessionOwner;\n\tif (options.cancelLaunch) {\n\t\tif (owner) {\n\t\t\tconst scope = managedBrowserScope(owner);\n\t\t\tscope.controller.abort(\n\t\t\t\tnew DOMException(\"Chrome DevTools browser launch cancelled during shutdown\", \"AbortError\"),\n\t\t\t);\n\t\t\tscope.generation += 1;\n\t\t} else {\n\t\t\tstate.shuttingDown = true;\n\t\t}\n\t}\n\tmanagedBrowser ??= managedBrowserForOwner(owner);\n\tif (options.awaitLaunch !== false) {\n\t\tawait launchPromiseForOwner(owner)?.catch(() => undefined);\n\t\tmanagedBrowser ??= managedBrowserForOwner(owner);\n\t}\n\tif (!managedBrowser) return;\n\tif (managedBrowser.cleanupPromise) return managedBrowser.cleanupPromise;\n\n\tconst cleanup = cleanupManagedBrowser(managedBrowser, owner);\n\tmanagedBrowser.cleanupPromise = cleanup;\n\treturn cleanup;\n}\n\nasync function cleanupManagedBrowser(managedBrowser: ManagedBrowser, owner?: object) {\n\tif (managedBrowserForOwner(owner) === managedBrowser) {\n\t\tif (owner) invalidateWebMcpOperations(owner, \"Chrome DevTools managed browser closed\");\n\t\tif (state.managedBrowser === managedBrowser) state.managedBrowser = undefined;\n\t\telse setManagedBrowser(owner, undefined);\n\t}\n\tif (!managedBrowser.exited) {\n\t\tkillManagedBrowserProcess(managedBrowser);\n\t\tawait waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(async () => {\n\t\t\tkillManagedBrowserProcess(managedBrowser, \"SIGKILL\");\n\t\t\tawait waitForManagedBrowserExit(managedBrowser, BROWSER_SHUTDOWN_WAIT_MS).catch(\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t});\n\t}\n\tawait browserManagerOperations\n\t\t.rm(managedBrowser.userDataDir, { recursive: true, force: true })\n\t\t.catch(() => undefined);\n\tif (!state.portConfigured && managedBrowser.port === managedBrowserPort(owner)) {\n\t\tsetManagedBrowserPort(owner, state.configuredPort);\n\t}\n}\n\nfunction killManagedBrowserProcess(managedBrowser: ManagedBrowser, signal?: NodeJS.Signals) {\n\ttry {\n\t\tmanagedBrowser.process.kill(signal);\n\t} catch {\n\t\t// Best-effort shutdown: the browser may have already exited or failed to spawn.\n\t}\n}\n\nfunction waitForManagedBrowserExit(managedBrowser: ManagedBrowser, waitMs: number) {\n\tif (managedBrowser.exited) return Promise.resolve();\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst settle = (callback: () => void) => {\n\t\t\tclearTimeout(timeout);\n\t\t\tmanagedBrowser.process.off(\"exit\", onExitOrClose);\n\t\t\tmanagedBrowser.process.off(\"close\", onExitOrClose);\n\t\t\tcallback();\n\t\t};\n\t\tconst onExitOrClose = () => {\n\t\t\tmanagedBrowser.exited = true;\n\t\t\tsettle(resolve);\n\t\t};\n\t\tconst timeout = setTimeout(\n\t\t\t() => settle(() => reject(new Error(\"Timed out waiting for browser shutdown.\"))),\n\t\t\twaitMs,\n\t\t);\n\t\tmanagedBrowser.process.once(\"exit\", onExitOrClose);\n\t\tmanagedBrowser.process.once(\"close\", onExitOrClose);\n\t});\n}\n\nexport async function fetchDevToolsJson<T>(path: string, init?: RequestInit, owner?: object) {\n\tconst url = `${devToolsEndpoint(owner)}${path}`;\n\tlet response: Response;\n\ttry {\n\t\tconst timeoutSignal = AbortSignal.timeout(DEFAULT_HTTP_TIMEOUT_MS);\n\t\tresponse = await browserManagerOperations.fetch(url, {\n\t\t\t...init,\n\t\t\tsignal: init?.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal,\n\t\t});\n\t} catch (error) {\n\t\tthrow new DevToolsEndpointError(endpointConnectionErrorMessage(error, owner), {\n\t\t\tlaunchable: true,\n\t\t\tretryable: true,\n\t\t});\n\t}\n\n\tif (!response.ok) {\n\t\tconst body = (await response.text().catch(() => \"\")).trim();\n\t\tconst suffix = body ? `: ${body.slice(0, 200)}` : \"\";\n\t\tthrow new DevToolsEndpointError(\n\t\t\t[\n\t\t\t\t`Chrome DevTools endpoint ${url} returned ${response.status} ${response.statusText}${suffix}.`,\n\t\t\t\tendpointConfigHint(),\n\t\t\t].join(\"\\n\"),\n\t\t\t{ retryable: response.status === 429 || response.status >= 500 },\n\t\t);\n\t}\n\n\ttry {\n\t\treturn (await response.json()) as T;\n\t} catch (error) {\n\t\tthrow new DevToolsEndpointError(\n\t\t\t[\n\t\t\t\t`Chrome DevTools endpoint ${url} returned invalid JSON: ${formatError(error)}.`,\n\t\t\t\tendpointConfigHint(),\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t}\n}\n\nexport async function withEndpointRetry<T>(\n\toperation: () => Promise<T>,\n\twaitMs: number,\n\tsignal?: AbortSignal,\n) {\n\tconst deadline = Date.now() + waitMs;\n\twhile (true) {\n\t\tsignal?.throwIfAborted();\n\t\ttry {\n\t\t\treturn await operation();\n\t\t} catch (error) {\n\t\t\tif (!isRetryableEndpointError(error)) throw error;\n\n\t\t\tconst remainingMs = deadline - Date.now();\n\t\t\tif (remainingMs <= 0) throw error;\n\n\t\t\tawait browserManagerOperations.sleep(\n\t\t\t\tMath.min(DEFAULT_ENDPOINT_RETRY_MS, remainingMs),\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction isRetryableEndpointError(error: unknown) {\n\treturn error instanceof DevToolsEndpointError && error.retryable;\n}\n\nfunction isLaunchableEndpointError(error: unknown) {\n\treturn error instanceof DevToolsEndpointError && error.launchable;\n}\n\nfunction shouldAutoLaunchAfterEndpointError(error: unknown) {\n\tif (!canAutoLaunchBrowser()) return false;\n\tif (isLaunchableEndpointError(error)) return true;\n\n\t// After the attach-first attempt (including its retry window, when applicable) fails, treat any\n\t// DevTools endpoint error on an unpinned port as a conflict we can avoid with a dynamic port.\n\treturn !state.portConfigured && error instanceof DevToolsEndpointError;\n}\n\nfunction canAutoLaunchBrowser() {\n\treturn state.autoLaunchEnabled && isLocalDevToolsHost(state.host);\n}\n\nfunction extensionsConfigured() {\n\treturn state.extensionPaths.length > 0;\n}\n\nfunction endpointConnectionErrorMessage(error: unknown, owner?: object) {\n\tconst reason = isTimeoutError(error) ? \"request timed out\" : \"connection failed\";\n\treturn [\n\t\t`Cannot connect to Chrome DevTools endpoint at ${devToolsEndpoint(owner)} (${reason}).`,\n\t\tlaunchHint(),\n\t\tendpointConfigHint(),\n\t].join(\"\\n\");\n}\n\nfunction isTimeoutError(error: unknown) {\n\treturn error instanceof Error && [\"AbortError\", \"TimeoutError\"].includes(error.name);\n}\n\nexport function devToolsEndpoint(owner?: object) {\n\treturn `http://${formatHostForUrl(state.host)}:${managedBrowserPort(owner)}`;\n}\n\nexport function formatHostForUrl(host: string) {\n\tif (host.startsWith(\"[\") && host.endsWith(\"]\")) return host;\n\treturn host.includes(\":\") ? `[${host}]` : host;\n}\n\nexport function endpointSourceLabel() {\n\treturn state.endpointSource;\n}\n\nexport type BrowserLifecycleState = \"starting\" | \"running\" | \"exited\" | \"failed\" | \"unobserved\";\n\nexport function browserLifecycleState(owner?: object): BrowserLifecycleState {\n\tif (launchPromiseForOwner(owner)) return \"starting\";\n\tif (managedBrowserForOwner(owner)?.exited) return \"exited\";\n\tif (managedBrowserForOwner(owner)?.ready) return \"running\";\n\tif (lastLaunchAttempt(owner)?.lastError) return \"failed\";\n\treturn \"unobserved\";\n}\n\nexport function launchModeLabel(owner?: object) {\n\tconst managedBrowser = managedBrowserForOwner(owner);\n\tif (extensionsConfigured()) {\n\t\tif (!isLocalDevToolsHost(state.host)) return \"invalid; extensions require a local endpoint\";\n\t\tif (!state.autoLaunchEnabled) return \"invalid; extensions require auto-launch\";\n\t\tif (managedBrowser && !managedBrowser.exited) {\n\t\t\treturn state.portConfigured\n\t\t\t\t? \"extension-owned browser on explicit port\"\n\t\t\t\t: \"extension-owned browser on dynamic port\";\n\t\t}\n\t\treturn state.portConfigured\n\t\t\t? \"force extension-owned launch on explicit port\"\n\t\t\t: \"force extension-owned launch on dynamic port\";\n\t}\n\tif (!isLocalDevToolsHost(state.host)) return \"manual remote endpoint\";\n\tif (!state.autoLaunchEnabled) return \"manual; auto-launch disabled\";\n\tif (managedBrowser && !managedBrowser.exited) {\n\t\treturn state.portConfigured\n\t\t\t? \"auto-launched on explicit port\"\n\t\t\t: \"auto-launched on dynamic port\";\n\t}\n\treturn state.portConfigured\n\t\t? \"attach first; auto-launch explicit port\"\n\t\t: \"attach first; auto-launch dynamic port\";\n}\n\nexport function launchAttemptLines(owner?: object) {\n\tconst attempt = lastLaunchAttempt(owner);\n\tif (!attempt) return [];\n\n\tconst lines = [`Last launch attempt: ${attempt.mode}`];\n\tif (attempt.selectedCandidate) {\n\t\tlines.push(`Launched browser: ${attempt.selectedCandidate}`);\n\t} else {\n\t\tlines.push(`Tried browser candidates: ${attempt.candidateLabels.join(\", \")}`);\n\t}\n\tif (attempt.userDataDir) lines.push(`Managed browser profile: ${attempt.userDataDir}`);\n\tif (attempt.lastError) lines.push(`Last launch error: ${attempt.lastError}`);\n\treturn lines;\n}\n\nexport function launchHint() {\n\tif (extensionsConfigured()) {\n\t\treturn \"Configured unpacked extensions force an isolated extension-owned launch; existing CDP browsers are never reused, modified, or closed.\";\n\t}\n\tif (!isLocalDevToolsHost(state.host)) {\n\t\treturn `Remote/non-local endpoints are not auto-launched. Start a browser with CDP enabled at ${devToolsEndpoint()}.`;\n\t}\n\tif (!state.autoLaunchEnabled) {\n\t\treturn `Auto-launch is disabled. Start a browser manually: ${chromeLaunchCommand()}`;\n\t}\n\tconst managedMode = state.portConfigured ? `port ${state.port}` : \"a dynamic DevTools port\";\n\treturn `If no endpoint is available, Pi will auto-launch a Chromium-family browser with ${managedMode} and an isolated temp profile. Manual command: ${chromeLaunchCommand()}`;\n}\n\nexport function browserCandidateHint() {\n\tif (extensionsConfigured()) {\n\t\treturn \"Extension browser requirement: configure Chrome for Testing or Chromium with browser.executablePath; branded Chrome is rejected because it may ignore unpacked-extension flags.\";\n\t}\n\treturn `Browser candidates: ${browserCandidateDefinitions()\n\t\t.map((candidate) => candidate.label)\n\t\t.join(\", \")}`;\n}\n\nexport function chromeLaunchCommand() {\n\tconst executable = state.browserExecutable ?? defaultManualBrowserExecutable();\n\tconst dataDir =\n\t\tprocess.platform === \"win32\" ? \"%TEMP%\\\\pi-chrome-devtools\" : \"/tmp/pi-chrome-devtools\";\n\treturn `${quoteCommandPart(executable)} --remote-debugging-port=${state.port} --user-data-dir=${dataDir}`;\n}\n\nfunction defaultManualBrowserExecutable() {\n\treturn process.platform === \"darwin\"\n\t\t? \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\"\n\t\t: process.platform === \"win32\"\n\t\t\t? \"chrome.exe\"\n\t\t\t: \"google-chrome\";\n}\n\nexport function quoteCommandPart(value: string) {\n\treturn /\\s/.test(value) ? `\"${value.replaceAll('\"', '\\\\\"')}\"` : value;\n}\n\nexport function endpointConfigHint() {\n\treturn \"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\tconst normalizedHost = host.toLowerCase().replace(/^\\[(.*)]$/, \"$1\");\n\treturn [\"localhost\", \"127.0.0.1\", \"::1\", \"0:0:0:0:0:0:0:1\"].includes(normalizedHost);\n}\n\nfunction browserCandidateDefinitions(): BrowserCandidateDefinition[] {\n\tconst explicitCandidate = explicitBrowserCandidateDefinition();\n\tif (explicitCandidate.length > 0) return explicitCandidate;\n\n\treturn uniqueBrowserCandidates(platformBrowserCandidateDefinitions());\n}\n\nfunction explicitBrowserCandidateDefinition(): BrowserCandidateDefinition[] {\n\tif (!state.browserExecutable) return [];\n\treturn [\n\t\t{\n\t\t\tlabel:\n\t\t\t\tstate.browserExecutableSource === \"environment\"\n\t\t\t\t\t? \"PI_CHROME_DEVTOOLS_BROWSER\"\n\t\t\t\t\t: \"browser.executablePath\",\n\t\t\texecutable: state.browserExecutable,\n\t\t\tsource: \"env\",\n\t\t},\n\t];\n}\n\nfunction platformBrowserCandidateDefinitions(): BrowserCandidateDefinition[] {\n\tif (process.platform === \"darwin\") {\n\t\treturn [\n\t\t\t{\n\t\t\t\tlabel: \"Google Chrome\",\n\t\t\t\texecutable: \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\n\t\t\t\tsource: \"wellKnownPath\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: \"Chromium\",\n\t\t\t\texecutable: \"/Applications/Chromium.app/Contents/MacOS/Chromium\",\n\t\t\t\tsource: \"wellKnownPath\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: \"Brave Browser\",\n\t\t\t\texecutable: \"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser\",\n\t\t\t\tsource: \"wellKnownPath\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: \"Microsoft Edge\",\n\t\t\t\texecutable: \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\n\t\t\t\tsource: \"wellKnownPath\",\n\t\t\t},\n\t\t];\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\treturn windowsBrowserCandidateDefinitions();\n\t}\n\n\treturn [\n\t\t{ label: \"Google Chrome\", executable: \"google-chrome\", source: \"path\" },\n\t\t{ label: \"Google Chrome Stable\", executable: \"google-chrome-stable\", source: \"path\" },\n\t\t{ label: \"Chromium\", executable: \"chromium\", source: \"path\" },\n\t\t{ label: \"Chromium Browser\", executable: \"chromium-browser\", source: \"path\" },\n\t\t{ label: \"Brave Browser\", executable: \"brave-browser\", source: \"path\" },\n\t\t{ label: \"Brave\", executable: \"brave\", source: \"path\" },\n\t\t{ label: \"Microsoft Edge\", executable: \"microsoft-edge\", source: \"path\" },\n\t\t{ label: \"Microsoft Edge Stable\", executable: \"microsoft-edge-stable\", source: \"path\" },\n\t];\n}\n\nfunction windowsBrowserCandidateDefinitions(): BrowserCandidateDefinition[] {\n\tconst programFiles = [\n\t\tprocess.env.PROGRAMFILES,\n\t\tprocess.env[\"PROGRAMFILES(X86)\"],\n\t\tprocess.env.LOCALAPPDATA,\n\t].filter((value): value is string => typeof value === \"string\" && value.length > 0);\n\tconst wellKnownPaths = programFiles.flatMap((root) => [\n\t\tjoin(root, \"Google\", \"Chrome\", \"Application\", \"chrome.exe\"),\n\t\tjoin(root, \"Chromium\", \"Application\", \"chrome.exe\"),\n\t\tjoin(root, \"BraveSoftware\", \"Brave-Browser\", \"Application\", \"brave.exe\"),\n\t\tjoin(root, \"Microsoft\", \"Edge\", \"Application\", \"msedge.exe\"),\n\t]);\n\treturn [\n\t\t...wellKnownPaths.map((executable) => ({\n\t\t\tlabel: browserLabelFromExecutable(executable),\n\t\t\texecutable,\n\t\t\tsource: \"wellKnownPath\" as const,\n\t\t})),\n\t\t{ label: \"Google Chrome\", executable: \"chrome.exe\", source: \"path\" },\n\t\t{ label: \"Chromium\", executable: \"chromium.exe\", source: \"path\" },\n\t\t{ label: \"Brave Browser\", executable: \"brave.exe\", source: \"path\" },\n\t\t{ label: \"Microsoft Edge\", executable: \"msedge.exe\", source: \"path\" },\n\t];\n}\n\nfunction browserLabelFromExecutable(executable: string) {\n\tconst normalizedExecutable = normalizePathForComparison(executable);\n\tif (normalizedExecutable.includes(\"brave\")) return \"Brave Browser\";\n\tif (normalizedExecutable.includes(\"edge\") || normalizedExecutable.includes(\"msedge\")) {\n\t\treturn \"Microsoft Edge\";\n\t}\n\tif (normalizedExecutable.includes(\"chromium\")) return \"Chromium\";\n\treturn \"Google Chrome\";\n}\n\nfunction uniqueBrowserCandidates(candidates: BrowserCandidateDefinition[]) {\n\tconst seen = new Set<string>();\n\treturn candidates.filter((candidate) => {\n\t\tconst key = normalizePathForComparison(candidate.executable);\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\treturn true;\n\t});\n}\n\nasync function resolveBrowserCandidates(\n\tdefinitions: BrowserCandidateDefinition[],\n\tgeneration: number,\n\tsignal: AbortSignal,\n\towner?: object,\n) {\n\tconst candidates: BrowserCandidate[] = [];\n\tfor (const definition of definitions) {\n\t\tconst resolvedExecutable = await resolveBrowserExecutable(definition.executable);\n\t\tthrowIfBrowserLaunchCancelled(generation, signal, owner);\n\t\tif (!resolvedExecutable) continue;\n\t\tcandidates.push({ ...definition, resolvedExecutable });\n\t}\n\treturn uniqueBrowserCandidatesByResolvedPath(candidates);\n}\n\nfunction uniqueBrowserCandidatesByResolvedPath(candidates: BrowserCandidate[]) {\n\tconst seen = new Set<string>();\n\treturn candidates.filter((candidate) => {\n\t\tconst key = normalizePathForComparison(resolve(candidate.resolvedExecutable));\n\t\tif (seen.has(key)) return false;\n\t\tseen.add(key);\n\t\treturn true;\n\t});\n}\n\nasync function resolveBrowserExecutable(executable: string) {\n\tif (hasPathSeparator(executable) || isAbsolute(executable)) {\n\t\tconst resolvedExecutable = isAbsolute(executable) ? executable : resolve(executable);\n\t\treturn (await canAccessExecutable(resolvedExecutable)) ? resolvedExecutable : undefined;\n\t}\n\n\tfor (const directory of executableSearchPath()) {\n\t\tfor (const executableName of executableSearchNames(executable)) {\n\t\t\tconst candidate = join(directory, executableName);\n\t\t\tif (await canAccessExecutable(candidate)) return candidate;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction hasPathSeparator(path: string) {\n\treturn path.includes(\"/\") || path.includes(\"\\\\\");\n}\n\nfunction executableSearchPath() {\n\treturn (process.env.PATH ?? \"\").split(delimiter).filter((part) => part.length > 0);\n}\n\nfunction executableSearchNames(executable: string) {\n\tif (process.platform !== \"win32\" || /\\.[a-z0-9]+$/i.test(executable)) return [executable];\n\treturn [executable, `${executable}.exe`, `${executable}.cmd`, `${executable}.bat`];\n}\n\nasync function canAccessExecutable(path: string) {\n\ttry {\n\t\tawait browserManagerOperations.access(\n\t\t\tpath,\n\t\t\tprocess.platform === \"win32\" ? constants.F_OK : constants.X_OK,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction formatBrowserCandidate(candidate: BrowserCandidate) {\n\treturn `${candidate.label} (${candidate.resolvedExecutable})`;\n}\n\nfunction formatBrowserCandidateDefinition(candidate: BrowserCandidateDefinition) {\n\treturn `${candidate.label} (${candidate.executable})`;\n}\n\nfunction noBrowserCandidateMessage(candidateDefinitions: BrowserCandidateDefinition[]) {\n\tif (extensionsConfigured()) {\n\t\treturn [\n\t\t\t\"Cannot launch unpacked extensions because the configured browser executable was not found or is not executable.\",\n\t\t\t`Tried: ${candidateDefinitions.map(formatBrowserCandidateDefinition).join(\", \")}`,\n\t\t\t\"Set browser.executablePath to an executable Chrome for Testing or Chromium binary.\",\n\t\t].join(\"\\n\");\n\t}\n\treturn [\n\t\t\"Cannot auto-launch Chrome DevTools because no Chromium-family browser executable was found.\",\n\t\t`Tried: ${candidateDefinitions.map(formatBrowserCandidateDefinition).join(\", \")}`,\n\t\tendpointConfigHint(),\n\t].join(\"\\n\");\n}\n\nexport function formatPageListItem(page: DevToolsPage) {\n\treturn `- ${page.id}: ${page.title || \"(untitled)\"} ${page.url}`;\n}\n\nfunction abortableSleep(ms: number, signal?: AbortSignal) {\n\treturn new Promise<void>((resolveSleep, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(signal.reason);\n\t\t\treturn;\n\t\t}\n\t\tconst timeout = setTimeout(settleResolve, ms);\n\t\tconst onAbort = () => settleReject(signal?.reason);\n\t\tfunction cleanup() {\n\t\t\tclearTimeout(timeout);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t}\n\t\tfunction settleResolve() {\n\t\t\tcleanup();\n\t\t\tresolveSleep();\n\t\t}\n\t\tfunction settleReject(reason: unknown) {\n\t\t\tcleanup();\n\t\t\treject(reason);\n\t\t}\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n}\n\nfunction inspectBrowserVersion(executable: string, signal: AbortSignal) {\n\treturn new Promise<string>((resolveVersion, reject) => {\n\t\texecFile(executable, [\"--version\"], { signal, timeout: 5_000 }, (error, stdout, stderr) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveVersion(`${stdout}${stderr}`.trim());\n\t\t});\n\t});\n}\n\nfunction isPortAvailable(host: string, port: number) {\n\treturn new Promise<boolean>((resolveAvailability, reject) => {\n\t\tconst server = createServer();\n\t\tconst normalizedHost = host.replace(/^\\[(.*)]$/, \"$1\");\n\t\tserver.unref();\n\t\tserver.once(\"error\", (error: NodeJS.ErrnoException) => {\n\t\t\tif (error.code === \"EADDRINUSE\") resolveAvailability(false);\n\t\t\telse reject(error);\n\t\t});\n\t\tserver.listen(port, normalizedHost, () => {\n\t\t\tserver.close((error) => {\n\t\t\t\tif (error) reject(error);\n\t\t\t\telse resolveAvailability(true);\n\t\t\t});\n\t\t});\n\t});\n}\n\nclass DevToolsEndpointError extends Error {\n\treadonly retryable: boolean;\n\treadonly launchable: boolean;\n\n\tconstructor(message: string, options: { retryable?: boolean; launchable?: boolean } = {}) {\n\t\tsuper(message);\n\t\tthis.name = \"DevToolsEndpointError\";\n\t\tthis.retryable = options.retryable ?? false;\n\t\tthis.launchable = options.launchable ?? false;\n\t}\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
+ }
@@ -0,0 +1,373 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ DEFAULT_ENDPOINT_WAIT_MS,
5
+ DEFAULT_TIMEOUT_MS,
6
+ devToolsEndpoint,
7
+ ensureDevToolsEndpoint,
8
+ fetchDevToolsJson,
9
+ formatPageListItem,
10
+ launchHint,
11
+ state,
12
+ withEndpointRetry
13
+ } from "./chunk-GVBXT3FB.js";
14
+
15
+ // src/cdp-client.ts
16
+ var MAX_BUFFERED_EVENTS_PER_METHOD = 32;
17
+ var MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;
18
+ async function listPages(options = {}) {
19
+ const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;
20
+ await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);
21
+ return withEndpointRetry(
22
+ async () => {
23
+ const pages = await fetchDevToolsJson(
24
+ "/json/list",
25
+ { signal: options.signal },
26
+ options.sessionOwner
27
+ );
28
+ return pages.filter((page) => page.type === "page" && page.webSocketDebuggerUrl);
29
+ },
30
+ waitMs,
31
+ options.signal
32
+ );
33
+ }
34
+ async function getPage(pageId, options = {}) {
35
+ const pages = await listPages(options);
36
+ return requirePage(pageId, pages);
37
+ }
38
+ async function resolvePage(pageId, options = {}) {
39
+ const pages = await listPages(options);
40
+ if (pageId) return requirePage(pageId, pages);
41
+ const page = resolveDefaultPage(pages);
42
+ if (!page) {
43
+ throw new Error(
44
+ [
45
+ `No Chrome pages found at ${devToolsEndpoint(options.sessionOwner)}.`,
46
+ "Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.",
47
+ launchHint()
48
+ ].join("\n")
49
+ );
50
+ }
51
+ return page;
52
+ }
53
+ async function resolvePageForNavigation(pageId, options = {}) {
54
+ const pages = await listPages(options);
55
+ if (pageId) return { created: false, page: requirePage(pageId, pages) };
56
+ const page = resolveDefaultPage(pages);
57
+ if (page) return { created: false, page };
58
+ return { created: true, page: await createPage("about:blank", options) };
59
+ }
60
+ function resolveDefaultPage(pages) {
61
+ if (!state.activePageId) return pages[0];
62
+ const activePage = pages.find((candidate) => candidate.id === state.activePageId);
63
+ if (activePage) return activePage;
64
+ state.activePageId = void 0;
65
+ return pages[0];
66
+ }
67
+ function requirePage(pageId, pages) {
68
+ const page = pages.find((candidate) => candidate.id === pageId);
69
+ if (page) return page;
70
+ const availablePages = pages.map(formatPageListItem).join("\n");
71
+ throw new Error(
72
+ [
73
+ `Chrome DevTools page not found: ${pageId}.`,
74
+ availablePages ? `Available pages:
75
+ ${availablePages}` : "No inspectable Chrome pages are currently available."
76
+ ].join("\n")
77
+ );
78
+ }
79
+ async function createPage(url, options = {}) {
80
+ const waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;
81
+ await ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);
82
+ const page = await withEndpointRetry(
83
+ () => fetchDevToolsJson(
84
+ `/json/new?${encodeURIComponent(url)}`,
85
+ { method: "PUT", signal: options.signal },
86
+ options.sessionOwner
87
+ ),
88
+ waitMs,
89
+ options.signal
90
+ );
91
+ if (page.type !== "page" || !page.webSocketDebuggerUrl) {
92
+ throw new Error("Chrome DevTools created a target that is not an inspectable page.");
93
+ }
94
+ return page;
95
+ }
96
+ function formatPage(page) {
97
+ return {
98
+ id: page.id,
99
+ type: page.type,
100
+ title: page.title,
101
+ url: page.url
102
+ };
103
+ }
104
+ function textResult(text, details) {
105
+ return {
106
+ content: [{ type: "text", text }],
107
+ details
108
+ };
109
+ }
110
+ async function withCdp(page, callback, options = {}) {
111
+ if (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);
112
+ const client = await CdpClient.connect(page.webSocketDebuggerUrl, options);
113
+ try {
114
+ return await callback(client);
115
+ } finally {
116
+ client.close();
117
+ }
118
+ }
119
+ var CdpClient = class _CdpClient {
120
+ #closed = false;
121
+ #eventBuffers = /* @__PURE__ */ new Map();
122
+ #eventWaiters = /* @__PURE__ */ new Set();
123
+ #nextId = 1;
124
+ #pending = /* @__PURE__ */ new Map();
125
+ #socket;
126
+ constructor(socket) {
127
+ this.#socket = socket;
128
+ socket.addEventListener("message", this.onMessage);
129
+ socket.addEventListener("close", this.onClose);
130
+ socket.addEventListener("error", this.onError);
131
+ }
132
+ static connect(url, options = {}) {
133
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
134
+ const WebSocketImplementation = options.webSocketConstructor ?? WebSocket;
135
+ options.signal?.throwIfAborted();
136
+ return new Promise((resolve, reject) => {
137
+ const socket = new WebSocketImplementation(url);
138
+ let settled = false;
139
+ const settle = (callback) => {
140
+ if (settled) return;
141
+ settled = true;
142
+ clearTimeout(timeout);
143
+ options.signal?.removeEventListener("abort", onAbort);
144
+ socket.removeEventListener("open", onOpen);
145
+ socket.removeEventListener("error", onConnectError);
146
+ callback();
147
+ };
148
+ const onOpen = () => settle(() => resolve(new _CdpClient(socket)));
149
+ const onConnectError = () => settle(() => {
150
+ socket.close();
151
+ reject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));
152
+ });
153
+ const onAbort = () => settle(() => {
154
+ socket.close();
155
+ reject(options.signal?.reason ?? abortError("Chrome DevTools connection aborted"));
156
+ });
157
+ const timeout = setTimeout(
158
+ () => settle(() => {
159
+ socket.close();
160
+ reject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));
161
+ }),
162
+ timeoutMs
163
+ );
164
+ options.signal?.addEventListener("abort", onAbort, { once: true });
165
+ socket.addEventListener("open", onOpen, { once: true });
166
+ socket.addEventListener("error", onConnectError, { once: true });
167
+ });
168
+ }
169
+ send(method, params = {}, options = {}) {
170
+ this.throwIfClosed();
171
+ options.signal?.throwIfAborted();
172
+ const id = this.#nextId;
173
+ this.#nextId += 1;
174
+ return new Promise((resolve, reject) => {
175
+ const onAbort = () => {
176
+ this.#pending.delete(id);
177
+ cleanup();
178
+ reject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));
179
+ };
180
+ const timeout = setTimeout(() => {
181
+ this.#pending.delete(id);
182
+ options.signal?.removeEventListener("abort", onAbort);
183
+ reject(new Error(`Timed out waiting for CDP response: ${method}`));
184
+ }, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
185
+ const cleanup = () => {
186
+ clearTimeout(timeout);
187
+ options.signal?.removeEventListener("abort", onAbort);
188
+ };
189
+ this.#pending.set(id, {
190
+ cleanup,
191
+ reject,
192
+ resolve
193
+ });
194
+ options.signal?.addEventListener("abort", onAbort, { once: true });
195
+ try {
196
+ this.#socket.send(JSON.stringify({ id, method, params }));
197
+ } catch (error) {
198
+ this.#pending.delete(id);
199
+ cleanup();
200
+ reject(error);
201
+ }
202
+ });
203
+ }
204
+ waitForEvent(method, predicate, options = {}) {
205
+ this.throwIfClosed();
206
+ options.signal?.throwIfAborted();
207
+ const buffered = this.#eventBuffers.get(method) ?? [];
208
+ for (const [index, params] of buffered.entries()) {
209
+ if (!predicate(params)) continue;
210
+ buffered.splice(index, 1);
211
+ if (buffered.length === 0) this.#eventBuffers.delete(method);
212
+ return Promise.resolve(params);
213
+ }
214
+ return new Promise((resolve, reject) => {
215
+ const waiter = {};
216
+ const onAbort = () => {
217
+ this.#eventWaiters.delete(waiter);
218
+ cleanup();
219
+ reject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));
220
+ };
221
+ const timeout = setTimeout(() => {
222
+ this.#eventWaiters.delete(waiter);
223
+ options.signal?.removeEventListener("abort", onAbort);
224
+ reject(new Error(`Timed out waiting for CDP event: ${method}`));
225
+ }, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
226
+ const cleanup = () => {
227
+ clearTimeout(timeout);
228
+ options.signal?.removeEventListener("abort", onAbort);
229
+ };
230
+ Object.assign(waiter, { cleanup, method, predicate, reject, resolve });
231
+ this.#eventWaiters.add(waiter);
232
+ options.signal?.addEventListener("abort", onAbort, { once: true });
233
+ });
234
+ }
235
+ close(reason = new Error("Chrome DevTools WebSocket closed")) {
236
+ if (this.#closed) return;
237
+ this.#closed = true;
238
+ this.#socket.removeEventListener("message", this.onMessage);
239
+ this.#socket.removeEventListener("close", this.onClose);
240
+ this.#socket.removeEventListener("error", this.onError);
241
+ this.rejectAll(reason);
242
+ this.#eventBuffers.clear();
243
+ try {
244
+ this.#socket.close();
245
+ } catch {
246
+ }
247
+ }
248
+ onClose = () => {
249
+ this.close(new Error("Chrome DevTools WebSocket closed"));
250
+ };
251
+ onError = () => {
252
+ this.close(new Error("Chrome DevTools WebSocket error"));
253
+ };
254
+ onMessage = (event) => {
255
+ if (typeof event.data !== "string") {
256
+ this.close(new Error("Chrome DevTools WebSocket sent an unsupported binary message"));
257
+ return;
258
+ }
259
+ if (event.data.length > MAX_CDP_MESSAGE_BYTES || Buffer.byteLength(event.data, "utf8") > MAX_CDP_MESSAGE_BYTES) {
260
+ this.close(new Error("Chrome DevTools WebSocket message exceeds the 8 MB limit"));
261
+ return;
262
+ }
263
+ let payload;
264
+ try {
265
+ payload = JSON.parse(event.data);
266
+ } catch {
267
+ this.close(new Error("Chrome DevTools WebSocket sent malformed JSON"));
268
+ return;
269
+ }
270
+ if (!isRecord(payload)) {
271
+ this.close(new Error("Chrome DevTools WebSocket sent a malformed message"));
272
+ return;
273
+ }
274
+ if (typeof payload.id === "number") {
275
+ this.handleResponse(payload);
276
+ return;
277
+ }
278
+ if (typeof payload.method !== "string") {
279
+ this.close(new Error("Chrome DevTools WebSocket sent a malformed event"));
280
+ return;
281
+ }
282
+ this.handleEvent(payload);
283
+ };
284
+ handleResponse(response) {
285
+ const pending = this.#pending.get(response.id);
286
+ if (!pending) return;
287
+ this.#pending.delete(response.id);
288
+ pending.cleanup();
289
+ if (response.error) {
290
+ pending.reject(
291
+ new Error(
292
+ `CDP error ${response.error.code}: ${response.error.message}${response.error.data === void 0 ? "" : ` (${safeJson(response.error.data)})`}`
293
+ )
294
+ );
295
+ return;
296
+ }
297
+ pending.resolve(response.result);
298
+ }
299
+ handleEvent(event) {
300
+ if (event.method === "Inspector.detached" || event.method === "Target.detachedFromTarget") {
301
+ this.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));
302
+ return;
303
+ }
304
+ for (const waiter of this.#eventWaiters) {
305
+ if (waiter.method !== event.method) continue;
306
+ let matched;
307
+ try {
308
+ matched = waiter.predicate(event.params);
309
+ } catch (error) {
310
+ this.#eventWaiters.delete(waiter);
311
+ waiter.cleanup();
312
+ waiter.reject(error);
313
+ return;
314
+ }
315
+ if (!matched) continue;
316
+ this.#eventWaiters.delete(waiter);
317
+ waiter.cleanup();
318
+ waiter.resolve(event.params);
319
+ return;
320
+ }
321
+ const buffer = this.#eventBuffers.get(event.method) ?? [];
322
+ buffer.push(event.params);
323
+ if (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {
324
+ this.close(
325
+ new Error(
326
+ `Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`
327
+ )
328
+ );
329
+ return;
330
+ }
331
+ this.#eventBuffers.set(event.method, buffer);
332
+ }
333
+ rejectAll(reason) {
334
+ for (const [id, pending] of this.#pending) {
335
+ this.#pending.delete(id);
336
+ pending.cleanup();
337
+ pending.reject(reason);
338
+ }
339
+ for (const waiter of this.#eventWaiters) {
340
+ this.#eventWaiters.delete(waiter);
341
+ waiter.cleanup();
342
+ waiter.reject(reason);
343
+ }
344
+ }
345
+ throwIfClosed() {
346
+ if (this.#closed) throw new Error("Chrome DevTools WebSocket is closed");
347
+ }
348
+ };
349
+ function abortError(message) {
350
+ return new DOMException(message, "AbortError");
351
+ }
352
+ function isRecord(value) {
353
+ return typeof value === "object" && value !== null && !Array.isArray(value);
354
+ }
355
+ function safeJson(value) {
356
+ try {
357
+ return JSON.stringify(value);
358
+ } catch {
359
+ return String(value);
360
+ }
361
+ }
362
+
363
+ export {
364
+ listPages,
365
+ getPage,
366
+ resolvePage,
367
+ resolvePageForNavigation,
368
+ formatPage,
369
+ textResult,
370
+ withCdp,
371
+ CdpClient
372
+ };
373
+ //# sourceMappingURL=chunk-RTECHAEZ.js.map