@narumitw/pi-chrome-devtools 0.53.2 → 0.53.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/chunks/{browser-settings-menu-IMB6HXSU.js → browser-settings-menu-FVMCCUPM.ts} +16 -42
- package/dist/chunks/browser-settings-menu-FVMCCUPM.ts.map +7 -0
- package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4B3EQHOH.ts} +2 -2
- package/dist/chunks/chunk-4B3EQHOH.ts.map +7 -0
- package/dist/chunks/{chunk-SRT3UUIP.js → chunk-LSJSDY2M.ts} +23 -74
- package/dist/chunks/chunk-LSJSDY2M.ts.map +7 -0
- package/dist/chunks/{chunk-LLXOCRNF.js → chunk-V7N3WI5B.ts} +12 -33
- package/dist/chunks/chunk-V7N3WI5B.ts.map +7 -0
- package/dist/chunks/{menu-UJETYMSB.js → menu-MTPSLDHZ.ts} +10 -23
- package/dist/chunks/menu-MTPSLDHZ.ts.map +7 -0
- package/dist/chunks/{tools-6P7EUX37.js → tools-OVNH45IJ.ts} +17 -59
- package/dist/chunks/tools-OVNH45IJ.ts.map +7 -0
- package/dist/index.ts +18 -42
- package/dist/index.ts.map +2 -2
- package/package.json +54 -55
- package/src/browser-manager.ts +872 -942
- package/src/browser-settings-menu.ts +315 -350
- package/src/cdp-client.ts +381 -398
- package/src/chrome-devtools.ts +205 -232
- package/src/display.ts +26 -29
- package/src/lazy-tools.ts +158 -181
- package/src/menu.ts +409 -446
- package/src/render.ts +72 -81
- package/src/runtime.ts +137 -140
- package/src/screenshot.ts +170 -186
- package/src/settings.ts +472 -523
- package/src/tool-names.ts +8 -14
- package/src/tool-selector.ts +242 -271
- package/src/tools.ts +218 -226
- package/src/webmcp/discovery.ts +184 -188
- package/src/webmcp/policy.ts +296 -329
- package/src/webmcp/protocol.ts +324 -337
- package/src/webmcp/tools.ts +136 -147
- package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +0 -7
- package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
- package/dist/chunks/chunk-LLXOCRNF.js.map +0 -7
- package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
- package/dist/chunks/menu-UJETYMSB.js.map +0 -7
- package/dist/chunks/tools-6P7EUX37.js.map +0 -7
|
@@ -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 \"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
|
+
}
|
|
@@ -20,12 +20,10 @@ import {
|
|
|
20
20
|
settingsFilePath,
|
|
21
21
|
state,
|
|
22
22
|
webMcpEnabled
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-LSJSDY2M.ts";
|
|
24
24
|
|
|
25
25
|
// src/lazy-tools.ts
|
|
26
|
-
import {
|
|
27
|
-
defineTool
|
|
28
|
-
} from "@earendil-works/pi-coding-agent";
|
|
26
|
+
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
29
27
|
import { Type } from "typebox";
|
|
30
28
|
var CHROME_DEVTOOLS_LOAD_TOOL_NAME = "chrome_devtools_load";
|
|
31
29
|
var AVAILABLE_TOOLS_STORE = /* @__PURE__ */ Symbol.for("@narumitw/pi-chrome-devtools.available-tools-store");
|
|
@@ -62,9 +60,7 @@ function configureChromeDevtoolsToolExposure(pi, availableTools, model) {
|
|
|
62
60
|
lazyExposureByApi.set(pi, lazyExposure);
|
|
63
61
|
const exposedTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));
|
|
64
62
|
const nonCapabilityTools = pi.getActiveTools().filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name));
|
|
65
|
-
pi.setActiveTools(
|
|
66
|
-
unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools])
|
|
67
|
-
);
|
|
63
|
+
pi.setActiveTools(unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools]));
|
|
68
64
|
}
|
|
69
65
|
function requireEagerChromeDevtoolsToolExposure(pi) {
|
|
70
66
|
lazyExposureByApi.set(pi, false);
|
|
@@ -88,6 +84,7 @@ function chromeDevtoolsToolExposureMode(pi) {
|
|
|
88
84
|
function supportsNativeDeferredToolLoading(model) {
|
|
89
85
|
if (!model) return false;
|
|
90
86
|
if (model.api === "anthropic-messages") {
|
|
87
|
+
if (model.provider === "fireworks") return false;
|
|
91
88
|
const configured = compatBoolean(model.compat, "supportsToolReferences");
|
|
92
89
|
if (configured !== void 0) return configured;
|
|
93
90
|
if (model.provider !== "anthropic" || model.id.includes("haiku")) return false;
|
|
@@ -173,9 +170,7 @@ function effectiveAvailableTools(pi) {
|
|
|
173
170
|
const owner = sessionOwnerByApi.get(pi);
|
|
174
171
|
const enabled = owner !== void 0 && webMcpEnabled(owner);
|
|
175
172
|
return new Set(
|
|
176
|
-
CHROME_DEVTOOLS_TOOL_NAMES.filter(
|
|
177
|
-
(name) => configured.has(name) && (enabled || !isWebMcpToolName(name))
|
|
178
|
-
)
|
|
173
|
+
CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => configured.has(name) && (enabled || !isWebMcpToolName(name)))
|
|
179
174
|
);
|
|
180
175
|
}
|
|
181
176
|
function compatBoolean(value, key) {
|
|
@@ -240,13 +235,7 @@ async function updateChromeDevtoolsTools(pi, ctx, selectedTools, action) {
|
|
|
240
235
|
${status}`, "info");
|
|
241
236
|
}
|
|
242
237
|
async function setSelectedChromeDevtoolsTools(pi, ctx, selectedTools, expectedActiveTools) {
|
|
243
|
-
return transactSelectedTools(
|
|
244
|
-
pi,
|
|
245
|
-
ctx,
|
|
246
|
-
selectedTools,
|
|
247
|
-
state.sessionGeneration,
|
|
248
|
-
expectedActiveTools
|
|
249
|
-
);
|
|
238
|
+
return transactSelectedTools(pi, ctx, selectedTools, state.sessionGeneration, expectedActiveTools);
|
|
250
239
|
}
|
|
251
240
|
var toolTransactionQueue = Promise.resolve();
|
|
252
241
|
async function waitForChromeDevtoolsSettings() {
|
|
@@ -277,10 +266,7 @@ async function transactSelectedToolsNow(pi, ctx, selectedTools, expectedGenerati
|
|
|
277
266
|
const previousWebMcpTools = previousAvailableTools.filter(isWebMcpToolName);
|
|
278
267
|
const selectedWebMcpTools = selectedTools.filter(isWebMcpToolName);
|
|
279
268
|
if (!arraysEqual(previousWebMcpTools, selectedWebMcpTools)) {
|
|
280
|
-
invalidateWebMcpOperations(
|
|
281
|
-
ctx.sessionManager,
|
|
282
|
-
"Chrome DevTools WebMCP gateway availability changed"
|
|
283
|
-
);
|
|
269
|
+
invalidateWebMcpOperations(ctx.sessionManager, "Chrome DevTools WebMCP gateway availability changed");
|
|
284
270
|
}
|
|
285
271
|
applyChromeDevtoolsTools(pi, selectedTools);
|
|
286
272
|
await persistSettings(selectedTools);
|
|
@@ -317,9 +303,7 @@ function applyChromeDevtoolsTools(pi, selectedTools) {
|
|
|
317
303
|
function getToolStatusSummary(pi, owner) {
|
|
318
304
|
const chromeToolNames = new Set(CHROME_DEVTOOLS_TOOL_NAMES);
|
|
319
305
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
320
|
-
const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter(
|
|
321
|
-
(name) => activeToolNames.has(name)
|
|
322
|
-
).length;
|
|
306
|
+
const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeToolNames.has(name)).length;
|
|
323
307
|
const availableChromeToolCount = availableChromeDevtoolsTools(pi).length;
|
|
324
308
|
const activeNonChromeToolCount = Array.from(activeToolNames).filter(
|
|
325
309
|
(name) => !chromeToolNames.has(name) && name !== CHROME_DEVTOOLS_LOAD_TOOL_NAME
|
|
@@ -373,9 +357,7 @@ function buildBrowserStatusMessage(owner) {
|
|
|
373
357
|
`Launch mode: ${launchModeLabel(owner)}`,
|
|
374
358
|
`Unpacked extensions: ${browser.extensionPaths.length} (${browser.extensionPathsSource})`,
|
|
375
359
|
`WebMCP: ${webMcpIsEnabled ? "enabled \xB7 experimental" : "disabled \xB7 experimental"}`,
|
|
376
|
-
...webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready ? [
|
|
377
|
-
"WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state."
|
|
378
|
-
] : [],
|
|
360
|
+
...webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready ? ["WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state."] : [],
|
|
379
361
|
...browser.extensionPaths.length > 0 ? ["Unpacked extensions execute trusted browser code in an isolated managed browser."] : [],
|
|
380
362
|
...launchAttemptLines(owner),
|
|
381
363
|
...needsRecovery ? [launchHint(owner), endpointConfigHint()] : []
|
|
@@ -411,9 +393,7 @@ function browserSettingsStatusLines(owner) {
|
|
|
411
393
|
...extensionLines,
|
|
412
394
|
`WebMCP: ${webMcpEnabled(owner) ? "enabled \xB7 experimental \xB7 every call requires confirmation" : "disabled \xB7 experimental"}`,
|
|
413
395
|
"Confirmed menu settings apply before the next browser connection; manual JSON edits require /reload or session replacement.",
|
|
414
|
-
...extensionPaths.length > 0 ? [
|
|
415
|
-
"Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code."
|
|
416
|
-
] : []
|
|
396
|
+
...extensionPaths.length > 0 ? ["Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code."] : []
|
|
417
397
|
];
|
|
418
398
|
}
|
|
419
399
|
function buildCommandGuide(owner) {
|
|
@@ -451,8 +431,7 @@ function formatPersistedSelection(tools) {
|
|
|
451
431
|
if (tools.length === CHROME_DEVTOOLS_TOOL_NAMES.length) {
|
|
452
432
|
return `all available (${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
453
433
|
}
|
|
454
|
-
if (tools.length === 0)
|
|
455
|
-
return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
434
|
+
if (tools.length === 0) return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
456
435
|
return `${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected: ${tools.join(", ")}`;
|
|
457
436
|
}
|
|
458
437
|
function effectiveCatalog(owner) {
|
|
@@ -482,4 +461,4 @@ export {
|
|
|
482
461
|
buildCommandGuide,
|
|
483
462
|
allChromeDevtoolsTools
|
|
484
463
|
};
|
|
485
|
-
//# sourceMappingURL=chunk-
|
|
464
|
+
//# sourceMappingURL=chunk-V7N3WI5B.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lazy-tools.ts", "../../src/display.ts", "../../src/tool-selector.ts"],
|
|
4
|
+
"sourcesContent": ["import { defineTool, type ExtensionAPI, type ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { Type } from \"typebox\";\nimport { webMcpEnabled } from \"./runtime.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName, isWebMcpToolName } from \"./tool-names.js\";\n\nexport const CHROME_DEVTOOLS_LOAD_TOOL_NAME = \"chrome_devtools_load\";\n\nconst AVAILABLE_TOOLS_STORE = Symbol.for(\"@narumitw/pi-chrome-devtools.available-tools-store\");\ntype ChromeDevtoolsGlobal = typeof globalThis & {\n [AVAILABLE_TOOLS_STORE]?: WeakMap<ExtensionAPI, Set<ChromeDevToolsToolName>>;\n};\nconst sharedGlobal = globalThis as ChromeDevtoolsGlobal;\nconst existingAvailableToolsStore = sharedGlobal[AVAILABLE_TOOLS_STORE];\nconst availableToolsByApi = existingAvailableToolsStore ?? new WeakMap<ExtensionAPI, Set<ChromeDevToolsToolName>>();\nif (!existingAvailableToolsStore) sharedGlobal[AVAILABLE_TOOLS_STORE] = availableToolsByApi;\nconst lazyExposureByApi = new WeakMap<ExtensionAPI, boolean>();\nconst sessionOwnerByApi = new WeakMap<ExtensionAPI, object>();\n\nconst SEARCH_TEXT: Record<ChromeDevToolsToolName, string> = {\n chrome_devtools_list_pages: \"list open inspectable chrome browser pages tabs targets\",\n chrome_devtools_select_page: \"select choose active chrome browser page tab target\",\n chrome_devtools_navigate: \"navigate open create chrome browser page url website\",\n chrome_devtools_evaluate: \"evaluate run javascript expression dom inspect chrome browser page\",\n chrome_devtools_screenshot: \"capture screenshot png image visual chrome browser page\",\n chrome_devtools_webmcp_list_tools: \"list discover page provided website webmcp tools capabilities experimental\",\n chrome_devtools_webmcp_call_tool: \"call invoke page provided website webmcp tool confirmation experimental\",\n};\n\nexport function setChromeDevtoolsSessionOwner(pi: ExtensionAPI, owner: object) {\n sessionOwnerByApi.set(pi, owner);\n}\n\nexport function initializeAvailableChromeDevtoolsTools(pi: ExtensionAPI) {\n if (availableToolsByApi.has(pi)) return;\n const activeTools = new Set(pi.getActiveTools());\n setAvailableTools(\n pi,\n CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeTools.has(name)),\n );\n}\n\nexport function configureChromeDevtoolsToolExposure(\n pi: ExtensionAPI,\n availableTools: readonly ChromeDevToolsToolName[],\n model?: ExtensionContext[\"model\"],\n) {\n setAvailableTools(pi, availableTools);\n const available = effectiveAvailableTools(pi);\n const lazyExposure = supportsNativeDeferredToolLoading(model);\n lazyExposureByApi.set(pi, lazyExposure);\n const exposedTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n const nonCapabilityTools = pi\n .getActiveTools()\n .filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));\n pi.setActiveTools(unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools]));\n}\n\nexport function requireEagerChromeDevtoolsToolExposure(pi: ExtensionAPI) {\n lazyExposureByApi.set(pi, false);\n const active = pi.getActiveTools();\n const available = availableChromeDevtoolsTools(pi);\n pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...available]));\n}\n\nexport function applyAvailableChromeDevtoolsTools(pi: ExtensionAPI, availableTools: readonly ChromeDevToolsToolName[]) {\n setAvailableTools(pi, availableTools);\n const available = effectiveAvailableTools(pi);\n const lazyExposure = lazyExposureByApi.get(pi) === true;\n const active = pi\n .getActiveTools()\n .filter(\n (name) =>\n !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName) ||\n (lazyExposure && available.has(name as ChromeDevToolsToolName)),\n );\n const eagerTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...eagerTools]));\n}\n\nexport function chromeDevtoolsToolExposureMode(pi: ExtensionAPI) {\n return lazyExposureByApi.get(pi) === true ? \"native deferred\" : \"eager\";\n}\n\nexport function supportsNativeDeferredToolLoading(model: ExtensionContext[\"model\"]): boolean {\n if (!model) return false;\n if (model.api === \"anthropic-messages\") {\n // Fireworks Messages requires the canonical ToolSearch/tool_search loader name.\n // chrome_devtools_load stays package-specific so independently installed loaders cannot collide.\n if (model.provider === \"fireworks\") return false;\n const configured = compatBoolean(model.compat, \"supportsToolReferences\");\n if (configured !== undefined) return configured;\n if (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n if (!version) return false;\n const major = Number(version[1]);\n const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n return major > 4 || (major === 4 && minor >= 5);\n }\n if (model.api === \"openai-completions\") {\n return compatString(model.compat, \"deferredToolsMode\") === \"kimi\";\n }\n if (model.api === \"openai-responses\" || model.api === \"openai-codex-responses\") {\n return (\n compatBoolean(model.compat, \"supportsAdditionalTools\") === true ||\n compatBoolean(model.compat, \"supportsToolSearch\") === true\n );\n }\n return false;\n}\n\nexport function availableChromeDevtoolsTools(pi: ExtensionAPI) {\n const available = effectiveAvailableTools(pi);\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n}\n\nexport function configuredChromeDevtoolsTools(pi: ExtensionAPI) {\n const available = availableToolsByApi.get(pi) ?? new Set();\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n}\n\nexport function createChromeDevtoolsLoadTool(pi: ExtensionAPI) {\n return defineTool({\n name: CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n label: \"Chrome DevTools: Load Tools\",\n description:\n \"Find and enable Chrome DevTools browser tools relevant to a task. Loaded tools remain available for the session.\",\n promptSnippet: \"Load Chrome DevTools browser capabilities on demand\",\n promptGuidelines: [\n \"Use chrome_devtools_load when a task requires inspecting or controlling a Chrome browser and the needed chrome_devtools_* capability is not active.\",\n ],\n parameters: Type.Object({\n query: Type.String({\n description: \"Browser capability or task to find tools for.\",\n maxLength: 500,\n }),\n limit: Type.Optional(\n Type.Integer({\n description: \"Maximum tools to load. Defaults to 3.\",\n minimum: 1,\n maximum: 5,\n }),\n ),\n }),\n async execute(_toolCallId, params, signal, _onUpdate, ctx) {\n signal?.throwIfAborted();\n setChromeDevtoolsSessionOwner(pi, ctx.sessionManager);\n const available = new Set(availableChromeDevtoolsTools(pi));\n const matches = matchChromeDevtoolsTools(params.query, params.limit ?? 3, available);\n const active = pi.getActiveTools();\n const activeSet = new Set(active);\n const added = matches.filter((name) => !activeSet.has(name));\n if (added.length > 0) {\n pi.setActiveTools(unique([...active, ...added]));\n }\n\n const text =\n matches.length === 0\n ? \"No available Chrome DevTools tools matched the query.\"\n : added.length > 0\n ? `Loaded Chrome DevTools tools: ${added.join(\", \")}`\n : `Matching Chrome DevTools tools are already loaded: ${matches.join(\", \")}`;\n return {\n content: [{ type: \"text\" as const, text }],\n details: { matches, added },\n };\n },\n });\n}\n\nfunction matchChromeDevtoolsTools(query: string, limit: number, available: ReadonlySet<ChromeDevToolsToolName>) {\n const terms = query\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((term) => term.length >= 2);\n if (terms.length === 0) return [];\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name))\n .map((name, index) => ({\n name,\n index,\n score: terms.reduce((score, term) => score + (SEARCH_TEXT[name].includes(term) ? 1 : 0), 0),\n }))\n .filter((match) => match.score > 0)\n .sort((left, right) => right.score - left.score || left.index - right.index)\n .slice(0, limit)\n .map((match) => match.name);\n}\n\nfunction setAvailableTools(pi: ExtensionAPI, availableTools: readonly ChromeDevToolsToolName[]) {\n const available = new Set(availableTools);\n availableToolsByApi.set(pi, available);\n return available;\n}\n\nfunction effectiveAvailableTools(pi: ExtensionAPI) {\n const configured = availableToolsByApi.get(pi) ?? new Set();\n const owner = sessionOwnerByApi.get(pi);\n const enabled = owner !== undefined && webMcpEnabled(owner);\n return new Set(\n CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => configured.has(name) && (enabled || !isWebMcpToolName(name))),\n );\n}\n\nfunction compatBoolean(value: unknown, key: string) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n return typeof record[key] === \"boolean\" ? record[key] : undefined;\n}\n\nfunction compatString(value: unknown, key: string) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n return typeof record[key] === \"string\" ? record[key] : undefined;\n}\n\nfunction unique(values: readonly string[]) {\n return [...new Set(values)];\n}\n", "const MAX_SANITIZER_INPUT_CODE_UNITS = 50_000;\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport function sanitizeChromeDevtoolsDisplay(value: string, maxCharacters = 50_000) {\n const inputWasTruncated = value.length > MAX_SANITIZER_INPUT_CODE_UNITS;\n const boundedInput = inputWasTruncated ? truncateAtGraphemeBoundary(value, MAX_SANITIZER_INPUT_CODE_UNITS) : value;\n const normalizedLineEndings = boundedInput.replace(/\\r\\n/g, \"\\n\");\n // Neutralize controls without parsing untrusted terminal sequences; keep printable payload visible.\n const sanitized = Array.from(normalizedLineEndings, (character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n const unsafeControl =\n (codePoint >= 0 && codePoint <= 8) ||\n (codePoint >= 11 && codePoint <= 31) ||\n (codePoint >= 127 && codePoint <= 159);\n const unsafeBidi = (codePoint >= 0x202a && codePoint <= 0x202e) || (codePoint >= 0x2066 && codePoint <= 0x2069);\n const loneSurrogate = character.length === 1 && codePoint >= 0xd800 && codePoint <= 0xdfff;\n return unsafeControl || unsafeBidi || loneSurrogate ? \"\uFFFD\" : character;\n }).join(\"\");\n const outputLimit = Math.min(maxCharacters, MAX_SANITIZER_INPUT_CODE_UNITS);\n if (!inputWasTruncated && sanitized.length <= outputLimit) return sanitized;\n\n return `${truncateAtGraphemeBoundary(sanitized, Math.max(0, outputLimit - 1))}\u2026`;\n}\n\nfunction truncateAtGraphemeBoundary(value: string, maxCodeUnits: number) {\n if (value.length <= maxCodeUnits) return value;\n const boundedLookahead = value.slice(0, Math.max(0, maxCodeUnits) + 2);\n let safeEnd = 0;\n for (const { index, segment } of graphemeSegmenter.segment(boundedLookahead)) {\n const segmentEnd = index + segment.length;\n if (segmentEnd > maxCodeUnits) break;\n safeEnd = segmentEnd;\n }\n return value.slice(0, safeEnd);\n}\n", "import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n browserCandidateHint,\n browserLifecycleState,\n browserSettingsForOwner,\n devToolsEndpoint,\n endpointConfigHint,\n endpointSourceLabel,\n launchAttemptLines,\n launchHint,\n launchModeLabel,\n managedBrowserForOwner,\n} from \"./browser-manager.js\";\nimport { sanitizeChromeDevtoolsDisplay } from \"./display.js\";\nimport {\n applyAvailableChromeDevtoolsTools,\n availableChromeDevtoolsTools,\n CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n chromeDevtoolsToolExposureMode,\n} from \"./lazy-tools.js\";\nimport { invalidateWebMcpOperations, state, webMcpEnabled } from \"./runtime.js\";\nimport { loadSettings, saveSettings, settingsFilePath } from \"./settings.js\";\nimport {\n CHROME_DEVTOOLS_TOOL_NAMES,\n type ChromeDevToolsToolName,\n CORE_CHROME_DEVTOOLS_TOOL_NAMES,\n isWebMcpToolName,\n} from \"./tool-names.js\";\n\nexport { sanitizeChromeDevtoolsDisplay };\n\ntype CommandContext = ExtensionCommandContext;\n\nfunction unique<T>(values: T[]) {\n return Array.from(new Set(values));\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n\ninterface ToolStatusSummary {\n availabilityStatus: \"enabled\" | \"disabled\" | \"partial\";\n availableChromeToolCount: number;\n loadedChromeToolCount: number;\n activeNonChromeToolCount: number;\n capabilityCount: number;\n}\n\ntype ToolSelectionSaveResult = \"saved\" | \"active-tools-changed\" | \"failed\";\n\nexport async function updateChromeDevtoolsTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n action: string,\n) {\n const generation = state.sessionGeneration;\n const result = await transactSelectedTools(pi, ctx, selectedTools, generation);\n if (result !== \"saved\" || generation !== state.sessionGeneration) return;\n const status = await buildToolStatusMessage(pi, ctx.sessionManager);\n if (generation !== state.sessionGeneration) return;\n ctx.ui.notify(`Chrome DevTools tool catalog ${action}.\\n\\n${status}`, \"info\");\n}\n\nexport async function setSelectedChromeDevtoolsTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedActiveTools: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n return transactSelectedTools(pi, ctx, selectedTools, state.sessionGeneration, expectedActiveTools);\n}\n\nlet toolTransactionQueue = Promise.resolve();\n\nexport async function waitForChromeDevtoolsSettings(): Promise<void> {\n await toolTransactionQueue;\n}\n\nfunction transactSelectedTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedGeneration: number,\n expectedActiveTools?: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n const operation = toolTransactionQueue.then(() =>\n transactSelectedToolsNow(pi, ctx, selectedTools, expectedGeneration, expectedActiveTools),\n );\n toolTransactionQueue = operation.then(\n () => undefined,\n () => undefined,\n );\n return operation;\n}\n\nasync function transactSelectedToolsNow(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedGeneration: number,\n expectedActiveTools?: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n if (expectedGeneration !== state.sessionGeneration) return \"failed\";\n if (expectedActiveTools && !arraysEqual(availableChromeDevtoolsTools(pi), expectedActiveTools)) {\n ctx.ui.notify(\n \"Browser tool selection changed while review was open. Review the current state, then apply again.\",\n \"warning\",\n );\n return \"active-tools-changed\";\n }\n const previousActiveTools = pi.getActiveTools();\n const previousAvailableTools = availableChromeDevtoolsTools(pi);\n try {\n const previousWebMcpTools = previousAvailableTools.filter(isWebMcpToolName);\n const selectedWebMcpTools = selectedTools.filter(isWebMcpToolName);\n if (!arraysEqual(previousWebMcpTools, selectedWebMcpTools)) {\n invalidateWebMcpOperations(ctx.sessionManager, \"Chrome DevTools WebMCP gateway availability changed\");\n }\n applyChromeDevtoolsTools(pi, selectedTools);\n await persistSettings(selectedTools);\n return expectedGeneration === state.sessionGeneration ? \"saved\" : \"failed\";\n } catch (error) {\n let rollbackError: unknown;\n try {\n applyAvailableChromeDevtoolsTools(pi, previousAvailableTools);\n const currentNonChromeTools = pi\n .getActiveTools()\n .filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));\n const previousLoadedChromeTools = previousActiveTools.filter((name) =>\n CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName),\n );\n const restoredChromeTools =\n chromeDevtoolsToolExposureMode(pi) === \"eager\" ? previousAvailableTools : previousLoadedChromeTools;\n pi.setActiveTools(unique([...currentNonChromeTools, ...restoredChromeTools]));\n } catch (caught) {\n rollbackError = caught;\n }\n if (expectedGeneration !== state.sessionGeneration) return \"failed\";\n ctx.ui.notify(\n sanitizeChromeDevtoolsDisplay(\n rollbackError\n ? `Chrome DevTools settings save failed: ${formatError(error)}; active-tool rollback failed: ${formatError(rollbackError)}`\n : `Chrome DevTools settings save failed; active tools restored: ${formatError(error)}`,\n ),\n \"warning\",\n );\n return \"failed\";\n }\n}\n\nfunction arraysEqual<T>(left: readonly T[], right: readonly T[]) {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nexport function applyChromeDevtoolsTools(pi: ExtensionAPI, selectedTools: readonly ChromeDevToolsToolName[]) {\n applyAvailableChromeDevtoolsTools(pi, selectedTools);\n}\n\nfunction getToolStatusSummary(pi: ExtensionAPI, owner: object): ToolStatusSummary {\n const chromeToolNames = new Set<string>(CHROME_DEVTOOLS_TOOL_NAMES);\n const activeToolNames = new Set(pi.getActiveTools());\n const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeToolNames.has(name)).length;\n const availableChromeToolCount = availableChromeDevtoolsTools(pi).length;\n const activeNonChromeToolCount = Array.from(activeToolNames).filter(\n (name) => !chromeToolNames.has(name) && name !== CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n ).length;\n const capabilityCount = effectiveCatalog(owner).length;\n const availabilityStatus =\n availableChromeToolCount === capabilityCount ? \"enabled\" : availableChromeToolCount === 0 ? \"disabled\" : \"partial\";\n\n return {\n availabilityStatus,\n availableChromeToolCount,\n loadedChromeToolCount,\n activeNonChromeToolCount,\n capabilityCount,\n };\n}\n\nexport async function buildToolStatusMessage(pi: ExtensionAPI, owner: object) {\n const summary = getToolStatusSummary(pi, owner);\n const persistedSetting = await persistedSettingLabel();\n return sanitizeChromeDevtoolsDisplay(\n [\n `Chrome DevTools tools available: ${formatRuntimeStatus(summary)}`,\n `Tool exposure: ${chromeDevtoolsToolExposureMode(pi)}`,\n `Loaded capability tools this session: ${summary.loadedChromeToolCount}/${summary.capabilityCount}`,\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 confirmation required for every call\" : \"disabled \u00B7 experimental\"}`,\n `Loader: ${pi.getActiveTools().includes(CHROME_DEVTOOLS_LOAD_TOOL_NAME) ? \"active\" : \"inactive\"}`,\n `Persisted tool catalog: ${persistedSetting}`,\n ...browserSettingsStatusLines(owner),\n ...(state.settingsNotice ? [`Settings note: ${state.settingsNotice}`] : []),\n `Other active tools preserved: ${summary.activeNonChromeToolCount}`,\n `Endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n ...launchAttemptLines(owner),\n ].join(\"\\n\"),\n );\n}\n\nexport function buildQuickstartMessage(owner: object) {\n return buildSettingsSetupMessage(owner);\n}\n\nexport function buildBrowserStatusMessage(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n const lifecycle = browserLifecycleState(owner);\n const webMcpIsEnabled = owner ? webMcpEnabled(owner) : false;\n const browserState =\n lifecycle === \"starting\"\n ? \"starting managed browser\"\n : lifecycle === \"running\"\n ? \"managed browser running\"\n : lifecycle === \"exited\"\n ? \"managed browser exited\"\n : lifecycle === \"failed\"\n ? \"last launch failed\"\n : \"not started; connection has not been checked\";\n const needsRecovery = lifecycle === \"exited\" || lifecycle === \"failed\";\n return sanitizeChromeDevtoolsDisplay(\n [\n `Browser: ${browserState}`,\n \"Viewing this status does not probe the endpoint or launch Chrome.\",\n `Endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n `Unpacked extensions: ${browser.extensionPaths.length} (${browser.extensionPathsSource})`,\n `WebMCP: ${webMcpIsEnabled ? \"enabled \u00B7 experimental\" : \"disabled \u00B7 experimental\"}`,\n ...(webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready\n ? [\"WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state.\"]\n : []),\n ...(browser.extensionPaths.length > 0\n ? [\"Unpacked extensions execute trusted browser code in an isolated managed browser.\"]\n : []),\n ...launchAttemptLines(owner),\n ...(needsRecovery ? [launchHint(owner), endpointConfigHint()] : []),\n ].join(\"\\n\"),\n );\n}\n\nexport function buildSettingsSetupMessage(owner: object) {\n return sanitizeChromeDevtoolsDisplay(\n [\n `Chrome DevTools endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n ...browserSettingsStatusLines(owner),\n launchHint(owner),\n browserCandidateHint(owner),\n ...launchAttemptLines(owner),\n endpointConfigHint(),\n ].join(\"\\n\"),\n );\n}\n\nfunction browserSettingsStatusLines(owner: object) {\n const browser = browserSettingsForOwner(owner);\n const extensionPaths = browser.extensionPaths;\n const extensionLines =\n extensionPaths.length > 0 ? extensionPaths.map((extensionPath) => ` - ${extensionPath}`) : [\" - none\"];\n return [\n `Settings file: ${state.settingsFilePath ?? settingsFilePath()} (user)`,\n ...(state.projectSettingsFilePath\n ? [\n `Project settings: ${state.projectSettingsFilePath} (${state.projectSettingsTrusted ? \"trusted\" : \"untrusted; ignored\"})`,\n ]\n : []),\n `Auto-launch: ${browser.autoLaunchEnabled ? \"on\" : \"off\"} (${browser.autoLaunchSource})`,\n `Browser executable: ${browser.executablePath ?? \"automatic discovery\"} (${browser.executablePathSource})`,\n `Unpacked extensions (${browser.extensionPathsSource}):`,\n ...extensionLines,\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 every call requires confirmation\" : \"disabled \u00B7 experimental\"}`,\n \"Confirmed menu settings apply before the next browser connection; manual JSON edits require /reload or session replacement.\",\n ...(extensionPaths.length > 0\n ? [\"Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code.\"]\n : []),\n ];\n}\n\nexport function buildCommandGuide(owner: object) {\n return [\n \"Chrome DevTools commands:\",\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled\" : \"disabled\"} \u00B7 experimental \u00B7 every page-provided call requires confirmation`,\n \"/chrome-devtools \u2014 open this menu\",\n \"/chrome-devtools help \u2014 show command usage\",\n \"/chrome-devtools quickstart \u2014 show endpoint and launch help\",\n \"/chrome-devtools status \u2014 show tool and settings status\",\n \"/chrome-devtools settings \u2014 edit browser connection settings\",\n \"/chrome-devtools tools \u2014 choose available Chrome DevTools tools\",\n \"/chrome-devtools toggle|select \u2014 compatibility aliases for tools\",\n \"/chrome-devtools enable|on \u2014 make all Chrome DevTools tools available\",\n \"/chrome-devtools disable|off \u2014 make all Chrome DevTools capability tools unavailable\",\n ].join(\"\\n\");\n}\n\nexport function allChromeDevtoolsTools(owner: object) {\n return effectiveCatalog(owner);\n}\n\nexport function orderedChromeDevtoolsTools(selectedTools: ReadonlySet<ChromeDevToolsToolName>) {\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => selectedTools.has(toolName));\n}\n\nfunction formatRuntimeStatus(summary: ToolStatusSummary) {\n return `${summary.availabilityStatus} (${summary.availableChromeToolCount}/${summary.capabilityCount} available)`;\n}\n\nasync function persistedSettingLabel() {\n const settings = await loadSettings();\n if (settings.kind === \"loaded\" && settings.settings.tools) {\n return formatPersistedSelection(settings.settings.tools);\n }\n if (settings.kind === \"invalid\") {\n return `none; current active-tool policy preserved (invalid settings ignored: ${settings.reason})`;\n }\n return \"none; current active-tool policy preserved\";\n}\n\nfunction formatPersistedSelection(tools: readonly ChromeDevToolsToolName[]) {\n if (tools.length === CHROME_DEVTOOLS_TOOL_NAMES.length) {\n return `all available (${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;\n }\n if (tools.length === 0) return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;\n return `${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected: ${tools.join(\", \")}`;\n}\n\nfunction effectiveCatalog(owner: object): ChromeDevToolsToolName[] {\n return webMcpEnabled(owner) ? [...CHROME_DEVTOOLS_TOOL_NAMES] : [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];\n}\n\nasync function persistSettings(selectedTools: readonly ChromeDevToolsToolName[]) {\n await saveSettings({ tools: [...selectedTools], updatedAt: Date.now() });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["unique"]
|
|
7
|
+
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
buildCommandGuide,
|
|
7
7
|
sanitizeChromeDevtoolsDisplay,
|
|
8
8
|
setSelectedChromeDevtoolsTools
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V7N3WI5B.ts";
|
|
10
10
|
import {
|
|
11
11
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
12
12
|
CORE_CHROME_DEVTOOLS_TOOL_NAMES,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
loadSettings,
|
|
18
18
|
state,
|
|
19
19
|
webMcpEnabled
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-LSJSDY2M.ts";
|
|
21
21
|
|
|
22
22
|
// src/menu.ts
|
|
23
23
|
import { defineMenu, runMenu, runTask } from "@narumitw/pi-tui-kit";
|
|
@@ -137,7 +137,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
|
|
|
137
137
|
return result?.closeParent ? { kind: "close" } : { kind: "stay" };
|
|
138
138
|
},
|
|
139
139
|
settings: async ({ state: current }) => {
|
|
140
|
-
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-
|
|
140
|
+
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-FVMCCUPM.ts");
|
|
141
141
|
if (!isCurrent()) return { kind: "stay" };
|
|
142
142
|
const result = await showChromeDevtoolsBrowserSettings(pi, ctx, generation);
|
|
143
143
|
if (!isCurrent()) return { kind: "stay" };
|
|
@@ -236,8 +236,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
236
236
|
},
|
|
237
237
|
actions: {
|
|
238
238
|
toggle: ({ state: current, itemId, selected }) => {
|
|
239
|
-
if (!isChromeDevtoolsToolName(itemId) || selected === void 0)
|
|
240
|
-
return { kind: "rejected" };
|
|
239
|
+
if (!isChromeDevtoolsToolName(itemId) || selected === void 0) return { kind: "rejected" };
|
|
241
240
|
if (selected) current.draft.add(itemId);
|
|
242
241
|
else current.draft.delete(itemId);
|
|
243
242
|
return { kind: "stay" };
|
|
@@ -258,12 +257,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
258
257
|
return { kind: "rejected" };
|
|
259
258
|
}
|
|
260
259
|
const selectedTools = orderedTools(current.draft);
|
|
261
|
-
const saveResult = await setSelectedChromeDevtoolsTools(
|
|
262
|
-
pi,
|
|
263
|
-
ctx,
|
|
264
|
-
selectedTools,
|
|
265
|
-
orderedTools(current.accepted)
|
|
266
|
-
);
|
|
260
|
+
const saveResult = await setSelectedChromeDevtoolsTools(pi, ctx, selectedTools, orderedTools(current.accepted));
|
|
267
261
|
if (!isCurrent()) return { kind: "rejected" };
|
|
268
262
|
if (saveResult === "active-tools-changed") {
|
|
269
263
|
current.accepted = new Set(activeChromeTools(pi));
|
|
@@ -285,9 +279,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
285
279
|
signal: menuSignal,
|
|
286
280
|
isCurrent,
|
|
287
281
|
onError: (currentCtx, error) => currentCtx.ui.notify(
|
|
288
|
-
sanitizeChromeDevtoolsDisplay(
|
|
289
|
-
`Chrome DevTools tool selection failed: ${formatError(error)}`
|
|
290
|
-
),
|
|
282
|
+
sanitizeChromeDevtoolsDisplay(`Chrome DevTools tool selection failed: ${formatError(error)}`),
|
|
291
283
|
"error"
|
|
292
284
|
)
|
|
293
285
|
});
|
|
@@ -324,9 +316,7 @@ function buildMenuSnapshot(pi, settings) {
|
|
|
324
316
|
const activeTools = activeChromeTools(pi);
|
|
325
317
|
const persistedTools = settings.kind === "loaded" && settings.settings.tools ? orderedTools(new Set(settings.settings.tools)) : void 0;
|
|
326
318
|
const persistenceLabel = settings.kind === "invalid" ? "settings need repair" : persistedTools === void 0 ? "not saved" : arraysEqual(activeTools, persistedTools) ? "saved" : "runtime catalog differs from saved catalog";
|
|
327
|
-
const settingsWarning = [
|
|
328
|
-
...new Set([settings.notice, state.settingsNotice].filter(Boolean))
|
|
329
|
-
].join("\n");
|
|
319
|
+
const settingsWarning = [...new Set([settings.notice, state.settingsNotice].filter(Boolean))].join("\n");
|
|
330
320
|
return {
|
|
331
321
|
activeTools,
|
|
332
322
|
persistenceLabel,
|
|
@@ -335,9 +325,7 @@ function buildMenuSnapshot(pi, settings) {
|
|
|
335
325
|
};
|
|
336
326
|
}
|
|
337
327
|
function mainStateLines(snapshot, owner) {
|
|
338
|
-
const launchError = launchAttemptLines(owner).find(
|
|
339
|
-
(line) => line.startsWith("Last launch error:")
|
|
340
|
-
);
|
|
328
|
+
const launchError = launchAttemptLines(owner).find((line) => line.startsWith("Last launch error:"));
|
|
341
329
|
return sanitizeLines([
|
|
342
330
|
`Tool catalog: ${snapshot.activeTools.length} of ${availableCatalogNames(owner).length} available \xB7 ${snapshot.persistenceLabel}`,
|
|
343
331
|
`WebMCP: ${webMcpEnabled(owner) ? "enabled \xB7 experimental \xB7 confirmation required for every call" : "disabled \xB7 experimental"}`,
|
|
@@ -357,8 +345,7 @@ function browserLifecycleSummary(owner) {
|
|
|
357
345
|
return launchMode.startsWith("attach first") ? "not started \xB7 attaches or launches on first use" : `not started \xB7 ${launchMode}`;
|
|
358
346
|
}
|
|
359
347
|
function toolDraftLines(current, owner) {
|
|
360
|
-
if (current.mutationBlockedReason)
|
|
361
|
-
return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);
|
|
348
|
+
if (current.mutationBlockedReason) return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);
|
|
362
349
|
const changes = symmetricDifferenceSize(current.accepted, current.draft);
|
|
363
350
|
return [
|
|
364
351
|
`Currently available: ${current.accepted.size}/${availableCatalogNames(owner).length}`,
|
|
@@ -428,4 +415,4 @@ export {
|
|
|
428
415
|
showChromeDevtoolsMenu,
|
|
429
416
|
showChromeDevtoolsToolWorkflow
|
|
430
417
|
};
|
|
431
|
-
//# sourceMappingURL=menu-
|
|
418
|
+
//# sourceMappingURL=menu-MTPSLDHZ.ts.map
|