@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.
Files changed (40) hide show
  1. package/README.md +1 -0
  2. package/dist/chunks/{browser-settings-menu-IMB6HXSU.js → browser-settings-menu-FVMCCUPM.ts} +16 -42
  3. package/dist/chunks/browser-settings-menu-FVMCCUPM.ts.map +7 -0
  4. package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4B3EQHOH.ts} +2 -2
  5. package/dist/chunks/chunk-4B3EQHOH.ts.map +7 -0
  6. package/dist/chunks/{chunk-SRT3UUIP.js → chunk-LSJSDY2M.ts} +23 -74
  7. package/dist/chunks/chunk-LSJSDY2M.ts.map +7 -0
  8. package/dist/chunks/{chunk-LLXOCRNF.js → chunk-V7N3WI5B.ts} +12 -33
  9. package/dist/chunks/chunk-V7N3WI5B.ts.map +7 -0
  10. package/dist/chunks/{menu-UJETYMSB.js → menu-MTPSLDHZ.ts} +10 -23
  11. package/dist/chunks/menu-MTPSLDHZ.ts.map +7 -0
  12. package/dist/chunks/{tools-6P7EUX37.js → tools-OVNH45IJ.ts} +17 -59
  13. package/dist/chunks/tools-OVNH45IJ.ts.map +7 -0
  14. package/dist/index.ts +18 -42
  15. package/dist/index.ts.map +2 -2
  16. package/package.json +54 -55
  17. package/src/browser-manager.ts +872 -942
  18. package/src/browser-settings-menu.ts +315 -350
  19. package/src/cdp-client.ts +381 -398
  20. package/src/chrome-devtools.ts +205 -232
  21. package/src/display.ts +26 -29
  22. package/src/lazy-tools.ts +158 -181
  23. package/src/menu.ts +409 -446
  24. package/src/render.ts +72 -81
  25. package/src/runtime.ts +137 -140
  26. package/src/screenshot.ts +170 -186
  27. package/src/settings.ts +472 -523
  28. package/src/tool-names.ts +8 -14
  29. package/src/tool-selector.ts +242 -271
  30. package/src/tools.ts +218 -226
  31. package/src/webmcp/discovery.ts +184 -188
  32. package/src/webmcp/policy.ts +296 -329
  33. package/src/webmcp/protocol.ts +324 -337
  34. package/src/webmcp/tools.ts +136 -147
  35. package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +0 -7
  36. package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
  37. package/dist/chunks/chunk-LLXOCRNF.js.map +0 -7
  38. package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
  39. package/dist/chunks/menu-UJETYMSB.js.map +0 -7
  40. package/dist/chunks/tools-6P7EUX37.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/menu.ts"],
