@narumitw/pi-chrome-devtools 0.53.0 → 0.53.1
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 -1
- package/dist/chunks/{browser-settings-menu-N5O65I7S.js → browser-settings-menu-REIU7C3Q.js} +5 -3
- package/dist/chunks/browser-settings-menu-REIU7C3Q.js.map +7 -0
- package/dist/chunks/{chunk-RTECHAEZ.js → chunk-GTTYS5GT.js} +20 -9
- package/dist/chunks/chunk-GTTYS5GT.js.map +7 -0
- package/dist/chunks/{chunk-GVBXT3FB.js → chunk-SRT3UUIP.js} +117 -73
- package/dist/chunks/chunk-SRT3UUIP.js.map +7 -0
- package/dist/chunks/{chunk-B7B63PWB.js → chunk-YJVYJ2L2.js} +19 -15
- package/dist/chunks/chunk-YJVYJ2L2.js.map +7 -0
- package/dist/chunks/{menu-UBHW6UP2.js → menu-H5HMVGHI.js} +4 -4
- package/dist/chunks/{tools-V7OR5KJ3.js → tools-6P7EUX37.js} +49 -30
- package/dist/chunks/tools-6P7EUX37.js.map +7 -0
- package/dist/index.ts +16 -12
- package/dist/index.ts.map +2 -2
- package/package.json +1 -1
- package/src/browser-manager.ts +138 -72
- package/src/browser-settings-menu.ts +2 -1
- package/src/cdp-client.ts +18 -7
- package/src/chrome-devtools.ts +8 -1
- package/src/tool-selector.ts +18 -14
- package/src/tools.ts +5 -5
- package/src/webmcp/policy.ts +14 -7
- package/src/webmcp/protocol.ts +33 -21
- package/dist/chunks/browser-settings-menu-N5O65I7S.js.map +0 -7
- package/dist/chunks/chunk-B7B63PWB.js.map +0 -7
- package/dist/chunks/chunk-GVBXT3FB.js.map +0 -7
- package/dist/chunks/chunk-RTECHAEZ.js.map +0 -7
- package/dist/chunks/tools-V7OR5KJ3.js.map +0 -7
- /package/dist/chunks/{menu-UBHW6UP2.js.map → menu-H5HMVGHI.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getPage,
|
|
6
6
|
resolvePage,
|
|
7
7
|
textResult
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GTTYS5GT.js";
|
|
9
9
|
import {
|
|
10
10
|
DEFAULT_TIMEOUT_MS,
|
|
11
11
|
beginWebMcpOperation,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
webMcpEnabled,
|
|
16
16
|
webMcpOperationIsCurrent,
|
|
17
17
|
webMcpSessionSignal
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SRT3UUIP.js";
|
|
19
19
|
|
|
20
20
|
// src/webmcp/policy.ts
|
|
21
21
|
import { createHash } from "node:crypto";
|
|
@@ -251,6 +251,14 @@ function rejectRegexBearingSchema(schema) {
|
|
|
251
251
|
}
|
|
252
252
|
function rejectExpensiveValidationSchema(schema) {
|
|
253
253
|
let branches = 0;
|
|
254
|
+
const countBranches = (count) => {
|
|
255
|
+
branches += count;
|
|
256
|
+
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
|
+
);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
254
262
|
const visit = (candidate) => {
|
|
255
263
|
if (Array.isArray(candidate)) {
|
|
256
264
|
for (const child of candidate) visit(child);
|
|
@@ -259,13 +267,12 @@ function rejectExpensiveValidationSchema(schema) {
|
|
|
259
267
|
if (!isRecord(candidate)) return;
|
|
260
268
|
for (const keyword of ["allOf", "anyOf", "oneOf"]) {
|
|
261
269
|
const alternatives = candidate[keyword];
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
270
|
+
if (Array.isArray(alternatives)) countBranches(alternatives.length);
|
|
271
|
+
}
|
|
272
|
+
for (const keyword of ["dependencies", "dependentSchemas"]) {
|
|
273
|
+
const dependencies = candidate[keyword];
|
|
274
|
+
if (!isRecord(dependencies)) continue;
|
|
275
|
+
countBranches(Object.values(dependencies).filter(isRecord).length);
|
|
269
276
|
}
|
|
270
277
|
for (const child of Object.values(candidate)) visit(child);
|
|
271
278
|
};
|
|
@@ -420,25 +427,14 @@ function watchWebMcpIdentity(client, expected, signal) {
|
|
|
420
427
|
const staleController = new AbortController();
|
|
421
428
|
const watchSignal = AbortSignal.any([signal, stopController.signal]);
|
|
422
429
|
const options = { signal: watchSignal, timeoutMs: IDENTITY_WATCH_TIMEOUT_MS };
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
(value) => toolChangeMatchesIdentity(value, expected),
|
|
432
|
-
options
|
|
433
|
-
),
|
|
434
|
-
client.waitForEvent(
|
|
435
|
-
"WebMCP.toolsRemoved",
|
|
436
|
-
(value) => toolChangeMatchesIdentity(value, expected),
|
|
437
|
-
options
|
|
438
|
-
)
|
|
439
|
-
];
|
|
440
|
-
const settledWatches = watches.map(
|
|
441
|
-
(watch) => watch.then(
|
|
430
|
+
const settleWatch = (create) => {
|
|
431
|
+
let watch;
|
|
432
|
+
try {
|
|
433
|
+
watch = create();
|
|
434
|
+
} catch (error) {
|
|
435
|
+
watch = Promise.reject(error);
|
|
436
|
+
}
|
|
437
|
+
return watch.then(
|
|
442
438
|
() => {
|
|
443
439
|
if (staleController.signal.aborted) return;
|
|
444
440
|
staleController.abort(
|
|
@@ -454,8 +450,31 @@ function watchWebMcpIdentity(client, expected, signal) {
|
|
|
454
450
|
}
|
|
455
451
|
staleController.abort(error);
|
|
456
452
|
}
|
|
453
|
+
);
|
|
454
|
+
};
|
|
455
|
+
const settledWatches = [
|
|
456
|
+
settleWatch(
|
|
457
|
+
() => client.waitForEvent(
|
|
458
|
+
"Page.frameNavigated",
|
|
459
|
+
(value) => frameNavigationChangesIdentity(value, expected.frameId, expected.documentId),
|
|
460
|
+
options
|
|
461
|
+
)
|
|
462
|
+
),
|
|
463
|
+
settleWatch(
|
|
464
|
+
() => client.waitForEvent(
|
|
465
|
+
"WebMCP.toolsAdded",
|
|
466
|
+
(value) => toolChangeMatchesIdentity(value, expected),
|
|
467
|
+
options
|
|
468
|
+
)
|
|
469
|
+
),
|
|
470
|
+
settleWatch(
|
|
471
|
+
() => client.waitForEvent(
|
|
472
|
+
"WebMCP.toolsRemoved",
|
|
473
|
+
(value) => toolChangeMatchesIdentity(value, expected),
|
|
474
|
+
options
|
|
475
|
+
)
|
|
457
476
|
)
|
|
458
|
-
|
|
477
|
+
];
|
|
459
478
|
return {
|
|
460
479
|
signal: AbortSignal.any([signal, staleController.signal]),
|
|
461
480
|
async dispose() {
|
|
@@ -942,4 +961,4 @@ export {
|
|
|
942
961
|
executeWebMcpCallTool,
|
|
943
962
|
executeWebMcpListTool
|
|
944
963
|
};
|
|
945
|
-
//# sourceMappingURL=tools-
|
|
964
|
+
//# sourceMappingURL=tools-6P7EUX37.js.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 {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttruncateHead,\n} 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\tannotations: WebMcpProtocolAnnotation;\n\tdescription: string;\n\tdocumentId: string;\n\tframeId: string;\n\tframeOrigin: string;\n\tinputSchema: Record<string, unknown>;\n\tname: string;\n\tpageId: string;\n\tpageUrl: string;\n\tschemaDigest: string;\n\tsessionGeneration: string;\n\ttitle?: string;\n}\n\nexport interface WebMcpToolIdentity {\n\tdocumentId: string;\n\tframeId: string;\n\tframeOrigin: string;\n\tname: string;\n\tpageId: string;\n\tschemaDigest: string;\n\tsessionGeneration: string;\n}\n\nexport function normalizeWebMcpTool(\n\ttool: WebMcpProtocolTool,\n\tcontext: {\n\t\tdocumentId: string;\n\t\tframeOrigin: string;\n\t\tpageId: string;\n\t\tpageUrl: string;\n\t\tsessionGeneration: string;\n\t},\n): WebMcpToolDescriptor {\n\tconst name = boundedString(tool.name, \"tool name\", 512, { nonEmpty: true });\n\tconst description = boundedString(tool.description, \"tool description\", 16 * 1024);\n\tconst title =\n\t\ttool.title === undefined ? undefined : boundedString(tool.title, \"tool title\", 1_024);\n\tconst documentId = boundedString(context.documentId, \"document loader ID\", 512, {\n\t\tnonEmpty: true,\n\t});\n\tconst frameId = boundedString(tool.frameId, \"frame ID\", 512, { nonEmpty: true });\n\tconst frameOrigin = boundedString(context.frameOrigin, \"frame origin\", 2_048, {\n\t\tnonEmpty: true,\n\t});\n\tconst pageId = boundedString(context.pageId, \"page ID\", 512, { nonEmpty: true });\n\tconst pageUrl = boundedString(context.pageUrl, \"page URL\", 8_192);\n\tconst inputSchema = tool.inputSchema ?? { type: \"object\", additionalProperties: true };\n\trejectRegexBearingSchema(inputSchema);\n\tconst canonicalSchema = canonicalJsonObject(inputSchema, {\n\t\tlabel: \"WebMCP input schema\",\n\t\tmaxBytes: MAX_SCHEMA_BYTES,\n\t\tmaxDepth: MAX_JSON_DEPTH,\n\t\tmaxNodes: MAX_JSON_NODES,\n\t});\n\trejectExpensiveValidationSchema(canonicalSchema);\n\tconst annotations = canonicalAnnotations(tool.annotations);\n\tconst schemaDigest = createHash(\"sha256\")\n\t\t.update(canonicalStringify({ inputSchema: canonicalSchema, annotations }))\n\t\t.digest(\"hex\");\n\treturn {\n\t\tannotations,\n\t\tdescription,\n\t\tdocumentId,\n\t\tframeId,\n\t\tframeOrigin,\n\t\tinputSchema: canonicalSchema,\n\t\tname,\n\t\tpageId,\n\t\tpageUrl,\n\t\tschemaDigest,\n\t\tsessionGeneration: context.sessionGeneration,\n\t\t...(title === undefined ? {} : { title }),\n\t};\n}\n\nexport function webMcpIdentity(tool: WebMcpToolDescriptor): WebMcpToolIdentity {\n\treturn {\n\t\tsessionGeneration: tool.sessionGeneration,\n\t\tpageId: tool.pageId,\n\t\tdocumentId: tool.documentId,\n\t\tframeId: tool.frameId,\n\t\tframeOrigin: tool.frameOrigin,\n\t\tname: tool.name,\n\t\tschemaDigest: tool.schemaDigest,\n\t};\n}\n\nexport function requireMatchingWebMcpTool(\n\ttools: readonly WebMcpToolDescriptor[],\n\texpected: WebMcpToolIdentity,\n) {\n\tconst candidates = tools.filter(\n\t\t(tool) => tool.frameId === expected.frameId && tool.name === expected.name,\n\t);\n\tif (candidates.length === 0) throw new Error(\"The selected WebMCP tool is no longer available.\");\n\tif (candidates.length > 1) {\n\t\tthrow new Error(\"The selected WebMCP tool identity is ambiguous in its frame.\");\n\t}\n\tconst current = candidates[0];\n\tif (!current) throw new Error(\"The selected WebMCP tool is no longer available.\");\n\tconst mismatches = (\n\t\t[\n\t\t\t[\"session generation\", current.sessionGeneration, expected.sessionGeneration],\n\t\t\t[\"page\", current.pageId, expected.pageId],\n\t\t\t[\"document\", current.documentId, expected.documentId],\n\t\t\t[\"frame\", current.frameId, expected.frameId],\n\t\t\t[\"frame origin\", current.frameOrigin, expected.frameOrigin],\n\t\t\t[\"schema or annotations\", current.schemaDigest, expected.schemaDigest],\n\t\t] as const\n\t).flatMap(([label, actual, wanted]) => (actual === wanted ? [] : [label]));\n\tif (mismatches.length > 0) {\n\t\tthrow new Error(`The selected WebMCP tool became stale: ${mismatches.join(\", \")} changed.`);\n\t}\n\treturn current;\n}\n\nexport function normalizeWebMcpInput(input: Record<string, unknown>) {\n\treturn canonicalJsonObject(input, {\n\t\tlabel: \"WebMCP tool input\",\n\t\tmaxBytes: MAX_INPUT_BYTES,\n\t\tmaxDepth: MAX_JSON_DEPTH,\n\t\tmaxNodes: MAX_JSON_NODES,\n\t});\n}\n\nexport function validateWebMcpInput(\n\tschema: Record<string, unknown>,\n\tinput: Record<string, unknown>,\n) {\n\tconst normalized = normalizeWebMcpInput(input);\n\tlet valid: boolean;\n\ttry {\n\t\tvalid = Check(schema as TSchema, normalized);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`The page provided a WebMCP input schema that cannot be validated: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t}\n\tif (!valid) throw new Error(\"WebMCP tool input does not match the current page-provided schema.\");\n\treturn normalized;\n}\n\nexport function normalizeWebMcpOutput(output: unknown) {\n\treturn canonicalJsonValue(output, {\n\t\tlabel: \"WebMCP tool output\",\n\t\tmaxBytes: MAX_OUTPUT_BYTES,\n\t\tmaxDepth: MAX_JSON_DEPTH * 2,\n\t\tmaxNodes: MAX_OUTPUT_NODES,\n\t});\n}\n\nexport function boundedWebMcpDiscovery(\n\tpage: { id: string; title: string; url: string },\n\ttools: readonly WebMcpToolDescriptor[],\n) {\n\tconst included: WebMcpToolDescriptor[] = [];\n\tfor (const tool of tools) {\n\t\tconst candidate = [...included, tool];\n\t\tconst publication = boundedWebMcpJson({\n\t\t\tpage,\n\t\t\ttools: candidate,\n\t\t\ttotalToolCount: tools.length,\n\t\t\ttruncated: candidate.length < tools.length,\n\t\t});\n\t\tif (publication.truncated) break;\n\t\tincluded.push(tool);\n\t}\n\tconst truncated = included.length < tools.length;\n\tconst publication = boundedWebMcpJson({\n\t\tpage,\n\t\ttools: included,\n\t\ttotalToolCount: tools.length,\n\t\ttruncated,\n\t});\n\tif (publication.truncated) {\n\t\tthrow new Error(\"WebMCP discovery metadata cannot fit within Pi's output limit.\");\n\t}\n\treturn { ...publication, included, truncated };\n}\n\nexport function boundedWebMcpJson(value: unknown) {\n\tconst serialized = sanitizeWebMcpDisplay(JSON.stringify(value, null, 2), Number.MAX_SAFE_INTEGER);\n\tconst result = truncateHead(serialized, {\n\t\tmaxBytes: Math.max(1, DEFAULT_MAX_BYTES - 256),\n\t\tmaxLines: Math.max(1, DEFAULT_MAX_LINES - 2),\n\t});\n\tif (!result.truncated) return { text: result.content, truncated: false };\n\tconst notice = `\\n[WebMCP output truncated: ${result.outputLines}/${result.totalLines} lines, ${formatSize(result.outputBytes)}/${formatSize(result.totalBytes)}.]`;\n\treturn { text: `${result.content}${notice}`, truncated: true };\n}\n\nexport function webMcpConfirmationMessage(\n\ttool: WebMcpToolDescriptor,\n\tinput: Record<string, unknown>,\n\tmanagedProfile: boolean,\n) {\n\tconst inputSummary = sanitizeWebMcpDisplay(JSON.stringify(input, null, 2), 2_000);\n\treturn [\n\t\tmanagedProfile\n\t\t\t? \"This call uses the isolated browser profile managed by Pi.\"\n\t\t\t: \"Warning: this call uses an attached browser profile that may contain everyday authenticated sessions and sensitive state.\",\n\t\t`Page: ${sanitizeWebMcpDisplay(tool.pageUrl, 4_096)}`,\n\t\t`Frame origin: ${sanitizeWebMcpDisplay(tool.frameOrigin, 2_048)}`,\n\t\t`Tool: ${sanitizeWebMcpDisplay(tool.name, 512)}`,\n\t\t\"Page annotations are untrusted and do not bypass this confirmation.\",\n\t\t\"Input:\",\n\t\tinputSummary,\n\t].join(\"\\n\");\n}\n\nexport function sanitizeWebMcpDisplay(value: string, maxCharacters = 50_000) {\n\tconst withoutBidi = stripVTControlCharacters(value).replace(\n\t\t/[\\u202a-\\u202e\\u2066-\\u2069]/gu,\n\t\t\"\uFFFD\",\n\t);\n\tconst sanitized = Array.from(withoutBidi, (character) => {\n\t\tconst codePoint = character.codePointAt(0) ?? 0;\n\t\tconst unsafeControl =\n\t\t\t(codePoint >= 0 && codePoint <= 8) ||\n\t\t\t(codePoint >= 11 && codePoint <= 31) ||\n\t\t\t(codePoint >= 127 && codePoint <= 159);\n\t\treturn unsafeControl ? \"\uFFFD\" : character;\n\t}).join(\"\");\n\tif (sanitized.length <= maxCharacters) return sanitized;\n\treturn `${sanitized.slice(0, Math.max(0, maxCharacters - 1))}\u2026`;\n}\n\nexport function webMcpErrorMessage(error: unknown) {\n\treturn sanitizeWebMcpDisplay(error instanceof Error ? error.message : String(error), 8_192);\n}\n\nfunction canonicalAnnotations(value: WebMcpProtocolAnnotation | undefined) {\n\tif (!value) return {};\n\treturn Object.fromEntries(\n\t\tObject.entries(value)\n\t\t\t.filter((entry): entry is [string, boolean] => typeof entry[1] === \"boolean\")\n\t\t\t.sort(([left], [right]) => left.localeCompare(right)),\n\t) as WebMcpProtocolAnnotation;\n}\n\nfunction rejectRegexBearingSchema(schema: unknown): void {\n\tif (Array.isArray(schema)) {\n\t\tfor (const child of schema) rejectRegexBearingSchema(child);\n\t\treturn;\n\t}\n\tif (!isRecord(schema)) return;\n\tif (schema.pattern !== undefined || schema.patternProperties !== undefined) {\n\t\tthrow new Error(\n\t\t\t\"WebMCP input schemas with pattern or patternProperties are unsupported because page-controlled regular expressions cannot be evaluated safely.\",\n\t\t);\n\t}\n\tfor (const keyword of [\n\t\t\"additionalItems\",\n\t\t\"additionalProperties\",\n\t\t\"contains\",\n\t\t\"else\",\n\t\t\"if\",\n\t\t\"items\",\n\t\t\"not\",\n\t\t\"propertyNames\",\n\t\t\"then\",\n\t\t\"unevaluatedItems\",\n\t\t\"unevaluatedProperties\",\n\t] as const) {\n\t\trejectRegexBearingSchema(schema[keyword]);\n\t}\n\tfor (const keyword of [\"allOf\", \"anyOf\", \"oneOf\", \"prefixItems\"] as const) {\n\t\tif (Array.isArray(schema[keyword])) {\n\t\t\tfor (const child of schema[keyword]) rejectRegexBearingSchema(child);\n\t\t}\n\t}\n\tfor (const keyword of [\n\t\t\"$defs\",\n\t\t\"definitions\",\n\t\t\"dependencies\",\n\t\t\"dependentSchemas\",\n\t\t\"properties\",\n\t] as const) {\n\t\tif (!isRecord(schema[keyword])) continue;\n\t\tfor (const child of Object.values(schema[keyword])) rejectRegexBearingSchema(child);\n\t}\n}\n\nfunction rejectExpensiveValidationSchema(schema: unknown) {\n\tlet branches = 0;\n\tconst countBranches = (count: number) => {\n\t\tbranches += count;\n\t\tif (branches > MAX_SCHEMA_VALIDATION_BRANCHES) {\n\t\t\tthrow new Error(\n\t\t\t\t`WebMCP input schema exceeds the validation branch limit of ${MAX_SCHEMA_VALIDATION_BRANCHES}.`,\n\t\t\t);\n\t\t}\n\t};\n\tconst visit = (candidate: unknown): void => {\n\t\tif (Array.isArray(candidate)) {\n\t\t\tfor (const child of candidate) visit(child);\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecord(candidate)) return;\n\t\tfor (const keyword of [\"allOf\", \"anyOf\", \"oneOf\"] as const) {\n\t\t\tconst alternatives = candidate[keyword];\n\t\t\tif (Array.isArray(alternatives)) countBranches(alternatives.length);\n\t\t}\n\t\tfor (const keyword of [\"dependencies\", \"dependentSchemas\"] as const) {\n\t\t\tconst dependencies = candidate[keyword];\n\t\t\tif (!isRecord(dependencies)) continue;\n\t\t\tcountBranches(Object.values(dependencies).filter(isRecord).length);\n\t\t}\n\t\tfor (const child of Object.values(candidate)) visit(child);\n\t};\n\tvisit(schema);\n}\n\ninterface JsonLimits {\n\tlabel: string;\n\tmaxBytes: number;\n\tmaxDepth: number;\n\tmaxNodes: number;\n}\n\nfunction canonicalJsonObject(value: Record<string, unknown>, limits: JsonLimits) {\n\tconst canonical = canonicalJsonValue(value, limits);\n\tif (!isRecord(canonical)) throw new Error(`${limits.label} must be a JSON object.`);\n\treturn canonical;\n}\n\nfunction canonicalJsonValue(value: unknown, limits: JsonLimits) {\n\tlet nodes = 0;\n\tconst visit = (candidate: unknown, depth: number): unknown => {\n\t\tnodes += 1;\n\t\tif (nodes > limits.maxNodes) {\n\t\t\tthrow new Error(`${limits.label} exceeds the ${limits.maxNodes} value limit.`);\n\t\t}\n\t\tif (depth > limits.maxDepth) {\n\t\t\tthrow new Error(`${limits.label} exceeds the depth limit of ${limits.maxDepth}.`);\n\t\t}\n\t\tif (candidate === null || typeof candidate === \"string\" || typeof candidate === \"boolean\") {\n\t\t\treturn candidate;\n\t\t}\n\t\tif (typeof candidate === \"number\") {\n\t\t\tif (!Number.isFinite(candidate))\n\t\t\t\tthrow new Error(`${limits.label} contains a non-finite number.`);\n\t\t\treturn candidate;\n\t\t}\n\t\tif (Array.isArray(candidate)) return candidate.map((entry) => visit(entry, depth + 1));\n\t\tif (isRecord(candidate)) {\n\t\t\treturn Object.fromEntries(\n\t\t\t\tObject.keys(candidate)\n\t\t\t\t\t.sort()\n\t\t\t\t\t.map((key) => [key, visit(candidate[key], depth + 1)]),\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`${limits.label} contains a value that is not JSON-compatible.`);\n\t};\n\tconst canonical = visit(value, 0);\n\tconst serialized = canonicalStringify(canonical);\n\tconst bytes = Buffer.byteLength(serialized, \"utf8\");\n\tif (bytes > limits.maxBytes) {\n\t\tthrow new Error(\n\t\t\t`${limits.label} exceeds ${formatSize(limits.maxBytes)} (${formatSize(bytes)}).`,\n\t\t);\n\t}\n\treturn canonical;\n}\n\nfunction canonicalStringify(value: unknown) {\n\tconst serialized = JSON.stringify(value);\n\tif (serialized === undefined) throw new Error(\"Value is not JSON-compatible.\");\n\treturn serialized;\n}\n\nfunction boundedString(\n\tvalue: string,\n\tlabel: string,\n\tmaxBytes: number,\n\toptions: { nonEmpty?: boolean } = {},\n) {\n\tif (options.nonEmpty && value.length === 0) throw new Error(`WebMCP ${label} must not be empty.`);\n\tconst bytes = Buffer.byteLength(value, \"utf8\");\n\tif (bytes > maxBytes) throw new Error(`WebMCP ${label} exceeds ${formatSize(maxBytes)}.`);\n\treturn value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn 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\tautosubmit?: boolean;\n\tconsequential?: boolean;\n\treadOnly?: boolean;\n\tuntrustedContent?: boolean;\n}\n\nexport interface WebMcpProtocolTool {\n\tannotations?: WebMcpProtocolAnnotation;\n\tbackendNodeId?: number;\n\tdescription: string;\n\tframeId: string;\n\tinputSchema?: Record<string, unknown>;\n\tname: string;\n\ttitle?: string;\n}\n\nexport interface WebMcpFrame {\n\tid: string;\n\tloaderId: string;\n\tsecurityOrigin?: string;\n\turl: string;\n}\n\nexport interface WebMcpInvocationResponse {\n\terrorText?: string;\n\texception?: unknown;\n\tinvocationId: string;\n\toutput?: unknown;\n\tstatus: \"Canceled\" | \"Completed\" | \"Error\";\n}\n\nexport interface WebMcpIdentityWatch {\n\tdispose(): Promise<void>;\n\tsignal: AbortSignal;\n}\n\ninterface ProtocolDescription {\n\tdomains?: 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\tsignal.throwIfAborted();\n\tconst protocol = await fetchDevToolsJson<ProtocolDescription>(\n\t\t\"/json/protocol\",\n\t\t{ signal },\n\t\towner,\n\t);\n\tsignal.throwIfAborted();\n\tconst domain = findDomain(protocol.domains, \"WebMCP\");\n\tif (\n\t\t!domain ||\n\t\t!hasNamedEntries(domain.commands, REQUIRED_COMMANDS) ||\n\t\t!hasNamedEntries(domain.events, REQUIRED_EVENTS)\n\t) {\n\t\tthrow new Error(\n\t\t\t\"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\t\t);\n\t}\n}\n\nexport async function connectWebMcpPage(page: DevToolsPage, signal: AbortSignal) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\treturn CdpClient.connect(page.webSocketDebuggerUrl, {\n\t\tsignal: withDeadline(signal),\n\t});\n}\n\nexport async function cancelWebMcpInvocation(page: DevToolsPage, invocationId: string) {\n\tconst cleanupSignal = AbortSignal.timeout(1_000);\n\tconst client = await connectWebMcpPage(page, cleanupSignal);\n\ttry {\n\t\tawait client.send(\"WebMCP.cancelInvocation\", { invocationId }, { signal: cleanupSignal });\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nexport async function enableWebMcpIdentityTracking(client: CdpClient, signal: AbortSignal) {\n\tawait client.send(\"Page.enable\", {}, { signal, timeoutMs: DEFAULT_TIMEOUT_MS });\n}\n\nexport async function enableWebMcp(client: CdpClient, signal: AbortSignal) {\n\tconst eventController = new AbortController();\n\tconst eventSignal = AbortSignal.any([signal, eventController.signal]);\n\tconst toolsAdded = client\n\t\t.waitForEvent(\n\t\t\t\"WebMCP.toolsAdded\",\n\t\t\t(value): value is { tools: WebMcpProtocolTool[] } => {\n\t\t\t\tconst parsed = parseToolsAdded(value);\n\t\t\t\tif (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolsAdded event\");\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\t{ signal: eventSignal, timeoutMs: DEFAULT_TIMEOUT_MS },\n\t\t)\n\t\t.then(\n\t\t\t(value) => ({ ok: true as const, value }),\n\t\t\t(error: unknown) => ({ error, ok: false as const }),\n\t\t);\n\ttry {\n\t\tawait client.send(\"WebMCP.enable\", {}, { signal, timeoutMs: DEFAULT_TIMEOUT_MS });\n\t} catch (error) {\n\t\teventController.abort();\n\t\tawait toolsAdded;\n\t\tthrow error;\n\t}\n\ttry {\n\t\tconst result = await toolsAdded;\n\t\tif (!result.ok) throw result.error;\n\t\tconst parsed = parseToolsAdded(result.value);\n\t\tif (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolsAdded event\");\n\t\treturn parsed.tools;\n\t} finally {\n\t\teventController.abort();\n\t}\n}\n\nexport async function disableWebMcp(client: CdpClient) {\n\ttry {\n\t\tawait client.send(\"WebMCP.disable\", {}, { timeoutMs: 1_000 });\n\t} catch {\n\t\t// Best-effort cleanup: the target may already be detached or the domain may be unavailable.\n\t}\n}\n\nexport async function readWebMcpFrames(client: CdpClient, signal: AbortSignal) {\n\tconst result = await client.send<unknown>(\n\t\t\"Page.getFrameTree\",\n\t\t{},\n\t\t{\n\t\t\tsignal,\n\t\t\ttimeoutMs: DEFAULT_TIMEOUT_MS,\n\t\t},\n\t);\n\tconst frames = parseFrameTree(result);\n\tif (!frames) throw new Error(\"Chrome sent a malformed Page.getFrameTree response\");\n\treturn frames;\n}\n\nexport function watchWebMcpIdentity(\n\tclient: CdpClient,\n\texpected: { documentId: string; frameId: string; toolName: string },\n\tsignal: AbortSignal,\n): WebMcpIdentityWatch {\n\tconst stopController = new AbortController();\n\tconst staleController = new AbortController();\n\tconst watchSignal = AbortSignal.any([signal, stopController.signal]);\n\tconst options = { signal: watchSignal, timeoutMs: IDENTITY_WATCH_TIMEOUT_MS };\n\tconst settleWatch = (create: () => Promise<unknown>) => {\n\t\tlet watch: Promise<unknown>;\n\t\ttry {\n\t\t\twatch = create();\n\t\t} catch (error) {\n\t\t\twatch = Promise.reject(error);\n\t\t}\n\t\treturn watch.then(\n\t\t\t() => {\n\t\t\t\tif (staleController.signal.aborted) return;\n\t\t\t\tstaleController.abort(\n\t\t\t\t\tnew DOMException(\n\t\t\t\t\t\t\"The selected WebMCP document or tool changed before Chrome completed the invocation boundary.\",\n\t\t\t\t\t\t\"AbortError\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\tif (stopController.signal.aborted || signal.aborted || staleController.signal.aborted) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tstaleController.abort(error);\n\t\t\t},\n\t\t);\n\t};\n\tconst settledWatches = [\n\t\tsettleWatch(() =>\n\t\t\tclient.waitForEvent(\n\t\t\t\t\"Page.frameNavigated\",\n\t\t\t\t(value): value is unknown =>\n\t\t\t\t\tframeNavigationChangesIdentity(value, expected.frameId, expected.documentId),\n\t\t\t\toptions,\n\t\t\t),\n\t\t),\n\t\tsettleWatch(() =>\n\t\t\tclient.waitForEvent(\n\t\t\t\t\"WebMCP.toolsAdded\",\n\t\t\t\t(value): value is unknown => toolChangeMatchesIdentity(value, expected),\n\t\t\t\toptions,\n\t\t\t),\n\t\t),\n\t\tsettleWatch(() =>\n\t\t\tclient.waitForEvent(\n\t\t\t\t\"WebMCP.toolsRemoved\",\n\t\t\t\t(value): value is unknown => toolChangeMatchesIdentity(value, expected),\n\t\t\t\toptions,\n\t\t\t),\n\t\t),\n\t];\n\treturn {\n\t\tsignal: AbortSignal.any([signal, staleController.signal]),\n\t\tasync dispose() {\n\t\t\tstopController.abort();\n\t\t\tawait Promise.allSettled(settledWatches);\n\t\t},\n\t};\n}\n\nexport async function invokeWebMcpTool(\n\tclient: CdpClient,\n\trequest: { frameId: string; input: Record<string, unknown>; toolName: string },\n\tsignal: AbortSignal,\n\tfallbackCancel?: (invocationId: string) => Promise<unknown>,\n): Promise<WebMcpInvocationResponse> {\n\tsignal.throwIfAborted();\n\tlet invocationId: string | undefined;\n\tlet cancellation: Promise<unknown> | undefined;\n\tconst cancel = () => {\n\t\tif (!invocationId || cancellation) return;\n\t\tconst invocationToCancel = invocationId;\n\t\tconst recoverCancellation = () =>\n\t\t\tfallbackCancel\n\t\t\t\t? fallbackCancel(invocationToCancel).catch(() => undefined)\n\t\t\t\t: Promise.resolve();\n\t\ttry {\n\t\t\tcancellation = client\n\t\t\t\t.send(\"WebMCP.cancelInvocation\", { invocationId }, { timeoutMs: 1_000 })\n\t\t\t\t.catch(recoverCancellation);\n\t\t} catch {\n\t\t\tcancellation = recoverCancellation();\n\t\t}\n\t};\n\tconst onAbort = () => cancel();\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\tlet response: unknown;\n\t\ttry {\n\t\t\tresponse = await client.send<unknown>(\n\t\t\t\t\"WebMCP.invokeTool\",\n\t\t\t\t{ frameId: request.frameId, toolName: request.toolName, input: request.input },\n\t\t\t\t{ timeoutMs: DEFAULT_TIMEOUT_MS },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tthrow error;\n\t\t}\n\t\tinvocationId = parseInvocationId(response);\n\t\tif (!invocationId) throw new Error(\"Chrome sent a malformed WebMCP.invokeTool response\");\n\t\tif (signal.aborted) cancel();\n\t\tlet event: WebMcpInvocationResponse;\n\t\ttry {\n\t\t\tevent = await client.waitForEvent(\n\t\t\t\t\"WebMCP.toolResponded\",\n\t\t\t\t(value): value is WebMcpInvocationResponse => {\n\t\t\t\t\tconst parsed = parseToolResponded(value);\n\t\t\t\t\tif (!parsed) throw new Error(\"Chrome sent a malformed WebMCP.toolResponded event\");\n\t\t\t\t\treturn parsed.invocationId === invocationId;\n\t\t\t\t},\n\t\t\t\t{ timeoutMs: DEFAULT_TIMEOUT_MS },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tcancel();\n\t\t\tawait cancellation;\n\t\t\tif (signal.aborted) throw signal.reason;\n\t\t\tthrow error;\n\t\t}\n\t\tif (signal.aborted) throw signal.reason;\n\t\treturn event;\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\tawait cancellation;\n\t}\n}\n\nfunction findDomain(value: unknown, name: string): Record<string, unknown> | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\treturn value.find(\n\t\t(candidate): candidate is Record<string, unknown> =>\n\t\t\tisRecord(candidate) && candidate.domain === name,\n\t);\n}\n\nfunction hasNamedEntries(value: unknown, required: readonly string[]) {\n\tif (!Array.isArray(value)) return false;\n\tconst names = new Set(\n\t\tvalue.flatMap((candidate) =>\n\t\t\tisRecord(candidate) && typeof candidate.name === \"string\" ? [candidate.name] : [],\n\t\t),\n\t);\n\treturn required.every((name) => names.has(name));\n}\n\nfunction parseToolsAdded(value: unknown): { tools: WebMcpProtocolTool[] } | undefined {\n\tif (!isRecord(value) || !Array.isArray(value.tools)) return undefined;\n\tconst tools: WebMcpProtocolTool[] = [];\n\tfor (const candidate of value.tools) {\n\t\tconst tool = parseTool(candidate);\n\t\tif (!tool) return undefined;\n\t\ttools.push(tool);\n\t}\n\treturn { tools };\n}\n\nfunction parseTool(value: unknown): WebMcpProtocolTool | undefined {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.name !== \"string\" ||\n\t\ttypeof value.description !== \"string\" ||\n\t\ttypeof value.frameId !== \"string\" ||\n\t\t(value.inputSchema !== undefined && !isRecord(value.inputSchema)) ||\n\t\t(value.title !== undefined && typeof value.title !== \"string\") ||\n\t\t(value.backendNodeId !== undefined && typeof value.backendNodeId !== \"number\")\n\t) {\n\t\treturn undefined;\n\t}\n\tconst annotations = parseAnnotations(value.annotations);\n\tif (value.annotations !== undefined && !annotations) return undefined;\n\treturn {\n\t\tname: value.name,\n\t\tdescription: value.description,\n\t\tframeId: value.frameId,\n\t\t...(value.title === undefined ? {} : { title: value.title }),\n\t\t...(value.inputSchema === undefined ? {} : { inputSchema: value.inputSchema }),\n\t\t...(annotations ? { annotations } : {}),\n\t\t...(value.backendNodeId === undefined ? {} : { backendNodeId: value.backendNodeId }),\n\t};\n}\n\nfunction parseAnnotations(value: unknown): WebMcpProtocolAnnotation | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isRecord(value)) return undefined;\n\tconst annotations: WebMcpProtocolAnnotation = {};\n\tfor (const key of [\"autosubmit\", \"consequential\", \"readOnly\", \"untrustedContent\"] as const) {\n\t\tif (value[key] === undefined) continue;\n\t\tif (typeof value[key] !== \"boolean\") return undefined;\n\t\tannotations[key] = value[key];\n\t}\n\treturn annotations;\n}\n\nfunction parseFrameTree(value: unknown): WebMcpFrame[] | undefined {\n\tif (!isRecord(value) || !isRecord(value.frameTree)) return undefined;\n\tconst frames: WebMcpFrame[] = [];\n\tconst visit = (tree: unknown): boolean => {\n\t\tif (!isRecord(tree) || !isRecord(tree.frame)) return false;\n\t\tconst frame = tree.frame;\n\t\tif (\n\t\t\ttypeof frame.id !== \"string\" ||\n\t\t\ttypeof frame.loaderId !== \"string\" ||\n\t\t\ttypeof frame.url !== \"string\" ||\n\t\t\t(frame.securityOrigin !== undefined && typeof frame.securityOrigin !== \"string\")\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tframes.push({\n\t\t\tid: frame.id,\n\t\t\tloaderId: frame.loaderId,\n\t\t\turl: frame.url,\n\t\t\t...(frame.securityOrigin === undefined ? {} : { securityOrigin: frame.securityOrigin }),\n\t\t});\n\t\tif (tree.childFrames === undefined) return true;\n\t\treturn Array.isArray(tree.childFrames) && tree.childFrames.every(visit);\n\t};\n\treturn visit(value.frameTree) ? frames : undefined;\n}\n\nfunction frameNavigationChangesIdentity(value: unknown, frameId: string, documentId: string) {\n\tif (!isRecord(value) || !isRecord(value.frame)) {\n\t\tthrow new Error(\"Chrome sent a malformed Page.frameNavigated event\");\n\t}\n\tif (typeof value.frame.id !== \"string\" || typeof value.frame.loaderId !== \"string\") {\n\t\tthrow new Error(\"Chrome sent a malformed Page.frameNavigated event\");\n\t}\n\treturn value.frame.id === frameId && value.frame.loaderId !== documentId;\n}\n\nfunction toolChangeMatchesIdentity(\n\tvalue: unknown,\n\texpected: { frameId: string; toolName: string },\n) {\n\tif (!isRecord(value) || !Array.isArray(value.tools)) {\n\t\tthrow new Error(\"Chrome sent a malformed WebMCP tool-change event\");\n\t}\n\treturn value.tools.some((tool) => {\n\t\tif (!isRecord(tool) || typeof tool.frameId !== \"string\" || typeof tool.name !== \"string\") {\n\t\t\tthrow new Error(\"Chrome sent a malformed WebMCP tool-change event\");\n\t\t}\n\t\treturn tool.frameId === expected.frameId && tool.name === expected.toolName;\n\t});\n}\n\nfunction parseInvocationId(value: unknown) {\n\treturn isRecord(value) && typeof value.invocationId === \"string\" ? value.invocationId : undefined;\n}\n\nfunction parseToolResponded(value: unknown): WebMcpInvocationResponse | undefined {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.invocationId !== \"string\" ||\n\t\t!([\"Canceled\", \"Completed\", \"Error\"] as const).includes(value.status as never) ||\n\t\t(value.errorText !== undefined && typeof value.errorText !== \"string\")\n\t) {\n\t\treturn undefined;\n\t}\n\treturn {\n\t\tinvocationId: value.invocationId,\n\t\tstatus: value.status as WebMcpInvocationResponse[\"status\"],\n\t\t...(value.output === undefined ? {} : { output: value.output }),\n\t\t...(value.errorText === undefined ? {} : { errorText: value.errorText }),\n\t\t...(value.exception === undefined ? {} : { exception: value.exception }),\n\t};\n}\n\nfunction withDeadline(signal: AbortSignal) {\n\treturn AbortSignal.any([signal, AbortSignal.timeout(DEFAULT_TIMEOUT_MS)]);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn 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\tMAX_WEBMCP_TOOLS,\n\tnormalizeWebMcpOutput,\n\tnormalizeWebMcpTool,\n\trequireMatchingWebMcpTool,\n\ttype WebMcpToolDescriptor,\n\ttype WebMcpToolIdentity,\n\twebMcpErrorMessage,\n} from \"./policy.js\";\nimport {\n\tcancelWebMcpInvocation,\n\tconnectWebMcpPage,\n\tdisableWebMcp,\n\tenableWebMcp,\n\tenableWebMcpIdentityTracking,\n\tinvokeWebMcpTool,\n\treadWebMcpFrames,\n\trequireWebMcpDomain,\n\ttype WebMcpFrame,\n\ttype WebMcpProtocolTool,\n\twatchWebMcpIdentity,\n} from \"./protocol.js\";\n\nexport interface WebMcpOperationIdentity {\n\towner: object;\n\tsessionGeneration: number;\n\tsignal: AbortSignal;\n\twebMcpGeneration: number;\n}\n\nexport interface WebMcpInvocationResult {\n\tinvocationId: string;\n\toutput: unknown;\n\ttool: WebMcpToolDescriptor;\n}\n\nexport async function discoverWebMcpTools(page: DevToolsPage, operation: WebMcpOperationIdentity) {\n\tassertOperationCurrent(operation);\n\tawait requireWebMcpDomain(operation.signal, operation.owner);\n\tassertOperationCurrent(operation);\n\tconst client = await connectWebMcpPage(page, operation.signal);\n\ttry {\n\t\tconst tools = await readInventory(client, page, operation);\n\t\tawait requireStablePage(client, page, tools, operation);\n\t\treturn tools;\n\t} finally {\n\t\tawait disableWebMcp(client);\n\t\tclient.close();\n\t}\n}\n\nexport async function invokeDiscoveredWebMcpTool(\n\tpage: DevToolsPage,\n\texpected: WebMcpToolIdentity,\n\tinput: Record<string, unknown>,\n\toperation: WebMcpOperationIdentity,\n): Promise<WebMcpInvocationResult> {\n\tassertOperationCurrent(operation);\n\tawait requireWebMcpDomain(operation.signal, operation.owner);\n\tassertOperationCurrent(operation);\n\tconst client = await connectWebMcpPage(page, operation.signal);\n\ttry {\n\t\tawait enableWebMcpIdentityTracking(client, operation.signal);\n\t\tassertOperationCurrent(operation);\n\t\tconst tools = await readInventory(client, page, operation);\n\t\tconst tool = requireMatchingWebMcpTool(tools, expected);\n\t\tconst identityWatch = watchWebMcpIdentity(\n\t\t\tclient,\n\t\t\t{ documentId: tool.documentId, frameId: tool.frameId, toolName: tool.name },\n\t\t\toperation.signal,\n\t\t);\n\t\tconst guardedOperation = { ...operation, signal: identityWatch.signal };\n\t\ttry {\n\t\t\tawait requireStablePage(client, page, [tool], guardedOperation);\n\t\t\tassertOperationCurrent(guardedOperation);\n\t\t\tconst response = await invokeWebMcpTool(\n\t\t\t\tclient,\n\t\t\t\t{ frameId: tool.frameId, toolName: tool.name, input },\n\t\t\t\tguardedOperation.signal,\n\t\t\t\t(invocationId) => cancelWebMcpInvocation(page, invocationId),\n\t\t\t);\n\t\t\tassertOperationCurrent(guardedOperation);\n\t\t\tif (response.status === \"Canceled\") {\n\t\t\t\tthrow new DOMException(\"Chrome canceled the WebMCP tool invocation.\", \"AbortError\");\n\t\t\t}\n\t\t\tif (response.status === \"Error\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`WebMCP tool failed: ${webMcpErrorMessage(response.errorText ?? remoteExceptionText(response.exception))}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tinvocationId: response.invocationId,\n\t\t\t\toutput: normalizeWebMcpOutput(response.output ?? null),\n\t\t\t\ttool,\n\t\t\t};\n\t\t} finally {\n\t\t\tawait identityWatch.dispose();\n\t\t}\n\t} finally {\n\t\tawait disableWebMcp(client);\n\t\tclient.close();\n\t}\n}\n\nasync function readInventory(\n\tclient: Awaited<ReturnType<typeof connectWebMcpPage>>,\n\tpage: DevToolsPage,\n\toperation: WebMcpOperationIdentity,\n) {\n\tconst framesBefore = await readWebMcpFrames(client, operation.signal);\n\tassertOperationCurrent(operation);\n\tconst protocolTools = await enableWebMcp(client, operation.signal);\n\tassertOperationCurrent(operation);\n\tif (protocolTools.length > MAX_WEBMCP_TOOLS) {\n\t\tthrow new Error(`WebMCP page exposes more than ${MAX_WEBMCP_TOOLS} tools.`);\n\t}\n\tconst framesAfter = await readWebMcpFrames(client, operation.signal);\n\tassertOperationCurrent(operation);\n\trequireStableInventoryDocuments(protocolTools, framesBefore, framesAfter);\n\treturn normalizeInventory(protocolTools, framesAfter, page, operation);\n}\n\nfunction requireStableInventoryDocuments(\n\ttools: readonly WebMcpProtocolTool[],\n\tbefore: readonly WebMcpFrame[],\n\tafter: readonly WebMcpFrame[],\n) {\n\tconst beforeLoaders = new Map(before.map((frame) => [frame.id, frame.loaderId]));\n\tconst afterLoaders = new Map(after.map((frame) => [frame.id, frame.loaderId]));\n\tfor (const frameId of new Set(tools.map((tool) => tool.frameId))) {\n\t\tconst beforeLoader = beforeLoaders.get(frameId);\n\t\tconst afterLoader = afterLoaders.get(frameId);\n\t\tif (!beforeLoader || !afterLoader || beforeLoader !== afterLoader) {\n\t\t\tthrow new Error(\n\t\t\t\t\"A WebMCP frame document changed while Chrome was publishing its tool inventory.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction normalizeInventory(\n\tprotocolTools: readonly WebMcpProtocolTool[],\n\tframes: readonly WebMcpFrame[],\n\tpage: DevToolsPage,\n\toperation: WebMcpOperationIdentity,\n) {\n\tconst frameDocuments = new Map(\n\t\tframes.map((frame) => [frame.id, { documentId: frame.loaderId, origin: frameOrigin(frame) }]),\n\t);\n\tconst tools = protocolTools.map((tool) => {\n\t\tconst frame = frameDocuments.get(tool.frameId);\n\t\tif (!frame) {\n\t\t\tthrow new Error(`WebMCP tool ${webMcpErrorMessage(tool.name)} belongs to an unknown frame.`);\n\t\t}\n\t\treturn normalizeWebMcpTool(tool, {\n\t\t\tdocumentId: frame.documentId,\n\t\t\tframeOrigin: frame.origin,\n\t\t\tpageId: page.id,\n\t\t\tpageUrl: page.url,\n\t\t\tsessionGeneration: generationToken(operation),\n\t\t});\n\t});\n\tconst identities = new Set<string>();\n\tfor (const tool of tools) {\n\t\tconst key = `${tool.frameId}\\u0000${tool.name}`;\n\t\tif (identities.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`WebMCP tool identity is duplicated: ${webMcpErrorMessage(tool.name)} in frame ${webMcpErrorMessage(tool.frameId)}.`,\n\t\t\t);\n\t\t}\n\t\tidentities.add(key);\n\t}\n\treturn tools;\n}\n\nasync function requireStablePage(\n\tclient: Awaited<ReturnType<typeof connectWebMcpPage>>,\n\tpage: DevToolsPage,\n\ttools: readonly WebMcpToolDescriptor[],\n\toperation: WebMcpOperationIdentity,\n) {\n\tconst current = await getPage(page.id, {\n\t\tsessionOwner: operation.owner,\n\t\tsignal: operation.signal,\n\t});\n\tassertOperationCurrent(operation);\n\tif (\n\t\tcurrent.url !== page.url ||\n\t\tcurrent.webSocketDebuggerUrl !== page.webSocketDebuggerUrl ||\n\t\tcurrent.type !== page.type\n\t) {\n\t\tthrow new Error(\"The Chrome page navigated or was replaced during the WebMCP operation.\");\n\t}\n\tconst finalFrames = await readWebMcpFrames(client, operation.signal);\n\tassertOperationCurrent(operation);\n\tconst finalDocuments = new Map(finalFrames.map((frame) => [frame.id, frame.loaderId]));\n\tfor (const tool of tools) {\n\t\tif (finalDocuments.get(tool.frameId) !== tool.documentId) {\n\t\t\tthrow new Error(\"A WebMCP frame document changed during the final page identity check.\");\n\t\t}\n\t}\n}\n\nfunction assertOperationCurrent(operation: WebMcpOperationIdentity) {\n\toperation.signal.throwIfAborted();\n\tif (!webMcpOperationIsCurrent(operation)) {\n\t\tthrow new DOMException(\"The WebMCP operation became stale.\", \"AbortError\");\n\t}\n}\n\nfunction generationToken(operation: WebMcpOperationIdentity) {\n\treturn `${operation.sessionGeneration}:${operation.webMcpGeneration}`;\n}\n\nfunction frameOrigin(frame: WebMcpFrame) {\n\tif (frame.securityOrigin && frame.securityOrigin !== \"://\") return frame.securityOrigin;\n\ttry {\n\t\treturn new URL(frame.url).origin;\n\t} catch {\n\t\tthrow new Error(\n\t\t\t`Chrome returned an invalid WebMCP frame URL: ${webMcpErrorMessage(frame.url)}`,\n\t\t);\n\t}\n}\n\nfunction remoteExceptionText(value: unknown) {\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst exception = value as { description?: unknown; value?: unknown };\n\t\tif (typeof exception.description === \"string\") return exception.description;\n\t\tif (typeof exception.value === \"string\") return exception.value;\n\t}\n\treturn \"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\tbeginWebMcpOperation,\n\tcurrentWebMcpGeneration,\n\twebMcpEnabled,\n\twebMcpOperationIsCurrent,\n\twebMcpSessionSignal,\n} from \"../runtime.js\";\nimport { discoverWebMcpTools, invokeDiscoveredWebMcpTool } from \"./discovery.js\";\nimport {\n\tboundedWebMcpDiscovery,\n\tboundedWebMcpJson,\n\tnormalizeWebMcpInput,\n\trequireMatchingWebMcpTool,\n\tsanitizeWebMcpDisplay,\n\tvalidateWebMcpInput,\n\ttype WebMcpToolIdentity,\n\twebMcpConfirmationMessage,\n\twebMcpErrorMessage,\n\twebMcpIdentity,\n} from \"./policy.js\";\n\ninterface ListInput {\n\tpageId?: string;\n}\n\ninterface CallInput extends Omit<WebMcpToolIdentity, \"name\"> {\n\tinput: Record<string, unknown>;\n\ttoolName: string;\n}\n\nexport async function executeWebMcpListTool(\n\tparams: ListInput,\n\ttoolSignal: AbortSignal | undefined,\n\tctx: ExtensionContext,\n) {\n\ttry {\n\t\trequireWebMcpEnabled(ctx.sessionManager);\n\t\tconst preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);\n\t\tconst preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);\n\t\tpreflightSignal.throwIfAborted();\n\t\tconst page = await resolvePage(params.pageId, {\n\t\t\tsessionOwner: ctx.sessionManager,\n\t\t\tsignal: preflightSignal,\n\t\t});\n\t\tpreflightSignal.throwIfAborted();\n\t\trequireCurrentPreflight(ctx.sessionManager, preflightGeneration);\n\t\tconst operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);\n\t\ttry {\n\t\t\tconst tools = await discoverWebMcpTools(page, operation);\n\t\t\tassertCurrent(operation);\n\t\t\tconst published = boundedWebMcpDiscovery(\n\t\t\t\t{ id: page.id, title: page.title, url: page.url },\n\t\t\t\ttools,\n\t\t\t);\n\t\t\treturn textResult(published.text, {\n\t\t\t\tpage: { id: page.id, url: page.url },\n\t\t\t\ttoolCount: tools.length,\n\t\t\t\tpublishedToolCount: published.included.length,\n\t\t\t\ttruncated: published.truncated,\n\t\t\t\tidentities: published.included.map(webMcpIdentity),\n\t\t\t});\n\t\t} finally {\n\t\t\toperation.dispose();\n\t\t}\n\t} catch (error) {\n\t\tthrow safeToolError(error);\n\t}\n}\n\nexport async function executeWebMcpCallTool(\n\tparams: CallInput,\n\ttoolSignal: AbortSignal | undefined,\n\tctx: ExtensionContext,\n) {\n\ttry {\n\t\trequireWebMcpEnabled(ctx.sessionManager);\n\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\tthrow new Error(\n\t\t\t\t\"chrome_devtools_webmcp_call_tool requires observable confirmation in TUI or RPC mode and is unavailable in print or JSON mode.\",\n\t\t\t);\n\t\t}\n\t\tconst input = normalizeWebMcpInput(params.input);\n\t\tconst expected = expectedIdentity(params);\n\t\tconst preflightGeneration = currentWebMcpGeneration(ctx.sessionManager);\n\t\tconst preflightSignal = combinedSignal(ctx.sessionManager, toolSignal);\n\t\tpreflightSignal.throwIfAborted();\n\t\tconst page = await getPage(params.pageId, {\n\t\t\tsessionOwner: ctx.sessionManager,\n\t\t\tsignal: preflightSignal,\n\t\t});\n\t\tpreflightSignal.throwIfAborted();\n\t\trequireCurrentPreflight(ctx.sessionManager, preflightGeneration);\n\t\tconst operation = beginWebMcpOperation(ctx.sessionManager, toolSignal);\n\t\ttry {\n\t\t\tconst discovered = await discoverWebMcpTools(page, operation);\n\t\t\tconst current = requireMatchingWebMcpTool(discovered, expected);\n\t\t\tconst validatedInput = validateWebMcpInput(current.inputSchema, input);\n\t\t\tassertCurrent(operation);\n\t\t\tconst confirmed = await ctx.ui.confirm(\n\t\t\t\t`Allow WebMCP tool: ${sanitizeWebMcpDisplay(current.name, 256)}`,\n\t\t\t\twebMcpConfirmationMessage(current, validatedInput, usesManagedProfile(ctx.sessionManager)),\n\t\t\t\t{ signal: operation.signal },\n\t\t\t);\n\t\t\tassertCurrent(operation);\n\t\t\tif (!confirmed) {\n\t\t\t\tthrow new DOMException(\"WebMCP tool call cancelled by the user.\", \"AbortError\");\n\t\t\t}\n\t\t\tconst invocation = await invokeDiscoveredWebMcpTool(\n\t\t\t\tpage,\n\t\t\t\texpected,\n\t\t\t\tvalidatedInput,\n\t\t\t\toperation,\n\t\t\t);\n\t\t\tassertCurrent(operation);\n\t\t\tconst published = boundedWebMcpJson({\n\t\t\t\tstatus: \"completed\",\n\t\t\t\ttool: webMcpIdentity(invocation.tool),\n\t\t\t\toutput: invocation.output,\n\t\t\t});\n\t\t\treturn textResult(published.text, {\n\t\t\t\tinvocationId: invocation.invocationId,\n\t\t\t\ttool: webMcpIdentity(invocation.tool),\n\t\t\t\ttruncated: published.truncated,\n\t\t\t\toutput: published.text,\n\t\t\t});\n\t\t} finally {\n\t\t\toperation.dispose();\n\t\t}\n\t} catch (error) {\n\t\tthrow safeToolError(error);\n\t}\n}\n\nfunction requireWebMcpEnabled(owner: object) {\n\tif (!webMcpEnabled(owner)) {\n\t\tthrow new Error(\n\t\t\t\"WebMCP is disabled. Enable the experimental user setting in /chrome-devtools settings, then make the WebMCP gateway tools available.\",\n\t\t);\n\t}\n}\n\nfunction combinedSignal(owner: object, toolSignal: AbortSignal | undefined) {\n\tconst sessionSignal = webMcpSessionSignal(owner);\n\treturn toolSignal ? AbortSignal.any([toolSignal, sessionSignal]) : sessionSignal;\n}\n\nfunction requireCurrentPreflight(owner: object, generation: number) {\n\trequireWebMcpEnabled(owner);\n\tif (generation !== currentWebMcpGeneration(owner)) {\n\t\tthrow new DOMException(\n\t\t\t\"The WebMCP operation became stale during page resolution.\",\n\t\t\t\"AbortError\",\n\t\t);\n\t}\n}\n\nfunction expectedIdentity(params: CallInput): WebMcpToolIdentity {\n\treturn {\n\t\tsessionGeneration: params.sessionGeneration,\n\t\tpageId: params.pageId,\n\t\tdocumentId: params.documentId,\n\t\tframeId: params.frameId,\n\t\tframeOrigin: params.frameOrigin,\n\t\tname: params.toolName,\n\t\tschemaDigest: params.schemaDigest,\n\t};\n}\n\nfunction assertCurrent(operation: ReturnType<typeof beginWebMcpOperation>) {\n\toperation.signal.throwIfAborted();\n\tif (!webMcpOperationIsCurrent(operation)) {\n\t\tthrow new DOMException(\"The WebMCP operation became stale.\", \"AbortError\");\n\t}\n}\n\nfunction usesManagedProfile(owner: object) {\n\tconst managedBrowser = managedBrowserForOwner(owner);\n\treturn Boolean(managedBrowser?.ready && !managedBrowser.exited);\n}\n\nfunction safeToolError(error: unknown) {\n\tconst message = webMcpErrorMessage(error);\n\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\treturn new DOMException(message, \"AbortError\");\n\t}\n\treturn new Error(message);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["frameOrigin", "publication", "isRecord"]
|
|
7
|
+
}
|
package/dist/index.ts
CHANGED
|
@@ -6,9 +6,10 @@ import {
|
|
|
6
6
|
listPages,
|
|
7
7
|
resolvePage,
|
|
8
8
|
resolvePageForNavigation,
|
|
9
|
+
setActivePageId,
|
|
9
10
|
textResult,
|
|
10
11
|
withCdp
|
|
11
|
-
} from "./chunks/chunk-
|
|
12
|
+
} from "./chunks/chunk-GTTYS5GT.js";
|
|
12
13
|
import {
|
|
13
14
|
allChromeDevtoolsTools,
|
|
14
15
|
availableChromeDevtoolsTools,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
supportsNativeDeferredToolLoading,
|
|
25
26
|
updateChromeDevtoolsTools,
|
|
26
27
|
waitForChromeDevtoolsSettings
|
|
27
|
-
} from "./chunks/chunk-
|
|
28
|
+
} from "./chunks/chunk-YJVYJ2L2.js";
|
|
28
29
|
import {
|
|
29
30
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
30
31
|
WEBMCP_TOOL_NAMES,
|
|
@@ -36,9 +37,10 @@ import {
|
|
|
36
37
|
shutdownManagedBrowser,
|
|
37
38
|
startManagedBrowserSession,
|
|
38
39
|
state,
|
|
40
|
+
syncManagedBrowserSettings,
|
|
39
41
|
waitForSettingsWrites,
|
|
40
42
|
webMcpEnabled
|
|
41
|
-
} from "./chunks/chunk-
|
|
43
|
+
} from "./chunks/chunk-SRT3UUIP.js";
|
|
42
44
|
|
|
43
45
|
// src/tools.ts
|
|
44
46
|
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
@@ -332,7 +334,7 @@ var selectPageTool = defineTool({
|
|
|
332
334
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
333
335
|
return withStatus(ctx, "select page", async () => {
|
|
334
336
|
const page = await getPage(params.pageId, { sessionOwner: ctx.sessionManager, signal });
|
|
335
|
-
|
|
337
|
+
setActivePageId(ctx.sessionManager, page.id);
|
|
336
338
|
return textResult(`Selected page ${page.id}: ${page.title}
|
|
337
339
|
${page.url}`, {
|
|
338
340
|
page: formatPage(page)
|
|
@@ -362,7 +364,7 @@ var navigateTool = defineTool({
|
|
|
362
364
|
await client.send("Page.enable");
|
|
363
365
|
return client.send("Page.navigate", { url: params.url });
|
|
364
366
|
});
|
|
365
|
-
|
|
367
|
+
setActivePageId(ctx.sessionManager, page.id);
|
|
366
368
|
const action = created ? "Created page and navigated" : "Navigated";
|
|
367
369
|
return textResult(`${action} ${page.id} to ${params.url}`, {
|
|
368
370
|
created,
|
|
@@ -401,7 +403,7 @@ var evaluateTool = defineTool({
|
|
|
401
403
|
returnByValue: true
|
|
402
404
|
})
|
|
403
405
|
);
|
|
404
|
-
|
|
406
|
+
setActivePageId(ctx.sessionManager, page.id);
|
|
405
407
|
return textResult(JSON.stringify(result, null, 2), { page: formatPage(page), result });
|
|
406
408
|
});
|
|
407
409
|
}
|
|
@@ -422,7 +424,7 @@ var webMcpListToolsTool = defineTool({
|
|
|
422
424
|
renderResult: renderTextResult,
|
|
423
425
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
424
426
|
return withStatus(ctx, "list WebMCP tools", async () => {
|
|
425
|
-
const implementation = await import("./chunks/tools-
|
|
427
|
+
const implementation = await import("./chunks/tools-6P7EUX37.js");
|
|
426
428
|
return implementation.executeWebMcpListTool(params, signal, ctx);
|
|
427
429
|
});
|
|
428
430
|
}
|
|
@@ -464,7 +466,7 @@ var webMcpCallTool = defineTool({
|
|
|
464
466
|
renderResult: renderTextResult,
|
|
465
467
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
466
468
|
return withStatus(ctx, "call WebMCP tool", async () => {
|
|
467
|
-
const implementation = await import("./chunks/tools-
|
|
469
|
+
const implementation = await import("./chunks/tools-6P7EUX37.js");
|
|
468
470
|
return implementation.executeWebMcpCallTool(params, signal, ctx);
|
|
469
471
|
});
|
|
470
472
|
}
|
|
@@ -514,7 +516,7 @@ var screenshotTool = defineTool({
|
|
|
514
516
|
}
|
|
515
517
|
});
|
|
516
518
|
});
|
|
517
|
-
|
|
519
|
+
setActivePageId(ctx.sessionManager, page.id);
|
|
518
520
|
const savedScreenshot = await saveScreenshot(result.data, params.savePath, ctx.cwd, signal);
|
|
519
521
|
return {
|
|
520
522
|
content: [
|
|
@@ -585,12 +587,14 @@ function chromeDevtools(pi) {
|
|
|
585
587
|
});
|
|
586
588
|
startManagedBrowserSession(ctx.sessionManager);
|
|
587
589
|
if (generation !== state.sessionGeneration) return;
|
|
590
|
+
setActivePageId(ctx.sessionManager, void 0);
|
|
588
591
|
state.activePageId = void 0;
|
|
589
592
|
state.lastLaunchAttempt = void 0;
|
|
590
593
|
const projectTrusted = ctx.isProjectTrusted();
|
|
591
594
|
const settings = await loadSettings({ cwd: ctx.cwd, projectTrusted });
|
|
592
595
|
if (generation !== state.sessionGeneration) return;
|
|
593
596
|
applyRuntimeBrowserSettings(settings.effectiveBrowser, settings.paths, projectTrusted);
|
|
597
|
+
syncManagedBrowserSettings(ctx.sessionManager, settings.effectiveBrowser);
|
|
594
598
|
applyRuntimeWebMcpSetting(settings.effectiveWebMcpEnabled, ctx.sessionManager);
|
|
595
599
|
state.settingsNotice = settings.notice;
|
|
596
600
|
for (const warning of settings.warnings) {
|
|
@@ -653,7 +657,7 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
|
|
|
653
657
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
654
658
|
throw new Error("/chrome-devtools settings requires TUI or RPC mode");
|
|
655
659
|
}
|
|
656
|
-
const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-
|
|
660
|
+
const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-REIU7C3Q.js");
|
|
657
661
|
if (generation !== state.sessionGeneration) return;
|
|
658
662
|
await showChromeDevtoolsBrowserSettings(pi, ctx, generation);
|
|
659
663
|
return;
|
|
@@ -662,7 +666,7 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
|
|
|
662
666
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
663
667
|
throw new Error("/chrome-devtools tools requires TUI or RPC mode");
|
|
664
668
|
}
|
|
665
|
-
const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-
|
|
669
|
+
const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-H5HMVGHI.js");
|
|
666
670
|
if (generation !== state.sessionGeneration) return;
|
|
667
671
|
await showChromeDevtoolsToolWorkflow(pi, ctx, generation);
|
|
668
672
|
return;
|
|
@@ -698,7 +702,7 @@ async function showMenu(pi, ctx, generation) {
|
|
|
698
702
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
699
703
|
throw new Error("/chrome-devtools menu requires TUI or RPC mode; use a direct subcommand");
|
|
700
704
|
}
|
|
701
|
-
const { showChromeDevtoolsMenu } = await import("./chunks/menu-
|
|
705
|
+
const { showChromeDevtoolsMenu } = await import("./chunks/menu-H5HMVGHI.js");
|
|
702
706
|
if (generation !== state.sessionGeneration) return;
|
|
703
707
|
await showChromeDevtoolsMenu(pi, ctx, generation);
|
|
704
708
|
}
|