@narumitw/pi-chrome-devtools 0.53.1 → 0.53.3
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 +89 -230
- package/dist/chunks/{browser-settings-menu-REIU7C3Q.js → browser-settings-menu-SR7KLZT6.js} +16 -42
- package/dist/chunks/browser-settings-menu-SR7KLZT6.js.map +7 -0
- package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4KMN4SFF.js} +2 -2
- package/dist/chunks/chunk-4KMN4SFF.js.map +7 -0
- package/dist/chunks/{chunk-SRT3UUIP.js → chunk-F5VG35UI.js} +23 -74
- package/dist/chunks/chunk-F5VG35UI.js.map +7 -0
- package/dist/chunks/{chunk-YJVYJ2L2.js → chunk-MZCGM6D3.js} +43 -48
- package/dist/chunks/chunk-MZCGM6D3.js.map +7 -0
- package/dist/chunks/{menu-H5HMVGHI.js → menu-YR4VRT7D.js} +10 -23
- package/dist/chunks/menu-YR4VRT7D.js.map +7 -0
- package/dist/chunks/{tools-6P7EUX37.js → tools-6R7Z6HWJ.js} +17 -59
- package/dist/chunks/tools-6R7Z6HWJ.js.map +7 -0
- package/dist/index.ts +23 -48
- package/dist/index.ts.map +2 -2
- package/docs/browser-setup.md +147 -0
- package/package.json +54 -55
- package/src/browser-manager.ts +872 -942
- package/src/browser-settings-menu.ts +315 -350
- package/src/cdp-client.ts +381 -398
- package/src/chrome-devtools.ts +205 -232
- package/src/display.ts +35 -0
- package/src/lazy-tools.ts +158 -181
- package/src/menu.ts +409 -446
- package/src/render.ts +74 -84
- package/src/runtime.ts +137 -140
- package/src/screenshot.ts +170 -186
- package/src/settings.ts +472 -523
- package/src/tool-names.ts +8 -14
- package/src/tool-selector.ts +245 -289
- package/src/tools.ts +218 -226
- package/src/webmcp/discovery.ts +184 -188
- package/src/webmcp/policy.ts +296 -329
- package/src/webmcp/protocol.ts +324 -337
- package/src/webmcp/tools.ts +136 -147
- package/dist/chunks/browser-settings-menu-REIU7C3Q.js.map +0 -7
- package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
- package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
- package/dist/chunks/chunk-YJVYJ2L2.js.map +0 -7
- package/dist/chunks/menu-H5HMVGHI.js.map +0 -7
- package/dist/chunks/tools-6P7EUX37.js.map +0 -7
|
@@ -20,12 +20,10 @@ import {
|
|
|
20
20
|
settingsFilePath,
|
|
21
21
|
state,
|
|
22
22
|
webMcpEnabled
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-F5VG35UI.js";
|
|
24
24
|
|
|
25
25
|
// src/lazy-tools.ts
|
|
26
|
-
import {
|
|
27
|
-
defineTool
|
|
28
|
-
} from "@earendil-works/pi-coding-agent";
|
|
26
|
+
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
29
27
|
import { Type } from "typebox";
|
|
30
28
|
var CHROME_DEVTOOLS_LOAD_TOOL_NAME = "chrome_devtools_load";
|
|
31
29
|
var AVAILABLE_TOOLS_STORE = /* @__PURE__ */ Symbol.for("@narumitw/pi-chrome-devtools.available-tools-store");
|
|
@@ -62,9 +60,7 @@ function configureChromeDevtoolsToolExposure(pi, availableTools, model) {
|
|
|
62
60
|
lazyExposureByApi.set(pi, lazyExposure);
|
|
63
61
|
const exposedTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));
|
|
64
62
|
const nonCapabilityTools = pi.getActiveTools().filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name));
|
|
65
|
-
pi.setActiveTools(
|
|
66
|
-
unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools])
|
|
67
|
-
);
|
|
63
|
+
pi.setActiveTools(unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools]));
|
|
68
64
|
}
|
|
69
65
|
function requireEagerChromeDevtoolsToolExposure(pi) {
|
|
70
66
|
lazyExposureByApi.set(pi, false);
|
|
@@ -88,6 +84,7 @@ function chromeDevtoolsToolExposureMode(pi) {
|
|
|
88
84
|
function supportsNativeDeferredToolLoading(model) {
|
|
89
85
|
if (!model) return false;
|
|
90
86
|
if (model.api === "anthropic-messages") {
|
|
87
|
+
if (model.provider === "fireworks") return false;
|
|
91
88
|
const configured = compatBoolean(model.compat, "supportsToolReferences");
|
|
92
89
|
if (configured !== void 0) return configured;
|
|
93
90
|
if (model.provider !== "anthropic" || model.id.includes("haiku")) return false;
|
|
@@ -173,9 +170,7 @@ function effectiveAvailableTools(pi) {
|
|
|
173
170
|
const owner = sessionOwnerByApi.get(pi);
|
|
174
171
|
const enabled = owner !== void 0 && webMcpEnabled(owner);
|
|
175
172
|
return new Set(
|
|
176
|
-
CHROME_DEVTOOLS_TOOL_NAMES.filter(
|
|
177
|
-
(name) => configured.has(name) && (enabled || !isWebMcpToolName(name))
|
|
178
|
-
)
|
|
173
|
+
CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => configured.has(name) && (enabled || !isWebMcpToolName(name)))
|
|
179
174
|
);
|
|
180
175
|
}
|
|
181
176
|
function compatBoolean(value, key) {
|
|
@@ -192,8 +187,37 @@ function unique(values) {
|
|
|
192
187
|
return [...new Set(values)];
|
|
193
188
|
}
|
|
194
189
|
|
|
190
|
+
// src/display.ts
|
|
191
|
+
var MAX_SANITIZER_INPUT_CODE_UNITS = 5e4;
|
|
192
|
+
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
193
|
+
function sanitizeChromeDevtoolsDisplay(value, maxCharacters = 5e4) {
|
|
194
|
+
const inputWasTruncated = value.length > MAX_SANITIZER_INPUT_CODE_UNITS;
|
|
195
|
+
const boundedInput = inputWasTruncated ? truncateAtGraphemeBoundary(value, MAX_SANITIZER_INPUT_CODE_UNITS) : value;
|
|
196
|
+
const normalizedLineEndings = boundedInput.replace(/\r\n/g, "\n");
|
|
197
|
+
const sanitized = Array.from(normalizedLineEndings, (character) => {
|
|
198
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
199
|
+
const unsafeControl = codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
200
|
+
const unsafeBidi = codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8294 && codePoint <= 8297;
|
|
201
|
+
const loneSurrogate = character.length === 1 && codePoint >= 55296 && codePoint <= 57343;
|
|
202
|
+
return unsafeControl || unsafeBidi || loneSurrogate ? "\uFFFD" : character;
|
|
203
|
+
}).join("");
|
|
204
|
+
const outputLimit = Math.min(maxCharacters, MAX_SANITIZER_INPUT_CODE_UNITS);
|
|
205
|
+
if (!inputWasTruncated && sanitized.length <= outputLimit) return sanitized;
|
|
206
|
+
return `${truncateAtGraphemeBoundary(sanitized, Math.max(0, outputLimit - 1))}\u2026`;
|
|
207
|
+
}
|
|
208
|
+
function truncateAtGraphemeBoundary(value, maxCodeUnits) {
|
|
209
|
+
if (value.length <= maxCodeUnits) return value;
|
|
210
|
+
const boundedLookahead = value.slice(0, Math.max(0, maxCodeUnits) + 2);
|
|
211
|
+
let safeEnd = 0;
|
|
212
|
+
for (const { index, segment } of graphemeSegmenter.segment(boundedLookahead)) {
|
|
213
|
+
const segmentEnd = index + segment.length;
|
|
214
|
+
if (segmentEnd > maxCodeUnits) break;
|
|
215
|
+
safeEnd = segmentEnd;
|
|
216
|
+
}
|
|
217
|
+
return value.slice(0, safeEnd);
|
|
218
|
+
}
|
|
219
|
+
|
|
195
220
|
// src/tool-selector.ts
|
|
196
|
-
import { stripVTControlCharacters } from "node:util";
|
|
197
221
|
function unique2(values) {
|
|
198
222
|
return Array.from(new Set(values));
|
|
199
223
|
}
|
|
@@ -211,13 +235,7 @@ async function updateChromeDevtoolsTools(pi, ctx, selectedTools, action) {
|
|
|
211
235
|
${status}`, "info");
|
|
212
236
|
}
|
|
213
237
|
async function setSelectedChromeDevtoolsTools(pi, ctx, selectedTools, expectedActiveTools) {
|
|
214
|
-
return transactSelectedTools(
|
|
215
|
-
pi,
|
|
216
|
-
ctx,
|
|
217
|
-
selectedTools,
|
|
218
|
-
state.sessionGeneration,
|
|
219
|
-
expectedActiveTools
|
|
220
|
-
);
|
|
238
|
+
return transactSelectedTools(pi, ctx, selectedTools, state.sessionGeneration, expectedActiveTools);
|
|
221
239
|
}
|
|
222
240
|
var toolTransactionQueue = Promise.resolve();
|
|
223
241
|
async function waitForChromeDevtoolsSettings() {
|
|
@@ -248,10 +266,7 @@ async function transactSelectedToolsNow(pi, ctx, selectedTools, expectedGenerati
|
|
|
248
266
|
const previousWebMcpTools = previousAvailableTools.filter(isWebMcpToolName);
|
|
249
267
|
const selectedWebMcpTools = selectedTools.filter(isWebMcpToolName);
|
|
250
268
|
if (!arraysEqual(previousWebMcpTools, selectedWebMcpTools)) {
|
|
251
|
-
invalidateWebMcpOperations(
|
|
252
|
-
ctx.sessionManager,
|
|
253
|
-
"Chrome DevTools WebMCP gateway availability changed"
|
|
254
|
-
);
|
|
269
|
+
invalidateWebMcpOperations(ctx.sessionManager, "Chrome DevTools WebMCP gateway availability changed");
|
|
255
270
|
}
|
|
256
271
|
applyChromeDevtoolsTools(pi, selectedTools);
|
|
257
272
|
await persistSettings(selectedTools);
|
|
@@ -288,9 +303,7 @@ function applyChromeDevtoolsTools(pi, selectedTools) {
|
|
|
288
303
|
function getToolStatusSummary(pi, owner) {
|
|
289
304
|
const chromeToolNames = new Set(CHROME_DEVTOOLS_TOOL_NAMES);
|
|
290
305
|
const activeToolNames = new Set(pi.getActiveTools());
|
|
291
|
-
const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter(
|
|
292
|
-
(name) => activeToolNames.has(name)
|
|
293
|
-
).length;
|
|
306
|
+
const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeToolNames.has(name)).length;
|
|
294
307
|
const availableChromeToolCount = availableChromeDevtoolsTools(pi).length;
|
|
295
308
|
const activeNonChromeToolCount = Array.from(activeToolNames).filter(
|
|
296
309
|
(name) => !chromeToolNames.has(name) && name !== CHROME_DEVTOOLS_LOAD_TOOL_NAME
|
|
@@ -344,9 +357,7 @@ function buildBrowserStatusMessage(owner) {
|
|
|
344
357
|
`Launch mode: ${launchModeLabel(owner)}`,
|
|
345
358
|
`Unpacked extensions: ${browser.extensionPaths.length} (${browser.extensionPathsSource})`,
|
|
346
359
|
`WebMCP: ${webMcpIsEnabled ? "enabled \xB7 experimental" : "disabled \xB7 experimental"}`,
|
|
347
|
-
...webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready ? [
|
|
348
|
-
"WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state."
|
|
349
|
-
] : [],
|
|
360
|
+
...webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready ? ["WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state."] : [],
|
|
350
361
|
...browser.extensionPaths.length > 0 ? ["Unpacked extensions execute trusted browser code in an isolated managed browser."] : [],
|
|
351
362
|
...launchAttemptLines(owner),
|
|
352
363
|
...needsRecovery ? [launchHint(owner), endpointConfigHint()] : []
|
|
@@ -367,19 +378,6 @@ function buildSettingsSetupMessage(owner) {
|
|
|
367
378
|
].join("\n")
|
|
368
379
|
);
|
|
369
380
|
}
|
|
370
|
-
function sanitizeChromeDevtoolsDisplay(value, maxCharacters = 5e4) {
|
|
371
|
-
const withoutBidi = stripVTControlCharacters(value).replace(
|
|
372
|
-
/[\u202a-\u202e\u2066-\u2069]/gu,
|
|
373
|
-
"\uFFFD"
|
|
374
|
-
);
|
|
375
|
-
const sanitized = Array.from(withoutBidi, (character) => {
|
|
376
|
-
const codePoint = character.codePointAt(0) ?? 0;
|
|
377
|
-
const unsafeControl = codePoint >= 0 && codePoint <= 8 || codePoint >= 11 && codePoint <= 31 || codePoint >= 127 && codePoint <= 159;
|
|
378
|
-
return unsafeControl ? "\uFFFD" : character;
|
|
379
|
-
}).join("");
|
|
380
|
-
if (sanitized.length <= maxCharacters) return sanitized;
|
|
381
|
-
return `${sanitized.slice(0, Math.max(0, maxCharacters - 1))}\u2026`;
|
|
382
|
-
}
|
|
383
381
|
function browserSettingsStatusLines(owner) {
|
|
384
382
|
const browser = browserSettingsForOwner(owner);
|
|
385
383
|
const extensionPaths = browser.extensionPaths;
|
|
@@ -395,9 +393,7 @@ function browserSettingsStatusLines(owner) {
|
|
|
395
393
|
...extensionLines,
|
|
396
394
|
`WebMCP: ${webMcpEnabled(owner) ? "enabled \xB7 experimental \xB7 every call requires confirmation" : "disabled \xB7 experimental"}`,
|
|
397
395
|
"Confirmed menu settings apply before the next browser connection; manual JSON edits require /reload or session replacement.",
|
|
398
|
-
...extensionPaths.length > 0 ? [
|
|
399
|
-
"Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code."
|
|
400
|
-
] : []
|
|
396
|
+
...extensionPaths.length > 0 ? ["Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code."] : []
|
|
401
397
|
];
|
|
402
398
|
}
|
|
403
399
|
function buildCommandGuide(owner) {
|
|
@@ -435,8 +431,7 @@ function formatPersistedSelection(tools) {
|
|
|
435
431
|
if (tools.length === CHROME_DEVTOOLS_TOOL_NAMES.length) {
|
|
436
432
|
return `all available (${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
437
433
|
}
|
|
438
|
-
if (tools.length === 0)
|
|
439
|
-
return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
434
|
+
if (tools.length === 0) return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;
|
|
440
435
|
return `${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected: ${tools.join(", ")}`;
|
|
441
436
|
}
|
|
442
437
|
function effectiveCatalog(owner) {
|
|
@@ -456,14 +451,14 @@ export {
|
|
|
456
451
|
availableChromeDevtoolsTools,
|
|
457
452
|
configuredChromeDevtoolsTools,
|
|
458
453
|
createChromeDevtoolsLoadTool,
|
|
454
|
+
sanitizeChromeDevtoolsDisplay,
|
|
459
455
|
updateChromeDevtoolsTools,
|
|
460
456
|
setSelectedChromeDevtoolsTools,
|
|
461
457
|
waitForChromeDevtoolsSettings,
|
|
462
458
|
buildToolStatusMessage,
|
|
463
459
|
buildQuickstartMessage,
|
|
464
460
|
buildBrowserStatusMessage,
|
|
465
|
-
sanitizeChromeDevtoolsDisplay,
|
|
466
461
|
buildCommandGuide,
|
|
467
462
|
allChromeDevtoolsTools
|
|
468
463
|
};
|
|
469
|
-
//# sourceMappingURL=chunk-
|
|
464
|
+
//# sourceMappingURL=chunk-MZCGM6D3.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lazy-tools.ts", "../../src/display.ts", "../../src/tool-selector.ts"],
|
|
4
|
+
"sourcesContent": ["import { defineTool, type ExtensionAPI, type ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { Type } from \"typebox\";\nimport { webMcpEnabled } from \"./runtime.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName, isWebMcpToolName } from \"./tool-names.js\";\n\nexport const CHROME_DEVTOOLS_LOAD_TOOL_NAME = \"chrome_devtools_load\";\n\nconst AVAILABLE_TOOLS_STORE = Symbol.for(\"@narumitw/pi-chrome-devtools.available-tools-store\");\ntype ChromeDevtoolsGlobal = typeof globalThis & {\n [AVAILABLE_TOOLS_STORE]?: WeakMap<ExtensionAPI, Set<ChromeDevToolsToolName>>;\n};\nconst sharedGlobal = globalThis as ChromeDevtoolsGlobal;\nconst existingAvailableToolsStore = sharedGlobal[AVAILABLE_TOOLS_STORE];\nconst availableToolsByApi = existingAvailableToolsStore ?? new WeakMap<ExtensionAPI, Set<ChromeDevToolsToolName>>();\nif (!existingAvailableToolsStore) sharedGlobal[AVAILABLE_TOOLS_STORE] = availableToolsByApi;\nconst lazyExposureByApi = new WeakMap<ExtensionAPI, boolean>();\nconst sessionOwnerByApi = new WeakMap<ExtensionAPI, object>();\n\nconst SEARCH_TEXT: Record<ChromeDevToolsToolName, string> = {\n chrome_devtools_list_pages: \"list open inspectable chrome browser pages tabs targets\",\n chrome_devtools_select_page: \"select choose active chrome browser page tab target\",\n chrome_devtools_navigate: \"navigate open create chrome browser page url website\",\n chrome_devtools_evaluate: \"evaluate run javascript expression dom inspect chrome browser page\",\n chrome_devtools_screenshot: \"capture screenshot png image visual chrome browser page\",\n chrome_devtools_webmcp_list_tools: \"list discover page provided website webmcp tools capabilities experimental\",\n chrome_devtools_webmcp_call_tool: \"call invoke page provided website webmcp tool confirmation experimental\",\n};\n\nexport function setChromeDevtoolsSessionOwner(pi: ExtensionAPI, owner: object) {\n sessionOwnerByApi.set(pi, owner);\n}\n\nexport function initializeAvailableChromeDevtoolsTools(pi: ExtensionAPI) {\n if (availableToolsByApi.has(pi)) return;\n const activeTools = new Set(pi.getActiveTools());\n setAvailableTools(\n pi,\n CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeTools.has(name)),\n );\n}\n\nexport function configureChromeDevtoolsToolExposure(\n pi: ExtensionAPI,\n availableTools: readonly ChromeDevToolsToolName[],\n model?: ExtensionContext[\"model\"],\n) {\n setAvailableTools(pi, availableTools);\n const available = effectiveAvailableTools(pi);\n const lazyExposure = supportsNativeDeferredToolLoading(model);\n lazyExposureByApi.set(pi, lazyExposure);\n const exposedTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n const nonCapabilityTools = pi\n .getActiveTools()\n .filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));\n pi.setActiveTools(unique([...nonCapabilityTools, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...exposedTools]));\n}\n\nexport function requireEagerChromeDevtoolsToolExposure(pi: ExtensionAPI) {\n lazyExposureByApi.set(pi, false);\n const active = pi.getActiveTools();\n const available = availableChromeDevtoolsTools(pi);\n pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...available]));\n}\n\nexport function applyAvailableChromeDevtoolsTools(pi: ExtensionAPI, availableTools: readonly ChromeDevToolsToolName[]) {\n setAvailableTools(pi, availableTools);\n const available = effectiveAvailableTools(pi);\n const lazyExposure = lazyExposureByApi.get(pi) === true;\n const active = pi\n .getActiveTools()\n .filter(\n (name) =>\n !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName) ||\n (lazyExposure && available.has(name as ChromeDevToolsToolName)),\n );\n const eagerTools = lazyExposure ? [] : CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n pi.setActiveTools(unique([...active, CHROME_DEVTOOLS_LOAD_TOOL_NAME, ...eagerTools]));\n}\n\nexport function chromeDevtoolsToolExposureMode(pi: ExtensionAPI) {\n return lazyExposureByApi.get(pi) === true ? \"native deferred\" : \"eager\";\n}\n\nexport function supportsNativeDeferredToolLoading(model: ExtensionContext[\"model\"]): boolean {\n if (!model) return false;\n if (model.api === \"anthropic-messages\") {\n // Fireworks Messages requires the canonical ToolSearch/tool_search loader name.\n // chrome_devtools_load stays package-specific so independently installed loaders cannot collide.\n if (model.provider === \"fireworks\") return false;\n const configured = compatBoolean(model.compat, \"supportsToolReferences\");\n if (configured !== undefined) return configured;\n if (model.provider !== \"anthropic\" || model.id.includes(\"haiku\")) return false;\n const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\\d+)(?:-(\\d+))?(?:-|$)/);\n if (!version) return false;\n const major = Number(version[1]);\n const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;\n return major > 4 || (major === 4 && minor >= 5);\n }\n if (model.api === \"openai-completions\") {\n return compatString(model.compat, \"deferredToolsMode\") === \"kimi\";\n }\n if (model.api === \"openai-responses\" || model.api === \"openai-codex-responses\") {\n return (\n compatBoolean(model.compat, \"supportsAdditionalTools\") === true ||\n compatBoolean(model.compat, \"supportsToolSearch\") === true\n );\n }\n return false;\n}\n\nexport function availableChromeDevtoolsTools(pi: ExtensionAPI) {\n const available = effectiveAvailableTools(pi);\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n}\n\nexport function configuredChromeDevtoolsTools(pi: ExtensionAPI) {\n const available = availableToolsByApi.get(pi) ?? new Set();\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name));\n}\n\nexport function createChromeDevtoolsLoadTool(pi: ExtensionAPI) {\n return defineTool({\n name: CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n label: \"Chrome DevTools: Load Tools\",\n description:\n \"Find and enable Chrome DevTools browser tools relevant to a task. Loaded tools remain available for the session.\",\n promptSnippet: \"Load Chrome DevTools browser capabilities on demand\",\n promptGuidelines: [\n \"Use chrome_devtools_load when a task requires inspecting or controlling a Chrome browser and the needed chrome_devtools_* capability is not active.\",\n ],\n parameters: Type.Object({\n query: Type.String({\n description: \"Browser capability or task to find tools for.\",\n maxLength: 500,\n }),\n limit: Type.Optional(\n Type.Integer({\n description: \"Maximum tools to load. Defaults to 3.\",\n minimum: 1,\n maximum: 5,\n }),\n ),\n }),\n async execute(_toolCallId, params, signal, _onUpdate, ctx) {\n signal?.throwIfAborted();\n setChromeDevtoolsSessionOwner(pi, ctx.sessionManager);\n const available = new Set(availableChromeDevtoolsTools(pi));\n const matches = matchChromeDevtoolsTools(params.query, params.limit ?? 3, available);\n const active = pi.getActiveTools();\n const activeSet = new Set(active);\n const added = matches.filter((name) => !activeSet.has(name));\n if (added.length > 0) {\n pi.setActiveTools(unique([...active, ...added]));\n }\n\n const text =\n matches.length === 0\n ? \"No available Chrome DevTools tools matched the query.\"\n : added.length > 0\n ? `Loaded Chrome DevTools tools: ${added.join(\", \")}`\n : `Matching Chrome DevTools tools are already loaded: ${matches.join(\", \")}`;\n return {\n content: [{ type: \"text\" as const, text }],\n details: { matches, added },\n };\n },\n });\n}\n\nfunction matchChromeDevtoolsTools(query: string, limit: number, available: ReadonlySet<ChromeDevToolsToolName>) {\n const terms = query\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((term) => term.length >= 2);\n if (terms.length === 0) return [];\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => available.has(name))\n .map((name, index) => ({\n name,\n index,\n score: terms.reduce((score, term) => score + (SEARCH_TEXT[name].includes(term) ? 1 : 0), 0),\n }))\n .filter((match) => match.score > 0)\n .sort((left, right) => right.score - left.score || left.index - right.index)\n .slice(0, limit)\n .map((match) => match.name);\n}\n\nfunction setAvailableTools(pi: ExtensionAPI, availableTools: readonly ChromeDevToolsToolName[]) {\n const available = new Set(availableTools);\n availableToolsByApi.set(pi, available);\n return available;\n}\n\nfunction effectiveAvailableTools(pi: ExtensionAPI) {\n const configured = availableToolsByApi.get(pi) ?? new Set();\n const owner = sessionOwnerByApi.get(pi);\n const enabled = owner !== undefined && webMcpEnabled(owner);\n return new Set(\n CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => configured.has(name) && (enabled || !isWebMcpToolName(name))),\n );\n}\n\nfunction compatBoolean(value: unknown, key: string) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n return typeof record[key] === \"boolean\" ? record[key] : undefined;\n}\n\nfunction compatString(value: unknown, key: string) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n return typeof record[key] === \"string\" ? record[key] : undefined;\n}\n\nfunction unique(values: readonly string[]) {\n return [...new Set(values)];\n}\n", "const MAX_SANITIZER_INPUT_CODE_UNITS = 50_000;\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport function sanitizeChromeDevtoolsDisplay(value: string, maxCharacters = 50_000) {\n const inputWasTruncated = value.length > MAX_SANITIZER_INPUT_CODE_UNITS;\n const boundedInput = inputWasTruncated ? truncateAtGraphemeBoundary(value, MAX_SANITIZER_INPUT_CODE_UNITS) : value;\n const normalizedLineEndings = boundedInput.replace(/\\r\\n/g, \"\\n\");\n // Neutralize controls without parsing untrusted terminal sequences; keep printable payload visible.\n const sanitized = Array.from(normalizedLineEndings, (character) => {\n const codePoint = character.codePointAt(0) ?? 0;\n const unsafeControl =\n (codePoint >= 0 && codePoint <= 8) ||\n (codePoint >= 11 && codePoint <= 31) ||\n (codePoint >= 127 && codePoint <= 159);\n const unsafeBidi = (codePoint >= 0x202a && codePoint <= 0x202e) || (codePoint >= 0x2066 && codePoint <= 0x2069);\n const loneSurrogate = character.length === 1 && codePoint >= 0xd800 && codePoint <= 0xdfff;\n return unsafeControl || unsafeBidi || loneSurrogate ? \"\uFFFD\" : character;\n }).join(\"\");\n const outputLimit = Math.min(maxCharacters, MAX_SANITIZER_INPUT_CODE_UNITS);\n if (!inputWasTruncated && sanitized.length <= outputLimit) return sanitized;\n\n return `${truncateAtGraphemeBoundary(sanitized, Math.max(0, outputLimit - 1))}\u2026`;\n}\n\nfunction truncateAtGraphemeBoundary(value: string, maxCodeUnits: number) {\n if (value.length <= maxCodeUnits) return value;\n const boundedLookahead = value.slice(0, Math.max(0, maxCodeUnits) + 2);\n let safeEnd = 0;\n for (const { index, segment } of graphemeSegmenter.segment(boundedLookahead)) {\n const segmentEnd = index + segment.length;\n if (segmentEnd > maxCodeUnits) break;\n safeEnd = segmentEnd;\n }\n return value.slice(0, safeEnd);\n}\n", "import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport {\n browserCandidateHint,\n browserLifecycleState,\n browserSettingsForOwner,\n devToolsEndpoint,\n endpointConfigHint,\n endpointSourceLabel,\n launchAttemptLines,\n launchHint,\n launchModeLabel,\n managedBrowserForOwner,\n} from \"./browser-manager.js\";\nimport { sanitizeChromeDevtoolsDisplay } from \"./display.js\";\nimport {\n applyAvailableChromeDevtoolsTools,\n availableChromeDevtoolsTools,\n CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n chromeDevtoolsToolExposureMode,\n} from \"./lazy-tools.js\";\nimport { invalidateWebMcpOperations, state, webMcpEnabled } from \"./runtime.js\";\nimport { loadSettings, saveSettings, settingsFilePath } from \"./settings.js\";\nimport {\n CHROME_DEVTOOLS_TOOL_NAMES,\n type ChromeDevToolsToolName,\n CORE_CHROME_DEVTOOLS_TOOL_NAMES,\n isWebMcpToolName,\n} from \"./tool-names.js\";\n\nexport { sanitizeChromeDevtoolsDisplay };\n\ntype CommandContext = ExtensionCommandContext;\n\nfunction unique<T>(values: T[]) {\n return Array.from(new Set(values));\n}\n\nfunction formatError(error: unknown) {\n return error instanceof Error ? error.message : String(error);\n}\n\ninterface ToolStatusSummary {\n availabilityStatus: \"enabled\" | \"disabled\" | \"partial\";\n availableChromeToolCount: number;\n loadedChromeToolCount: number;\n activeNonChromeToolCount: number;\n capabilityCount: number;\n}\n\ntype ToolSelectionSaveResult = \"saved\" | \"active-tools-changed\" | \"failed\";\n\nexport async function updateChromeDevtoolsTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n action: string,\n) {\n const generation = state.sessionGeneration;\n const result = await transactSelectedTools(pi, ctx, selectedTools, generation);\n if (result !== \"saved\" || generation !== state.sessionGeneration) return;\n const status = await buildToolStatusMessage(pi, ctx.sessionManager);\n if (generation !== state.sessionGeneration) return;\n ctx.ui.notify(`Chrome DevTools tool catalog ${action}.\\n\\n${status}`, \"info\");\n}\n\nexport async function setSelectedChromeDevtoolsTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedActiveTools: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n return transactSelectedTools(pi, ctx, selectedTools, state.sessionGeneration, expectedActiveTools);\n}\n\nlet toolTransactionQueue = Promise.resolve();\n\nexport async function waitForChromeDevtoolsSettings(): Promise<void> {\n await toolTransactionQueue;\n}\n\nfunction transactSelectedTools(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedGeneration: number,\n expectedActiveTools?: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n const operation = toolTransactionQueue.then(() =>\n transactSelectedToolsNow(pi, ctx, selectedTools, expectedGeneration, expectedActiveTools),\n );\n toolTransactionQueue = operation.then(\n () => undefined,\n () => undefined,\n );\n return operation;\n}\n\nasync function transactSelectedToolsNow(\n pi: ExtensionAPI,\n ctx: CommandContext,\n selectedTools: readonly ChromeDevToolsToolName[],\n expectedGeneration: number,\n expectedActiveTools?: readonly ChromeDevToolsToolName[],\n): Promise<ToolSelectionSaveResult> {\n if (expectedGeneration !== state.sessionGeneration) return \"failed\";\n if (expectedActiveTools && !arraysEqual(availableChromeDevtoolsTools(pi), expectedActiveTools)) {\n ctx.ui.notify(\n \"Browser tool selection changed while review was open. Review the current state, then apply again.\",\n \"warning\",\n );\n return \"active-tools-changed\";\n }\n const previousActiveTools = pi.getActiveTools();\n const previousAvailableTools = availableChromeDevtoolsTools(pi);\n try {\n const previousWebMcpTools = previousAvailableTools.filter(isWebMcpToolName);\n const selectedWebMcpTools = selectedTools.filter(isWebMcpToolName);\n if (!arraysEqual(previousWebMcpTools, selectedWebMcpTools)) {\n invalidateWebMcpOperations(ctx.sessionManager, \"Chrome DevTools WebMCP gateway availability changed\");\n }\n applyChromeDevtoolsTools(pi, selectedTools);\n await persistSettings(selectedTools);\n return expectedGeneration === state.sessionGeneration ? \"saved\" : \"failed\";\n } catch (error) {\n let rollbackError: unknown;\n try {\n applyAvailableChromeDevtoolsTools(pi, previousAvailableTools);\n const currentNonChromeTools = pi\n .getActiveTools()\n .filter((name) => !CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName));\n const previousLoadedChromeTools = previousActiveTools.filter((name) =>\n CHROME_DEVTOOLS_TOOL_NAMES.includes(name as ChromeDevToolsToolName),\n );\n const restoredChromeTools =\n chromeDevtoolsToolExposureMode(pi) === \"eager\" ? previousAvailableTools : previousLoadedChromeTools;\n pi.setActiveTools(unique([...currentNonChromeTools, ...restoredChromeTools]));\n } catch (caught) {\n rollbackError = caught;\n }\n if (expectedGeneration !== state.sessionGeneration) return \"failed\";\n ctx.ui.notify(\n sanitizeChromeDevtoolsDisplay(\n rollbackError\n ? `Chrome DevTools settings save failed: ${formatError(error)}; active-tool rollback failed: ${formatError(rollbackError)}`\n : `Chrome DevTools settings save failed; active tools restored: ${formatError(error)}`,\n ),\n \"warning\",\n );\n return \"failed\";\n }\n}\n\nfunction arraysEqual<T>(left: readonly T[], right: readonly T[]) {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nexport function applyChromeDevtoolsTools(pi: ExtensionAPI, selectedTools: readonly ChromeDevToolsToolName[]) {\n applyAvailableChromeDevtoolsTools(pi, selectedTools);\n}\n\nfunction getToolStatusSummary(pi: ExtensionAPI, owner: object): ToolStatusSummary {\n const chromeToolNames = new Set<string>(CHROME_DEVTOOLS_TOOL_NAMES);\n const activeToolNames = new Set(pi.getActiveTools());\n const loadedChromeToolCount = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => activeToolNames.has(name)).length;\n const availableChromeToolCount = availableChromeDevtoolsTools(pi).length;\n const activeNonChromeToolCount = Array.from(activeToolNames).filter(\n (name) => !chromeToolNames.has(name) && name !== CHROME_DEVTOOLS_LOAD_TOOL_NAME,\n ).length;\n const capabilityCount = effectiveCatalog(owner).length;\n const availabilityStatus =\n availableChromeToolCount === capabilityCount ? \"enabled\" : availableChromeToolCount === 0 ? \"disabled\" : \"partial\";\n\n return {\n availabilityStatus,\n availableChromeToolCount,\n loadedChromeToolCount,\n activeNonChromeToolCount,\n capabilityCount,\n };\n}\n\nexport async function buildToolStatusMessage(pi: ExtensionAPI, owner: object) {\n const summary = getToolStatusSummary(pi, owner);\n const persistedSetting = await persistedSettingLabel();\n return sanitizeChromeDevtoolsDisplay(\n [\n `Chrome DevTools tools available: ${formatRuntimeStatus(summary)}`,\n `Tool exposure: ${chromeDevtoolsToolExposureMode(pi)}`,\n `Loaded capability tools this session: ${summary.loadedChromeToolCount}/${summary.capabilityCount}`,\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 confirmation required for every call\" : \"disabled \u00B7 experimental\"}`,\n `Loader: ${pi.getActiveTools().includes(CHROME_DEVTOOLS_LOAD_TOOL_NAME) ? \"active\" : \"inactive\"}`,\n `Persisted tool catalog: ${persistedSetting}`,\n ...browserSettingsStatusLines(owner),\n ...(state.settingsNotice ? [`Settings note: ${state.settingsNotice}`] : []),\n `Other active tools preserved: ${summary.activeNonChromeToolCount}`,\n `Endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n ...launchAttemptLines(owner),\n ].join(\"\\n\"),\n );\n}\n\nexport function buildQuickstartMessage(owner: object) {\n return buildSettingsSetupMessage(owner);\n}\n\nexport function buildBrowserStatusMessage(owner?: object) {\n const browser = browserSettingsForOwner(owner);\n const lifecycle = browserLifecycleState(owner);\n const webMcpIsEnabled = owner ? webMcpEnabled(owner) : false;\n const browserState =\n lifecycle === \"starting\"\n ? \"starting managed browser\"\n : lifecycle === \"running\"\n ? \"managed browser running\"\n : lifecycle === \"exited\"\n ? \"managed browser exited\"\n : lifecycle === \"failed\"\n ? \"last launch failed\"\n : \"not started; connection has not been checked\";\n const needsRecovery = lifecycle === \"exited\" || lifecycle === \"failed\";\n return sanitizeChromeDevtoolsDisplay(\n [\n `Browser: ${browserState}`,\n \"Viewing this status does not probe the endpoint or launch Chrome.\",\n `Endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n `Unpacked extensions: ${browser.extensionPaths.length} (${browser.extensionPathsSource})`,\n `WebMCP: ${webMcpIsEnabled ? \"enabled \u00B7 experimental\" : \"disabled \u00B7 experimental\"}`,\n ...(webMcpIsEnabled && !managedBrowserForOwner(owner)?.ready\n ? [\"WebMCP warning: attached browser profiles may contain everyday authenticated sessions and sensitive state.\"]\n : []),\n ...(browser.extensionPaths.length > 0\n ? [\"Unpacked extensions execute trusted browser code in an isolated managed browser.\"]\n : []),\n ...launchAttemptLines(owner),\n ...(needsRecovery ? [launchHint(owner), endpointConfigHint()] : []),\n ].join(\"\\n\"),\n );\n}\n\nexport function buildSettingsSetupMessage(owner: object) {\n return sanitizeChromeDevtoolsDisplay(\n [\n `Chrome DevTools endpoint: ${devToolsEndpoint(owner)}`,\n `Endpoint source: ${endpointSourceLabel(owner)}`,\n `Launch mode: ${launchModeLabel(owner)}`,\n ...browserSettingsStatusLines(owner),\n launchHint(owner),\n browserCandidateHint(owner),\n ...launchAttemptLines(owner),\n endpointConfigHint(),\n ].join(\"\\n\"),\n );\n}\n\nfunction browserSettingsStatusLines(owner: object) {\n const browser = browserSettingsForOwner(owner);\n const extensionPaths = browser.extensionPaths;\n const extensionLines =\n extensionPaths.length > 0 ? extensionPaths.map((extensionPath) => ` - ${extensionPath}`) : [\" - none\"];\n return [\n `Settings file: ${state.settingsFilePath ?? settingsFilePath()} (user)`,\n ...(state.projectSettingsFilePath\n ? [\n `Project settings: ${state.projectSettingsFilePath} (${state.projectSettingsTrusted ? \"trusted\" : \"untrusted; ignored\"})`,\n ]\n : []),\n `Auto-launch: ${browser.autoLaunchEnabled ? \"on\" : \"off\"} (${browser.autoLaunchSource})`,\n `Browser executable: ${browser.executablePath ?? \"automatic discovery\"} (${browser.executablePathSource})`,\n `Unpacked extensions (${browser.extensionPathsSource}):`,\n ...extensionLines,\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 every call requires confirmation\" : \"disabled \u00B7 experimental\"}`,\n \"Confirmed menu settings apply before the next browser connection; manual JSON edits require /reload or session replacement.\",\n ...(extensionPaths.length > 0\n ? [\"Unpacked extensions require Chrome for Testing or Chromium and execute trusted browser code.\"]\n : []),\n ];\n}\n\nexport function buildCommandGuide(owner: object) {\n return [\n \"Chrome DevTools commands:\",\n `WebMCP: ${webMcpEnabled(owner) ? \"enabled\" : \"disabled\"} \u00B7 experimental \u00B7 every page-provided call requires confirmation`,\n \"/chrome-devtools \u2014 open this menu\",\n \"/chrome-devtools help \u2014 show command usage\",\n \"/chrome-devtools quickstart \u2014 show endpoint and launch help\",\n \"/chrome-devtools status \u2014 show tool and settings status\",\n \"/chrome-devtools settings \u2014 edit browser connection settings\",\n \"/chrome-devtools tools \u2014 choose available Chrome DevTools tools\",\n \"/chrome-devtools toggle|select \u2014 compatibility aliases for tools\",\n \"/chrome-devtools enable|on \u2014 make all Chrome DevTools tools available\",\n \"/chrome-devtools disable|off \u2014 make all Chrome DevTools capability tools unavailable\",\n ].join(\"\\n\");\n}\n\nexport function allChromeDevtoolsTools(owner: object) {\n return effectiveCatalog(owner);\n}\n\nexport function orderedChromeDevtoolsTools(selectedTools: ReadonlySet<ChromeDevToolsToolName>) {\n return CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => selectedTools.has(toolName));\n}\n\nfunction formatRuntimeStatus(summary: ToolStatusSummary) {\n return `${summary.availabilityStatus} (${summary.availableChromeToolCount}/${summary.capabilityCount} available)`;\n}\n\nasync function persistedSettingLabel() {\n const settings = await loadSettings();\n if (settings.kind === \"loaded\" && settings.settings.tools) {\n return formatPersistedSelection(settings.settings.tools);\n }\n if (settings.kind === \"invalid\") {\n return `none; current active-tool policy preserved (invalid settings ignored: ${settings.reason})`;\n }\n return \"none; current active-tool policy preserved\";\n}\n\nfunction formatPersistedSelection(tools: readonly ChromeDevToolsToolName[]) {\n if (tools.length === CHROME_DEVTOOLS_TOOL_NAMES.length) {\n return `all available (${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;\n }\n if (tools.length === 0) return `all unavailable (0/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected)`;\n return `${tools.length}/${CHROME_DEVTOOLS_TOOL_NAMES.length} selected: ${tools.join(\", \")}`;\n}\n\nfunction effectiveCatalog(owner: object): ChromeDevToolsToolName[] {\n return webMcpEnabled(owner) ? [...CHROME_DEVTOOLS_TOOL_NAMES] : [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];\n}\n\nasync function persistSettings(selectedTools: readonly ChromeDevToolsToolName[]) {\n await saveSettings({ tools: [...selectedTools], updatedAt: Date.now() });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["unique"]
|
|
7
|
+
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
buildCommandGuide,
|
|
7
7
|
sanitizeChromeDevtoolsDisplay,
|
|
8
8
|
setSelectedChromeDevtoolsTools
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MZCGM6D3.js";
|
|
10
10
|
import {
|
|
11
11
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
12
12
|
CORE_CHROME_DEVTOOLS_TOOL_NAMES,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
loadSettings,
|
|
18
18
|
state,
|
|
19
19
|
webMcpEnabled
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-F5VG35UI.js";
|
|
21
21
|
|
|
22
22
|
// src/menu.ts
|
|
23
23
|
import { defineMenu, runMenu, runTask } from "@narumitw/pi-tui-kit";
|
|
@@ -137,7 +137,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
|
|
|
137
137
|
return result?.closeParent ? { kind: "close" } : { kind: "stay" };
|
|
138
138
|
},
|
|
139
139
|
settings: async ({ state: current }) => {
|
|
140
|
-
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-
|
|
140
|
+
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-SR7KLZT6.js");
|
|
141
141
|
if (!isCurrent()) return { kind: "stay" };
|
|
142
142
|
const result = await showChromeDevtoolsBrowserSettings(pi, ctx, generation);
|
|
143
143
|
if (!isCurrent()) return { kind: "stay" };
|
|
@@ -236,8 +236,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
236
236
|
},
|
|
237
237
|
actions: {
|
|
238
238
|
toggle: ({ state: current, itemId, selected }) => {
|
|
239
|
-
if (!isChromeDevtoolsToolName(itemId) || selected === void 0)
|
|
240
|
-
return { kind: "rejected" };
|
|
239
|
+
if (!isChromeDevtoolsToolName(itemId) || selected === void 0) return { kind: "rejected" };
|
|
241
240
|
if (selected) current.draft.add(itemId);
|
|
242
241
|
else current.draft.delete(itemId);
|
|
243
242
|
return { kind: "stay" };
|
|
@@ -258,12 +257,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
258
257
|
return { kind: "rejected" };
|
|
259
258
|
}
|
|
260
259
|
const selectedTools = orderedTools(current.draft);
|
|
261
|
-
const saveResult = await setSelectedChromeDevtoolsTools(
|
|
262
|
-
pi,
|
|
263
|
-
ctx,
|
|
264
|
-
selectedTools,
|
|
265
|
-
orderedTools(current.accepted)
|
|
266
|
-
);
|
|
260
|
+
const saveResult = await setSelectedChromeDevtoolsTools(pi, ctx, selectedTools, orderedTools(current.accepted));
|
|
267
261
|
if (!isCurrent()) return { kind: "rejected" };
|
|
268
262
|
if (saveResult === "active-tools-changed") {
|
|
269
263
|
current.accepted = new Set(activeChromeTools(pi));
|
|
@@ -285,9 +279,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
285
279
|
signal: menuSignal,
|
|
286
280
|
isCurrent,
|
|
287
281
|
onError: (currentCtx, error) => currentCtx.ui.notify(
|
|
288
|
-
sanitizeChromeDevtoolsDisplay(
|
|
289
|
-
`Chrome DevTools tool selection failed: ${formatError(error)}`
|
|
290
|
-
),
|
|
282
|
+
sanitizeChromeDevtoolsDisplay(`Chrome DevTools tool selection failed: ${formatError(error)}`),
|
|
291
283
|
"error"
|
|
292
284
|
)
|
|
293
285
|
});
|
|
@@ -324,9 +316,7 @@ function buildMenuSnapshot(pi, settings) {
|
|
|
324
316
|
const activeTools = activeChromeTools(pi);
|
|
325
317
|
const persistedTools = settings.kind === "loaded" && settings.settings.tools ? orderedTools(new Set(settings.settings.tools)) : void 0;
|
|
326
318
|
const persistenceLabel = settings.kind === "invalid" ? "settings need repair" : persistedTools === void 0 ? "not saved" : arraysEqual(activeTools, persistedTools) ? "saved" : "runtime catalog differs from saved catalog";
|
|
327
|
-
const settingsWarning = [
|
|
328
|
-
...new Set([settings.notice, state.settingsNotice].filter(Boolean))
|
|
329
|
-
].join("\n");
|
|
319
|
+
const settingsWarning = [...new Set([settings.notice, state.settingsNotice].filter(Boolean))].join("\n");
|
|
330
320
|
return {
|
|
331
321
|
activeTools,
|
|
332
322
|
persistenceLabel,
|
|
@@ -335,9 +325,7 @@ function buildMenuSnapshot(pi, settings) {
|
|
|
335
325
|
};
|
|
336
326
|
}
|
|
337
327
|
function mainStateLines(snapshot, owner) {
|
|
338
|
-
const launchError = launchAttemptLines(owner).find(
|
|
339
|
-
(line) => line.startsWith("Last launch error:")
|
|
340
|
-
);
|
|
328
|
+
const launchError = launchAttemptLines(owner).find((line) => line.startsWith("Last launch error:"));
|
|
341
329
|
return sanitizeLines([
|
|
342
330
|
`Tool catalog: ${snapshot.activeTools.length} of ${availableCatalogNames(owner).length} available \xB7 ${snapshot.persistenceLabel}`,
|
|
343
331
|
`WebMCP: ${webMcpEnabled(owner) ? "enabled \xB7 experimental \xB7 confirmation required for every call" : "disabled \xB7 experimental"}`,
|
|
@@ -357,8 +345,7 @@ function browserLifecycleSummary(owner) {
|
|
|
357
345
|
return launchMode.startsWith("attach first") ? "not started \xB7 attaches or launches on first use" : `not started \xB7 ${launchMode}`;
|
|
358
346
|
}
|
|
359
347
|
function toolDraftLines(current, owner) {
|
|
360
|
-
if (current.mutationBlockedReason)
|
|
361
|
-
return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);
|
|
348
|
+
if (current.mutationBlockedReason) return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);
|
|
362
349
|
const changes = symmetricDifferenceSize(current.accepted, current.draft);
|
|
363
350
|
return [
|
|
364
351
|
`Currently available: ${current.accepted.size}/${availableCatalogNames(owner).length}`,
|
|
@@ -428,4 +415,4 @@ export {
|
|
|
428
415
|
showChromeDevtoolsMenu,
|
|
429
416
|
showChromeDevtoolsToolWorkflow
|
|
430
417
|
};
|
|
431
|
-
//# sourceMappingURL=menu-
|
|
418
|
+
//# sourceMappingURL=menu-YR4VRT7D.js.map
|
|
@@ -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": ";;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,YAAY,SAAS,eAAe;AAsC7C,IAAM,oBAA4F;AAAA,EAChG,4BAA4B;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,6BAA6B;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,0BAA0B;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,0BAA0B;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,4BAA4B;AAAA,IAC1B,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,mCAAmC;AAAA,IACjC,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,kCAAkC;AAAA,IAChC,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;AAEA,eAAsB,uBAAuB,IAAkB,KAAqB,YAAoB;AACtG,QAAM,WAAW,MAAM,yBAAyB,IAAI,KAAK,UAAU;AACnE,MAAI,CAAC,SAAU;AACf,QAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAM,YAAY,MAAM,eAAe,MAAM,qBAAqB,CAAC,WAAW;AAC9E,QAAM,OAAO,WAAiD;AAAA,IAC5D,OAAO;AAAA,IACP,SAAS;AAAA,MACP,MAAM,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO,eAAe,SAAS,IAAI,cAAc;AAAA,QACjD,OAAO;AAAA,UACL;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,UAAU,QAAQ,QAAQ,qBAAqB;AAAA,YAC/C,gBAAgB,QAAQ;AAAA,YACxB,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OACE,QAAQ,YAAY,WAAW,sBAAsB,IAAI,cAAc,EAAE,SACrE,6CACA;AAAA,YACN,aACE,QAAQ,YAAY,WAAW,sBAAsB,IAAI,cAAc,EAAE,SACrE,gBAAgB,sBAAsB,IAAI,cAAc,EAAE,MAAM,uCAChE,WAAW,sBAAsB,IAAI,cAAc,EAAE,MAAM,OAAO,sBAAsB,IAAI,cAAc,EAAE,MAAM;AAAA,YACxH,UAAU,QAAQ,QAAQ,qBAAqB;AAAA,YAC/C,gBAAgB,QAAQ;AAAA,YACxB,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,IAAI;AAAA,UACN;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,IAAI;AAAA,UACN;AAAA,QACF;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,eAAe,OAAO;AAAA,QACpB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,0BAA0B,IAAI,cAAc;AAAA,QACrD,QAAQ,EAAE,MAAM,OAAO;AAAA,QACvB,cAAc;AAAA,QACd,MAAM;AAAA,MACR;AAAA,MACA,MAAM,OAAO;AAAA,QACX,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,kBAAkB,IAAI,cAAc;AAAA,QAC7C,QAAQ,EAAE,MAAM,OAAO;AAAA,QACvB,cAAc;AAAA,QACd,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,OAAO,OAAO,EAAE,OAAO,QAAQ,MAAM;AACnC,cAAM,SAAS,MAAM,+BAA+B,IAAI,KAAK,YAAY;AAAA,UACvE,UAAU;AAAA,QACZ,CAAC;AACD,YAAI,QAAQ,WAAW,UAAU,EAAG,0BAAyB,SAAS,OAAO,aAAa;AAC1F,eAAO,QAAQ,cAAc,EAAE,MAAM,QAAQ,IAAI,EAAE,MAAM,OAAO;AAAA,MAClE;AAAA,MACA,MAAM,OAAO,EAAE,OAAO,QAAQ,MAAM;AAClC,cAAM,gBACJ,QAAQ,YAAY,WAAW,sBAAsB,IAAI,cAAc,EAAE,SACrE,CAAC,IACD,sBAAsB,IAAI,cAAc;AAC9C,cAAM,SAAS,MAAM,+BAA+B,IAAI,KAAK,YAAY;AAAA,UACvE,UAAU;AAAA,UACV,cAAc;AAAA,UACd,eAAe;AAAA,QACjB,CAAC;AACD,YAAI,QAAQ,WAAW,UAAU,EAAG,0BAAyB,SAAS,OAAO,aAAa;AAC1F,eAAO,QAAQ,cAAc,EAAE,MAAM,QAAQ,IAAI,EAAE,MAAM,OAAO;AAAA,MAClE;AAAA,MACA,UAAU,OAAO,EAAE,OAAO,QAAQ,MAAM;AACtC,cAAM,EAAE,kCAAkC,IAAI,MAAM,OAAO,qCAA4B;AACvF,YAAI,CAAC,UAAU,EAAG,QAAO,EAAE,MAAM,OAAO;AACxC,cAAM,SAAS,MAAM,kCAAkC,IAAI,KAAK,UAAU;AAC1E,YAAI,CAAC,UAAU,EAAG,QAAO,EAAE,MAAM,OAAO;AACxC,cAAM,YAAY,MAAM,+BAA+B,IAAI,GAAG;AAC9D,YAAI,CAAC,UAAU,EAAG,QAAO,EAAE,MAAM,OAAO;AACxC,eAAO,OAAO,SAAS,SAAS;AAChC,eAAO,OAAO,cAAc,EAAE,MAAM,QAAQ,IAAI,EAAE,MAAM,OAAO;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,KAAK,MAAM;AAAA,IACvB,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,SAAS,CAAC,YAAY,UACpB,WAAW,GAAG;AAAA,MACZ,8BAA8B,gCAAgC,YAAY,KAAK,CAAC,EAAE;AAAA,MAClF;AAAA,IACF;AAAA,EACJ,CAAC;AACH;AAEA,eAAsB,+BACpB,IACA,KACA,YACA,UAII,CAAC,GACqG;AAC1G,QAAM,WAAW,QAAQ,YAAa,MAAM,yBAAyB,IAAI,KAAK,UAAU;AACxF,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAM,YAAY,MAAM,eAAe,MAAM,qBAAqB,CAAC,WAAW;AAC9E,QAAM,WAAW,IAAI,IAAI,SAAS,WAAW;AAC7C,QAAM,WAA8B;AAAA,IAClC;AAAA,IACA,OAAO,IAAI,IAAI,QAAQ,gBAAgB,SAAS,WAAW;AAAA,IAC3D,uBAAuB,SAAS;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,EACX;AACA,QAAM,OAAO,WAAsD;AAAA,IACjE,OAAO,QAAQ,gBAAgB,WAAW;AAAA,IAC1C,SAAS;AAAA,MACP,OAAO,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QAC9B,MAAM;AAAA,QACN,OAAO,kBAAkB,QAAQ,MAAM,IAAI,IAAI,sBAAsB,IAAI,cAAc,EAAE,MAAM;AAAA,QAC/F,OAAO,eAAe,SAAS,IAAI,cAAc;AAAA,QACjD,OAAO,sBAAsB,IAAI,cAAc,EAAE,IAAI,CAAC,cAAc;AAAA,UAClE,IAAI;AAAA,UACJ,OAAO,kBAAkB,QAAQ,EAAE;AAAA,UACnC,aAAa,kBAAkB,QAAQ,EAAE;AAAA,UACzC,YAAY,GAAG,QAAQ,IAAI,kBAAkB,QAAQ,EAAE,WAAW;AAAA,UAClE,UAAU,QAAQ,MAAM,IAAI,QAAQ;AAAA,UACpC,UAAU,QAAQ,QAAQ,qBAAqB;AAAA,UAC/C,gBAAgB,QAAQ;AAAA,QAC1B,EAAE;AAAA,QACF,QAAQ;AAAA,QACR,SAAS;AAAA,UACP;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,QAAQ,QAAQ,qBAAqB;AAAA,YAC/C,gBAAgB,QAAQ;AAAA,YACxB,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,QAAQ,QAAQ,qBAAqB;AAAA,YAC/C,gBAAgB,QAAQ;AAAA,YACxB,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,YACE,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,UAAU,QAAQ,QAAQ,qBAAqB,KAAK,UAAU,QAAQ,UAAU,QAAQ,KAAK;AAAA,YAC7F,gBACE,QAAQ,0BACP,UAAU,QAAQ,UAAU,QAAQ,KAAK,IAAI,yBAAyB;AAAA,YACzE,IAAI;AAAA,UACN;AAAA,UACA,EAAE,IAAI,UAAU,OAAO,UAAU,QAAQ,SAAS;AAAA,QACpD;AAAA,QACA,MAAM;AAAA,MACR;AAAA,MACA,QAAQ,CAAC,EAAE,OAAO,QAAQ,OAAO;AAAA,QAC/B,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,UACL,wBAAwB,QAAQ,SAAS,IAAI,IAAI,sBAAsB,IAAI,cAAc,EAAE,MAAM;AAAA,UACjG,0BAA0B,QAAQ,MAAM,IAAI,IAAI,sBAAsB,IAAI,cAAc,EAAE,MAAM;AAAA,QAClG;AAAA,QACA,SAAS,gBAAgB,SAAS,IAAI,cAAc;AAAA,QACpD,QAAQ,EAAE,MAAM,OAAO;AAAA,QACvB,cAAc;AAAA,QACd,GAAI,QAAQ,yBAAyB,UAAU,QAAQ,UAAU,QAAQ,KAAK,IAC1E,CAAC,IACD;AAAA,UACE,SAAS;AAAA,YACP,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,QAAQ,CAAC,EAAE,OAAO,SAAS,QAAQ,SAAS,MAAM;AAChD,YAAI,CAAC,yBAAyB,MAAM,KAAK,aAAa,OAAW,QAAO,EAAE,MAAM,WAAW;AAC3F,YAAI,SAAU,SAAQ,MAAM,IAAI,MAAM;AAAA,YACjC,SAAQ,MAAM,OAAO,MAAM;AAChC,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,WAAW,CAAC,EAAE,OAAO,QAAQ,MAAM;AACjC,gBAAQ,QAAQ,IAAI,IAAI,sBAAsB,IAAI,cAAc,CAAC;AACjE,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,YAAY,CAAC,EAAE,OAAO,QAAQ,MAAM;AAClC,gBAAQ,QAAQ,oBAAI,IAAI;AACxB,eAAO,EAAE,MAAM,OAAO;AAAA,MACxB;AAAA,MACA,QAAQ,OAAO,EAAE,MAAM,MAAM,QAAQ,SAAS;AAAA,MAC9C,QAAQ,OAAO,EAAE,MAAM,OAAO;AAAA,MAC9B,OAAO,OAAO,EAAE,OAAO,SAAS,OAAO,MAAM;AAC3C,cAAM,IAAI,YAAY;AACtB,YAAI,OAAO,WAAW,CAAC,UAAU,KAAK,QAAQ,eAAe,MAAM,mBAAmB;AACpF,iBAAO,EAAE,MAAM,WAAW;AAAA,QAC5B;AACA,cAAM,gBAAgB,aAAa,QAAQ,KAAK;AAChD,cAAM,aAAa,MAAM,+BAA+B,IAAI,KAAK,eAAe,aAAa,QAAQ,QAAQ,CAAC;AAC9G,YAAI,CAAC,UAAU,EAAG,QAAO,EAAE,MAAM,WAAW;AAC5C,YAAI,eAAe,wBAAwB;AACzC,kBAAQ,WAAW,IAAI,IAAI,kBAAkB,EAAE,CAAC;AAAA,QAClD;AACA,YAAI,eAAe,QAAS,QAAO,EAAE,MAAM,WAAW;AACtD,gBAAQ,WAAW,IAAI,IAAI,aAAa;AACxC,gBAAQ,QAAQ,IAAI,IAAI,aAAa;AACrC,gBAAQ,UAAU;AAClB,YAAI,GAAG;AAAA,UACL,UAAU,cAAc,MAAM,OAAO,sBAAsB,IAAI,cAAc,EAAE,MAAM;AAAA,UACrF;AAAA,QACF;AACA,eAAO,EAAE,MAAM,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,SAAS,MAAM,QAAQ,KAAK,MAAM;AAAA,IACtC,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,SAAS,CAAC,YAAY,UACpB,WAAW,GAAG;AAAA,MACZ,8BAA8B,0CAA0C,YAAY,KAAK,CAAC,EAAE;AAAA,MAC5F;AAAA,IACF;AAAA,EACJ,CAAC;AACD,SAAO;AAAA,IACL,SAAS,SAAS;AAAA,IAClB,aAAa,CAAC,SAAS,WAAW,OAAO,SAAS,YAAY,OAAO,WAAW;AAAA,IAChF,eAAe,aAAa,SAAS,QAAQ;AAAA,EAC/C;AACF;AAEA,eAAe,yBAAyB,IAAkB,KAAqB,YAAoB;AACjG,QAAM,aAAa,MAAM,kBAAkB;AAC3C,QAAM,YAAY,MAAM,eAAe,MAAM,qBAAqB,CAAC,WAAW;AAC9E,QAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,IAChC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,OAAO,EAAE,OAAO,MAAM;AAC1B,aAAO,eAAe;AACtB,YAAM,WAAW,MAAM,aAAa;AACpC,aAAO,eAAe;AACtB,aAAO,kBAAkB,IAAI,QAAQ;AAAA,IACvC;AAAA,EACF,CAAC;AACD,SAAO,OAAO,SAAS,cAAc,OAAO,QAAQ;AACtD;AAEA,eAAsB,+BAA+B,IAAkB,KAA8B;AACnG,QAAM,WAAW,MAAM,aAAa;AAAA,IAClC,KAAK,IAAI;AAAA,IACT,gBAAgB,IAAI,iBAAiB;AAAA,EACvC,CAAC;AACD,SAAO,kBAAkB,IAAI,QAAQ;AACvC;AAEA,SAAS,kBAAkB,IAAkB,UAA4C;AACvF,QAAM,cAAc,kBAAkB,EAAE;AACxC,QAAM,iBACJ,SAAS,SAAS,YAAY,SAAS,SAAS,QAAQ,aAAa,IAAI,IAAI,SAAS,SAAS,KAAK,CAAC,IAAI;AAC3G,QAAM,mBACJ,SAAS,SAAS,YACd,yBACA,mBAAmB,SACjB,cACA,YAAY,aAAa,cAAc,IACrC,UACA;AACV,QAAM,kBAAkB,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,QAAQ,MAAM,cAAc,EAAE,OAAO,OAAO,CAAC,CAAC,EAAE,KAAK,IAAI;AACvG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAI,SAAS,SAAS,YAAY,EAAE,uBAAuB,UAAU,SAAS,MAAM,iBAAiB,IAAI,CAAC;AAAA,IAC1G,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,EAC/C;AACF;AAEA,SAAS,eAAe,UAAwB,OAAe;AAC7D,QAAM,cAAc,mBAAmB,KAAK,EAAE,KAAK,CAAC,SAAS,KAAK,WAAW,oBAAoB,CAAC;AAClG,SAAO,cAAc;AAAA,IACnB,iBAAiB,SAAS,YAAY,MAAM,OAAO,sBAAsB,KAAK,EAAE,MAAM,mBAAgB,SAAS,gBAAgB;AAAA,IAC/H,WAAW,cAAc,KAAK,IAAI,wEAAkE,4BAAyB;AAAA,IAC7H,YAAY,wBAAwB,KAAK,CAAC;AAAA,IAC1C,aAAa,iBAAiB,KAAK,CAAC;AAAA,IACpC,GAAI,SAAS,kBAAkB,CAAC,qBAAqB,SAAS,eAAe,EAAE,IAAI,CAAC;AAAA,IACpF,GAAI,cAAc,CAAC,mBAAmB,YAAY,MAAM,sBAAsB,MAAM,CAAC,EAAE,IAAI,CAAC;AAAA,EAC9F,CAAC;AACH;AAEA,SAAS,wBAAwB,OAAe;AAC9C,QAAM,YAAY,sBAAsB,KAAK;AAC7C,MAAI,cAAc,WAAY,QAAO;AACrC,MAAI,cAAc,UAAW,QAAO;AACpC,MAAI,cAAc,SAAU,QAAO;AACnC,MAAI,cAAc,SAAU,QAAO;AACnC,QAAM,aAAa,gBAAgB,KAAK;AACxC,SAAO,WAAW,WAAW,cAAc,IACvC,uDACA,oBAAiB,UAAU;AACjC;AAEA,SAAS,eAAe,SAA4B,OAAe;AACjE,MAAI,QAAQ,sBAAuB,QAAO,cAAc,CAAC,gBAAgB,QAAQ,qBAAqB,EAAE,CAAC;AACzG,QAAM,UAAU,wBAAwB,QAAQ,UAAU,QAAQ,KAAK;AACvE,SAAO;AAAA,IACL,wBAAwB,QAAQ,SAAS,IAAI,IAAI,sBAAsB,KAAK,EAAE,MAAM;AAAA,IACpF,YAAY,IACR,6CACA,GAAG,OAAO,cAAc,YAAY,IAAI,WAAW,SAAS;AAAA,IAChE,oBAAoB,cAAc,KAAK,IAAI,8CAA2C,8CAA8C;AAAA,IACpI;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,SAA4B,OAAe;AAClE,QAAM,UAAU,sBAAsB,KAAK;AAC3C,QAAM,YAAY,QAAQ,OAAO,CAAC,SAAS,QAAQ,MAAM,IAAI,IAAI,CAAC;AAClE,QAAM,cAAc,QAAQ,OAAO,CAAC,SAAS,CAAC,QAAQ,MAAM,IAAI,IAAI,CAAC;AACrE,SAAO;AAAA,IACL;AAAA,MACE,oCAAoC,QAAQ,SAAS,IAAI,IAAI,QAAQ,MAAM;AAAA,MAC3E,qCAAqC,QAAQ,MAAM,IAAI,IAAI,QAAQ,MAAM;AAAA,MACzE;AAAA,MACA;AAAA,MACA,GAAI,UAAU,SAAS,IACnB,UAAU,IAAI,CAAC,SAAS,OAAO,kBAAkB,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,IACxE,CAAC,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA,GAAI,YAAY,SAAS,IACrB,YAAY,IAAI,CAAC,SAAS,OAAO,kBAAkB,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,IAC1E,CAAC,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,SAAS,yBAAyB,UAAwB,eAAkD;AAC1G,WAAS,cAAc,CAAC,GAAG,aAAa;AACxC,WAAS,mBAAmB;AAC9B;AAEA,SAAS,kBAAkB,IAAkB;AAC3C,SAAO,6BAA6B,EAAE;AACxC;AAEA,SAAS,aAAa,OAA4C;AAChE,SAAO,2BAA2B,OAAO,CAAC,aAAa,MAAM,IAAI,QAAQ,CAAC;AAC5E;AAEA,SAAS,yBAAyB,OAAgD;AAChF,SAAO,2BAA2B,SAAS,KAA+B;AAC5E;AAEA,SAAS,UAAa,MAAsB,OAAuB;AACjE,SAAO,KAAK,SAAS,MAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,UAAU,MAAM,IAAI,KAAK,CAAC;AAChF;AAEA,SAAS,wBAA2B,MAAsB,OAAuB;AAC/E,MAAI,UAAU;AACd,aAAW,SAAS,KAAM,KAAI,CAAC,MAAM,IAAI,KAAK,EAAG,YAAW;AAC5D,aAAW,SAAS,MAAO,KAAI,CAAC,KAAK,IAAI,KAAK,EAAG,YAAW;AAC5D,SAAO;AACT;AAEA,SAAS,YAAe,MAAoB,OAAqB;AAC/D,SAAO,KAAK,WAAW,MAAM,UAAU,KAAK,MAAM,CAAC,OAAO,UAAU,UAAU,MAAM,KAAK,CAAC;AAC5F;AAEA,SAAS,cAAc,OAA0B;AAC/C,SAAO,8BAA8B,MAAM,KAAK,IAAI,CAAC,EAAE,MAAM,IAAI;AACnE;AAEA,SAAS,sBAAsB,OAAyC;AACtE,SAAO,cAAc,KAAK,IAAI,CAAC,GAAG,0BAA0B,IAAI,CAAC,GAAG,+BAA+B;AACrG;AAEA,SAAS,YAAY,OAAgB;AACnC,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getPage,
|
|
6
6
|
resolvePage,
|
|
7
7
|
textResult
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4KMN4SFF.js";
|
|
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-
|
|
18
|
+
} from "./chunk-F5VG35UI.js";
|
|
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-
|
|
922
|
+
//# sourceMappingURL=tools-6R7Z6HWJ.js.map
|