4
+ "sourcesContent": ["import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu, runTask } from \"@narumitw/pi-tui-kit\";\nimport { browserLifecycleState, devToolsEndpoint, launchAttemptLines, launchModeLabel } from \"./browser-manager.js\";\nimport { availableChromeDevtoolsTools } from \"./lazy-tools.js\";\nimport { state, webMcpEnabled } from \"./runtime.js\";\nimport { loadSettings, type SettingsLoadResult } from \"./settings.js\";\nimport {\n CHROME_DEVTOOLS_TOOL_NAMES,\n type ChromeDevToolsToolName,\n CORE_CHROME_DEVTOOLS_TOOL_NAMES,\n} from \"./tool-names.js\";\nimport {\n buildBrowserStatusMessage,\n buildCommandGuide,\n sanitizeChromeDevtoolsDisplay,\n setSelectedChromeDevtoolsTools,\n} from \"./tool-selector.js\";\n\ntype CommandContext = ExtensionCommandContext;\ntype MainScreen = \"main\" | \"browserStatus\" | \"help\";\ntype MainAction = \"tools\" | \"bulk\" | \"settings\";\ntype ToolScreen = \"tools\" | \"review\";\ntype ToolAction = \"toggle\" | \"selectAll\" | \"selectNone\" | \"review\" | \"apply\" | \"cancel\";\n\ninterface MenuSnapshot {\n activeTools: ChromeDevToolsToolName[];\n persistenceLabel: string;\n mutationBlockedReason?: string;\n settingsWarning?: string;\n}\n\ninterface ToolWorkflowState {\n accepted: Set<ChromeDevToolsToolName>;\n draft: Set<ChromeDevToolsToolName>;\n mutationBlockedReason?: string;\n generation: number;\n applied: boolean;\n}\n\nconst TOOL_PRESENTATION: Record<ChromeDevToolsToolName, { label: string; description: string }> = {\n chrome_devtools_list_pages: {\n label: \"List open pages\",\n description: \"List inspectable Chrome tabs and pages (chrome_devtools_list_pages).\",\n },\n chrome_devtools_select_page: {\n label: \"Select the active page\",\n description: \"Choose the page later browser actions use (chrome_devtools_select_page).\",\n },\n chrome_devtools_navigate: {\n label: \"Navigate a page\",\n description: \"Open a URL, creating a page when needed (chrome_devtools_navigate).\",\n },\n chrome_devtools_evaluate: {\n label: \"Run JavaScript\",\n description: \"Evaluate JavaScript in the selected page (chrome_devtools_evaluate).\",\n },\n chrome_devtools_screenshot: {\n label: \"Capture a screenshot\",\n description: \"Save a PNG of the selected page (chrome_devtools_screenshot).\",\n },\n chrome_devtools_webmcp_list_tools: {\n label: \"List page WebMCP tools \u00B7 Experimental\",\n description: \"Discover page-provided WebMCP capabilities (chrome_devtools_webmcp_list_tools).\",\n },\n chrome_devtools_webmcp_call_tool: {\n label: \"Call a page WebMCP tool \u00B7 Experimental\",\n description: \"Invoke a listed page tool after confirmation (chrome_devtools_webmcp_call_tool).\",\n },\n};\n\nexport async function showChromeDevtoolsMenu(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n const snapshot = await loadSnapshotWithFeedback(pi, ctx, generation);\n if (!snapshot) return;\n const menuSignal = state.sessionController.signal;\n const isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n const menu = defineMenu<MenuSnapshot, MainScreen, MainAction>({\n start: \"main\",\n screens: {\n main: ({ state: current }) => ({\n kind: \"actions\",\n title: \"Chrome DevTools\",\n lines: mainStateLines(current, ctx.sessionManager),\n items: [\n {\n id: \"tools\",\n label: \"Choose available browser tools\u2026\",\n description: \"Choose which capabilities the loader may expose.\",\n disabled: Boolean(current.mutationBlockedReason),\n disabledReason: current.mutationBlockedReason,\n action: \"tools\",\n },\n {\n id: \"bulk\",\n label:\n current.activeTools.length === availableCatalogNames(ctx.sessionManager).length\n ? \"Make all browser tools unavailable\u2026\"\n : \"Make all browser tools available\u2026\",\n description:\n current.activeTools.length === availableCatalogNames(ctx.sessionManager).length\n ? `Preview 0 of ${availableCatalogNames(ctx.sessionManager).length}; other active tools stay enabled.`\n : `Preview ${availableCatalogNames(ctx.sessionManager).length} of ${availableCatalogNames(ctx.sessionManager).length}; other active tools stay enabled.`,\n disabled: Boolean(current.mutationBlockedReason),\n disabledReason: current.mutationBlockedReason,\n action: \"bulk\",\n },\n {\n id: \"browser-status\",\n label: \"Browser status\",\n description: \"Runtime, endpoint, and last launch attempt.\",\n to: \"browserStatus\",\n },\n {\n id: \"settings\",\n label: \"Browser settings\",\n description: \"Edit endpoint, auto-launch, and browser executable settings.\",\n action: \"settings\",\n },\n {\n id: \"help\",\n label: \"Help\",\n description: \"Commands and usage.\",\n to: \"help\",\n },\n ],\n hint: \"close\",\n }),\n browserStatus: () => ({\n kind: \"review\",\n title: \"Browser status\",\n content: buildBrowserStatusMessage(ctx.sessionManager),\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n }),\n help: () => ({\n kind: \"review\",\n title: \"Chrome DevTools help\",\n content: buildCommandGuide(ctx.sessionManager),\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n hint: \"back\",\n }),\n },\n actions: {\n tools: async ({ state: current }) => {\n const result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n snapshot: current,\n });\n if (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n return result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n },\n bulk: async ({ state: current }) => {\n const selectedTools =\n current.activeTools.length === availableCatalogNames(ctx.sessionManager).length\n ? []\n : availableCatalogNames(ctx.sessionManager);\n const result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n snapshot: current,\n initialDraft: selectedTools,\n startAtReview: true,\n });\n if (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n return result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n },\n settings: async ({ state: current }) => {\n const { showChromeDevtoolsBrowserSettings } = await import(\"./browser-settings-menu.js\");\n if (!isCurrent()) return { kind: \"stay\" };\n const result = await showChromeDevtoolsBrowserSettings(pi, ctx, generation);\n if (!isCurrent()) return { kind: \"stay\" };\n const refreshed = await loadChromeDevtoolsMenuSnapshot(pi, ctx);\n if (!isCurrent()) return { kind: \"stay\" };\n Object.assign(current, refreshed);\n return result.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n },\n },\n });\n await runMenu(ctx, menu, {\n getState: () => snapshot,\n signal: menuSignal,\n isCurrent,\n onError: (currentCtx, error) =>\n currentCtx.ui.notify(\n sanitizeChromeDevtoolsDisplay(`Chrome DevTools menu failed: ${formatError(error)}`),\n \"error\",\n ),\n });\n}\n\nexport async function showChromeDevtoolsToolWorkflow(\n pi: ExtensionAPI,\n ctx: CommandContext,\n generation: number,\n options: {\n snapshot?: MenuSnapshot;\n initialDraft?: readonly ChromeDevToolsToolName[];\n startAtReview?: boolean;\n } = {},\n): Promise<{ applied: boolean; closeParent: boolean; selectedTools: ChromeDevToolsToolName[] } | undefined> {\n const snapshot = options.snapshot ?? (await loadSnapshotWithFeedback(pi, ctx, generation));\n if (!snapshot) return undefined;\n const menuSignal = state.sessionController.signal;\n const isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n const accepted = new Set(snapshot.activeTools);\n const workflow: ToolWorkflowState = {\n accepted,\n draft: new Set(options.initialDraft ?? snapshot.activeTools),\n mutationBlockedReason: snapshot.mutationBlockedReason,\n generation,\n applied: false,\n };\n const menu = defineMenu<ToolWorkflowState, ToolScreen, ToolAction>({\n start: options.startAtReview ? \"review\" : \"tools\",\n screens: {\n tools: ({ state: current }) => ({\n kind: \"multiSelect\",\n title: `Browser tools (${current.draft.size}/${availableCatalogNames(ctx.sessionManager).length})`,\n lines: toolDraftLines(current, ctx.sessionManager),\n items: availableCatalogNames(ctx.sessionManager).map((toolName) => ({\n id: toolName,\n label: TOOL_PRESENTATION[toolName].label,\n description: TOOL_PRESENTATION[toolName].description,\n searchText: `${toolName} ${TOOL_PRESENTATION[toolName].description}`,\n selected: current.draft.has(toolName),\n disabled: Boolean(current.mutationBlockedReason),\n disabledReason: current.mutationBlockedReason,\n })),\n action: \"toggle\",\n actions: [\n {\n id: \"select-all\",\n label: \"Select all\",\n disabled: Boolean(current.mutationBlockedReason),\n disabledReason: current.mutationBlockedReason,\n action: \"selectAll\",\n },\n {\n id: \"select-none\",\n label: \"Select none\",\n disabled: Boolean(current.mutationBlockedReason),\n disabledReason: current.mutationBlockedReason,\n action: \"selectNone\",\n },\n {\n id: \"review\",\n label: \"Review changes\u2026\",\n disabled: Boolean(current.mutationBlockedReason) || setsEqual(current.accepted, current.draft),\n disabledReason:\n current.mutationBlockedReason ??\n (setsEqual(current.accepted, current.draft) ? \"No unapplied changes\" : undefined),\n to: \"review\",\n },\n { id: \"cancel\", label: \"Cancel\", action: \"cancel\" },\n ],\n hint: \"back\",\n }),\n review: ({ state: current }) => ({\n kind: \"review\",\n title: \"Review tool changes\",\n lines: [\n `Currently available: ${current.accepted.size}/${availableCatalogNames(ctx.sessionManager).length}`,\n `Proposed availability: ${current.draft.size}/${availableCatalogNames(ctx.sessionManager).length}`,\n ],\n content: buildToolReview(current, ctx.sessionManager),\n format: { kind: \"text\" },\n viewportSize: \"adaptive\",\n ...(current.mutationBlockedReason || setsEqual(current.accepted, current.draft)\n ? {}\n : {\n confirm: {\n id: \"apply\",\n label: \"Apply tool changes\",\n action: \"apply\" as const,\n },\n }),\n hint: \"back\",\n }),\n },\n actions: {\n toggle: ({ state: current, itemId, selected }) => {\n if (!isChromeDevtoolsToolName(itemId) || selected === undefined) return { kind: \"rejected\" };\n if (selected) current.draft.add(itemId);\n else current.draft.delete(itemId);\n return { kind: \"stay\" };\n },\n selectAll: ({ state: current }) => {\n current.draft = new Set(availableCatalogNames(ctx.sessionManager));\n return { kind: \"stay\" };\n },\n selectNone: ({ state: current }) => {\n current.draft = new Set();\n return { kind: \"stay\" };\n },\n review: () => ({ kind: \"to\", screen: \"review\" }),\n cancel: () => ({ kind: \"back\" }),\n apply: async ({ state: current, signal }) => {\n await ctx.waitForIdle();\n if (signal.aborted || !isCurrent() || current.generation !== state.sessionGeneration) {\n return { kind: \"rejected\" };\n }\n const selectedTools = orderedTools(current.draft);\n const saveResult = await setSelectedChromeDevtoolsTools(pi, ctx, selectedTools, orderedTools(current.accepted));\n if (!isCurrent()) return { kind: \"rejected\" };\n if (saveResult === \"active-tools-changed\") {\n current.accepted = new Set(activeChromeTools(pi));\n }\n if (saveResult !== \"saved\") return { kind: \"rejected\" };\n current.accepted = new Set(selectedTools);\n current.draft = new Set(selectedTools);\n current.applied = true;\n ctx.ui.notify(\n `Saved: ${selectedTools.length} of ${availableCatalogNames(ctx.sessionManager).length} browser tools available.`,\n \"info\",\n );\n return { kind: \"close\" };\n },\n },\n });\n const result = await runMenu(ctx, menu, {\n getState: () => workflow,\n signal: menuSignal,\n isCurrent,\n onError: (currentCtx, error) =>\n currentCtx.ui.notify(\n sanitizeChromeDevtoolsDisplay(`Chrome DevTools tool selection failed: ${formatError(error)}`),\n \"error\",\n ),\n });\n return {\n applied: workflow.applied,\n closeParent: !workflow.applied && result.kind === \"closed\" && result.reason === \"close\",\n selectedTools: orderedTools(workflow.accepted),\n };\n}\n\nasync function loadSnapshotWithFeedback(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n const menuSignal = state.sessionController.signal;\n const isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n const result = await runTask(ctx, {\n label: \"Loading Chrome DevTools settings\u2026\",\n signal: menuSignal,\n isCurrent,\n task: async ({ signal }) => {\n signal.throwIfAborted();\n const settings = await loadSettings();\n signal.throwIfAborted();\n return buildMenuSnapshot(pi, settings);\n },\n });\n return result.kind === \"completed\" ? result.value : undefined;\n}\n\nexport async function loadChromeDevtoolsMenuSnapshot(pi: ExtensionAPI, ctx: ExtensionCommandContext) {\n const settings = await loadSettings({\n cwd: ctx.cwd,\n projectTrusted: ctx.isProjectTrusted(),\n });\n return buildMenuSnapshot(pi, settings);\n}\n\nfunction buildMenuSnapshot(pi: ExtensionAPI, settings: SettingsLoadResult): MenuSnapshot {\n const activeTools = activeChromeTools(pi);\n const persistedTools =\n settings.kind === \"loaded\" && settings.settings.tools ? orderedTools(new Set(settings.settings.tools)) : undefined;\n const persistenceLabel =\n settings.kind === \"invalid\"\n ? \"settings need repair\"\n : persistedTools === undefined\n ? \"not saved\"\n : arraysEqual(activeTools, persistedTools)\n ? \"saved\"\n : \"runtime catalog differs from saved catalog\";\n const settingsWarning = [...new Set([settings.notice, state.settingsNotice].filter(Boolean))].join(\"\\n\");\n return {\n activeTools,\n persistenceLabel,\n ...(settings.kind === \"invalid\" ? { mutationBlockedReason: `Repair ${settings.reason} before saving` } : {}),\n ...(settingsWarning ? { settingsWarning } : {}),\n };\n}\n\nfunction mainStateLines(snapshot: MenuSnapshot, owner: object) {\n const launchError = launchAttemptLines(owner).find((line) => line.startsWith(\"Last launch error:\"));\n return sanitizeLines([\n `Tool catalog: ${snapshot.activeTools.length} of ${availableCatalogNames(owner).length} available \u00B7 ${snapshot.persistenceLabel}`,\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 confirmation required for every call\" : \"disabled \u00B7 experimental\"}`,\n `Browser: ${browserLifecycleSummary(owner)}`,\n `Endpoint: ${devToolsEndpoint(owner)}`,\n ...(snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : []),\n ...(launchError ? [`Launch warning: ${launchError.slice(\"Last launch error: \".length)}`] : []),\n ]);\n}\n\nfunction browserLifecycleSummary(owner: object) {\n const lifecycle = browserLifecycleState(owner);\n if (lifecycle === \"starting\") return \"starting managed browser\";\n if (lifecycle === \"running\") return \"managed browser running\";\n if (lifecycle === \"exited\") return \"managed browser exited \u00B7 open Browser status to recover\";\n if (lifecycle === \"failed\") return \"last launch failed \u00B7 open Browser status to recover\";\n const launchMode = launchModeLabel(owner);\n return launchMode.startsWith(\"attach first\")\n ? \"not started \u00B7 attaches or launches on first use\"\n : `not started \u00B7 ${launchMode}`;\n}\n\nfunction toolDraftLines(current: ToolWorkflowState, owner: object) {\n if (current.mutationBlockedReason) return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);\n const changes = symmetricDifferenceSize(current.accepted, current.draft);\n return [\n `Currently available: ${current.accepted.size}/${availableCatalogNames(owner).length}`,\n changes === 0\n ? \"No unapplied changes \u00B7 Escape cancels\"\n : `${changes} unapplied ${changes === 1 ? \"change\" : \"changes\"} \u00B7 Escape cancels`,\n `WebMCP gateways: ${webMcpEnabled(owner) ? \"available for selection \u00B7 experimental\" : \"hidden while experimental WebMCP is disabled\"}`,\n \"Changes are not applied until Review changes and Apply tool changes.\",\n ];\n}\n\nfunction buildToolReview(current: ToolWorkflowState, owner: object) {\n const catalog = availableCatalogNames(owner);\n const available = catalog.filter((name) => current.draft.has(name));\n const unavailable = catalog.filter((name) => !current.draft.has(name));\n return sanitizeChromeDevtoolsDisplay(\n [\n `Current available browser tools: ${current.accepted.size}/${catalog.length}`,\n `Proposed available browser tools: ${current.draft.size}/${catalog.length}`,\n \"\",\n \"Available after apply:\",\n ...(available.length > 0\n ? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n : [\" - none\"]),\n \"\",\n \"Unavailable after apply:\",\n ...(unavailable.length > 0\n ? unavailable.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n : [\" - none\"]),\n \"\",\n \"Other active Pi tools remain unchanged.\",\n \"Native-capable models defer these tools until chrome_devtools_load selects them.\",\n \"Other models expose available tools eagerly before the next model request.\",\n \"The accepted availability policy is saved for future sessions.\",\n ].join(\"\\n\"),\n );\n}\n\nfunction updateSnapshotAfterApply(snapshot: MenuSnapshot, selectedTools: readonly ChromeDevToolsToolName[]) {\n snapshot.activeTools = [...selectedTools];\n snapshot.persistenceLabel = \"saved\";\n}\n\nfunction activeChromeTools(pi: ExtensionAPI) {\n return availableChromeDevtoolsTools(pi);\n}\n\nfunction orderedTools(tools: ReadonlySet<ChromeDevToolsToolName>) {\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => tools.has(toolName));\n}\n\nfunction isChromeDevtoolsToolName(value: string): value is ChromeDevToolsToolName {\n return CHROME_DEVTOOLS_TOOL_NAMES.includes(value as ChromeDevToolsToolName);\n}\n\nfunction setsEqual<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n return left.size === right.size && [...left].every((value) => right.has(value));\n}\n\nfunction symmetricDifferenceSize<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n let changes = 0;\n for (const value of left) if (!right.has(value)) changes += 1;\n for (const value of right) if (!left.has(value)) changes += 1;\n return changes;\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\nfunction sanitizeLines(lines: readonly string[]) {\n return sanitizeChromeDevtoolsDisplay(lines.join(\"\\n\")).split(\"\\n\");\n}\n\nfunction availableCatalogNames(owner: object): ChromeDevToolsToolName[] {\n return webMcpEnabled(owner) ? [...CHROME_DEVTOOLS_TOOL_NAMES] : [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -5,7 +5,7 @@ import {
5
5
  getPage,
6
6
  resolvePage,
7
7
  textResult
8
- } from "./chunk-GTTYS5GT.js";
8
+ } from "./chunk-4B3EQHOH.ts";
9
9
  import {
10
10
  DEFAULT_TIMEOUT_MS,
11
11
  beginWebMcpOperation,
@@ -15,17 +15,12 @@ import {
15
15
  webMcpEnabled,
16
16
  webMcpOperationIsCurrent,
17
17
  webMcpSessionSignal
18
- } from "./chunk-SRT3UUIP.js";
18
+ } from "./chunk-LSJSDY2M.ts";
19
19
 
