@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.
Files changed (41) hide show
  1. package/README.md +89 -230
  2. package/dist/chunks/{browser-settings-menu-REIU7C3Q.js → browser-settings-menu-SR7KLZT6.js} +16 -42
  3. package/dist/chunks/browser-settings-menu-SR7KLZT6.js.map +7 -0
  4. package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4KMN4SFF.js} +2 -2
  5. package/dist/chunks/chunk-4KMN4SFF.js.map +7 -0
  6. package/dist/chunks/{chunk-SRT3UUIP.js → chunk-F5VG35UI.js} +23 -74
  7. package/dist/chunks/chunk-F5VG35UI.js.map +7 -0
  8. package/dist/chunks/{chunk-YJVYJ2L2.js → chunk-MZCGM6D3.js} +43 -48
  9. package/dist/chunks/chunk-MZCGM6D3.js.map +7 -0
  10. package/dist/chunks/{menu-H5HMVGHI.js → menu-YR4VRT7D.js} +10 -23
  11. package/dist/chunks/menu-YR4VRT7D.js.map +7 -0
  12. package/dist/chunks/{tools-6P7EUX37.js → tools-6R7Z6HWJ.js} +17 -59
  13. package/dist/chunks/tools-6R7Z6HWJ.js.map +7 -0
  14. package/dist/index.ts +23 -48
  15. package/dist/index.ts.map +2 -2
  16. package/docs/browser-setup.md +147 -0
  17. package/package.json +54 -55
  18. package/src/browser-manager.ts +872 -942
  19. package/src/browser-settings-menu.ts +315 -350
  20. package/src/cdp-client.ts +381 -398
  21. package/src/chrome-devtools.ts +205 -232
  22. package/src/display.ts +35 -0
  23. package/src/lazy-tools.ts +158 -181
  24. package/src/menu.ts +409 -446
  25. package/src/render.ts +74 -84
  26. package/src/runtime.ts +137 -140
  27. package/src/screenshot.ts +170 -186
  28. package/src/settings.ts +472 -523
  29. package/src/tool-names.ts +8 -14
  30. package/src/tool-selector.ts +245 -289
  31. package/src/tools.ts +218 -226
  32. package/src/webmcp/discovery.ts +184 -188
  33. package/src/webmcp/policy.ts +296 -329
  34. package/src/webmcp/protocol.ts +324 -337
  35. package/src/webmcp/tools.ts +136 -147
  36. package/dist/chunks/browser-settings-menu-REIU7C3Q.js.map +0 -7
  37. package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
  38. package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
  39. package/dist/chunks/chunk-YJVYJ2L2.js.map +0 -7
  40. package/dist/chunks/menu-H5HMVGHI.js.map +0 -7
  41. 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-SRT3UUIP.js";
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-YJVYJ2L2.js.map
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": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,kBAA4D;AACrE,SAAS,YAAY;AAId,IAAM,iCAAiC;AAE9C,IAAM,wBAAwB,uBAAO,IAAI,oDAAoD;AAI7F,IAAM,eAAe;AACrB,IAAM,8BAA8B,aAAa,qBAAqB;AACtE,IAAM,sBAAsB,+BAA+B,oBAAI,QAAmD;AAClH,IAAI,CAAC,4BAA6B,cAAa,qBAAqB,IAAI;AACxE,IAAM,oBAAoB,oBAAI,QAA+B;AAC7D,IAAM,oBAAoB,oBAAI,QAA8B;AAE5D,IAAM,cAAsD;AAAA,EAC1D,4BAA4B;AAAA,EAC5B,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,mCAAmC;AAAA,EACnC,kCAAkC;AACpC;AAEO,SAAS,8BAA8B,IAAkB,OAAe;AAC7E,oBAAkB,IAAI,IAAI,KAAK;AACjC;AAEO,SAAS,uCAAuC,IAAkB;AACvE,MAAI,oBAAoB,IAAI,EAAE,EAAG;AACjC,QAAM,cAAc,IAAI,IAAI,GAAG,eAAe,CAAC;AAC/C;AAAA,IACE;AAAA,IACA,2BAA2B,OAAO,CAAC,SAAS,YAAY,IAAI,IAAI,CAAC;AAAA,EACnE;AACF;AAEO,SAAS,oCACd,IACA,gBACA,OACA;AACA,oBAAkB,IAAI,cAAc;AACpC,QAAM,YAAY,wBAAwB,EAAE;AAC5C,QAAM,eAAe,kCAAkC,KAAK;AAC5D,oBAAkB,IAAI,IAAI,YAAY;AACtC,QAAM,eAAe,eAAe,CAAC,IAAI,2BAA2B,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC;AACxG,QAAM,qBAAqB,GACxB,eAAe,EACf,OAAO,CAAC,SAAS,CAAC,2BAA2B,SAAS,IAA8B,CAAC;AACxF,KAAG,eAAe,OAAO,CAAC,GAAG,oBAAoB,gCAAgC,GAAG,YAAY,CAAC,CAAC;AACpG;AAEO,SAAS,uCAAuC,IAAkB;AACvE,oBAAkB,IAAI,IAAI,KAAK;AAC/B,QAAM,SAAS,GAAG,eAAe;AACjC,QAAM,YAAY,6BAA6B,EAAE;AACjD,KAAG,eAAe,OAAO,CAAC,GAAG,QAAQ,gCAAgC,GAAG,SAAS,CAAC,CAAC;AACrF;AAEO,SAAS,kCAAkC,IAAkB,gBAAmD;AACrH,oBAAkB,IAAI,cAAc;AACpC,QAAM,YAAY,wBAAwB,EAAE;AAC5C,QAAM,eAAe,kBAAkB,IAAI,EAAE,MAAM;AACnD,QAAM,SAAS,GACZ,eAAe,EACf;AAAA,IACC,CAAC,SACC,CAAC,2BAA2B,SAAS,IAA8B,KAClE,gBAAgB,UAAU,IAAI,IAA8B;AAAA,EACjE;AACF,QAAM,aAAa,eAAe,CAAC,IAAI,2BAA2B,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC;AACtG,KAAG,eAAe,OAAO,CAAC,GAAG,QAAQ,gCAAgC,GAAG,UAAU,CAAC,CAAC;AACtF;AAEO,SAAS,+BAA+B,IAAkB;AAC/D,SAAO,kBAAkB,IAAI,EAAE,MAAM,OAAO,oBAAoB;AAClE;AAEO,SAAS,kCAAkC,OAA2C;AAC3F,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,QAAQ,sBAAsB;AAGtC,QAAI,MAAM,aAAa,YAAa,QAAO;AAC3C,UAAM,aAAa,cAAc,MAAM,QAAQ,wBAAwB;AACvE,QAAI,eAAe,OAAW,QAAO;AACrC,QAAI,MAAM,aAAa,eAAe,MAAM,GAAG,SAAS,OAAO,EAAG,QAAO;AACzE,UAAM,UAAU,MAAM,GAAG,MAAM,uDAAuD;AACtF,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,QAAQ,OAAO,QAAQ,CAAC,CAAC;AAC/B,UAAM,QAAQ,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,SAAS,IAAI,OAAO,QAAQ,CAAC,CAAC,IAAI;AACzE,WAAO,QAAQ,KAAM,UAAU,KAAK,SAAS;AAAA,EAC/C;AACA,MAAI,MAAM,QAAQ,sBAAsB;AACtC,WAAO,aAAa,MAAM,QAAQ,mBAAmB,MAAM;AAAA,EAC7D;AACA,MAAI,MAAM,QAAQ,sBAAsB,MAAM,QAAQ,0BAA0B;AAC9E,WACE,cAAc,MAAM,QAAQ,yBAAyB,MAAM,QAC3D,cAAc,MAAM,QAAQ,oBAAoB,MAAM;AAAA,EAE1D;AACA,SAAO;AACT;AAEO,SAAS,6BAA6B,IAAkB;AAC7D,QAAM,YAAY,wBAAwB,EAAE;AAC5C,SAAO,2BAA2B,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC;AACxE;AAEO,SAAS,8BAA8B,IAAkB;AAC9D,QAAM,YAAY,oBAAoB,IAAI,EAAE,KAAK,oBAAI,IAAI;AACzD,SAAO,2BAA2B,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC;AACxE;AAEO,SAAS,6BAA6B,IAAkB;AAC7D,SAAO,WAAW;AAAA,IAChB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,eAAe;AAAA,IACf,kBAAkB;AAAA,MAChB;AAAA,IACF;AAAA,IACA,YAAY,KAAK,OAAO;AAAA,MACtB,OAAO,KAAK,OAAO;AAAA,QACjB,aAAa;AAAA,QACb,WAAW;AAAA,MACb,CAAC;AAAA,MACD,OAAO,KAAK;AAAA,QACV,KAAK,QAAQ;AAAA,UACX,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,IACD,MAAM,QAAQ,aAAa,QAAQ,QAAQ,WAAW,KAAK;AACzD,cAAQ,eAAe;AACvB,oCAA8B,IAAI,IAAI,cAAc;AACpD,YAAM,YAAY,IAAI,IAAI,6BAA6B,EAAE,CAAC;AAC1D,YAAM,UAAU,yBAAyB,OAAO,OAAO,OAAO,SAAS,GAAG,SAAS;AACnF,YAAM,SAAS,GAAG,eAAe;AACjC,YAAM,YAAY,IAAI,IAAI,MAAM;AAChC,YAAM,QAAQ,QAAQ,OAAO,CAAC,SAAS,CAAC,UAAU,IAAI,IAAI,CAAC;AAC3D,UAAI,MAAM,SAAS,GAAG;AACpB,WAAG,eAAe,OAAO,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;AAAA,MACjD;AAEA,YAAM,OACJ,QAAQ,WAAW,IACf,0DACA,MAAM,SAAS,IACb,iCAAiC,MAAM,KAAK,IAAI,CAAC,KACjD,sDAAsD,QAAQ,KAAK,IAAI,CAAC;AAChF,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,QACzC,SAAS,EAAE,SAAS,MAAM;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,yBAAyB,OAAe,OAAe,WAAgD;AAC9G,QAAM,QAAQ,MACX,YAAY,EACZ,MAAM,YAAY,EAClB,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC;AACpC,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,SAAO,2BAA2B,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC,EACnE,IAAI,CAAC,MAAM,WAAW;AAAA,IACrB;AAAA,IACA;AAAA,IACA,OAAO,MAAM,OAAO,CAAC,OAAO,SAAS,SAAS,YAAY,IAAI,EAAE,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC;AAAA,EAC5F,EAAE,EACD,OAAO,CAAC,UAAU,MAAM,QAAQ,CAAC,EACjC,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,SAAS,KAAK,QAAQ,MAAM,KAAK,EAC1E,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,UAAU,MAAM,IAAI;AAC9B;AAEA,SAAS,kBAAkB,IAAkB,gBAAmD;AAC9F,QAAM,YAAY,IAAI,IAAI,cAAc;AACxC,sBAAoB,IAAI,IAAI,SAAS;AACrC,SAAO;AACT;AAEA,SAAS,wBAAwB,IAAkB;AACjD,QAAM,aAAa,oBAAoB,IAAI,EAAE,KAAK,oBAAI,IAAI;AAC1D,QAAM,QAAQ,kBAAkB,IAAI,EAAE;AACtC,QAAM,UAAU,UAAU,UAAa,cAAc,KAAK;AAC1D,SAAO,IAAI;AAAA,IACT,2BAA2B,OAAO,CAAC,SAAS,WAAW,IAAI,IAAI,MAAM,WAAW,CAAC,iBAAiB,IAAI,EAAE;AAAA,EAC1G;AACF;AAEA,SAAS,cAAc,OAAgB,KAAa;AAClD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,EAAG,QAAO;AAChF,QAAM,SAAS;AACf,SAAO,OAAO,OAAO,GAAG,MAAM,YAAY,OAAO,GAAG,IAAI;AAC1D;AAEA,SAAS,aAAa,OAAgB,KAAa;AACjD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,EAAG,QAAO;AAChF,QAAM,SAAS;AACf,SAAO,OAAO,OAAO,GAAG,MAAM,WAAW,OAAO,GAAG,IAAI;AACzD;AAEA,SAAS,OAAO,QAA2B;AACzC,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAC5B;;;ACxNA,IAAM,iCAAiC;AACvC,IAAM,oBAAoB,IAAI,KAAK,UAAU,QAAW,EAAE,aAAa,WAAW,CAAC;AAE5E,SAAS,8BAA8B,OAAe,gBAAgB,KAAQ;AACnF,QAAM,oBAAoB,MAAM,SAAS;AACzC,QAAM,eAAe,oBAAoB,2BAA2B,OAAO,8BAA8B,IAAI;AAC7G,QAAM,wBAAwB,aAAa,QAAQ,SAAS,IAAI;AAEhE,QAAM,YAAY,MAAM,KAAK,uBAAuB,CAAC,cAAc;AACjE,UAAM,YAAY,UAAU,YAAY,CAAC,KAAK;AAC9C,UAAM,gBACH,aAAa,KAAK,aAAa,KAC/B,aAAa,MAAM,aAAa,MAChC,aAAa,OAAO,aAAa;AACpC,UAAM,aAAc,aAAa,QAAU,aAAa,QAAY,aAAa,QAAU,aAAa;AACxG,UAAM,gBAAgB,UAAU,WAAW,KAAK,aAAa,SAAU,aAAa;AACpF,WAAO,iBAAiB,cAAc,gBAAgB,WAAM;AAAA,EAC9D,CAAC,EAAE,KAAK,EAAE;AACV,QAAM,cAAc,KAAK,IAAI,eAAe,8BAA8B;AAC1E,MAAI,CAAC,qBAAqB,UAAU,UAAU,YAAa,QAAO;AAElE,SAAO,GAAG,2BAA2B,WAAW,KAAK,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC;AAC/E;AAEA,SAAS,2BAA2B,OAAe,cAAsB;AACvE,MAAI,MAAM,UAAU,aAAc,QAAO;AACzC,QAAM,mBAAmB,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACrE,MAAI,UAAU;AACd,aAAW,EAAE,OAAO,QAAQ,KAAK,kBAAkB,QAAQ,gBAAgB,GAAG;AAC5E,UAAM,aAAa,QAAQ,QAAQ;AACnC,QAAI,aAAa,aAAc;AAC/B,cAAU;AAAA,EACZ;AACA,SAAO,MAAM,MAAM,GAAG,OAAO;AAC/B;;;ACDA,SAASA,QAAU,QAAa;AAC9B,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;AAEA,SAAS,YAAY,OAAgB;AACnC,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAYA,eAAsB,0BACpB,IACA,KACA,eACA,QACA;AACA,QAAM,aAAa,MAAM;AACzB,QAAM,SAAS,MAAM,sBAAsB,IAAI,KAAK,eAAe,UAAU;AAC7E,MAAI,WAAW,WAAW,eAAe,MAAM,kBAAmB;AAClE,QAAM,SAAS,MAAM,uBAAuB,IAAI,IAAI,cAAc;AAClE,MAAI,eAAe,MAAM,kBAAmB;AAC5C,MAAI,GAAG,OAAO,gCAAgC,MAAM;AAAA;AAAA,EAAQ,MAAM,IAAI,MAAM;AAC9E;AAEA,eAAsB,+BACpB,IACA,KACA,eACA,qBACkC;AAClC,SAAO,sBAAsB,IAAI,KAAK,eAAe,MAAM,mBAAmB,mBAAmB;AACnG;AAEA,IAAI,uBAAuB,QAAQ,QAAQ;AAE3C,eAAsB,gCAA+C;AACnE,QAAM;AACR;AAEA,SAAS,sBACP,IACA,KACA,eACA,oBACA,qBACkC;AAClC,QAAM,YAAY,qBAAqB;AAAA,IAAK,MAC1C,yBAAyB,IAAI,KAAK,eAAe,oBAAoB,mBAAmB;AAAA,EAC1F;AACA,yBAAuB,UAAU;AAAA,IAC/B,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,eAAe,yBACb,IACA,KACA,eACA,oBACA,qBACkC;AAClC,MAAI,uBAAuB,MAAM,kBAAmB,QAAO;AAC3D,MAAI,uBAAuB,CAAC,YAAY,6BAA6B,EAAE,GAAG,mBAAmB,GAAG;AAC9F,QAAI,GAAG;AAAA,MACL;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,sBAAsB,GAAG,eAAe;AAC9C,QAAM,yBAAyB,6BAA6B,EAAE;AAC9D,MAAI;AACF,UAAM,sBAAsB,uBAAuB,OAAO,gBAAgB;AAC1E,UAAM,sBAAsB,cAAc,OAAO,gBAAgB;AACjE,QAAI,CAAC,YAAY,qBAAqB,mBAAmB,GAAG;AAC1D,iCAA2B,IAAI,gBAAgB,qDAAqD;AAAA,IACtG;AACA,6BAAyB,IAAI,aAAa;AAC1C,UAAM,gBAAgB,aAAa;AACnC,WAAO,uBAAuB,MAAM,oBAAoB,UAAU;AAAA,EACpE,SAAS,OAAO;AACd,QAAI;AACJ,QAAI;AACF,wCAAkC,IAAI,sBAAsB;AAC5D,YAAM,wBAAwB,GAC3B,eAAe,EACf,OAAO,CAAC,SAAS,CAAC,2BAA2B,SAAS,IAA8B,CAAC;AACxF,YAAM,4BAA4B,oBAAoB;AAAA,QAAO,CAAC,SAC5D,2BAA2B,SAAS,IAA8B;AAAA,MACpE;AACA,YAAM,sBACJ,+BAA+B,EAAE,MAAM,UAAU,yBAAyB;AAC5E,SAAG,eAAeA,QAAO,CAAC,GAAG,uBAAuB,GAAG,mBAAmB,CAAC,CAAC;AAAA,IAC9E,SAAS,QAAQ;AACf,sBAAgB;AAAA,IAClB;AACA,QAAI,uBAAuB,MAAM,kBAAmB,QAAO;AAC3D,QAAI,GAAG;AAAA,MACL;AAAA,QACE,gBACI,yCAAyC,YAAY,KAAK,CAAC,kCAAkC,YAAY,aAAa,CAAC,KACvH,gEAAgE,YAAY,KAAK,CAAC;AAAA,MACxF;AAAA,MACA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAe,MAAoB,OAAqB;AAC/D,SAAO,KAAK,WAAW,MAAM,UAAU,KAAK,MAAM,CAAC,OAAO,UAAU,UAAU,MAAM,KAAK,CAAC;AAC5F;AAEO,SAAS,yBAAyB,IAAkB,eAAkD;AAC3G,oCAAkC,IAAI,aAAa;AACrD;AAEA,SAAS,qBAAqB,IAAkB,OAAkC;AAChF,QAAM,kBAAkB,IAAI,IAAY,0BAA0B;AAClE,QAAM,kBAAkB,IAAI,IAAI,GAAG,eAAe,CAAC;AACnD,QAAM,wBAAwB,2BAA2B,OAAO,CAAC,SAAS,gBAAgB,IAAI,IAAI,CAAC,EAAE;AACrG,QAAM,2BAA2B,6BAA6B,EAAE,EAAE;AAClE,QAAM,2BAA2B,MAAM,KAAK,eAAe,EAAE;AAAA,IAC3D,CAAC,SAAS,CAAC,gBAAgB,IAAI,IAAI,KAAK,SAAS;AAAA,EACnD,EAAE;AACF,QAAM,kBAAkB,iBAAiB,KAAK,EAAE;AAChD,QAAM,qBACJ,6BAA6B,kBAAkB,YAAY,6BAA6B,IAAI,aAAa;AAE3G,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,uBAAuB,IAAkB,OAAe;AAC5E,QAAM,UAAU,qBAAqB,IAAI,KAAK;AAC9C,QAAM,mBAAmB,MAAM,sBAAsB;AACrD,SAAO;AAAA,IACL;AAAA,MACE,oCAAoC,oBAAoB,OAAO,CAAC;AAAA,MAChE,kBAAkB,+BAA+B,EAAE,CAAC;AAAA,MACpD,yCAAyC,QAAQ,qBAAqB,IAAI,QAAQ,eAAe;AAAA,MACjG,WAAW,cAAc,KAAK,IAAI,wEAAkE,4BAAyB;AAAA,MAC7H,WAAW,GAAG,eAAe,EAAE,SAAS,8BAA8B,IAAI,WAAW,UAAU;AAAA,MAC/F,2BAA2B,gBAAgB;AAAA,MAC3C,GAAG,2BAA2B,KAAK;AAAA,MACnC,GAAI,MAAM,iBAAiB,CAAC,kBAAkB,MAAM,cAAc,EAAE,IAAI,CAAC;AAAA,MACzE,iCAAiC,QAAQ,wBAAwB;AAAA,MACjE,aAAa,iBAAiB,KAAK,CAAC;AAAA,MACpC,oBAAoB,oBAAoB,KAAK,CAAC;AAAA,MAC9C,gBAAgB,gBAAgB,KAAK,CAAC;AAAA,MACtC,GAAG,mBAAmB,KAAK;AAAA,IAC7B,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEO,SAAS,uBAAuB,OAAe;AACpD,SAAO,0BAA0B,KAAK;AACxC;AAEO,SAAS,0BAA0B,OAAgB;AACxD,QAAM,UAAU,wBAAwB,KAAK;AAC7C,QAAM,YAAY,sBAAsB,KAAK;AAC7C,QAAM,kBAAkB,QAAQ,cAAc,KAAK,IAAI;AACvD,QAAM,eACJ,cAAc,aACV,6BACA,cAAc,YACZ,4BACA,cAAc,WACZ,2BACA,cAAc,WACZ,uBACA;AACZ,QAAM,gBAAgB,cAAc,YAAY,cAAc;AAC9D,SAAO;AAAA,IACL;AAAA,MACE,YAAY,YAAY;AAAA,MACxB;AAAA,MACA,aAAa,iBAAiB,KAAK,CAAC;AAAA,MACpC,oBAAoB,oBAAoB,KAAK,CAAC;AAAA,MAC9C,gBAAgB,gBAAgB,KAAK,CAAC;AAAA,MACtC,wBAAwB,QAAQ,eAAe,MAAM,KAAK,QAAQ,oBAAoB;AAAA,MACtF,WAAW,kBAAkB,8BAA2B,4BAAyB;AAAA,MACjF,GAAI,mBAAmB,CAAC,uBAAuB,KAAK,GAAG,QACnD,CAAC,4GAA4G,IAC7G,CAAC;AAAA,MACL,GAAI,QAAQ,eAAe,SAAS,IAChC,CAAC,kFAAkF,IACnF,CAAC;AAAA,MACL,GAAG,mBAAmB,KAAK;AAAA,MAC3B,GAAI,gBAAgB,CAAC,WAAW,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC;AAAA,IACnE,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEO,SAAS,0BAA0B,OAAe;AACvD,SAAO;AAAA,IACL;AAAA,MACE,6BAA6B,iBAAiB,KAAK,CAAC;AAAA,MACpD,oBAAoB,oBAAoB,KAAK,CAAC;AAAA,MAC9C,gBAAgB,gBAAgB,KAAK,CAAC;AAAA,MACtC,GAAG,2BAA2B,KAAK;AAAA,MACnC,WAAW,KAAK;AAAA,MAChB,qBAAqB,KAAK;AAAA,MAC1B,GAAG,mBAAmB,KAAK;AAAA,MAC3B,mBAAmB;AAAA,IACrB,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,SAAS,2BAA2B,OAAe;AACjD,QAAM,UAAU,wBAAwB,KAAK;AAC7C,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,iBACJ,eAAe,SAAS,IAAI,eAAe,IAAI,CAAC,kBAAkB,OAAO,aAAa,EAAE,IAAI,CAAC,UAAU;AACzG,SAAO;AAAA,IACL,kBAAkB,MAAM,oBAAoB,iBAAiB,CAAC;AAAA,IAC9D,GAAI,MAAM,0BACN;AAAA,MACE,qBAAqB,MAAM,uBAAuB,KAAK,MAAM,yBAAyB,YAAY,oBAAoB;AAAA,IACxH,IACA,CAAC;AAAA,IACL,gBAAgB,QAAQ,oBAAoB,OAAO,KAAK,KAAK,QAAQ,gBAAgB;AAAA,IACrF,uBAAuB,QAAQ,kBAAkB,qBAAqB,KAAK,QAAQ,oBAAoB;AAAA,IACvG,wBAAwB,QAAQ,oBAAoB;AAAA,IACpD,GAAG;AAAA,IACH,WAAW,cAAc,KAAK,IAAI,oEAA8D,4BAAyB;AAAA,IACzH;AAAA,IACA,GAAI,eAAe,SAAS,IACxB,CAAC,8FAA8F,IAC/F,CAAC;AAAA,EACP;AACF;AAEO,SAAS,kBAAkB,OAAe;AAC/C,SAAO;AAAA,IACL;AAAA,IACA,WAAW,cAAc,KAAK,IAAI,YAAY,UAAU;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEO,SAAS,uBAAuB,OAAe;AACpD,SAAO,iBAAiB,KAAK;AAC/B;AAMA,SAAS,oBAAoB,SAA4B;AACvD,SAAO,GAAG,QAAQ,kBAAkB,KAAK,QAAQ,wBAAwB,IAAI,QAAQ,eAAe;AACtG;AAEA,eAAe,wBAAwB;AACrC,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,SAAS,SAAS,YAAY,SAAS,SAAS,OAAO;AACzD,WAAO,yBAAyB,SAAS,SAAS,KAAK;AAAA,EACzD;AACA,MAAI,SAAS,SAAS,WAAW;AAC/B,WAAO,yEAAyE,SAAS,MAAM;AAAA,EACjG;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,OAA0C;AAC1E,MAAI,MAAM,WAAW,2BAA2B,QAAQ;AACtD,WAAO,kBAAkB,MAAM,MAAM,IAAI,2BAA2B,MAAM;AAAA,EAC5E;AACA,MAAI,MAAM,WAAW,EAAG,QAAO,sBAAsB,2BAA2B,MAAM;AACtF,SAAO,GAAG,MAAM,MAAM,IAAI,2BAA2B,MAAM,cAAc,MAAM,KAAK,IAAI,CAAC;AAC3F;AAEA,SAAS,iBAAiB,OAAyC;AACjE,SAAO,cAAc,KAAK,IAAI,CAAC,GAAG,0BAA0B,IAAI,CAAC,GAAG,+BAA+B;AACrG;AAEA,eAAe,gBAAgB,eAAkD;AAC/E,QAAM,aAAa,EAAE,OAAO,CAAC,GAAG,aAAa,GAAG,WAAW,KAAK,IAAI,EAAE,CAAC;AACzE;",
6
+ "names": ["unique"]
7
+ }
@@ -6,7 +6,7 @@ import {
6
6
  buildCommandGuide,
7
7
  sanitizeChromeDevtoolsDisplay,
8
8
  setSelectedChromeDevtoolsTools
9
- } from "./chunk-YJVYJ2L2.js";
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-SRT3UUIP.js";
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-REIU7C3Q.js");
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-H5HMVGHI.js.map
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": "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",
6
+ "names": []
7
+ }
@@ -5,7 +5,7 @@ import {
5
5
  getPage,
6
6
  resolvePage,
7
7
  textResult
8
- } from "./chunk-GTTYS5GT.js";
8
+ } from "./chunk-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-SRT3UUIP.js";
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-6P7EUX37.js.map
922
+ //# sourceMappingURL=tools-6R7Z6HWJ.js.map