20
20
  // src/webmcp/policy.ts
21
21
  import { createHash } from "node:crypto";
22
22
  import { stripVTControlCharacters } from "node:util";
23
- import {
24
- DEFAULT_MAX_BYTES,
25
- DEFAULT_MAX_LINES,
26
- formatSize,
27
- truncateHead
28
- } from "@earendil-works/pi-coding-agent";
23
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from "@earendil-works/pi-coding-agent";
29
24
  import { Check } from "typebox/value";
30
25
  var MAX_WEBMCP_TOOLS = 100;
31
26
  var MAX_SCHEMA_BYTES = 64 * 1024;
@@ -86,9 +81,7 @@ function webMcpIdentity(tool) {
86
81
  };
87
82
  }
88
83
  function requireMatchingWebMcpTool(tools, expected) {
89
- const candidates = tools.filter(
90
- (tool) => tool.frameId === expected.frameId && tool.name === expected.name
91
- );
84
+ const candidates = tools.filter((tool) => tool.frameId === expected.frameId && tool.name === expected.name);
92
85
  if (candidates.length === 0) throw new Error("The selected WebMCP tool is no longer available.");
93
86
  if (candidates.length > 1) {
94
87
  throw new Error("The selected WebMCP tool identity is ambiguous in its frame.");
@@ -186,10 +179,7 @@ function webMcpConfirmationMessage(tool, input, managedProfile) {
186
179
  ].join("\n");
187
180
  }
188
181
  function sanitizeWebMcpDisplay(value, maxCharacters = 5e4) {
189
- const withoutBidi = stripVTControlCharacters(value).replace(
190
- /[\u202a-\u202e\u2066-\u2069]/gu,
191
- "\uFFFD"
192
- );
182
+ const withoutBidi = stripVTControlCharacters(value).replace(/[\u202a-\u202e\u2066-\u2069]/gu, "\uFFFD");
193
183
  const sanitized = Array.from(withoutBidi, (character) => {
194
184
  const codePoint = character.codePointAt(0) ?? 0;
195
185
  const unsafeControl = codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
@@ -238,13 +228,7 @@ function rejectRegexBearingSchema(schema) {
238
228
  for (const child of schema[keyword]) rejectRegexBearingSchema(child);
239
229
  }
240
230
  }
241
- for (const keyword of [
242
- "$defs",
243
- "definitions",
244
- "dependencies",
245
- "dependentSchemas",
246
- "properties"
247
- ]) {
231
+ for (const keyword of ["$defs", "definitions", "dependencies", "dependentSchemas", "properties"]) {
248
232
  if (!isRecord(schema[keyword])) continue;
249
233
  for (const child of Object.values(schema[keyword])) rejectRegexBearingSchema(child);
250
234
  }
@@ -254,9 +238,7 @@ function rejectExpensiveValidationSchema(schema) {
254
238
  const countBranches = (count) => {
255
239
  branches += count;
256
240
  if (branches > MAX_SCHEMA_VALIDATION_BRANCHES) {
257
- throw new Error(
258
- `WebMCP input schema exceeds the validation branch limit of ${MAX_SCHEMA_VALIDATION_BRANCHES}.`
259
- );
241
+ throw new Error(`WebMCP input schema exceeds the validation branch limit of ${MAX_SCHEMA_VALIDATION_BRANCHES}.`);
260
242
  }
261
243
  };
262
244
  const visit = (candidate) => {
@@ -297,8 +279,7 @@ function canonicalJsonValue(value, limits) {
297
279
  return candidate;
298
280
  }
299
281
  if (typeof candidate === "number") {
300
- if (!Number.isFinite(candidate))
301
- throw new Error(`${limits.label} contains a non-finite number.`);
282
+ if (!Number.isFinite(candidate)) throw new Error(`${limits.label} contains a non-finite number.`);
302
283
  return candidate;
303
284
  }
304
285
  if (Array.isArray(candidate)) return candidate.map((entry) => visit(entry, depth + 1));
@@ -313,9 +294,7 @@ function canonicalJsonValue(value, limits) {
313
294
  const serialized = canonicalStringify(canonical);
314
295
  const bytes = Buffer.byteLength(serialized, "utf8");
315
296
  if (bytes > limits.maxBytes) {
316
- throw new Error(
317
- `${limits.label} exceeds ${formatSize(limits.maxBytes)} (${formatSize(bytes)}).`
318
- );
297
+ throw new Error(`${limits.label} exceeds ${formatSize(limits.maxBytes)} (${formatSize(bytes)}).`);
319
298
  }
320
299
  return canonical;
321
300
  }
@@ -340,11 +319,7 @@ var REQUIRED_EVENTS = ["toolsAdded", "toolsRemoved", "toolInvoked", "toolRespond
340
319
  var IDENTITY_WATCH_TIMEOUT_MS = DEFAULT_TIMEOUT_MS * 4;
341
320
  async function requireWebMcpDomain(signal, owner) {
342
321
  signal.throwIfAborted();
343
- const protocol = await fetchDevToolsJson(
344
- "/json/protocol",
345
- { signal },
346
- owner
347
- );
322
+ const protocol = await fetchDevToolsJson("/json/protocol", { signal }, owner);
348
323
  signal.throwIfAborted();
349
324
  const domain = findDomain(protocol.domains, "WebMCP");
350
325
  if (!domain || !hasNamedEntries(domain.commands, REQUIRED_COMMANDS) || !hasNamedEntries(domain.events, REQUIRED_EVENTS)) {
@@ -547,9 +522,7 @@ function findDomain(value, name) {
547
522
  function hasNamedEntries(value, required) {
548
523
  if (!Array.isArray(value)) return false;
549
524
  const names = new Set(
550
- value.flatMap(
551
- (candidate) => isRecord2(candidate) && typeof candidate.name === "string" ? [candidate.name] : []
552
- )
525
+ value.flatMap((candidate) => isRecord2(candidate) && typeof candidate.name === "string" ? [candidate.name] : [])
553
526
  );
554
527
  return required.every((name) => names.has(name));
555
528
  }
@@ -734,9 +707,7 @@ function requireStableInventoryDocuments(tools, before, after) {
734
707
  const beforeLoader = beforeLoaders.get(frameId);
735
708
  const afterLoader = afterLoaders.get(frameId);
736
709
  if (!beforeLoader || !afterLoader || beforeLoader !== afterLoader) {
737
- throw new Error(
738
- "A WebMCP frame document changed while Chrome was publishing its tool inventory."
739
- );
710
+ throw new Error("A WebMCP frame document changed while Chrome was publishing its tool inventory.");
740
711
  }
741
712
  }
742
713
  }
@@ -801,9 +772,7 @@ function frameOrigin(frame) {
801
772
  try {
802
773
  return new URL(frame.url).origin;
803
774
  } catch {
804
- throw new Error(
805
- `Chrome returned an invalid WebMCP frame URL: ${webMcpErrorMessage(frame.url)}`
806
- );
775
+ throw new Error(`Chrome returned an invalid WebMCP frame URL: ${webMcpErrorMessage(frame.url)}`);
807
776
  }
808
777
  }
809
778
  function remoteExceptionText(value) {
@@ -832,10 +801,7 @@ async function executeWebMcpListTool(params, toolSignal, ctx) {
832
801
  try {
833
802
  const tools = await discoverWebMcpTools(page, operation);
834
803
  assertCurrent(operation);
835
- const published = boundedWebMcpDiscovery(
836
- { id: page.id, title: page.title, url: page.url },
837
- tools
838
- );
804
+ const published = boundedWebMcpDiscovery({ id: page.id, title: page.title, url: page.url }, tools);
839
805
  return textResult(published.text, {
840
806
  page: { id: page.id, url: page.url },
841
807
  toolCount: tools.length,
@@ -884,12 +850,7 @@ async function executeWebMcpCallTool(params, toolSignal, ctx) {
884
850
  if (!confirmed) {
885
851
  throw new DOMException("WebMCP tool call cancelled by the user.", "AbortError");
886
852
  }
887
- const invocation = await invokeDiscoveredWebMcpTool(
888
- page,
889
- expected,
890
- validatedInput,
891
- operation
892
- );
853
+ const invocation = await invokeDiscoveredWebMcpTool(page, expected, validatedInput, operation);
893
854
  assertCurrent(operation);
894
855
  const published = boundedWebMcpJson({
895
856
  status: "completed",
@@ -923,10 +884,7 @@ function combinedSignal(owner, toolSignal) {
923
884
  function requireCurrentPreflight(owner, generation) {
924
885
  requireWebMcpEnabled(owner);
925
886
  if (generation !== currentWebMcpGeneration(owner)) {
926
- throw new DOMException(
927
- "The WebMCP operation became stale during page resolution.",
928
- "AbortError"
929
- );
887
+ throw new DOMException("The WebMCP operation became stale during page resolution.", "AbortError");
930
888
  }
931
889
  }
932
890
  function expectedIdentity(params) {
@@ -961,4 +919,4 @@ export {
961
919
  executeWebMcpCallTool,
962
920
  executeWebMcpListTool
963
921
  };
964
- //# sourceMappingURL=tools-6P7EUX37.js.map
922
+ //# sourceMappingURL=tools-OVNH45IJ.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/webmcp/policy.ts", "../../src/webmcp/protocol.ts", "../../src/webmcp/discovery.ts", "../../src/webmcp/tools.ts"],
4
+ "sourcesContent": ["import { createHash } from \"node:crypto\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead } from \"@earendil-works/pi-coding-agent\";\nimport type { TSchema } from \"typebox\";\nimport { Check } from \"typebox/value\";\nimport type { WebMcpProtocolAnnotation, WebMcpProtocolTool } from \"./protocol.js\";\n\nexport const MAX_WEBMCP_TOOLS = 100;\nconst MAX_SCHEMA_BYTES = 64 * 1024;\nconst MAX_INPUT_BYTES = 64 * 1024;\nconst MAX_OUTPUT_BYTES = 1024 * 1024;\nconst MAX_JSON_DEPTH = 32;\nconst MAX_JSON_NODES = 10_000;\nconst MAX_OUTPUT_NODES = 100_000;\nconst MAX_SCHEMA_VALIDATION_BRANCHES = 128;\n\nexport interface WebMcpToolDescriptor {\n annotations: WebMcpProtocolAnnotation;\n description: string;\n documentId: string;\n frameId: string;\n frameOrigin: string;\n inputSchema: Record<string, unknown>;\n name: string;\n pageId: string;\n pageUrl: string;\n schemaDigest: string;\n sessionGeneration: string;\n title?: string;\n}\n\nexport interface WebMcpToolIdentity {\n documentId: string;\n frameId: string;\n frameOrigin: string;\n name: string;\n pageId: string;\n schemaDigest: string;\n sessionGeneration: string;\n}\n\nexport function normalizeWebMcpTool(\n tool: WebMcpProtocolTool,\n context: {\n documentId: string;\n frameOrigin: string;\n pageId: string;\n pageUrl: string;\n sessionGeneration: string;\n },\n): WebMcpToolDescriptor {\n const name = boundedString(tool.name, \"tool name\", 512, { nonEmpty: true });\n const description = boundedString(tool.description, \"tool description\", 16 * 1024);\n const title = tool.title === undefined ? undefined : boundedString(tool.title, \"tool title\", 1_024);\n const documentId = boundedString(context.documentId, \"document loader ID\", 512, {\n nonEmpty: true,\n });\n const frameId = boundedString(tool.frameId, \"frame ID\", 512, { nonEmpty: true });\n const frameOrigin = boundedString(context.frameOrigin, \"frame origin\", 2_048, {\n nonEmpty: true,\n });\n const pageId = boundedString(context.pageId, \"page ID\", 512, { nonEmpty: true });\n const pageUrl = boundedString(context.pageUrl, \"page URL\", 8_192);\n const inputSchema = tool.inputSchema ?? { type: \"object\", additionalProperties: true };\n rejectRegexBearingSchema(inputSchema);\n const canonicalSchema = canonicalJsonObject(inputSchema, {\n label: \"WebMCP input schema\",\n maxBytes: MAX_SCHEMA_BYTES,\n maxDepth: MAX_JSON_DEPTH,\n maxNodes: MAX_JSON_NODES,\n });\n rejectExpensiveValidationSchema(canonicalSchema);\n const annotations = canonicalAnnotations(tool.annotations);\n const schemaDigest = createHash(\"sha256\")\n .update(canonicalStringify({ inputSchema: canonicalSchema, annotations }))\n .digest(\"hex\");\n return {\n annotations,\n description,\n documentId,\n frameId,\n frameOrigin,\n inputSchema: canonicalSchema,\n name,\n pageId,\n pageUrl,\n schemaDigest,\n sessionGeneration: context.sessionGeneration,\n ...(title === undefined ? {} : { title }),\n };\n}\n\nexport function webMcpIdentity(tool: WebMcpToolDescriptor): WebMcpToolIdentity {\n return {\n sessionGeneration: tool.sessionGeneration,\n pageId: tool.pageId,\n documentId: tool.documentId,\n frameId: tool.frameId,\n frameOrigin: tool.frameOrigin,\n name: tool.name,\n schemaDigest: tool.schemaDigest,\n };\n}\n\nexport function requireMatchingWebMcpTool(tools: readonly WebMcpToolDescriptor[], expected: WebMcpToolIdentity) {\n const candidates = tools.filter((tool) => tool.frameId === expected.frameId && tool.name === expected.name);\n if (candidates.length === 0) throw new Error(\"The selected WebMCP tool is no longer available.\");\n if (candidates.length > 1) {\n throw new Error(\"The selected WebMCP tool identity is ambiguous in its frame.\");\n }\n const current = candidates[0];\n if (!current) throw new Error(\"The selected WebMCP tool is no longer available.\");\n const mismatches = (\n [\n [\"session generation\", current.sessionGeneration, expected.sessionGeneration],\n [\"page\", current.pageId, expected.pageId],\n [\"document\", current.documentId, expected.documentId],\n [\"frame\", current.frameId, expected.frameId],\n [\"frame origin\", current.frameOrigin, expected.frameOrigin],\n [\"schema or annotations\", current.schemaDigest, expected.schemaDigest],\n ] as const\n ).flatMap(([label, actual, wanted]) => (actual === wanted ? [] : [label]));\n if (mismatches.length > 0) {\n throw new Error(`The selected WebMCP tool became stale: ${mismatches.join(\", \")} changed.`);\n }\n return current;\n}\n\nexport function normalizeWebMcpInput(input: Record<string, unknown>) {\n return canonicalJsonObject(input, {\n label: \"WebMCP tool input\",\n maxBytes: MAX_INPUT_BYTES,\n maxDepth: MAX_JSON_DEPTH,\n maxNodes: MAX_JSON_NODES,\n });\n}\n\nexport function validateWebMcpInput(schema: Record<string, unknown>, input: Record<string, unknown>) {\n const normalized = normalizeWebMcpInput(input);\n let valid: boolean;\n try {\n valid = Check(schema as TSchema, normalized);\n } catch (error) {\n throw new Error(\n `The page provided a WebMCP input schema that cannot be validated: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (!valid) throw new Error(\"WebMCP tool input does not match the current page-provided schema.\");\n return normalized;\n}\n\nexport function normalizeWebMcpOutput(output: unknown) {\n return canonicalJsonValue(output, {\n label: \"WebMCP tool output\",\n maxBytes: MAX_OUTPUT_BYTES,\n maxDepth: MAX_JSON_DEPTH * 2,\n maxNodes: MAX_OUTPUT_NODES,\n });\n}\n\nexport function boundedWebMcpDiscovery(\n page: { id: string; title: string; url: string },\n tools: readonly WebMcpToolDescriptor[],\n) {\n const included: WebMcpToolDescriptor[] = [];\n for (const tool of tools) {\n const candidate = [...included, tool];\n const publication = boundedWebMcpJson({\n page,\n tools: candidate,\n totalToolCount: tools.length,\n truncated: candidate.length < tools.length,\n });\n if (publication.truncated) break;\n included.push(tool);\n }\n const truncated = included.length < tools.length;\n const publication = boundedWebMcpJson({\n page,\n tools: included,\n totalToolCount: tools.length,\n truncated,\n });\n if (publication.truncated) {\n throw new Error(\"WebMCP discovery metadata cannot fit within Pi's output limit.\");\n }\n return { ...publication, included, truncated };\n}\n\nexport function boundedWebMcpJson(value: unknown) {\n const serialized = sanitizeWebMcpDisplay(JSON.stringify(value, null, 2), Number.MAX_SAFE_INTEGER);\n const result = truncateHead(serialized, {\n maxBytes: Math.max(1, DEFAULT_MAX_BYTES - 256),\n maxLines: Math.max(1, DEFAULT_MAX_LINES - 2),\n });\n if (!result.truncated) return { text: result.content, truncated: false };\n const notice = `\\n[WebMCP output truncated: ${result.outputLines}/${result.totalLines} lines, ${formatSize(result.outputBytes)}/${formatSize(result.totalBytes)}.]`;\n return { text: `${result.content}${notice}`, truncated: true };\n}\n\nexport function webMcpConfirmationMessage(\n tool: WebMcpToolDescriptor,\n input: Record<string, unknown>,\n managedProfile: boolean,\n) {\n const inputSummary = sanitizeWebMcpDisplay(JSON.stringify(input, null, 2), 2_000);\n return [\n managedProfile\n ? \"This call uses the isolated browser profile managed by Pi.\"\n : \"Warning: this call uses an attached browser profile that may contain everyday authenticated sessions and sensitive state.\",\n `Page: ${sanitizeWebMcpDisplay(tool.pageUrl, 4_096)}`,\n `Frame origin: ${sanitizeWebMcpDisplay(tool.frameOrigin, 2_048)}`,\n `Tool: ${sanitizeWebMcpDisplay(tool.name, 512)}`,\n \"Page annotations are untrusted and do not bypass this confirmation.\",\n \"Input:\",\n inputSummary,\n ].join(\"\\n\");\n}\n\nexport function sanitizeWebMcpDisplay(value: string, maxCharacters = 50_000) {\n const withoutBidi = stripVTControlCharacters(value).replace(/[\\u202a-\\u202e\\u2066-\\u2069]/gu, \"\uFFFD\");\n const sanitized = Array.from(withoutBidi, (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 return unsafeControl ? \"\uFFFD\" : character;\n }).join(\"\");\n if (sanitized.length <= maxCharacters) return sanitized;\n return `${sanitized.slice(0, Math.max(0, maxCharacters - 1))}\u2026`;\n}\n\nexport function webMcpErrorMessage(error: unknown) {\n return sanitizeWebMcpDisplay(error instanceof Error ? error.message : String(error), 8_192);\n}\n\nfunction canonicalAnnotations(value: WebMcpProtocolAnnotation | undefined) {\n if (!value) return {};\n return Object.fromEntries(\n Object.entries(value)\n .filter((entry): entry is [string, boolean] => typeof entry[1] === \"boolean\")\n .sort(([left], [right]) => left.localeCompare(right)),\n ) as WebMcpProtocolAnnotation;\n}\n\nfunction rejectRegexBearingSchema(schema: unknown): void {\n if (Array.isArray(schema)) {\n for (const child of schema) rejectRegexBearingSchema(child);\n return;\n }\n if (!isRecord(schema)) return;\n if (schema.pattern !== undefined || schema.patternProperties !== undefined) {\n throw new Error(\n \"WebMCP input schemas with pattern or patternProperties are unsupported because page-controlled regular expressions cannot be evaluated safely.\",\n );\n }\n for (const keyword of [\n \"additionalItems\",\n \"additionalProperties\",\n \"contains\",\n \"else\",\n \"if\",\n \"items\",\n \"not\",\n \"propertyNames\",\n \"then\",\n \"unevaluatedItems\",\n \"unevaluatedProperties\",\n ] as const) {\n rejectRegexBearingSchema(schema[keyword]);\n }\n for (const keyword of [\"allOf\", \"anyOf\", \"oneOf\", \"prefixItems\"] as const) {\n if (Array.isArray(schema[keyword])) {\n for (const child of schema[keyword]) rejectRegexBearingSchema(child);\n }\n }\n for (const keyword of [\"$defs\", \"definitions\", \"dependencies\", \"dependentSchemas\", \"properties\"] as const) {\n if (!isRecord(schema[keyword])) continue;\n for (const child of Object.values(schema[keyword])) rejectRegexBearingSchema(child);\n }\n}\n\nfunction rejectExpensiveValidationSchema(schema: unknown) {\n let branches = 0;\n const countBranches = (count: number) => {\n branches += count;\n if (branches > MAX_SCHEMA_VALIDATION_BRANCHES) {\n throw new Error(`WebMCP input schema exceeds the validation branch limit of ${MAX_SCHEMA_VALIDATION_BRANCHES}.`);\n }\n };\n const visit = (candidate: unknown): void => {\n if (Array.isArray(candidate)) {\n for (const child of candidate) visit(child);\n return;\n }\n if (!isRecord(candidate)) return;\n for (const keyword of [\"allOf\", \"anyOf\", \"oneOf\"] as const) {\n const alternatives = candidate[keyword];\n if (Array.isArray(alternatives)) countBranches(alternatives.length);\n }\n for (const keyword of [\"dependencies\", \"dependentSchemas\"] as const) {\n const dependencies = candidate[keyword];\n if (!isRecord(dependencies)) continue;\n countBranches(Object.values(dependencies).filter(isRecord).length);\n }\n for (const child of Object.values(candidate)) visit(child);\n };\n visit(schema);\n}\n\ninterface JsonLimits {\n label: string;\n maxBytes: number;\n maxDepth: number;\n maxNodes: number;\n}\n\nfunction canonicalJsonObject(value: Record<string, unknown>, limits: JsonLimits) {\n const canonical = canonicalJsonValue(value, limits);\n if (!isRecord(canonical)) throw new Error(`${limits.label} must be a JSON object.`);\n return canonical;\n}\n\nfunction canonicalJsonValue(value: unknown, limits: JsonLimits) {\n let nodes = 0;\n const visit = (candidate: unknown, depth: number): unknown => {\n nodes += 1;\n if (nodes > limits.maxNodes) {\n throw new Error(`${limits.label} exceeds the ${limits.maxNodes} value limit.`);\n }\n if (depth > limits.maxDepth) {\n throw new Error(`${limits.label} exceeds the depth limit of ${limits.maxDepth}.`);\n }\n if (candidate === null || typeof candidate === \"string\" || typeof candidate === \"boolean\") {\n return candidate;\n }\n if (typeof candidate === \"number\") {\n if (!Number.isFinite(candidate)) throw new Error(`${limits.label} contains a non-finite number.`);\n return candidate;\n }\n if (Array.isArray(candidate)) return candidate.map((entry) => visit(entry, depth + 1));\n if (isRecord(candidate)) {\n return Object.fromEntries(\n Object.keys(candidate)\n .sort()\n .map((key) => [key, visit(candidate[key], depth + 1)]),\n );\n }\n throw new Error(`${limits.label} contains a value that is not JSON-compatible.`);\n };\n const canonical = visit(value, 0);\n const serialized = canonicalStringify(canonical);\n const bytes = Buffer.byteLength(serialized, \"utf8\");\n if (bytes > limits.maxBytes) {\n throw new Error(`${limits.label} exceeds ${formatSize(limits.maxBytes)} (${formatSize(bytes)}).`);\n }\n return canonical;\n}\n\nfunction canonicalStringify(value: unknown) {\n const serialized = JSON.stringify(value);\n if (serialized === undefined) throw new Error(\"Value is not JSON-compatible.\");\n return serialized;\n}\n\nfunction boundedString(value: string, label: string, maxBytes: number, options: { nonEmpty?: boolean } = {}) {\n if (options.nonEmpty && value.length === 0) throw new Error(`WebMCP ${label} must not be empty.`);\n const bytes = Buffer.byteLength(value, \"utf8\");\n if (bytes > maxBytes) throw new Error(`WebMCP ${label} exceeds ${formatSize(maxBytes)}.`);\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n", "import { fetchDevToolsJson } from \"../browser-manager.js\";\nimport { CdpClient } from \"../cdp-client.js\";\nimport { DEFAULT_TIMEOUT_MS, type DevToolsPage } from \"../runtime.js\";\n\nexport interface WebMcpProtocolAnnotation {\n autosubmit?: boolean;\n consequential?: boolean;\n readOnly?: boolean;\n untrustedContent?: boolean;\n}\n\nexport interface WebMcpProtocolTool {\n annotations?: WebMcpProtocolAnnotation;\n backendNodeId?: number;\n description: string;\n frameId: string;\n inputSchema?: Record<string, unknown>;\n name: string;\n title?: string;\n}\n\nexport interface WebMcpFrame {\n id: string;\n loaderId: string;\n securityOrigin?: string;\n url: string;\n}\n\nexport interface WebMcpInvocationResponse {\n errorText?: string;\n exception?: unknown;\n invocationId: string;\n output?: unknown;\n status: \"Canceled\" | \"Completed\" | \"Error\";\n}\n\nexport interface WebMcpIdentityWatch {\n dispose(): Promise<void>;\n signal: AbortSignal;\n}\n\ninterface ProtocolDescription {\n domains?: unknown;\n}\n\nconst REQUIRED_COMMANDS = [\"enable\", \"disable\", \"invokeTool\", \"cancelInvocation\"];\nconst REQUIRED_EVENTS = [\"toolsAdded\", \"toolsRemoved\", \"toolInvoked\", \"toolResponded\"];\nconst IDENTITY_WATCH_TIMEOUT_MS = DEFAULT_TIMEOUT_MS * 4;\n\nexport async function requireWebMcpDomain(signal: AbortSignal, owner: object) {\n signal.throwIfAborted();\n const protocol = await fetchDevToolsJson<ProtocolDescription>(\"/json/protocol\", { signal }, owner);\n signal.throwIfAborted();\n const domain = findDomain(protocol.domains, \"WebMCP\");\n if (\n !domain ||\n !hasNamedEntries(domain.commands, REQUIRED_COMMANDS) ||\n !hasNamedEntries(domain.events, REQUIRED_EVENTS)\n ) {\n throw new Error(\n \"This browser does not expose the experimental Chrome DevTools WebMCP domain. Use a compatible Chrome build and enable the website's required Origin Trial or WebMCP testing feature.\",\n );\n }\n}\n\nexport async function connectWebMcpPage(page: DevToolsPage, signal: AbortSignal) {\n if (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n return CdpClient.connect(page.webSocketDebuggerUrl, {\n signal: withDeadline(signal),\n });\n}\n\nexport async function cancelWebMcpInvocation(page: DevToolsPage, invocationId: string) {\n const cleanupSignal = AbortSignal.timeout(1_000);\n const client = await connectWebMcpPage(page, cleanupSignal);\n try {\n await client.send(\"WebMCP.cancelInvocation\", { invocationId }, { signal: cleanupSignal });\n } finally {\n client.close();\n }\n}\n\nexport async function enableWebMcpIdentityTracking(client: CdpClient, signal: AbortSignal) {\n await client.send(\"Page.enable\", {}, { signal, timeoutMs: DEFAULT_TIMEOUT_MS });\n}\n\nexport async function enableWebMcp(client: CdpClient, signal: AbortSignal) {\n const eventController = new AbortController();\n const eventSignal = AbortSignal.any([signal, eventController.signal]);\n const toolsAdded = client\n .waitForEvent(\n \"WebMCP.toolsAdded\",\n (value): value is { tools: WebMcpProtocolTool[] } => {\n const parsed = parseToolsAdded(value);\n if (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolsAdded event\");\n return true;\n },\n { signal: eventSignal, timeoutMs: DEFAULT_TIMEOUT_MS },\n )\n .then(\n (value) => ({ ok: true as const, value }),\n (error: unknown) => ({ error, ok: false as const }),\n );\n try {\n await client.send(\"WebMCP.enable\", {}, { signal, timeoutMs: DEFAULT_TIMEOUT_MS });\n } catch (error) {\n eventController.abort();\n await toolsAdded;\n throw error;\n }\n try {\n const result = await toolsAdded;\n if (!result.ok) throw result.error;\n const parsed = parseToolsAdded(result.value);\n if (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolsAdded event\");\n return parsed.tools;\n } finally {\n eventController.abort();\n }\n}\n\nexport async function disableWebMcp(client: CdpClient) {\n try {\n await client.send(\"WebMCP.disable\", {}, { timeoutMs: 1_000 });\n } catch {\n // Best-effort cleanup: the target may already be detached or the domain may be unavailable.\n }\n}\n\nexport async function readWebMcpFrames(client: CdpClient, signal: AbortSignal) {\n const result = await client.send<unknown>(\n \"Page.getFrameTree\",\n {},\n {\n signal,\n timeoutMs: DEFAULT_TIMEOUT_MS,\n },\n );\n const frames = parseFrameTree(result);\n if (!frames) throw new Error(\"Chrome sent a malformed Page.getFrameTree response\");\n return frames;\n}\n\nexport function watchWebMcpIdentity(\n client: CdpClient,\n expected: { documentId: string; frameId: string; toolName: string },\n signal: AbortSignal,\n): WebMcpIdentityWatch {\n const stopController = new AbortController();\n const staleController = new AbortController();\n const watchSignal = AbortSignal.any([signal, stopController.signal]);\n const options = { signal: watchSignal, timeoutMs: IDENTITY_WATCH_TIMEOUT_MS };\n const settleWatch = (create: () => Promise<unknown>) => {\n let watch: Promise<unknown>;\n try {\n watch = create();\n } catch (error) {\n watch = Promise.reject(error);\n }\n return watch.then(\n () => {\n if (staleController.signal.aborted) return;\n staleController.abort(\n new DOMException(\n \"The selected WebMCP document or tool changed before Chrome completed the invocation boundary.\",\n \"AbortError\",\n ),\n );\n },\n (error) => {\n if (stopController.signal.aborted || signal.aborted || staleController.signal.aborted) {\n return;\n }\n staleController.abort(error);\n },\n );\n };\n const settledWatches = [\n settleWatch(() =>\n client.waitForEvent(\n \"Page.frameNavigated\",\n (value): value is unknown => frameNavigationChangesIdentity(value, expected.frameId, expected.documentId),\n options,\n ),\n ),\n settleWatch(() =>\n client.waitForEvent(\n \"WebMCP.toolsAdded\",\n (value): value is unknown => toolChangeMatchesIdentity(value, expected),\n options,\n ),\n ),\n settleWatch(() =>\n client.waitForEvent(\n \"WebMCP.toolsRemoved\",\n (value): value is unknown => toolChangeMatchesIdentity(value, expected),\n options,\n ),\n ),\n ];\n return {\n signal: AbortSignal.any([signal, staleController.signal]),\n async dispose() {\n stopController.abort();\n await Promise.allSettled(settledWatches);\n },\n };\n}\n\nexport async function invokeWebMcpTool(\n client: CdpClient,\n request: { frameId: string; input: Record<string, unknown>; toolName: string },\n signal: AbortSignal,\n fallbackCancel?: (invocationId: string) => Promise<unknown>,\n): Promise<WebMcpInvocationResponse> {\n signal.throwIfAborted();\n let invocationId: string | undefined;\n let cancellation: Promise<unknown> | undefined;\n const cancel = () => {\n if (!invocationId || cancellation) return;\n const invocationToCancel = invocationId;\n const recoverCancellation = () =>\n fallbackCancel ? fallbackCancel(invocationToCancel).catch(() => undefined) : Promise.resolve();\n try {\n cancellation = client\n .send(\"WebMCP.cancelInvocation\", { invocationId }, { timeoutMs: 1_000 })\n .catch(recoverCancellation);\n } catch {\n cancellation = recoverCancellation();\n }\n };\n const onAbort = () => cancel();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n try {\n let response: unknown;\n try {\n response = await client.send<unknown>(\n \"WebMCP.invokeTool\",\n { frameId: request.frameId, toolName: request.toolName, input: request.input },\n { timeoutMs: DEFAULT_TIMEOUT_MS },\n );\n } catch (error) {\n if (signal.aborted) throw signal.reason;\n throw error;\n }\n invocationId = parseInvocationId(response);\n if (!invocationId) throw new Error(\"Chrome sent a malformed WebMCP.invokeTool response\");\n if (signal.aborted) cancel();\n let event: WebMcpInvocationResponse;\n try {\n event = await client.waitForEvent(\n \"WebMCP.toolResponded\",\n (value): value is WebMcpInvocationResponse => {\n const parsed = parseToolResponded(value);\n if (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolResponded event\");\n return parsed.invocationId === invocationId;\n },\n { timeoutMs: DEFAULT_TIMEOUT_MS },\n );\n } catch (error) {\n cancel();\n await cancellation;\n if (signal.aborted) throw signal.reason;\n throw error;\n }\n if (signal.aborted) throw signal.reason;\n return event;\n } finally {\n signal.removeEventListener(\"abort\", onAbort);\n await cancellation;\n }\n}\n\nfunction findDomain(value: unknown, name: string): Record<string, unknown> | undefined {\n if (!Array.isArray(value)) return undefined;\n return value.find(\n (candidate): candidate is Record<string, unknown> => isRecord(candidate) && candidate.domain === name,\n );\n}\n\nfunction hasNamedEntries(value: unknown, required: readonly string[]) {\n if (!Array.isArray(value)) return false;\n const names = new Set(\n value.flatMap((candidate) => (isRecord(candidate) && typeof candidate.name === \"string\" ? [candidate.name] : [])),\n );\n return required.every((name) => names.has(name));\n}\n\nfunction parseToolsAdded(value: unknown): { tools: WebMcpProtocolTool[] } | undefined {\n if (!isRecord(value) || !Array.isArray(value.tools)) return undefined;\n const tools: WebMcpProtocolTool[] = [];\n for (const candidate of value.tools) {\n const tool = parseTool(candidate);\n if (!tool) return undefined;\n tools.push(tool);\n }\n return { tools };\n}\n\nfunction parseTool(value: unknown): WebMcpProtocolTool | undefined {\n if (\n !isRecord(value) ||\n typeof value.name !== \"string\" ||\n typeof value.description !== \"string\" ||\n typeof value.frameId !== \"string\" ||\n (value.inputSchema !== undefined && !isRecord(value.inputSchema)) ||\n (value.title !== undefined && typeof value.title !== \"string\") ||\n (value.backendNodeId !== undefined && typeof value.backendNodeId !== \"number\")\n ) {\n return undefined;\n }\n const annotations = parseAnnotations(value.annotations);\n if (value.annotations !== undefined && !annotations) return undefined;\n return {\n name: value.name,\n description: value.description,\n frameId: value.frameId,\n ...(value.title === undefined ? {} : { title: value.title }),\n ...(value.inputSchema === undefined ? {} : { inputSchema: value.inputSchema }),\n ...(annotations ? { annotations } : {}),\n ...(value.backendNodeId === undefined ? {} : { backendNodeId: value.backendNodeId }),\n };\n}\n\nfunction parseAnnotations(value: unknown): WebMcpProtocolAnnotation | undefined {\n if (value === undefined) return undefined;\n if (!isRecord(value)) return undefined;\n const annotations: WebMcpProtocolAnnotation = {};\n for (const key of [\"autosubmit\", \"consequential\", \"readOnly\", \"untrustedContent\"] as const) {\n if (value[key] === undefined) continue;\n if (typeof value[key] !== \"boolean\") return undefined;\n annotations[key] = value[key];\n }\n return annotations;\n}\n\nfunction parseFrameTree(value: unknown): WebMcpFrame[] | undefined {\n if (!isRecord(value) || !isRecord(value.frameTree)) return undefined;\n const frames: WebMcpFrame[] = [];\n const visit = (tree: unknown): boolean => {\n if (!isRecord(tree) || !isRecord(tree.frame)) return false;\n const frame = tree.frame;\n if (\n typeof frame.id !== \"string\" ||\n typeof frame.loaderId !== \"string\" ||\n typeof frame.url !== \"string\" ||\n (frame.securityOrigin !== undefined && typeof frame.securityOrigin !== \"string\")\n ) {\n return false;\n }\n frames.push({\n id: frame.id,\n loaderId: frame.loaderId,\n url: frame.url,\n ...(frame.securityOrigin === undefined ? {} : { securityOrigin: frame.securityOrigin }),\n });\n if (tree.childFrames === undefined) return true;\n return Array.isArray(tree.childFrames) && tree.childFrames.every(visit);\n };\n return visit(value.frameTree) ? frames : undefined;\n}\n\nfunction frameNavigationChangesIdentity(value: unknown, frameId: string, documentId: string) {\n if (!isRecord(value) || !isRecord(value.frame)) {\n throw new Error(\"Chrome sent a malformed Page.frameNavigated event\");\n }\n if (typeof value.frame.id !== \"string\" || typeof value.frame.loaderId !== \"string\") {\n throw new Error(\"Chrome sent a malformed Page.frameNavigated event\");\n }\n return value.frame.id === frameId && value.frame.loaderId !== documentId;\n}\n\nfunction toolChangeMatchesIdentity(value: unknown, expected: { frameId: string; toolName: string }) {\n if (!isRecord(value) || !Array.isArray(value.tools)) {\n throw new Error(\"Chrome sent a malformed WebMCP tool-change event\");\n }\n return value.tools.some((tool) => {\n if (!isRecord(tool) || typeof tool.frameId !== \"string\" || typeof tool.name !== \"string\") {\n throw new Error(\"Chrome sent a malformed WebMCP tool-change event\");\n }\n return tool.frameId === expected.frameId && tool.name === expected.toolName;\n });\n}\n\nfunction parseInvocationId(value: unknown) {\n return isRecord(value) && typeof value.invocationId === \"string\" ? value.invocationId : undefined;\n}\n\nfunction parseToolResponded(value: unknown): WebMcpInvocationResponse | undefined {\n if (\n !isRecord(value) ||\n typeof value.invocationId !== \"string\" ||\n !([\"Canceled\", \"Completed\", \"Error\"] as const).includes(value.status as never) ||\n (value.errorText !== undefined && typeof value.errorText !== \"string\")\n ) {\n return undefined;\n }\n return {\n invocationId: value.invocationId,\n status: value.status as WebMcpInvocationResponse[\"status\"],\n ...(value.output === undefined ? {} : { output: value.output }),\n ...(value.errorText === undefined ? {} : { errorText: value.errorText }),\n ...(value.exception === undefined ? {} : { exception: value.exception }),\n };\n}\n\nfunction withDeadline(signal: AbortSignal) {\n return AbortSignal.any([signal, AbortSignal.timeout(DEFAULT_TIMEOUT_MS)]);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n", "import { getPage } from \"../cdp-client.js\";\nimport { type DevToolsPage, webMcpOperationIsCurrent } from \"../runtime.js\";\nimport {\n MAX_WEBMCP_TOOLS,\n normalizeWebMcpOutput,\n normalizeWebMcpTool,\n requireMatchingWebMcpTool,\n type WebMcpToolDescriptor,\n type WebMcpToolIdentity,\n webMcpErrorMessage,\n} from \"./policy.js\";\nimport {\n cancelWebMcpInvocation,\n connectWebMcpPage,\n disableWebMcp,\n enableWebMcp,\n enableWebMcpIdentityTracking,\n invokeWebMcpTool,\n readWebMcpFrames,\n requireWebMcpDomain,\n type WebMcpFrame,\n type WebMcpProtocolTool,\n watchWebMcpIdentity,\n} from \"./protocol.js\";\n\nexport interface WebMcpOperationIdentity {\n owner: object;\n sessionGeneration: number;\n signal: AbortSignal;\n webMcpGeneration: number;\n}\n\nexport interface WebMcpInvocationResult {\n invocationId: string;\n output: unknown;\n tool: WebMcpToolDescriptor;\n}\n\nexport async function discoverWebMcpTools(page: DevToolsPage, operation: WebMcpOperationIdentity) {\n assertOperationCurrent(operation);\n await requireWebMcpDomain(operation.signal, operation.owner);\n assertOperationCurrent(operation);\n const client = await connectWebMcpPage(page, operation.signal);\n try {\n const tools = await readInventory(client, page, operation);\n await requireStablePage(client, page, tools, operation);\n return tools;\n } finally {\n await disableWebMcp(client);\n client.close();\n }\n}\n\nexport async function invokeDiscoveredWebMcpTool(\n page: DevToolsPage,\n expected: WebMcpToolIdentity,\n input: Record<string, unknown>,\n operation: WebMcpOperationIdentity,\n): Promise<WebMcpInvocationResult> {\n assertOperationCurrent(operation);\n await requireWebMcpDomain(operation.signal, operation.owner);\n assertOperationCurrent(operation);\n const client = await connectWebMcpPage(page, operation.signal);\n try {\n await enableWebMcpIdentityTracking(client, operation.signal);\n assertOperationCurrent(operation);\n const tools = await readInventory(client, page, operation);\n const tool = requireMatchingWebMcpTool(tools, expected);\n const identityWatch = watchWebMcpIdentity(\n client,\n { documentId: tool.documentId, frameId: tool.frameId, toolName: tool.name },\n operation.signal,\n );\n const guardedOperation = { ...operation, signal: identityWatch.signal };\n try {\n await requireStablePage(client, page, [tool], guardedOperation);\n assertOperationCurrent(guardedOperation);\n const response = await invokeWebMcpTool(\n client,\n { frameId: tool.frameId, toolName: tool.name, input },\n guardedOperation.signal,\n (invocationId) => cancelWebMcpInvocation(page, invocationId),\n );\n assertOperationCurrent(guardedOperation);\n if (response.status === \"Canceled\") {\n throw new DOMException(\"Chrome canceled the WebMCP tool invocation.\", \"AbortError\");\n }\n if (response.status === \"Error\") {\n throw new Error(\n `WebMCP tool failed: ${webMcpErrorMessage(response.errorText ?? remoteExceptionText(response.exception))}`,\n );\n }\n return {\n invocationId: response.invocationId,\n output: normalizeWebMcpOutput(response.output ?? null),\n tool,\n };\n } finally {\n await identityWatch.dispose();\n }\n } finally {\n await disableWebMcp(client);\n client.close();\n }\n}\n\nasync function readInventory(\n client: Awaited<ReturnType<typeof connectWebMcpPage>>,\n page: DevToolsPage,\n operation: WebMcpOperationIdentity,\n) {\n const framesBefore = await readWebMcpFrames(client, operation.signal);\n assertOperationCurrent(operation);\n const protocolTools = await enableWebMcp(client, operation.signal);\n assertOperationCurrent(operation);\n if (protocolTools.length > MAX_WEBMCP_TOOLS) {\n throw new Error(`WebMCP page exposes more than ${MAX_WEBMCP_TOOLS} tools.`);\n }\n const framesAfter = await readWebMcpFrames(client, operation.signal);\n assertOperationCurrent(operation);\n requireStableInventoryDocuments(protocolTools, framesBefore, framesAfter);\n return normalizeInventory(protocolTools, framesAfter, page, operation);\n}\n\nfunction requireStableInventoryDocuments(\n tools: readonly WebMcpProtocolTool[],\n before: readonly WebMcpFrame[],\n after: readonly WebMcpFrame[],\n) {\n const beforeLoaders = new Map(before.map((frame) => [frame.id, frame.loaderId]));\n const afterLoaders = new Map(after.map((frame) => [frame.id, frame.loaderId]));\n for (const frameId of new Set(tools.map((tool) => tool.frameId))) {\n const beforeLoader = beforeLoaders.get(frameId);\n const afterLoader = afterLoaders.get(frameId);\n if (!beforeLoader || !afterLoader || beforeLoader !== afterLoader) {\n throw new Error(\"A WebMCP frame document changed while Chrome was publishing its tool inventory.\");\n }\n }\n}\n\nfunction normalizeInventory(\n protocolTools: readonly WebMcpProtocolTool[],\n frames: readonly WebMcpFrame[],\n page: DevToolsPage,\n operation: WebMcpOperationIdentity,\n) {\n const frameDocuments = new Map(\n frames.map((frame) => [frame.id, { documentId: frame.loaderId, origin: frameOrigin(frame) }]),\n );\n const tools = protocolTools.map((tool) => {\n const frame = frameDocuments.get(tool.frameId);\n if (!frame) {\n throw new Error(`WebMCP tool ${webMcpErrorMessage(tool.name)} belongs to an unknown frame.`);\n }\n return normalizeWebMcpTool(tool, {\n documentId: frame.documentId,\n frameOrigin: frame.origin,\n pageId: page.id,\n pageUrl: page.url,\n sessionGeneration: generationToken(operation),\n });\n });\n const identities = new Set<string>();\n for (const tool of tools) {\n const key = `${tool.frameId}\\u0000${tool.name}`;\n if (identities.has(key)) {\n throw new Error(\n `WebMCP tool identity is duplicated: ${webMcpErrorMessage(tool.name)} in frame ${webMcpErrorMessage(tool.frameId)}.`,\n );\n }\n identities.add(key);\n }\n return tools;\n}\n\nasync function requireStablePage(\n client: Awaited<ReturnType<typeof connectWebMcpPage>>,\n page: DevToolsPage,\n tools: readonly WebMcpToolDescriptor[],\n operation: WebMcpOperationIdentity,\n) {\n const current = await getPage(page.id, {\n sessionOwner: operation.owner,\n signal: operation.signal,\n });\n assertOperationCurrent(operation);\n if (\n current.url !== page.url ||\n current.webSocketDebuggerUrl !== page.webSocketDebuggerUrl ||\n current.type !== page.type\n ) {\n throw new Error(\"The Chrome page navigated or was replaced during the WebMCP operation.\");\n }\n const finalFrames = await readWebMcpFrames(client, operation.signal);\n assertOperationCurrent(operation);\n const finalDocuments = new Map(finalFrames.map((frame) => [frame.id, frame.loaderId]));\n for (const tool of tools) {\n if (finalDocuments.get(tool.frameId) !== tool.documentId) {\n throw new Error(\"A WebMCP frame document changed during the final page identity check.\");\n }\n }\n}\n\nfunction assertOperationCurrent(operation: WebMcpOperationIdentity) {\n operation.signal.throwIfAborted();\n if (!webMcpOperationIsCurrent(operation)) {\n throw new DOMException(\"The WebMCP operation became stale.\", \"AbortError\");\n }\n}\n\nfunction generationToken(operation: WebMcpOperationIdentity) {\n return `${operation.sessionGeneration}:${operation.webMcpGeneration}`;\n}\n\nfunction frameOrigin(frame: WebMcpFrame) {\n if (frame.securityOrigin && frame.securityOrigin !== \"://\") return frame.securityOrigin;\n try {\n return new URL(frame.url).origin;\n } catch {\n throw new Error(`Chrome returned an invalid WebMCP frame URL: ${webMcpErrorMessage(frame.url)}`);\n }\n}\n\nfunction remoteExceptionText(value: unknown) {\n if (typeof value === \"object\" && value !== null) {\n const exception = value as { description?: unknown; value?: unknown };\n if (typeof exception.description === \"string\") return exception.description;\n if (typeof exception.value === \"string\") return exception.value;\n }\n return \"The page reported an unknown tool error.\";\n}\n", "import type { ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { managedBrowserForOwner } from \"../browser-manager.js\";\nimport { getPage, resolvePage, textResult } from \"../cdp-client.js\";\nimport {\n beginWebMcpOperation,\n currentWebMcpGeneration,\n webMcpEnabled,\n webMcpOperationIsCurrent,\n webMcpSessionSignal,\n} from \"../runtime.js\";\nimport { discoverWebMcpTools, invokeDiscoveredWebMcpTool } from \"./discovery.js\";\nimport {\n boundedWebMcpDiscovery,\n boundedWebMcpJson,\n normalizeWebMcpInput,\n requireMatchingWebMcpTool,\n sanitizeWebMcpDisplay,\n validateWebMcpInput,\n type WebMcpToolIdentity,\n webMcpConfirmationMessage,\n webMcpErrorMessage,\n webMcpIdentity,\n} from \"./policy.js\";\n\ninterface ListInput {\n pageId?: string;\n}\n\ninterface CallInput extends Omit<WebMcpToolIdentity, \"name\"> {\n input: Record<string, unknown>;\n toolName: string;\n}\n\nexport async function executeWebMcpListTool(\n params: ListInput,\n toolSignal: AbortSignal | undefined,\n ctx: ExtensionContext,\n) {\n try {\n requireWebMcpEnabled(ctx.sessionManager);\n const preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);\n const preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);\n preflightSignal.throwIfAborted();\n const page = await resolvePage(params.pageId, {\n sessionOwner: ctx.sessionManager,\n signal: preflightSignal,\n });\n preflightSignal.throwIfAborted();\n requireCurrentPreflight(ctx.sessionManager, preflightGeneration);\n const operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);\n try {\n const tools = await discoverWebMcpTools(page, operation);\n assertCurrent(operation);\n const published = boundedWebMcpDiscovery({ id: page.id, title: page.title, url: page.url }, tools);\n return textResult(published.text, {\n page: { id: page.id, url: page.url },\n toolCount: tools.length,\n publishedToolCount: published.included.length,\n truncated: published.truncated,\n identities: published.included.map(webMcpIdentity),\n });\n } finally {\n operation.dispose();\n }\n } catch (error) {\n throw safeToolError(error);\n }\n}\n\nexport async function executeWebMcpCallTool(\n params: CallInput,\n toolSignal: AbortSignal | undefined,\n ctx: ExtensionContext,\n) {\n try {\n requireWebMcpEnabled(ctx.sessionManager);\n if (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n throw new Error(\n \"chrome_devtools_webmcp_call_tool requires observable confirmation in TUI or RPC mode and is unavailable in print or JSON mode.\",\n );\n }\n const input = normalizeWebMcpInput(params.input);\n const expected = expectedIdentity(params);\n const preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);\n const preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);\n preflightSignal.throwIfAborted();\n const page = await getPage(params.pageId, {\n sessionOwner: ctx.sessionManager,\n signal: preflightSignal,\n });\n preflightSignal.throwIfAborted();\n requireCurrentPreflight(ctx.sessionManager, preflightGeneration);\n const operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);\n try {\n const discovered = await discoverWebMcpTools(page, operation);\n const current = requireMatchingWebMcpTool(discovered, expected);\n const validatedInput = validateWebMcpInput(current.inputSchema, input);\n assertCurrent(operation);\n const confirmed = await ctx.ui.confirm(\n `Allow WebMCP tool: ${sanitizeWebMcpDisplay(current.name, 256)}`,\n webMcpConfirmationMessage(current, validatedInput, usesManagedProfile(ctx.sessionManager)),\n { signal: operation.signal },\n );\n assertCurrent(operation);\n if (!confirmed) {\n throw new DOMException(\"WebMCP tool call cancelled by the user.\", \"AbortError\");\n }\n const invocation = await invokeDiscoveredWebMcpTool(page, expected, validatedInput, operation);\n assertCurrent(operation);\n const published = boundedWebMcpJson({\n status: \"completed\",\n tool: webMcpIdentity(invocation.tool),\n output: invocation.output,\n });\n return textResult(published.text, {\n invocationId: invocation.invocationId,\n tool: webMcpIdentity(invocation.tool),\n truncated: published.truncated,\n output: published.text,\n });\n } finally {\n operation.dispose();\n }\n } catch (error) {\n throw safeToolError(error);\n }\n}\n\nfunction requireWebMcpEnabled(owner: object) {\n if (!webMcpEnabled(owner)) {\n throw new Error(\n \"WebMCP is disabled. Enable the experimental user setting in /chrome-devtools settings, then make the WebMCP gateway tools available.\",\n );\n }\n}\n\nfunction combinedSignal(owner: object, toolSignal: AbortSignal | undefined) {\n const sessionSignal = webMcpSessionSignal(owner);\n return toolSignal ? AbortSignal.any([toolSignal, sessionSignal]) : sessionSignal;\n}\n\nfunction requireCurrentPreflight(owner: object, generation: number) {\n requireWebMcpEnabled(owner);\n if (generation !== currentWebMcpGeneration(owner)) {\n throw new DOMException(\"The WebMCP operation became stale during page resolution.\", \"AbortError\");\n }\n}\n\nfunction expectedIdentity(params: CallInput): WebMcpToolIdentity {\n return {\n sessionGeneration: params.sessionGeneration,\n pageId: params.pageId,\n documentId: params.documentId,\n frameId: params.frameId,\n frameOrigin: params.frameOrigin,\n name: params.toolName,\n schemaDigest: params.schemaDigest,\n };\n}\n\nfunction assertCurrent(operation: ReturnType<typeof beginWebMcpOperation>) {\n operation.signal.throwIfAborted();\n if (!webMcpOperationIsCurrent(operation)) {\n throw new DOMException(\"The WebMCP operation became stale.\", \"AbortError\");\n }\n}\n\nfunction usesManagedProfile(owner: object) {\n const managedBrowser = managedBrowserForOwner(owner);\n return Boolean(managedBrowser?.ready && !managedBrowser.exited);\n}\n\nfunction safeToolError(error: unknown) {\n const message = webMcpErrorMessage(error);\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return new DOMException(message, \"AbortError\");\n }\n return new Error(message);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["frameOrigin", "publication", "isRecord"]
7
+ }
package/dist/index.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  setActivePageId,
10
10
  textResult,
11
11
  withCdp
12
- } from "./chunks/chunk-GTTYS5GT.js";
12
+ } from "./chunks/chunk-4B3EQHOH.ts";
13
13
  import {
14
14
  allChromeDevtoolsTools,
15
15
  availableChromeDevtoolsTools,
@@ -25,7 +25,7 @@ import {
25
25
  supportsNativeDeferredToolLoading,
26
26
  updateChromeDevtoolsTools,
27
27
  waitForChromeDevtoolsSettings
28
- } from "./chunks/chunk-LLXOCRNF.js";
28
+ } from "./chunks/chunk-V7N3WI5B.ts";
29
29
  import {
30
30
  CHROME_DEVTOOLS_TOOL_NAMES,
31
31
  WEBMCP_TOOL_NAMES,
@@ -40,7 +40,7 @@ import {
40
40
  syncManagedBrowserSettings,
41
41
  waitForSettingsWrites,
42
42
  webMcpEnabled
43
- } from "./chunks/chunk-SRT3UUIP.js";
43
+ } from "./chunks/chunk-LSJSDY2M.ts";
44
44
 
45
45
  // src/tools.ts
46
46
  import { defineTool } from "@earendil-works/pi-coding-agent";
@@ -184,9 +184,7 @@ async function ensureSafeScreenshotParent(resolvedPath) {
184
184
  const parentPath = dirname(resolvedPath.path);
185
185
  const rootPath = selectAllowedRoot(parentPath, resolvedPath.allowedRoots);
186
186
  if (!rootPath) {
187
- throw new Error(
188
- "Screenshot savePath parent must stay inside the current working directory or OS temp directory."
189
- );
187
+ throw new Error("Screenshot savePath parent must stay inside the current working directory or OS temp directory.");
190
188
  }
191
189
  const realRootPath = await realpath(rootPath);
192
190
  let currentPath = rootPath;
@@ -237,17 +235,13 @@ async function assertSafeScreenshotTargetPath(resolvedPath) {
237
235
  const realParent = await realpath(dirname(resolvedPath.path));
238
236
  const realTargetPath = join(realParent, basename(resolvedPath.path));
239
237
  if (!realAllowedRoots.some((root) => isPathInsideRoot(realTargetPath, root))) {
240
- throw new Error(
241
- "Screenshot savePath resolves outside the current working directory or OS temp directory."
242
- );
238
+ throw new Error("Screenshot savePath resolves outside the current working directory or OS temp directory.");
243
239
  }
244
240
  }
245
241
  async function assertPathWithinRealRoot(path, realRootPath) {
246
242
  const realPath = await realpath(path);
247
243
  if (!isPathInsideRoot(realPath, realRootPath)) {
248
- throw new Error(
249
- "Screenshot savePath parent resolves outside the current working directory or OS temp directory."
250
- );
244
+ throw new Error("Screenshot savePath parent resolves outside the current working directory or OS temp directory.");
251
245
  }
252
246
  }
253
247
  async function writeScreenshotFileSafely(resolvedPath, pngBytes, signal) {
@@ -347,9 +341,7 @@ var navigateTool = defineTool({
347
341
  description: "Navigate a Chrome page to a URL through Chrome DevTools Protocol, creating a page first if none is available.",
348
342
  parameters: Type.Object({
349
343
  url: Type.String({ description: "URL to navigate to." }),
350
- pageId: Type.Optional(
351
- Type.String({ description: "Optional page id. Defaults to selected or first page." })
352
- )
344
+ pageId: Type.Optional(Type.String({ description: "Optional page id. Defaults to selected or first page." }))
353
345
  }),
354
346
  renderCall: renderToolCall("navigate"),
355
347
  renderResult: renderTextResult,
@@ -379,9 +371,7 @@ var evaluateTool = defineTool({
379
371
  description: "Evaluate JavaScript in a Chrome page through Chrome DevTools Protocol.",
380
372
  parameters: Type.Object({
381
373
  expression: Type.String({ description: "JavaScript expression to evaluate." }),
382
- pageId: Type.Optional(
383
- Type.String({ description: "Optional page id. Defaults to selected or first page." })
384
- ),
374
+ pageId: Type.Optional(Type.String({ description: "Optional page id. Defaults to selected or first page." })),
385
375
  awaitPromise: Type.Optional(
386
376
  Type.Boolean({ description: "Whether to await a returned Promise. Defaults to true." })
387
377
  )
@@ -423,7 +413,7 @@ var webMcpListToolsTool = defineTool({
423
413
  renderResult: renderTextResult,
424
414
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
425
415
  return withStatus(ctx, "list WebMCP tools", async () => {
426
- const implementation = await import("./chunks/tools-6P7EUX37.js");
416
+ const implementation = await import("./chunks/tools-OVNH45IJ.ts");
427
417
  return implementation.executeWebMcpListTool(params, signal, ctx);
428
418
  });
429
419
  }
@@ -465,7 +455,7 @@ var webMcpCallTool = defineTool({
465
455
  renderResult: renderTextResult,
466
456
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
467
457
  return withStatus(ctx, "call WebMCP tool", async () => {
468
- const implementation = await import("./chunks/tools-6P7EUX37.js");
458
+ const implementation = await import("./chunks/tools-OVNH45IJ.ts");
469
459
  return implementation.executeWebMcpCallTool(params, signal, ctx);
470
460
  });
471
461
  }
@@ -475,12 +465,8 @@ var screenshotTool = defineTool({
475
465
  label: "Chrome DevTools: Screenshot",
476
466
  description: "Capture a PNG screenshot from a Chrome page through Chrome DevTools Protocol.",
477
467
  parameters: Type.Object({
478
- pageId: Type.Optional(
479
- Type.String({ description: "Optional page id. Defaults to selected or first page." })
480
- ),
481
- fullPage: Type.Optional(
482
- Type.Boolean({ description: "Capture the full document, not just the viewport." })
483
- ),
468
+ pageId: Type.Optional(Type.String({ description: "Optional page id. Defaults to selected or first page." })),
469
+ fullPage: Type.Optional(Type.Boolean({ description: "Capture the full document, not just the viewport." })),
484
470
  savePath: Type.Optional(
485
471
  Type.String({
486
472
  description: "Screenshot is always saved as a PNG file. Optional output path; omitted defaults to a unique temp file. Relative paths resolve from the current working directory. A single leading @ is stripped to match Pi file-mention paths. Existing regular files are replaced."
@@ -609,10 +595,7 @@ function chromeDevtools(pi) {
609
595
  configureChromeDevtoolsToolExposure(pi, availableTools, ctx.model);
610
596
  });
611
597
  pi.on("model_select", (event, ctx) => {
612
- invalidateWebMcpOperations(
613
- ctx.sessionManager,
614
- "Chrome DevTools model and tool exposure changed"
615
- );
598
+ invalidateWebMcpOperations(ctx.sessionManager, "Chrome DevTools model and tool exposure changed");
616
599
  if (!supportsNativeDeferredToolLoading(event.model)) {
617
600
  requireEagerChromeDevtoolsToolExposure(pi);
618
601
  }
@@ -656,7 +639,7 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
656
639
  if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
657
640
  throw new Error("/chrome-devtools settings requires TUI or RPC mode");
658
641
  }
659
- const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-IMB6HXSU.js");
642
+ const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-FVMCCUPM.ts");
660
643
  if (generation !== state.sessionGeneration) return;
661
644
  await showChromeDevtoolsBrowserSettings(pi, ctx, generation);
662
645
  return;
@@ -665,18 +648,13 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
665
648
  if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
666
649
  throw new Error("/chrome-devtools tools requires TUI or RPC mode");
667
650
  }
668
- const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-UJETYMSB.js");
651
+ const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-MTPSLDHZ.ts");
669
652
  if (generation !== state.sessionGeneration) return;
670
653
  await showChromeDevtoolsToolWorkflow(pi, ctx, generation);
671
654
  return;
672
655
  }
673
656
  case "enable":
674
- await updateChromeDevtoolsTools(
675
- pi,
676
- ctx,
677
- allChromeDevtoolsTools(ctx.sessionManager),
678
- "made all available"
679
- );
657
+ await updateChromeDevtoolsTools(pi, ctx, allChromeDevtoolsTools(ctx.sessionManager), "made all available");
680
658
  return;
681
659
  case "disable":
682
660
  await updateChromeDevtoolsTools(pi, ctx, [], "made all unavailable");
@@ -701,7 +679,7 @@ async function showMenu(pi, ctx, generation) {
701
679
  if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
702
680
  throw new Error("/chrome-devtools menu requires TUI or RPC mode; use a direct subcommand");
703
681
  }
704
- const { showChromeDevtoolsMenu } = await import("./chunks/menu-UJETYMSB.js");
682
+ const { showChromeDevtoolsMenu } = await import("./chunks/menu-MTPSLDHZ.ts");
705
683
  if (generation !== state.sessionGeneration) return;
706
684
  await showChromeDevtoolsMenu(pi, ctx, generation);
707
685
  }
@@ -724,9 +702,7 @@ function parseCommand(args) {
724
702
  function commandCompletions(prefix) {
725
703
  const normalized = prefix.trimStart().toLowerCase();
726
704
  if (/\s/.test(normalized)) return null;
727
- const matches = COMMAND_COMPLETIONS.filter(
728
- (completion) => completion.value.startsWith(normalized)
729
- );
705
+ const matches = COMMAND_COMPLETIONS.filter((completion) => completion.value.startsWith(normalized));
730
706
  return matches.length > 0 ? matches : null;
731
707
  }
732
708
  export {