@narumitw/pi-chrome-devtools 0.52.1 → 0.52.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 +126 -152
- package/dist/chunks/{browser-settings-menu-L4CZINWO.ts → browser-settings-menu-VWCNG4HB.js} +3 -3
- package/dist/chunks/{chunk-RM7OGXVL.ts → chunk-RH6KESL3.js} +68 -15
- package/dist/chunks/{chunk-RM7OGXVL.ts.map → chunk-RH6KESL3.js.map} +2 -2
- package/dist/chunks/{menu-U4AIAN7V.ts → menu-PLD3S3EO.js} +9 -8
- package/dist/chunks/{menu-U4AIAN7V.ts.map → menu-PLD3S3EO.js.map} +2 -2
- package/dist/index.ts +15 -8
- package/dist/index.ts.map +2 -2
- package/package.json +6 -6
- package/src/chrome-devtools.ts +11 -3
- package/src/lazy-tools.ts +70 -6
- package/src/menu.ts +5 -4
- package/src/tool-selector.ts +12 -6
- /package/dist/chunks/{browser-settings-menu-L4CZINWO.ts.map → browser-settings-menu-VWCNG4HB.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
-
// @ts-nocheck -- generated
|
|
2
|
+
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
5
5
|
availableChromeDevtoolsTools,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
sanitizeChromeDevtoolsDisplay,
|
|
13
13
|
setSelectedChromeDevtoolsTools,
|
|
14
14
|
state
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-RH6KESL3.js";
|
|
16
16
|
|
|
17
17
|
// src/menu.ts
|
|
18
18
|
import { defineMenu, runMenu, runTask } from "@narumitw/pi-tui-kit";
|
|
@@ -124,7 +124,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
|
|
|
124
124
|
return result?.closeParent ? { kind: "close" } : { kind: "stay" };
|
|
125
125
|
},
|
|
126
126
|
settings: async () => {
|
|
127
|
-
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-
|
|
127
|
+
const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-VWCNG4HB.js");
|
|
128
128
|
if (!isCurrent()) return { kind: "stay" };
|
|
129
129
|
const result = await showChromeDevtoolsBrowserSettings(ctx, generation);
|
|
130
130
|
if (!isCurrent()) return { kind: "stay" };
|
|
@@ -257,7 +257,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
|
|
|
257
257
|
current.draft = new Set(selectedTools);
|
|
258
258
|
current.applied = true;
|
|
259
259
|
ctx.ui.notify(
|
|
260
|
-
`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available
|
|
260
|
+
`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available.`,
|
|
261
261
|
"info"
|
|
262
262
|
);
|
|
263
263
|
return { kind: "close" };
|
|
@@ -313,7 +313,7 @@ function buildMenuSnapshot(pi, settings) {
|
|
|
313
313
|
}
|
|
314
314
|
function mainStateLines(snapshot) {
|
|
315
315
|
return sanitizeLines([
|
|
316
|
-
`
|
|
316
|
+
`Tool catalog: ${snapshot.activeTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} available \xB7 ${snapshot.persistenceLabel}`,
|
|
317
317
|
`Browser: ${browserLifecycleSummary()}`,
|
|
318
318
|
`Endpoint: ${devToolsEndpoint()}`,
|
|
319
319
|
...snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : [],
|
|
@@ -347,14 +347,15 @@ function buildToolReview(current) {
|
|
|
347
347
|
`Current available browser tools: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
|
|
348
348
|
`Proposed available browser tools: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
|
|
349
349
|
"",
|
|
350
|
-
"Available
|
|
350
|
+
"Available after apply:",
|
|
351
351
|
...available.length > 0 ? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`) : [" - none"],
|
|
352
352
|
"",
|
|
353
353
|
"Unavailable after apply:",
|
|
354
354
|
...unavailable.length > 0 ? unavailable.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`) : [" - none"],
|
|
355
355
|
"",
|
|
356
356
|
"Other active Pi tools remain unchanged.",
|
|
357
|
-
"
|
|
357
|
+
"Native-capable models defer these tools until chrome_devtools_load selects them.",
|
|
358
|
+
"Other models expose available tools eagerly before the next model request.",
|
|
358
359
|
"The accepted availability policy is saved for future sessions."
|
|
359
360
|
].join("\n")
|
|
360
361
|
);
|
|
@@ -394,4 +395,4 @@ export {
|
|
|
394
395
|
showChromeDevtoolsMenu,
|
|
395
396
|
showChromeDevtoolsToolWorkflow
|
|
396
397
|
};
|
|
397
|
-
//# sourceMappingURL=menu-
|
|
398
|
+
//# sourceMappingURL=menu-PLD3S3EO.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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, launchModeLabel } from \"./browser-manager.js\";\nimport { availableChromeDevtoolsTools } from \"./lazy-tools.js\";\nimport { state } from \"./runtime.js\";\nimport { loadSettings, type SettingsLoadResult } from \"./settings.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName } from \"./tool-names.js\";\nimport {\n\tbuildBrowserStatusMessage,\n\tbuildCommandGuide,\n\tsanitizeChromeDevtoolsDisplay,\n\tsetSelectedChromeDevtoolsTools,\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\tactiveTools: ChromeDevToolsToolName[];\n\tpersistenceLabel: string;\n\tmutationBlockedReason?: string;\n\tsettingsWarning?: string;\n}\n\ninterface ToolWorkflowState {\n\taccepted: Set<ChromeDevToolsToolName>;\n\tdraft: Set<ChromeDevToolsToolName>;\n\tmutationBlockedReason?: string;\n\tgeneration: number;\n\tapplied: boolean;\n}\n\nconst TOOL_PRESENTATION: Record<ChromeDevToolsToolName, { label: string; description: string }> = {\n\tchrome_devtools_list_pages: {\n\t\tlabel: \"List open pages\",\n\t\tdescription: \"List inspectable Chrome tabs and pages (chrome_devtools_list_pages).\",\n\t},\n\tchrome_devtools_select_page: {\n\t\tlabel: \"Select the active page\",\n\t\tdescription: \"Choose the page later browser actions use (chrome_devtools_select_page).\",\n\t},\n\tchrome_devtools_navigate: {\n\t\tlabel: \"Navigate a page\",\n\t\tdescription: \"Open a URL, creating a page when needed (chrome_devtools_navigate).\",\n\t},\n\tchrome_devtools_evaluate: {\n\t\tlabel: \"Run JavaScript\",\n\t\tdescription: \"Evaluate JavaScript in the selected page (chrome_devtools_evaluate).\",\n\t},\n\tchrome_devtools_screenshot: {\n\t\tlabel: \"Capture a screenshot\",\n\t\tdescription: \"Save a PNG of the selected page (chrome_devtools_screenshot).\",\n\t},\n};\n\nexport async function showChromeDevtoolsMenu(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n) {\n\tconst snapshot = await loadSnapshotWithFeedback(pi, ctx, generation);\n\tif (!snapshot) return;\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst menu = defineMenu<MenuSnapshot, MainScreen, MainAction>({\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state: current }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Chrome DevTools\",\n\t\t\t\tlines: mainStateLines(current),\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tools\",\n\t\t\t\t\t\tlabel: \"Choose available browser tools\u2026\",\n\t\t\t\t\t\tdescription: \"Choose which capabilities the loader may expose.\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"tools\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"bulk\",\n\t\t\t\t\t\tlabel:\n\t\t\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t\t\t? \"Make all browser tools unavailable\u2026\"\n\t\t\t\t\t\t\t\t: \"Make all browser tools available\u2026\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t\t\t? \"Preview 0 of 5; other active tools stay enabled.\"\n\t\t\t\t\t\t\t\t: \"Preview 5 of 5; other active tools stay enabled.\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"bulk\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"browser-status\",\n\t\t\t\t\t\tlabel: \"Browser status\",\n\t\t\t\t\t\tdescription: \"Runtime, endpoint, and last launch attempt.\",\n\t\t\t\t\t\tto: \"browserStatus\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"settings\",\n\t\t\t\t\t\tlabel: \"Browser settings\",\n\t\t\t\t\t\tdescription: \"Edit endpoint, auto-launch, and browser executable settings.\",\n\t\t\t\t\t\taction: \"settings\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"help\",\n\t\t\t\t\t\tlabel: \"Help\",\n\t\t\t\t\t\tdescription: \"Commands and usage.\",\n\t\t\t\t\t\tto: \"help\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\tbrowserStatus: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Browser status\",\n\t\t\t\tcontent: buildBrowserStatusMessage(),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\thelp: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Chrome DevTools help\",\n\t\t\t\tcontent: buildCommandGuide(),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\ttools: async ({ state: current }) => {\n\t\t\t\tconst result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n\t\t\t\t\tsnapshot: current,\n\t\t\t\t});\n\t\t\t\tif (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n\t\t\t\treturn result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t\tbulk: async ({ state: current }) => {\n\t\t\t\tconst selectedTools =\n\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: [...CHROME_DEVTOOLS_TOOL_NAMES];\n\t\t\t\tconst result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n\t\t\t\t\tsnapshot: current,\n\t\t\t\t\tinitialDraft: selectedTools,\n\t\t\t\t\tstartAtReview: true,\n\t\t\t\t});\n\t\t\t\tif (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n\t\t\t\treturn result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t\tsettings: async () => {\n\t\t\t\tconst { showChromeDevtoolsBrowserSettings } = await import(\"./browser-settings-menu.js\");\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\tconst result = await showChromeDevtoolsBrowserSettings(ctx, generation);\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\treturn result.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t},\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => snapshot,\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\tonError: (currentCtx, error) =>\n\t\t\tcurrentCtx.ui.notify(\n\t\t\t\tsanitizeChromeDevtoolsDisplay(`Chrome DevTools menu failed: ${formatError(error)}`),\n\t\t\t\t\"error\",\n\t\t\t),\n\t});\n}\n\nexport async function showChromeDevtoolsToolWorkflow(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n\toptions: {\n\t\tsnapshot?: MenuSnapshot;\n\t\tinitialDraft?: readonly ChromeDevToolsToolName[];\n\t\tstartAtReview?: boolean;\n\t} = {},\n): Promise<\n\t{ applied: boolean; closeParent: boolean; selectedTools: ChromeDevToolsToolName[] } | undefined\n> {\n\tconst snapshot = options.snapshot ?? (await loadSnapshotWithFeedback(pi, ctx, generation));\n\tif (!snapshot) return undefined;\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst accepted = new Set(snapshot.activeTools);\n\tconst workflow: ToolWorkflowState = {\n\t\taccepted,\n\t\tdraft: new Set(options.initialDraft ?? snapshot.activeTools),\n\t\tmutationBlockedReason: snapshot.mutationBlockedReason,\n\t\tgeneration,\n\t\tapplied: false,\n\t};\n\tconst menu = defineMenu<ToolWorkflowState, ToolScreen, ToolAction>({\n\t\tstart: options.startAtReview ? \"review\" : \"tools\",\n\t\tscreens: {\n\t\t\ttools: ({ state: current }) => ({\n\t\t\t\tkind: \"multiSelect\",\n\t\t\t\ttitle: `Browser tools (${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length})`,\n\t\t\t\tlines: toolDraftLines(current),\n\t\t\t\titems: CHROME_DEVTOOLS_TOOL_NAMES.map((toolName) => ({\n\t\t\t\t\tid: toolName,\n\t\t\t\t\tlabel: TOOL_PRESENTATION[toolName].label,\n\t\t\t\t\tdescription: TOOL_PRESENTATION[toolName].description,\n\t\t\t\t\tsearchText: `${toolName} ${TOOL_PRESENTATION[toolName].description}`,\n\t\t\t\t\tselected: current.draft.has(toolName),\n\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t})),\n\t\t\t\taction: \"toggle\",\n\t\t\t\tactions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"select-all\",\n\t\t\t\t\t\tlabel: \"Select all\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"selectAll\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"select-none\",\n\t\t\t\t\t\tlabel: \"Select none\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"selectNone\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"review\",\n\t\t\t\t\t\tlabel: \"Review changes\u2026\",\n\t\t\t\t\t\tdisabled:\n\t\t\t\t\t\t\tBoolean(current.mutationBlockedReason) || setsEqual(current.accepted, current.draft),\n\t\t\t\t\t\tdisabledReason:\n\t\t\t\t\t\t\tcurrent.mutationBlockedReason ??\n\t\t\t\t\t\t\t(setsEqual(current.accepted, current.draft) ? \"No unapplied changes\" : undefined),\n\t\t\t\t\t\tto: \"review\",\n\t\t\t\t\t},\n\t\t\t\t\t{ id: \"cancel\", label: \"Cancel\", action: \"cancel\" },\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\treview: ({ state: current }) => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Review tool changes\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\t\t`Proposed availability: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\t],\n\t\t\t\tcontent: buildToolReview(current),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\t...(current.mutationBlockedReason || setsEqual(current.accepted, current.draft)\n\t\t\t\t\t? {}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tconfirm: {\n\t\t\t\t\t\t\t\tid: \"apply\",\n\t\t\t\t\t\t\t\tlabel: \"Apply tool changes\",\n\t\t\t\t\t\t\t\taction: \"apply\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\ttoggle: ({ state: current, itemId, selected }) => {\n\t\t\t\tif (!isChromeDevtoolsToolName(itemId) || selected === undefined)\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\tif (selected) current.draft.add(itemId);\n\t\t\t\telse current.draft.delete(itemId);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\tselectAll: ({ state: current }) => {\n\t\t\t\tcurrent.draft = new Set(CHROME_DEVTOOLS_TOOL_NAMES);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\tselectNone: ({ state: current }) => {\n\t\t\t\tcurrent.draft = new Set();\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\treview: () => ({ kind: \"to\", screen: \"review\" }),\n\t\t\tcancel: () => ({ kind: \"back\" }),\n\t\t\tapply: async ({ state: current, signal }) => {\n\t\t\t\tawait ctx.waitForIdle();\n\t\t\t\tif (signal.aborted || !isCurrent() || current.generation !== state.sessionGeneration) {\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\t}\n\t\t\t\tconst selectedTools = orderedTools(current.draft);\n\t\t\t\tconst saveResult = await setSelectedChromeDevtoolsTools(\n\t\t\t\t\tpi,\n\t\t\t\t\tctx,\n\t\t\t\t\tselectedTools,\n\t\t\t\t\torderedTools(current.accepted),\n\t\t\t\t);\n\t\t\t\tif (!isCurrent()) return { kind: \"rejected\" };\n\t\t\t\tif (saveResult === \"active-tools-changed\") {\n\t\t\t\t\tcurrent.accepted = new Set(activeChromeTools(pi));\n\t\t\t\t}\n\t\t\t\tif (saveResult !== \"saved\") return { kind: \"rejected\" };\n\t\t\t\tcurrent.accepted = new Set(selectedTools);\n\t\t\t\tcurrent.draft = new Set(selectedTools);\n\t\t\t\tcurrent.applied = true;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available to lazy-load.`,\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t},\n\t});\n\tconst result = await runMenu(ctx, menu, {\n\t\tgetState: () => workflow,\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\tonError: (currentCtx, error) =>\n\t\t\tcurrentCtx.ui.notify(\n\t\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t\t`Chrome DevTools tool selection failed: ${formatError(error)}`,\n\t\t\t\t),\n\t\t\t\t\"error\",\n\t\t\t),\n\t});\n\treturn {\n\t\tapplied: workflow.applied,\n\t\tcloseParent: !workflow.applied && result.kind === \"closed\" && result.reason === \"close\",\n\t\tselectedTools: orderedTools(workflow.accepted),\n\t};\n}\n\nasync function loadSnapshotWithFeedback(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst result = await runTask(ctx, {\n\t\tlabel: \"Loading Chrome DevTools settings\u2026\",\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\ttask: async ({ signal }) => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst settings = await loadSettings();\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn buildMenuSnapshot(pi, settings);\n\t\t},\n\t});\n\treturn result.kind === \"completed\" ? result.value : undefined;\n}\n\nfunction buildMenuSnapshot(pi: ExtensionAPI, settings: SettingsLoadResult): MenuSnapshot {\n\tconst activeTools = activeChromeTools(pi);\n\tconst persistedTools =\n\t\tsettings.kind === \"loaded\" && settings.settings.tools\n\t\t\t? orderedTools(new Set(settings.settings.tools))\n\t\t\t: undefined;\n\tconst persistenceLabel =\n\t\tsettings.kind === \"invalid\"\n\t\t\t? \"settings need repair\"\n\t\t\t: persistedTools === undefined\n\t\t\t\t? \"not saved\"\n\t\t\t\t: arraysEqual(activeTools, persistedTools)\n\t\t\t\t\t? \"saved\"\n\t\t\t\t\t: \"runtime catalog differs from saved catalog\";\n\tconst settingsWarning = [\n\t\t...new Set([settings.notice, state.settingsNotice].filter(Boolean)),\n\t].join(\"\\n\");\n\treturn {\n\t\tactiveTools,\n\t\tpersistenceLabel,\n\t\t...(settings.kind === \"invalid\"\n\t\t\t? { mutationBlockedReason: `Repair ${settings.reason} before saving` }\n\t\t\t: {}),\n\t\t...(settingsWarning ? { settingsWarning } : {}),\n\t};\n}\n\nfunction mainStateLines(snapshot: MenuSnapshot) {\n\treturn sanitizeLines([\n\t\t`Lazy catalog: ${snapshot.activeTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} available \u00B7 ${snapshot.persistenceLabel}`,\n\t\t`Browser: ${browserLifecycleSummary()}`,\n\t\t`Endpoint: ${devToolsEndpoint()}`,\n\t\t...(snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : []),\n\t\t...(state.lastLaunchAttempt?.lastError\n\t\t\t? [`Launch warning: ${state.lastLaunchAttempt.lastError}`]\n\t\t\t: []),\n\t]);\n}\n\nfunction browserLifecycleSummary() {\n\tconst lifecycle = browserLifecycleState();\n\tif (lifecycle === \"starting\") return \"starting managed browser\";\n\tif (lifecycle === \"running\") return \"managed browser running\";\n\tif (lifecycle === \"exited\") return \"managed browser exited \u00B7 open Browser status to recover\";\n\tif (lifecycle === \"failed\") return \"last launch failed \u00B7 open Browser status to recover\";\n\tconst launchMode = launchModeLabel();\n\treturn launchMode.startsWith(\"attach first\")\n\t\t? \"not started \u00B7 attaches or launches on first use\"\n\t\t: `not started \u00B7 ${launchMode}`;\n}\n\nfunction toolDraftLines(current: ToolWorkflowState) {\n\tif (current.mutationBlockedReason)\n\t\treturn sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);\n\tconst changes = symmetricDifferenceSize(current.accepted, current.draft);\n\treturn [\n\t\t`Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\tchanges === 0\n\t\t\t? \"No unapplied changes \u00B7 Escape cancels\"\n\t\t\t: `${changes} unapplied ${changes === 1 ? \"change\" : \"changes\"} \u00B7 Escape cancels`,\n\t\t\"Changes are not applied until Review changes and Apply tool changes.\",\n\t];\n}\n\nfunction buildToolReview(current: ToolWorkflowState) {\n\tconst available = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => current.draft.has(name));\n\tconst unavailable = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => !current.draft.has(name));\n\treturn sanitizeChromeDevtoolsDisplay(\n\t\t[\n\t\t\t`Current available browser tools: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t`Proposed available browser tools: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\"\",\n\t\t\t\"Available to lazy-load after apply:\",\n\t\t\t...(available.length > 0\n\t\t\t\t? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n\t\t\t\t: [\" - none\"]),\n\t\t\t\"\",\n\t\t\t\"Unavailable after apply:\",\n\t\t\t...(unavailable.length > 0\n\t\t\t\t? unavailable.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n\t\t\t\t: [\" - none\"]),\n\t\t\t\"\",\n\t\t\t\"Other active Pi tools remain unchanged.\",\n\t\t\t\"Newly available tools remain deferred until chrome_devtools_load selects them.\",\n\t\t\t\"The accepted availability policy is saved for future sessions.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nfunction updateSnapshotAfterApply(\n\tsnapshot: MenuSnapshot,\n\tselectedTools: readonly ChromeDevToolsToolName[],\n) {\n\tsnapshot.activeTools = [...selectedTools];\n\tsnapshot.persistenceLabel = \"saved\";\n}\n\nfunction activeChromeTools(pi: ExtensionAPI) {\n\treturn availableChromeDevtoolsTools(pi);\n}\n\nfunction orderedTools(tools: ReadonlySet<ChromeDevToolsToolName>) {\n\treturn CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => tools.has(toolName));\n}\n\nfunction isChromeDevtoolsToolName(value: string): value is ChromeDevToolsToolName {\n\treturn CHROME_DEVTOOLS_TOOL_NAMES.includes(value as ChromeDevToolsToolName);\n}\n\nfunction setsEqual<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n\treturn left.size === right.size && [...left].every((value) => right.has(value));\n}\n\nfunction symmetricDifferenceSize<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n\tlet changes = 0;\n\tfor (const value of left) if (!right.has(value)) changes += 1;\n\tfor (const value of right) if (!left.has(value)) changes += 1;\n\treturn changes;\n}\n\nfunction arraysEqual<T>(left: readonly T[], right: readonly T[]) {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction sanitizeLines(lines: readonly string[]) {\n\treturn sanitizeChromeDevtoolsDisplay(lines.join(\"\\n\")).split(\"\\n\");\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu, runTask } from \"@narumitw/pi-tui-kit\";\nimport { browserLifecycleState, devToolsEndpoint, launchModeLabel } from \"./browser-manager.js\";\nimport { availableChromeDevtoolsTools } from \"./lazy-tools.js\";\nimport { state } from \"./runtime.js\";\nimport { loadSettings, type SettingsLoadResult } from \"./settings.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES, type ChromeDevToolsToolName } from \"./tool-names.js\";\nimport {\n\tbuildBrowserStatusMessage,\n\tbuildCommandGuide,\n\tsanitizeChromeDevtoolsDisplay,\n\tsetSelectedChromeDevtoolsTools,\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\tactiveTools: ChromeDevToolsToolName[];\n\tpersistenceLabel: string;\n\tmutationBlockedReason?: string;\n\tsettingsWarning?: string;\n}\n\ninterface ToolWorkflowState {\n\taccepted: Set<ChromeDevToolsToolName>;\n\tdraft: Set<ChromeDevToolsToolName>;\n\tmutationBlockedReason?: string;\n\tgeneration: number;\n\tapplied: boolean;\n}\n\nconst TOOL_PRESENTATION: Record<ChromeDevToolsToolName, { label: string; description: string }> = {\n\tchrome_devtools_list_pages: {\n\t\tlabel: \"List open pages\",\n\t\tdescription: \"List inspectable Chrome tabs and pages (chrome_devtools_list_pages).\",\n\t},\n\tchrome_devtools_select_page: {\n\t\tlabel: \"Select the active page\",\n\t\tdescription: \"Choose the page later browser actions use (chrome_devtools_select_page).\",\n\t},\n\tchrome_devtools_navigate: {\n\t\tlabel: \"Navigate a page\",\n\t\tdescription: \"Open a URL, creating a page when needed (chrome_devtools_navigate).\",\n\t},\n\tchrome_devtools_evaluate: {\n\t\tlabel: \"Run JavaScript\",\n\t\tdescription: \"Evaluate JavaScript in the selected page (chrome_devtools_evaluate).\",\n\t},\n\tchrome_devtools_screenshot: {\n\t\tlabel: \"Capture a screenshot\",\n\t\tdescription: \"Save a PNG of the selected page (chrome_devtools_screenshot).\",\n\t},\n};\n\nexport async function showChromeDevtoolsMenu(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n) {\n\tconst snapshot = await loadSnapshotWithFeedback(pi, ctx, generation);\n\tif (!snapshot) return;\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst menu = defineMenu<MenuSnapshot, MainScreen, MainAction>({\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state: current }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Chrome DevTools\",\n\t\t\t\tlines: mainStateLines(current),\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"tools\",\n\t\t\t\t\t\tlabel: \"Choose available browser tools\u2026\",\n\t\t\t\t\t\tdescription: \"Choose which capabilities the loader may expose.\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"tools\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"bulk\",\n\t\t\t\t\t\tlabel:\n\t\t\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t\t\t? \"Make all browser tools unavailable\u2026\"\n\t\t\t\t\t\t\t\t: \"Make all browser tools available\u2026\",\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t\t\t? \"Preview 0 of 5; other active tools stay enabled.\"\n\t\t\t\t\t\t\t\t: \"Preview 5 of 5; other active tools stay enabled.\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"bulk\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"browser-status\",\n\t\t\t\t\t\tlabel: \"Browser status\",\n\t\t\t\t\t\tdescription: \"Runtime, endpoint, and last launch attempt.\",\n\t\t\t\t\t\tto: \"browserStatus\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"settings\",\n\t\t\t\t\t\tlabel: \"Browser settings\",\n\t\t\t\t\t\tdescription: \"Edit endpoint, auto-launch, and browser executable settings.\",\n\t\t\t\t\t\taction: \"settings\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"help\",\n\t\t\t\t\t\tlabel: \"Help\",\n\t\t\t\t\t\tdescription: \"Commands and usage.\",\n\t\t\t\t\t\tto: \"help\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\tbrowserStatus: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Browser status\",\n\t\t\t\tcontent: buildBrowserStatusMessage(),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\thelp: () => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Chrome DevTools help\",\n\t\t\t\tcontent: buildCommandGuide(),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\ttools: async ({ state: current }) => {\n\t\t\t\tconst result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n\t\t\t\t\tsnapshot: current,\n\t\t\t\t});\n\t\t\t\tif (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n\t\t\t\treturn result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t\tbulk: async ({ state: current }) => {\n\t\t\t\tconst selectedTools =\n\t\t\t\t\tcurrent.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: [...CHROME_DEVTOOLS_TOOL_NAMES];\n\t\t\t\tconst result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {\n\t\t\t\t\tsnapshot: current,\n\t\t\t\t\tinitialDraft: selectedTools,\n\t\t\t\t\tstartAtReview: true,\n\t\t\t\t});\n\t\t\t\tif (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);\n\t\t\t\treturn result?.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t\tsettings: async () => {\n\t\t\t\tconst { showChromeDevtoolsBrowserSettings } = await import(\"./browser-settings-menu.js\");\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\tconst result = await showChromeDevtoolsBrowserSettings(ctx, generation);\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\treturn result.closeParent ? { kind: \"close\" } : { kind: \"stay\" };\n\t\t\t},\n\t\t},\n\t});\n\tawait runMenu(ctx, menu, {\n\t\tgetState: () => snapshot,\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\tonError: (currentCtx, error) =>\n\t\t\tcurrentCtx.ui.notify(\n\t\t\t\tsanitizeChromeDevtoolsDisplay(`Chrome DevTools menu failed: ${formatError(error)}`),\n\t\t\t\t\"error\",\n\t\t\t),\n\t});\n}\n\nexport async function showChromeDevtoolsToolWorkflow(\n\tpi: ExtensionAPI,\n\tctx: CommandContext,\n\tgeneration: number,\n\toptions: {\n\t\tsnapshot?: MenuSnapshot;\n\t\tinitialDraft?: readonly ChromeDevToolsToolName[];\n\t\tstartAtReview?: boolean;\n\t} = {},\n): Promise<\n\t{ applied: boolean; closeParent: boolean; selectedTools: ChromeDevToolsToolName[] } | undefined\n> {\n\tconst snapshot = options.snapshot ?? (await loadSnapshotWithFeedback(pi, ctx, generation));\n\tif (!snapshot) return undefined;\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst accepted = new Set(snapshot.activeTools);\n\tconst workflow: ToolWorkflowState = {\n\t\taccepted,\n\t\tdraft: new Set(options.initialDraft ?? snapshot.activeTools),\n\t\tmutationBlockedReason: snapshot.mutationBlockedReason,\n\t\tgeneration,\n\t\tapplied: false,\n\t};\n\tconst menu = defineMenu<ToolWorkflowState, ToolScreen, ToolAction>({\n\t\tstart: options.startAtReview ? \"review\" : \"tools\",\n\t\tscreens: {\n\t\t\ttools: ({ state: current }) => ({\n\t\t\t\tkind: \"multiSelect\",\n\t\t\t\ttitle: `Browser tools (${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length})`,\n\t\t\t\tlines: toolDraftLines(current),\n\t\t\t\titems: CHROME_DEVTOOLS_TOOL_NAMES.map((toolName) => ({\n\t\t\t\t\tid: toolName,\n\t\t\t\t\tlabel: TOOL_PRESENTATION[toolName].label,\n\t\t\t\t\tdescription: TOOL_PRESENTATION[toolName].description,\n\t\t\t\t\tsearchText: `${toolName} ${TOOL_PRESENTATION[toolName].description}`,\n\t\t\t\t\tselected: current.draft.has(toolName),\n\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t})),\n\t\t\t\taction: \"toggle\",\n\t\t\t\tactions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"select-all\",\n\t\t\t\t\t\tlabel: \"Select all\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"selectAll\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"select-none\",\n\t\t\t\t\t\tlabel: \"Select none\",\n\t\t\t\t\t\tdisabled: Boolean(current.mutationBlockedReason),\n\t\t\t\t\t\tdisabledReason: current.mutationBlockedReason,\n\t\t\t\t\t\taction: \"selectNone\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"review\",\n\t\t\t\t\t\tlabel: \"Review changes\u2026\",\n\t\t\t\t\t\tdisabled:\n\t\t\t\t\t\t\tBoolean(current.mutationBlockedReason) || setsEqual(current.accepted, current.draft),\n\t\t\t\t\t\tdisabledReason:\n\t\t\t\t\t\t\tcurrent.mutationBlockedReason ??\n\t\t\t\t\t\t\t(setsEqual(current.accepted, current.draft) ? \"No unapplied changes\" : undefined),\n\t\t\t\t\t\tto: \"review\",\n\t\t\t\t\t},\n\t\t\t\t\t{ id: \"cancel\", label: \"Cancel\", action: \"cancel\" },\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t\treview: ({ state: current }) => ({\n\t\t\t\tkind: \"review\",\n\t\t\t\ttitle: \"Review tool changes\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\t\t`Proposed availability: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\t],\n\t\t\t\tcontent: buildToolReview(current),\n\t\t\t\tformat: { kind: \"text\" },\n\t\t\t\tviewportSize: \"adaptive\",\n\t\t\t\t...(current.mutationBlockedReason || setsEqual(current.accepted, current.draft)\n\t\t\t\t\t? {}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tconfirm: {\n\t\t\t\t\t\t\t\tid: \"apply\",\n\t\t\t\t\t\t\t\tlabel: \"Apply tool changes\",\n\t\t\t\t\t\t\t\taction: \"apply\" as const,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\ttoggle: ({ state: current, itemId, selected }) => {\n\t\t\t\tif (!isChromeDevtoolsToolName(itemId) || selected === undefined)\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\tif (selected) current.draft.add(itemId);\n\t\t\t\telse current.draft.delete(itemId);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\tselectAll: ({ state: current }) => {\n\t\t\t\tcurrent.draft = new Set(CHROME_DEVTOOLS_TOOL_NAMES);\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\tselectNone: ({ state: current }) => {\n\t\t\t\tcurrent.draft = new Set();\n\t\t\t\treturn { kind: \"stay\" };\n\t\t\t},\n\t\t\treview: () => ({ kind: \"to\", screen: \"review\" }),\n\t\t\tcancel: () => ({ kind: \"back\" }),\n\t\t\tapply: async ({ state: current, signal }) => {\n\t\t\t\tawait ctx.waitForIdle();\n\t\t\t\tif (signal.aborted || !isCurrent() || current.generation !== state.sessionGeneration) {\n\t\t\t\t\treturn { kind: \"rejected\" };\n\t\t\t\t}\n\t\t\t\tconst selectedTools = orderedTools(current.draft);\n\t\t\t\tconst saveResult = await setSelectedChromeDevtoolsTools(\n\t\t\t\t\tpi,\n\t\t\t\t\tctx,\n\t\t\t\t\tselectedTools,\n\t\t\t\t\torderedTools(current.accepted),\n\t\t\t\t);\n\t\t\t\tif (!isCurrent()) return { kind: \"rejected\" };\n\t\t\t\tif (saveResult === \"active-tools-changed\") {\n\t\t\t\t\tcurrent.accepted = new Set(activeChromeTools(pi));\n\t\t\t\t}\n\t\t\t\tif (saveResult !== \"saved\") return { kind: \"rejected\" };\n\t\t\t\tcurrent.accepted = new Set(selectedTools);\n\t\t\t\tcurrent.draft = new Set(selectedTools);\n\t\t\t\tcurrent.applied = true;\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available.`,\n\t\t\t\t\t\"info\",\n\t\t\t\t);\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t},\n\t});\n\tconst result = await runMenu(ctx, menu, {\n\t\tgetState: () => workflow,\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\tonError: (currentCtx, error) =>\n\t\t\tcurrentCtx.ui.notify(\n\t\t\t\tsanitizeChromeDevtoolsDisplay(\n\t\t\t\t\t`Chrome DevTools tool selection failed: ${formatError(error)}`,\n\t\t\t\t),\n\t\t\t\t\"error\",\n\t\t\t),\n\t});\n\treturn {\n\t\tapplied: workflow.applied,\n\t\tcloseParent: !workflow.applied && result.kind === \"closed\" && result.reason === \"close\",\n\t\tselectedTools: orderedTools(workflow.accepted),\n\t};\n}\n\nasync function loadSnapshotWithFeedback(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n\tconst menuSignal = state.sessionController.signal;\n\tconst isCurrent = () => generation === state.sessionGeneration && !menuSignal.aborted;\n\tconst result = await runTask(ctx, {\n\t\tlabel: \"Loading Chrome DevTools settings\u2026\",\n\t\tsignal: menuSignal,\n\t\tisCurrent,\n\t\ttask: async ({ signal }) => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst settings = await loadSettings();\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn buildMenuSnapshot(pi, settings);\n\t\t},\n\t});\n\treturn result.kind === \"completed\" ? result.value : undefined;\n}\n\nfunction buildMenuSnapshot(pi: ExtensionAPI, settings: SettingsLoadResult): MenuSnapshot {\n\tconst activeTools = activeChromeTools(pi);\n\tconst persistedTools =\n\t\tsettings.kind === \"loaded\" && settings.settings.tools\n\t\t\t? orderedTools(new Set(settings.settings.tools))\n\t\t\t: undefined;\n\tconst persistenceLabel =\n\t\tsettings.kind === \"invalid\"\n\t\t\t? \"settings need repair\"\n\t\t\t: persistedTools === undefined\n\t\t\t\t? \"not saved\"\n\t\t\t\t: arraysEqual(activeTools, persistedTools)\n\t\t\t\t\t? \"saved\"\n\t\t\t\t\t: \"runtime catalog differs from saved catalog\";\n\tconst settingsWarning = [\n\t\t...new Set([settings.notice, state.settingsNotice].filter(Boolean)),\n\t].join(\"\\n\");\n\treturn {\n\t\tactiveTools,\n\t\tpersistenceLabel,\n\t\t...(settings.kind === \"invalid\"\n\t\t\t? { mutationBlockedReason: `Repair ${settings.reason} before saving` }\n\t\t\t: {}),\n\t\t...(settingsWarning ? { settingsWarning } : {}),\n\t};\n}\n\nfunction mainStateLines(snapshot: MenuSnapshot) {\n\treturn sanitizeLines([\n\t\t`Tool catalog: ${snapshot.activeTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} available \u00B7 ${snapshot.persistenceLabel}`,\n\t\t`Browser: ${browserLifecycleSummary()}`,\n\t\t`Endpoint: ${devToolsEndpoint()}`,\n\t\t...(snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : []),\n\t\t...(state.lastLaunchAttempt?.lastError\n\t\t\t? [`Launch warning: ${state.lastLaunchAttempt.lastError}`]\n\t\t\t: []),\n\t]);\n}\n\nfunction browserLifecycleSummary() {\n\tconst lifecycle = browserLifecycleState();\n\tif (lifecycle === \"starting\") return \"starting managed browser\";\n\tif (lifecycle === \"running\") return \"managed browser running\";\n\tif (lifecycle === \"exited\") return \"managed browser exited \u00B7 open Browser status to recover\";\n\tif (lifecycle === \"failed\") return \"last launch failed \u00B7 open Browser status to recover\";\n\tconst launchMode = launchModeLabel();\n\treturn launchMode.startsWith(\"attach first\")\n\t\t? \"not started \u00B7 attaches or launches on first use\"\n\t\t: `not started \u00B7 ${launchMode}`;\n}\n\nfunction toolDraftLines(current: ToolWorkflowState) {\n\tif (current.mutationBlockedReason)\n\t\treturn sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);\n\tconst changes = symmetricDifferenceSize(current.accepted, current.draft);\n\treturn [\n\t\t`Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\tchanges === 0\n\t\t\t? \"No unapplied changes \u00B7 Escape cancels\"\n\t\t\t: `${changes} unapplied ${changes === 1 ? \"change\" : \"changes\"} \u00B7 Escape cancels`,\n\t\t\"Changes are not applied until Review changes and Apply tool changes.\",\n\t];\n}\n\nfunction buildToolReview(current: ToolWorkflowState) {\n\tconst available = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => current.draft.has(name));\n\tconst unavailable = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => !current.draft.has(name));\n\treturn sanitizeChromeDevtoolsDisplay(\n\t\t[\n\t\t\t`Current available browser tools: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t`Proposed available browser tools: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,\n\t\t\t\"\",\n\t\t\t\"Available after apply:\",\n\t\t\t...(available.length > 0\n\t\t\t\t? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n\t\t\t\t: [\" - none\"]),\n\t\t\t\"\",\n\t\t\t\"Unavailable after apply:\",\n\t\t\t...(unavailable.length > 0\n\t\t\t\t? unavailable.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`)\n\t\t\t\t: [\" - none\"]),\n\t\t\t\"\",\n\t\t\t\"Other active Pi tools remain unchanged.\",\n\t\t\t\"Native-capable models defer these tools until chrome_devtools_load selects them.\",\n\t\t\t\"Other models expose available tools eagerly before the next model request.\",\n\t\t\t\"The accepted availability policy is saved for future sessions.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nfunction updateSnapshotAfterApply(\n\tsnapshot: MenuSnapshot,\n\tselectedTools: readonly ChromeDevToolsToolName[],\n) {\n\tsnapshot.activeTools = [...selectedTools];\n\tsnapshot.persistenceLabel = \"saved\";\n}\n\nfunction activeChromeTools(pi: ExtensionAPI) {\n\treturn availableChromeDevtoolsTools(pi);\n}\n\nfunction orderedTools(tools: ReadonlySet<ChromeDevToolsToolName>) {\n\treturn CHROME_DEVTOOLS_TOOL_NAMES.filter((toolName) => tools.has(toolName));\n}\n\nfunction isChromeDevtoolsToolName(value: string): value is ChromeDevToolsToolName {\n\treturn CHROME_DEVTOOLS_TOOL_NAMES.includes(value as ChromeDevToolsToolName);\n}\n\nfunction setsEqual<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n\treturn left.size === right.size && [...left].every((value) => right.has(value));\n}\n\nfunction symmetricDifferenceSize<T>(left: ReadonlySet<T>, right: ReadonlySet<T>) {\n\tlet changes = 0;\n\tfor (const value of left) if (!right.has(value)) changes += 1;\n\tfor (const value of right) if (!left.has(value)) changes += 1;\n\treturn changes;\n}\n\nfunction arraysEqual<T>(left: readonly T[], right: readonly T[]) {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction sanitizeLines(lines: readonly string[]) {\n\treturn sanitizeChromeDevtoolsDisplay(lines.join(\"\\n\")).split(\"\\n\");\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
-
// @ts-nocheck -- generated
|
|
2
|
+
// @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
|
|
3
3
|
import {
|
|
4
4
|
CHROME_DEVTOOLS_TOOL_NAMES,
|
|
5
5
|
DEFAULT_ENDPOINT_WAIT_MS,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
buildCommandGuide,
|
|
11
11
|
buildQuickstartMessage,
|
|
12
12
|
buildToolStatusMessage,
|
|
13
|
-
|
|
13
|
+
configureChromeDevtoolsToolExposure,
|
|
14
14
|
createChromeDevtoolsLoadTool,
|
|
15
15
|
devToolsEndpoint,
|
|
16
16
|
ensureDevToolsEndpoint,
|
|
@@ -19,14 +19,16 @@ import {
|
|
|
19
19
|
initializeAvailableChromeDevtoolsTools,
|
|
20
20
|
launchHint,
|
|
21
21
|
loadSettings,
|
|
22
|
+
requireEagerChromeDevtoolsToolExposure,
|
|
22
23
|
sanitizeChromeDevtoolsDisplay,
|
|
23
24
|
shutdownManagedBrowser,
|
|
24
25
|
state,
|
|
26
|
+
supportsNativeDeferredToolLoading,
|
|
25
27
|
updateChromeDevtoolsTools,
|
|
26
28
|
waitForChromeDevtoolsSettings,
|
|
27
29
|
waitForSettingsWrites,
|
|
28
30
|
withEndpointRetry
|
|
29
|
-
} from "./chunks/chunk-
|
|
31
|
+
} from "./chunks/chunk-RH6KESL3.js";
|
|
30
32
|
|
|
31
33
|
// src/tools.ts
|
|
32
34
|
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
@@ -607,7 +609,7 @@ var COMMAND_COMPLETIONS = [
|
|
|
607
609
|
{ value: "quickstart", label: "quickstart", description: "Show endpoint and launch help" },
|
|
608
610
|
{ value: "status", label: "status", description: "Show tool and settings status" },
|
|
609
611
|
{ value: "settings", label: "settings", description: "Edit browser connection settings" },
|
|
610
|
-
{ value: "tools", label: "tools", description: "Choose
|
|
612
|
+
{ value: "tools", label: "tools", description: "Choose available Chrome DevTools tools" },
|
|
611
613
|
{ value: "toggle", label: "toggle", description: "Alias for tools" },
|
|
612
614
|
{ value: "select", label: "select", description: "Compatibility alias for tools" },
|
|
613
615
|
{ value: "enable", label: "enable", description: "Make all Chrome DevTools tools available" },
|
|
@@ -651,7 +653,12 @@ function chromeDevtools(pi) {
|
|
|
651
653
|
ctx.ui.notify(sanitizeChromeDevtoolsDisplay(warning), "warning");
|
|
652
654
|
}
|
|
653
655
|
const availableTools = settings.kind === "loaded" && settings.settings.tools ? settings.settings.tools : availableChromeDevtoolsTools(pi);
|
|
654
|
-
|
|
656
|
+
configureChromeDevtoolsToolExposure(pi, availableTools, ctx.model);
|
|
657
|
+
});
|
|
658
|
+
pi.on("model_select", (event) => {
|
|
659
|
+
if (!supportsNativeDeferredToolLoading(event.model)) {
|
|
660
|
+
requireEagerChromeDevtoolsToolExposure(pi);
|
|
661
|
+
}
|
|
655
662
|
});
|
|
656
663
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
657
664
|
state.sessionGeneration += 1;
|
|
@@ -688,7 +695,7 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
|
|
|
688
695
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
689
696
|
throw new Error("/chrome-devtools settings requires TUI or RPC mode");
|
|
690
697
|
}
|
|
691
|
-
const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-
|
|
698
|
+
const { showChromeDevtoolsBrowserSettings } = await import("./chunks/browser-settings-menu-VWCNG4HB.js");
|
|
692
699
|
if (generation !== state.sessionGeneration) return;
|
|
693
700
|
await showChromeDevtoolsBrowserSettings(ctx, generation);
|
|
694
701
|
return;
|
|
@@ -697,7 +704,7 @@ async function handleChromeDevtoolsCommand(pi, args, ctx, generation) {
|
|
|
697
704
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
698
705
|
throw new Error("/chrome-devtools tools requires TUI or RPC mode");
|
|
699
706
|
}
|
|
700
|
-
const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-
|
|
707
|
+
const { showChromeDevtoolsToolWorkflow } = await import("./chunks/menu-PLD3S3EO.js");
|
|
701
708
|
if (generation !== state.sessionGeneration) return;
|
|
702
709
|
await showChromeDevtoolsToolWorkflow(pi, ctx, generation);
|
|
703
710
|
return;
|
|
@@ -728,7 +735,7 @@ async function showMenu(pi, ctx, generation) {
|
|
|
728
735
|
if (!ctx.hasUI || ctx.mode !== "tui" && ctx.mode !== "rpc") {
|
|
729
736
|
throw new Error("/chrome-devtools menu requires TUI or RPC mode; use a direct subcommand");
|
|
730
737
|
}
|
|
731
|
-
const { showChromeDevtoolsMenu } = await import("./chunks/menu-
|
|
738
|
+
const { showChromeDevtoolsMenu } = await import("./chunks/menu-PLD3S3EO.js");
|
|
732
739
|
if (generation !== state.sessionGeneration) return;
|
|
733
740
|
await showChromeDevtoolsMenu(pi, ctx, generation);
|
|
734
741
|
}
|
package/dist/index.ts.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/tools.ts", "../src/cdp-client.ts", "../src/render.ts", "../src/screenshot.ts", "../src/chrome-devtools.ts"],
|
|
4
|
-
"sourcesContent": ["import { defineTool } from \"@earendil-works/pi-coding-agent\";\nimport { Type } from \"typebox\";\nimport {\n\tformatPage,\n\tgetPage,\n\tlistPages,\n\tresolvePage,\n\tresolvePageForNavigation,\n\ttextResult,\n\twithCdp,\n} from \"./cdp-client.js\";\nimport { renderScreenshotResult, renderTextResult, renderToolCall, withStatus } from \"./render.js\";\nimport { state } from \"./runtime.js\";\nimport { formatScreenshotText, saveScreenshot, throwIfAborted } from \"./screenshot.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES } from \"./tool-names.js\";\n\nexport const listPagesTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[0],\n\tlabel: \"Chrome DevTools: List Pages\",\n\tdescription: \"List Chrome tabs/pages from a running Chrome DevTools Protocol endpoint.\",\n\tparameters: Type.Object({}),\n\trenderCall: renderToolCall(\"list pages\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, _params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"list pages\", async () => {\n\t\t\tconst pages = await listPages();\n\t\t\treturn textResult(JSON.stringify(pages.map(formatPage), null, 2), { pages });\n\t\t});\n\t},\n});\n\nexport const selectPageTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[1],\n\tlabel: \"Chrome DevTools: Select Page\",\n\tdescription: \"Select the active Chrome page for later chrome_devtools_* tool calls.\",\n\tparameters: Type.Object({\n\t\tpageId: Type.String({ description: \"Page id from chrome_devtools_list_pages.\" }),\n\t}),\n\trenderCall: renderToolCall(\"select page\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"select page\", async () => {\n\t\t\tconst page = await getPage(params.pageId);\n\t\t\tstate.activePageId = page.id;\n\t\t\treturn textResult(`Selected page ${page.id}: ${page.title}\\n${page.url}`, {\n\t\t\t\tpage: formatPage(page),\n\t\t\t});\n\t\t});\n\t},\n});\n\nexport const navigateTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[2],\n\tlabel: \"Chrome DevTools: Navigate\",\n\tdescription:\n\t\t\"Navigate a Chrome page to a URL through Chrome DevTools Protocol, creating a page first if none is available.\",\n\tparameters: Type.Object({\n\t\turl: Type.String({ description: \"URL to navigate to.\" }),\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"navigate\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"navigate\", async () => {\n\t\t\tconst { created, page } = await resolvePageForNavigation(params.pageId);\n\t\t\tconst result = await withCdp(page, async (client) => {\n\t\t\t\tawait client.send(\"Page.enable\");\n\t\t\t\treturn client.send(\"Page.navigate\", { url: params.url });\n\t\t\t});\n\n\t\t\tstate.activePageId = page.id;\n\t\t\tconst action = created ? \"Created page and navigated\" : \"Navigated\";\n\t\t\treturn textResult(`${action} ${page.id} to ${params.url}`, {\n\t\t\t\tcreated,\n\t\t\t\tpage: formatPage(page),\n\t\t\t\tresult,\n\t\t\t});\n\t\t});\n\t},\n});\n\nexport const evaluateTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[3],\n\tlabel: \"Chrome DevTools: Evaluate\",\n\tdescription: \"Evaluate JavaScript in a Chrome page through Chrome DevTools Protocol.\",\n\tparameters: Type.Object({\n\t\texpression: Type.String({ description: \"JavaScript expression to evaluate.\" }),\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t\tawaitPromise: Type.Optional(\n\t\t\tType.Boolean({ description: \"Whether to await a returned Promise. Defaults to true.\" }),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"evaluate\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"evaluate\", async () => {\n\t\t\tconst page = await resolvePage(params.pageId);\n\t\t\tconst result = await withCdp(page, (client) =>\n\t\t\t\tclient.send(\"Runtime.evaluate\", {\n\t\t\t\t\texpression: params.expression,\n\t\t\t\t\tawaitPromise: params.awaitPromise ?? true,\n\t\t\t\t\treturnByValue: true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tstate.activePageId = page.id;\n\t\t\treturn textResult(JSON.stringify(result, null, 2), { page: formatPage(page), result });\n\t\t});\n\t},\n});\n\nexport const screenshotTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[4],\n\tlabel: \"Chrome DevTools: Screenshot\",\n\tdescription: \"Capture a PNG screenshot from a Chrome page through Chrome DevTools Protocol.\",\n\tparameters: Type.Object({\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t\tfullPage: Type.Optional(\n\t\t\tType.Boolean({ description: \"Capture the full document, not just the viewport.\" }),\n\t\t),\n\t\tsavePath: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Screenshot is always saved as a PNG file. Optional output path; omitted defaults to a unique temp file. Relative paths resolve from the current working directory. A single leading @ is stripped to match Pi file-mention paths. Existing regular files are replaced.\",\n\t\t\t}),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"screenshot\"),\n\trenderResult: renderScreenshotResult,\n\tasync execute(_toolCallId, params, signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"screenshot\", async () => {\n\t\t\tconst page = await resolvePage(params.pageId);\n\t\t\tconst result = await withCdp(page, async (client) => {\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tawait client.send(\"Page.enable\");\n\n\t\t\t\tif (!params.fullPage) {\n\t\t\t\t\treturn client.send<{ data: string }>(\"Page.captureScreenshot\", { format: \"png\" });\n\t\t\t\t}\n\n\t\t\t\tconst metrics = await client.send<{\n\t\t\t\t\tcontentSize: { x: number; y: number; width: number; height: number };\n\t\t\t\t}>(\"Page.getLayoutMetrics\");\n\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\treturn client.send<{ data: string }>(\"Page.captureScreenshot\", {\n\t\t\t\t\tcaptureBeyondViewport: true,\n\t\t\t\t\tformat: \"png\",\n\t\t\t\t\tclip: {\n\t\t\t\t\t\tx: metrics.contentSize.x,\n\t\t\t\t\t\ty: metrics.contentSize.y,\n\t\t\t\t\t\twidth: metrics.contentSize.width,\n\t\t\t\t\t\theight: metrics.contentSize.height,\n\t\t\t\t\t\tscale: 1,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tstate.activePageId = page.id;\n\t\t\tconst savedScreenshot = await saveScreenshot(result.data, params.savePath, ctx.cwd, signal);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: formatScreenshotText(page, savedScreenshot),\n\t\t\t\t\t},\n\t\t\t\t\t{ type: \"image\", data: result.data, mimeType: \"image/png\" },\n\t\t\t\t],\n\t\t\t\tdetails: {\n\t\t\t\t\tpage: formatPage(page),\n\t\t\t\t\tbytes: savedScreenshot.bytes,\n\t\t\t\t\tsavedPath: savedScreenshot.savedPath,\n\t\t\t\t\tisDefaultPath: savedScreenshot.isDefaultPath,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t},\n});\n", "import {\n\tdevToolsEndpoint,\n\tensureDevToolsEndpoint,\n\tfetchDevToolsJson,\n\tformatPageListItem,\n\tlaunchHint,\n\twithEndpointRetry,\n} from \"./browser-manager.js\";\nimport {\n\tDEFAULT_ENDPOINT_WAIT_MS,\n\tDEFAULT_TIMEOUT_MS,\n\ttype DevToolsPage,\n\tstate,\n} from \"./runtime.js\";\n\ninterface CdpResponse<T = unknown> {\n\tid: number;\n\tresult?: T;\n\terror?: { code: number; message: string; data?: unknown };\n}\n\nexport async function listPages(options: { waitMs?: number } = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs);\n\treturn withEndpointRetry(async () => {\n\t\tconst pages = await fetchDevToolsJson<DevToolsPage[]>(\"/json/list\");\n\t\treturn pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n\t}, waitMs);\n}\n\nexport async function getPage(pageId: string) {\n\tconst pages = await listPages();\n\treturn requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string) {\n\tconst pages = await listPages();\n\tif (pageId) return requirePage(pageId, pages);\n\n\tconst page = resolveDefaultPage(pages);\n\tif (!page) {\n\t\tthrow new Error(\n\t\t\t[\n\t\t\t\t`No Chrome pages found at ${devToolsEndpoint()}.`,\n\t\t\t\t\"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.\",\n\t\t\t\tlaunchHint(),\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t}\n\n\treturn page;\n}\n\nexport async function resolvePageForNavigation(pageId?: string) {\n\tconst pages = await listPages();\n\tif (pageId) return { created: false, page: requirePage(pageId, pages) };\n\n\tconst page = resolveDefaultPage(pages);\n\tif (page) return { created: false, page };\n\n\treturn { created: true, page: await createPage(\"about:blank\") };\n}\n\nfunction resolveDefaultPage(pages: DevToolsPage[]) {\n\tif (!state.activePageId) return pages[0];\n\n\tconst activePage = pages.find((candidate) => candidate.id === state.activePageId);\n\tif (activePage) return activePage;\n\n\tstate.activePageId = undefined;\n\treturn pages[0];\n}\n\nfunction requirePage(pageId: string, pages: DevToolsPage[]) {\n\tconst page = pages.find((candidate) => candidate.id === pageId);\n\tif (page) return page;\n\n\tconst availablePages = pages.map(formatPageListItem).join(\"\\n\");\n\tthrow new Error(\n\t\t[\n\t\t\t`Chrome DevTools page not found: ${pageId}.`,\n\t\t\tavailablePages\n\t\t\t\t? `Available pages:\\n${availablePages}`\n\t\t\t\t: \"No inspectable Chrome pages are currently available.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nexport async function createPage(url: string, options: { waitMs?: number } = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs);\n\tconst page = await withEndpointRetry(\n\t\t() =>\n\t\t\tfetchDevToolsJson<DevToolsPage>(`/json/new?${encodeURIComponent(url)}`, {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t}),\n\t\twaitMs,\n\t);\n\tif (page.type !== \"page\" || !page.webSocketDebuggerUrl) {\n\t\tthrow new Error(\"Chrome DevTools created a target that is not an inspectable page.\");\n\t}\n\n\treturn page;\n}\n\nexport function formatPage(page: DevToolsPage) {\n\treturn {\n\t\tid: page.id,\n\t\ttype: page.type,\n\t\ttitle: page.title,\n\t\turl: page.url,\n\t};\n}\n\nexport function textResult(text: string, details: unknown) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport async function withCdp<T>(page: DevToolsPage, callback: (client: CdpClient) => Promise<T>) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n\tconst client = await CdpClient.connect(page.webSocketDebuggerUrl);\n\ttry {\n\t\treturn await callback(client);\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nclass CdpClient {\n\t#nextId = 1;\n\t#pending = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (value: unknown) => void;\n\t\t\treject: (reason: unknown) => void;\n\t\t\ttimeout: NodeJS.Timeout;\n\t\t}\n\t>();\n\tprivate readonly socket: WebSocket;\n\n\tprivate constructor(socket: WebSocket) {\n\t\tthis.socket = socket;\n\t\tsocket.addEventListener(\"message\", (event) => {\n\t\t\tconst response = JSON.parse(String(event.data)) as CdpResponse;\n\t\t\tif (typeof response.id !== \"number\") return;\n\n\t\t\tconst pending = this.#pending.get(response.id);\n\t\t\tif (!pending) return;\n\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tthis.#pending.delete(response.id);\n\n\t\t\tif (response.error) {\n\t\t\t\tpending.reject(new Error(`CDP error ${response.error.code}: ${response.error.message}`));\n\t\t\t} else {\n\t\t\t\tpending.resolve(response.result);\n\t\t\t}\n\t\t});\n\n\t\tsocket.addEventListener(\"close\", () => {\n\t\t\tthis.rejectAll(new Error(\"Chrome DevTools WebSocket closed\"));\n\t\t});\n\n\t\tsocket.addEventListener(\"error\", () => {\n\t\t\tthis.rejectAll(new Error(\"Chrome DevTools WebSocket error\"));\n\t\t});\n\t}\n\n\tstatic connect(url: string) {\n\t\treturn new Promise<CdpClient>((resolve, reject) => {\n\t\t\tconst socket = new WebSocket(url);\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tsocket.close();\n\t\t\t\treject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n\t\t\t}, DEFAULT_TIMEOUT_MS);\n\n\t\t\tsocket.addEventListener(\"open\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tresolve(new CdpClient(socket));\n\t\t\t});\n\n\t\t\tsocket.addEventListener(\"error\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n\t\t\t});\n\t\t});\n\t}\n\n\tsend<T = unknown>(method: string, params?: Record<string, unknown>) {\n\t\tconst id = this.#nextId;\n\t\tthis.#nextId += 1;\n\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\treject(new Error(`Timed out waiting for CDP response: ${method}`));\n\t\t\t}, DEFAULT_TIMEOUT_MS);\n\n\t\t\tthis.#pending.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout });\n\t\t\tthis.socket.send(JSON.stringify({ id, method, params: params ?? {} }));\n\t\t});\n\t}\n\n\tclose() {\n\t\tthis.socket.close();\n\t}\n\n\tprivate rejectAll(error: Error) {\n\t\tfor (const [id, pending] of this.#pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.#pending.delete(id);\n\t\t}\n\t}\n}\n", "import type { AgentToolResult, ToolRenderResultOptions } from \"@earendil-works/pi-coding-agent\";\n\nconst STATUS_KEY = \"chrome-devtools\";\ninterface StatusContext {\n\tui: { setStatus: (key: string, value: string | undefined) => void };\n}\ninterface RenderTheme {\n\tbold(text: string): string;\n\tfg(color: string, text: string): string;\n}\ninterface RenderComponent {\n\tinvalidate(): void;\n\trender(width: number): string[];\n}\n\nexport function renderToolCall(action: string) {\n\treturn () => new PiTextComponent(`Chrome DevTools: ${action}`);\n}\n\nexport function renderTextResult(\n\tresult: AgentToolResult<unknown>,\n\toptions: ToolRenderResultOptions,\n\ttheme: RenderTheme,\n) {\n\tconst output = formatCollapsibleOutput(textContent(result), options);\n\treturn new PiTextComponent(output.text, theme, output.color);\n}\n\nexport function renderScreenshotResult(\n\tresult: AgentToolResult<unknown>,\n\toptions: ToolRenderResultOptions,\n\ttheme: RenderTheme,\n): RenderComponent {\n\tconst output = formatCollapsibleOutput(screenshotTextContent(result), options);\n\treturn new PiTextComponent(output.text, theme, output.color);\n}\n\nfunction textContent(result: AgentToolResult<unknown>) {\n\treturn result.content\n\t\t.flatMap((content) => (content.type === \"text\" ? [content.text] : []))\n\t\t.join(\"\\n\");\n}\n\nfunction screenshotTextContent(result: AgentToolResult<unknown>) {\n\tconst text = textContent(result);\n\tif (text.trim()) return text;\n\n\tconst details = result.details as { savedPath?: unknown; bytes?: unknown } | undefined;\n\tif (typeof details?.savedPath !== \"string\") return text;\n\tconst bytes = typeof details.bytes === \"number\" ? ` (${details.bytes} bytes)` : \"\";\n\treturn `Saved screenshot to ${details.savedPath}${bytes}`;\n}\n\nfunction formatCollapsibleOutput(\n\ttext: string,\n\toptions: ToolRenderResultOptions,\n): { text: string; color?: string } {\n\tif (options.isPartial) return { text: \"Running...\", color: \"warning\" };\n\tif (options.expanded) return { text, color: \"toolOutput\" };\n\n\treturn { text: \"\" };\n}\n\nclass PiTextComponent implements RenderComponent {\n\tprivate text: string;\n\tprivate readonly theme?: RenderTheme;\n\tprivate readonly color?: string;\n\n\tconstructor(text = \"\", theme?: RenderTheme, color?: string) {\n\t\tthis.text = text;\n\t\tthis.theme = theme;\n\t\tthis.color = color;\n\t}\n\n\tsetText(text: string) {\n\t\tthis.text = text;\n\t}\n\n\tinvalidate() {\n\t\t// Stateless renderer: no cached layout to invalidate.\n\t}\n\n\trender(width: number) {\n\t\tif (!this.text.trim()) return [];\n\t\treturn this.text\n\t\t\t.replace(/\\t/g, \" \")\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.map((line) => {\n\t\t\t\tconst truncatedLine = truncateLine(line, Math.max(1, width));\n\t\t\t\treturn this.theme && this.color ? this.theme.fg(this.color, truncatedLine) : truncatedLine;\n\t\t\t});\n\t}\n}\n\nfunction truncateLine(line: string, maxWidth: number) {\n\treturn Array.from(line).slice(0, maxWidth).join(\"\");\n}\n\nexport async function withStatus<T>(\n\tctx: StatusContext,\n\tstatus: string,\n\tcallback: () => Promise<T>,\n) {\n\tctx.ui.setStatus(STATUS_KEY, status);\n\ttry {\n\t\treturn await callback();\n\t} finally {\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { lstat, mkdir, realpath, rename, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport { withFileMutationQueue } from \"@earendil-works/pi-coding-agent\";\nimport type { DevToolsPage } from \"./runtime.js\";\n\nfunction unique<T>(values: T[]) {\n\treturn Array.from(new Set(values));\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nexport interface ResolvedScreenshotPath {\n\tpath: string;\n\tallowedRoots: string[];\n\tisDefault: boolean;\n}\nexport interface ScreenshotSaveResult {\n\tsavedPath: string;\n\tbytes: number;\n\tisDefaultPath: boolean;\n}\n\nexport async function saveScreenshot(\n\tbase64Png: string,\n\tsavePath: string | undefined,\n\tcwd: string,\n\tsignal: AbortSignal | undefined,\n): Promise<ScreenshotSaveResult> {\n\tconst resolvedPath = resolveScreenshotPath(savePath, cwd);\n\tconst pngBytes = Buffer.from(base64Png, \"base64\");\n\n\tawait withFileMutationQueue(resolvedPath.path, async () => {\n\t\tthrowIfAborted(signal);\n\t\tawait ensureSafeScreenshotParent(resolvedPath);\n\t\tawait assertSafeScreenshotTargetPath(resolvedPath);\n\t\tawait writeScreenshotFileSafely(resolvedPath, pngBytes, signal);\n\t});\n\n\treturn {\n\t\tsavedPath: resolvedPath.path,\n\t\tbytes: pngBytes.byteLength,\n\t\tisDefaultPath: resolvedPath.isDefault,\n\t};\n}\n\nexport function resolveScreenshotPath(\n\tsavePath: string | undefined,\n\tcwd: string,\n): ResolvedScreenshotPath {\n\tconst cwdRoot = resolve(cwd);\n\tconst tempRoot = resolve(tmpdir());\n\n\tif (savePath === undefined) {\n\t\treturn {\n\t\t\tpath: join(tempRoot, `pi-chrome-devtools-screenshot-${randomUUID()}.png`),\n\t\t\tallowedRoots: [tempRoot],\n\t\t\tisDefault: true,\n\t\t};\n\t}\n\n\tconst normalizedPath = stripLeadingAtPath(savePath);\n\tif (!normalizedPath.trim()) {\n\t\tthrow new Error(\"Screenshot savePath must not be empty.\");\n\t}\n\tif (normalizedPath.includes(\"\\0\")) {\n\t\tthrow new Error(\"Screenshot savePath must not contain NUL bytes.\");\n\t}\n\tif (hasParentPathSegment(normalizedPath)) {\n\t\tthrow new Error(\"Screenshot savePath must not contain '..' path segments.\");\n\t}\n\n\tconst isAbsolutePath = isAbsolute(normalizedPath);\n\tconst path = isAbsolutePath ? resolve(normalizedPath) : resolve(cwdRoot, normalizedPath);\n\tconst allowedRoots = isAbsolutePath ? unique([cwdRoot, tempRoot]) : [cwdRoot];\n\tif (!allowedRoots.some((root) => isPathInsideRoot(path, root))) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath must be relative to the current working directory, or an absolute path inside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n\n\treturn { path, allowedRoots, isDefault: false };\n}\n\nfunction stripLeadingAtPath(path: string) {\n\treturn path.startsWith(\"@\") ? path.slice(1) : path;\n}\n\nexport function hasParentPathSegment(path: string) {\n\treturn path.split(/[\\\\/]+/).some((part) => part === \"..\");\n}\n\nasync function ensureSafeScreenshotParent(resolvedPath: ResolvedScreenshotPath) {\n\tconst parentPath = dirname(resolvedPath.path);\n\tconst rootPath = selectAllowedRoot(parentPath, resolvedPath.allowedRoots);\n\tif (!rootPath) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath parent must stay inside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n\n\tconst realRootPath = await realpath(rootPath);\n\tlet currentPath = rootPath;\n\tconst parentSegments = relative(rootPath, parentPath)\n\t\t.split(/[\\\\/]+/)\n\t\t.filter((part) => part.length > 0);\n\n\tfor (const segment of parentSegments) {\n\t\tcurrentPath = join(currentPath, segment);\n\t\tawait ensureSafeDirectorySegment(currentPath, realRootPath);\n\t}\n}\n\nexport function selectAllowedRoot(path: string, roots: readonly string[]) {\n\tconst matchingRoots = roots.filter((root) => isPathInsideRoot(path, root));\n\tmatchingRoots.sort(\n\t\t(left, right) =>\n\t\t\tnormalizePathForComparison(resolve(right)).length -\n\t\t\tnormalizePathForComparison(resolve(left)).length,\n\t);\n\treturn matchingRoots[0];\n}\n\nasync function ensureSafeDirectorySegment(path: string, realRootPath: string) {\n\tconst existingDirectory = await lstat(path).catch(async (error: unknown) => {\n\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\tawait mkdir(path).catch((mkdirError: unknown) => {\n\t\t\tif (!isNodeError(mkdirError) || mkdirError.code !== \"EEXIST\") throw mkdirError;\n\t\t});\n\t\treturn lstat(path);\n\t});\n\n\tif (existingDirectory.isSymbolicLink()) {\n\t\tthrow new Error(\"Screenshot savePath parent directories must not contain symbolic links.\");\n\t}\n\tif (!existingDirectory.isDirectory()) {\n\t\tthrow new Error(\"Screenshot savePath parent must be a directory.\");\n\t}\n\tawait assertPathWithinRealRoot(path, realRootPath);\n}\n\nasync function assertSafeScreenshotTargetPath(resolvedPath: ResolvedScreenshotPath) {\n\tconst existingTarget = await lstat(resolvedPath.path).catch((error: unknown) => {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n\t\tthrow error;\n\t});\n\tif (existingTarget?.isSymbolicLink()) {\n\t\tthrow new Error(\"Screenshot savePath must not point to a symbolic link.\");\n\t}\n\tif (existingTarget?.isDirectory()) {\n\t\tthrow new Error(\"Screenshot savePath must point to a file, not a directory.\");\n\t}\n\tif (existingTarget && !existingTarget.isFile()) {\n\t\tthrow new Error(\"Screenshot savePath may only replace regular files.\");\n\t}\n\n\tconst realAllowedRoots = await Promise.all(resolvedPath.allowedRoots.map(realpathOrResolvedPath));\n\tconst realParent = await realpath(dirname(resolvedPath.path));\n\tconst realTargetPath = join(realParent, basename(resolvedPath.path));\n\tif (!realAllowedRoots.some((root) => isPathInsideRoot(realTargetPath, root))) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath resolves outside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n}\n\nasync function assertPathWithinRealRoot(path: string, realRootPath: string) {\n\tconst realPath = await realpath(path);\n\tif (!isPathInsideRoot(realPath, realRootPath)) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath parent resolves outside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n}\n\nasync function writeScreenshotFileSafely(\n\tresolvedPath: ResolvedScreenshotPath,\n\tpngBytes: Buffer,\n\tsignal: AbortSignal | undefined,\n) {\n\tconst tempFile = join(\n\t\tdirname(resolvedPath.path),\n\t\t`.${basename(resolvedPath.path)}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`,\n\t);\n\ttry {\n\t\tawait writeFile(tempFile, pngBytes, { flag: \"wx\", signal });\n\t\tthrowIfAborted(signal);\n\t\tawait replaceScreenshotFile(resolvedPath, tempFile, signal);\n\t} catch (error) {\n\t\tawait rm(tempFile, { force: true }).catch(() => undefined);\n\t\tthrow error;\n\t}\n}\n\nasync function replaceScreenshotFile(\n\tresolvedPath: ResolvedScreenshotPath,\n\ttempFile: string,\n\tsignal: AbortSignal | undefined,\n) {\n\ttry {\n\t\tawait rename(tempFile, resolvedPath.path);\n\t\treturn;\n\t} catch (error) {\n\t\tif (!shouldRetryRenameAfterRemovingDestination(error)) throw error;\n\t}\n\n\t// Some Windows filesystems reject renaming over an existing file. Revalidate before\n\t// removing the destination so the fallback still refuses directories and symlinks.\n\tawait assertSafeScreenshotTargetPath(resolvedPath);\n\tthrowIfAborted(signal);\n\tawait rm(resolvedPath.path, { force: true });\n\tawait rename(tempFile, resolvedPath.path);\n}\n\nfunction shouldRetryRenameAfterRemovingDestination(error: unknown) {\n\treturn (\n\t\tprocess.platform === \"win32\" &&\n\t\tisNodeError(error) &&\n\t\t[\"EACCES\", \"EEXIST\", \"EPERM\"].includes(error.code ?? \"\")\n\t);\n}\n\nasync function realpathOrResolvedPath(path: string) {\n\treturn realpath(path).catch(() => resolve(path));\n}\n\nexport function isPathInsideRoot(path: string, root: string) {\n\tconst normalizedPath = normalizePathForComparison(resolve(path));\n\tconst normalizedRoot = normalizePathForComparison(resolve(root));\n\tif (normalizedPath === normalizedRoot) return true;\n\tconst rootWithSeparator = normalizedRoot.endsWith(sep)\n\t\t? normalizedRoot\n\t\t: `${normalizedRoot}${sep}`;\n\treturn normalizedPath.startsWith(rootWithSeparator);\n}\n\nfunction normalizePathForComparison(path: string) {\n\treturn process.platform === \"win32\" ? path.toLowerCase() : path;\n}\n\nexport function throwIfAborted(signal: AbortSignal | undefined) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error ? signal.reason : new Error(\"Screenshot capture cancelled.\");\n}\n\nexport function formatScreenshotText(page: DevToolsPage, screenshot: ScreenshotSaveResult) {\n\tconst pathLabel = screenshot.isDefaultPath ? \"Saved to temp file\" : \"Saved to\";\n\treturn [\n\t\t`Captured PNG screenshot from ${page.title || page.url || page.id}.`,\n\t\t`${pathLabel}: ${screenshot.savedPath}`,\n\t\t`Bytes: ${screenshot.bytes}`,\n\t\t`Use read({ path: ${JSON.stringify(screenshot.savedPath)} }) to inspect the saved screenshot if inline image content is not available.`,\n\t].join(\"\\n\");\n}\n", "import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { shutdownManagedBrowser } from \"./browser-manager.js\";\nimport {\n\tavailableChromeDevtoolsTools,\n\tconfigureLazyChromeDevtoolsTools,\n\tcreateChromeDevtoolsLoadTool,\n\tinitializeAvailableChromeDevtoolsTools,\n} from \"./lazy-tools.js\";\nimport { applyRuntimeBrowserSettings, state } from \"./runtime.js\";\nimport { loadSettings, waitForSettingsWrites } from \"./settings.js\";\nimport {\n\tallChromeDevtoolsTools,\n\tbuildCommandGuide,\n\tbuildQuickstartMessage,\n\tbuildToolStatusMessage,\n\tsanitizeChromeDevtoolsDisplay,\n\tupdateChromeDevtoolsTools,\n\twaitForChromeDevtoolsSettings,\n} from \"./tool-selector.js\";\nimport {\n\tevaluateTool,\n\tlistPagesTool,\n\tnavigateTool,\n\tscreenshotTool,\n\tselectPageTool,\n} from \"./tools.js\";\n\ntype CommandAction =\n\t| \"menu\"\n\t| \"help\"\n\t| \"quickstart\"\n\t| \"status\"\n\t| \"settings\"\n\t| \"tools\"\n\t| \"enable\"\n\t| \"disable\";\ntype CommandContext = ExtensionCommandContext;\nconst STATUS_KEY = \"chrome-devtools\";\nconst COMMAND_COMPLETIONS = [\n\t{ value: \"help\", label: \"help\", description: \"Show command usage\" },\n\t{ value: \"quickstart\", label: \"quickstart\", description: \"Show endpoint and launch help\" },\n\t{ value: \"status\", label: \"status\", description: \"Show tool and settings status\" },\n\t{ value: \"settings\", label: \"settings\", description: \"Edit browser connection settings\" },\n\t{ value: \"tools\", label: \"tools\", description: \"Choose lazy-loadable Chrome DevTools tools\" },\n\t{ value: \"toggle\", label: \"toggle\", description: \"Alias for tools\" },\n\t{ value: \"select\", label: \"select\", description: \"Compatibility alias for tools\" },\n\t{ value: \"enable\", label: \"enable\", description: \"Make all Chrome DevTools tools available\" },\n\t{ value: \"on\", label: \"on\", description: \"Compatibility alias for enable\" },\n\t{ value: \"disable\", label: \"disable\", description: \"Make all Chrome DevTools tools unavailable\" },\n\t{ value: \"off\", label: \"off\", description: \"Compatibility alias for disable\" },\n];\nexport default function chromeDevtools(pi: ExtensionAPI) {\n\tpi.registerTool(listPagesTool);\n\tpi.registerTool(selectPageTool);\n\tpi.registerTool(navigateTool);\n\tpi.registerTool(evaluateTool);\n\tpi.registerTool(screenshotTool);\n\tpi.registerTool(createChromeDevtoolsLoadTool(pi));\n\n\tpi.registerCommand(\"chrome-devtools\", {\n\t\tdescription: \"Open Chrome DevTools help and tool controls\",\n\t\tgetArgumentCompletions: (prefix) => commandCompletions(prefix),\n\t\thandler: async (args, ctx) => {\n\t\t\tinitializeAvailableChromeDevtoolsTools(pi);\n\t\t\tconst generation = state.sessionGeneration;\n\t\t\tawait handleChromeDevtoolsCommand(pi, args, ctx, generation);\n\t\t},\n\t});\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tconst generation = ++state.sessionGeneration;\n\t\tinitializeAvailableChromeDevtoolsTools(pi);\n\t\treplaceSessionController(\"Chrome DevTools session replaced\");\n\t\tstate.shuttingDown = false;\n\t\tstate.settingsNotice = undefined;\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\tawait shutdownManagedBrowser();\n\t\tif (generation !== state.sessionGeneration) return;\n\t\tstate.activePageId = undefined;\n\t\tstate.lastLaunchAttempt = undefined;\n\t\tconst projectTrusted = ctx.isProjectTrusted();\n\t\tconst settings = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n\t\tif (generation !== state.sessionGeneration) return;\n\t\tapplyRuntimeBrowserSettings(settings.effectiveBrowser, settings.paths, projectTrusted);\n\t\tstate.settingsNotice = settings.notice;\n\t\tfor (const warning of settings.warnings) {\n\t\t\tctx.ui.notify(sanitizeChromeDevtoolsDisplay(warning), \"warning\");\n\t\t}\n\t\tconst availableTools =\n\t\t\tsettings.kind === \"loaded\" && settings.settings.tools\n\t\t\t\t? settings.settings.tools\n\t\t\t\t: availableChromeDevtoolsTools(pi);\n\t\tconfigureLazyChromeDevtoolsTools(pi, availableTools);\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tstate.sessionGeneration += 1;\n\t\treplaceSessionController(\"Chrome DevTools session shut down\");\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\tconst browserShutdown = shutdownManagedBrowser(undefined, { cancelLaunch: true });\n\t\tawait waitForChromeDevtoolsSettings();\n\t\tawait waitForSettingsWrites();\n\t\tawait browserShutdown;\n\t});\n}\n\nasync function handleChromeDevtoolsCommand(\n\tpi: ExtensionAPI,\n\targs: string,\n\tctx: CommandContext,\n\tgeneration: number,\n) {\n\tconst command = parseCommand(args);\n\tswitch (command) {\n\t\tcase \"menu\":\n\t\t\tawait showMenu(pi, ctx, generation);\n\t\t\treturn;\n\t\tcase \"help\":\n\t\t\trequireObservableUi(ctx, \"help\");\n\t\t\tctx.ui.notify(buildCommandGuide(), \"info\");\n\t\t\treturn;\n\t\tcase \"quickstart\":\n\t\t\trequireObservableUi(ctx, \"quickstart\");\n\t\t\tctx.ui.notify(buildQuickstartMessage(), \"info\");\n\t\t\treturn;\n\t\tcase \"status\": {\n\t\t\trequireObservableUi(ctx, \"status\");\n\t\t\tconst status = await buildToolStatusMessage(pi);\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tctx.ui.notify(status, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tcase \"settings\": {\n\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\tthrow new Error(\"/chrome-devtools settings requires TUI or RPC mode\");\n\t\t\t}\n\t\t\tconst { showChromeDevtoolsBrowserSettings } = await import(\"./browser-settings-menu.js\");\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tawait showChromeDevtoolsBrowserSettings(ctx, generation);\n\t\t\treturn;\n\t\t}\n\t\tcase \"tools\": {\n\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\tthrow new Error(\"/chrome-devtools tools requires TUI or RPC mode\");\n\t\t\t}\n\t\t\tconst { showChromeDevtoolsToolWorkflow } = await import(\"./menu.js\");\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tawait showChromeDevtoolsToolWorkflow(pi, ctx, generation);\n\t\t\treturn;\n\t\t}\n\t\tcase \"enable\":\n\t\t\tawait updateChromeDevtoolsTools(pi, ctx, allChromeDevtoolsTools(), \"made all available\");\n\t\t\treturn;\n\t\tcase \"disable\":\n\t\t\tawait updateChromeDevtoolsTools(pi, ctx, [], \"made all unavailable\");\n\t\t\treturn;\n\t}\n\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(`Unknown /chrome-devtools command: ${args.trim()}`);\n\t}\n\tctx.ui.notify(\n\t\t`Unknown /chrome-devtools command: ${args.trim()}\n\n${buildCommandGuide()}`,\n\t\t\"warning\",\n\t);\n}\n\nfunction requireObservableUi(ctx: CommandContext, route: string) {\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(`/chrome-devtools ${route} requires TUI or RPC mode`);\n\t}\n}\n\nasync function showMenu(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(\"/chrome-devtools menu requires TUI or RPC mode; use a direct subcommand\");\n\t}\n\tconst { showChromeDevtoolsMenu } = await import(\"./menu.js\");\n\tif (generation !== state.sessionGeneration) return;\n\tawait showChromeDevtoolsMenu(pi, ctx, generation);\n}\n\nfunction replaceSessionController(reason: string) {\n\tstate.sessionController.abort(new DOMException(reason, \"AbortError\"));\n\tstate.sessionController = new AbortController();\n}\n\nexport function parseCommand(args: string): CommandAction | \"unknown\" {\n\tconst command = args.trim().toLowerCase();\n\tif (!command) return \"menu\";\n\tif (command === \"help\") return \"help\";\n\tif (command === \"quickstart\") return \"quickstart\";\n\tif (command === \"status\") return \"status\";\n\tif (command === \"settings\") return \"settings\";\n\tif (command === \"tools\" || command === \"select\" || command === \"toggle\") return \"tools\";\n\tif (command === \"enable\" || command === \"on\") return \"enable\";\n\tif (command === \"disable\" || command === \"off\") return \"disable\";\n\treturn \"unknown\";\n}\n\nexport function commandCompletions(prefix: string) {\n\tconst normalized = prefix.trimStart().toLowerCase();\n\tif (/\\s/.test(normalized)) return null;\n\n\tconst matches = COMMAND_COMPLETIONS.filter((completion) =>\n\t\tcompletion.value.startsWith(normalized),\n\t);\n\treturn matches.length > 0 ? matches : null;\n}\n\nexport {\n\tformatHostForUrl,\n\tisLocalDevToolsHost,\n\tquoteCommandPart,\n} from \"./browser-manager.js\";\nexport { CHROME_DEVTOOLS_LOAD_TOOL_NAME } from \"./lazy-tools.js\";\nexport { parseConfiguredPort } from \"./runtime.js\";\nexport {\n\thasParentPathSegment,\n\tisPathInsideRoot,\n\tresolveScreenshotPath,\n\tselectAllowedRoot,\n} from \"./screenshot.js\";\nexport { normalizeChromeDevtoolsSettings } from \"./settings.js\";\nexport {\n\torderedChromeDevtoolsTools,\n\tsanitizeChromeDevtoolsDisplay,\n} from \"./tool-selector.js\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { defineTool } from \"@earendil-works/pi-coding-agent\";\nimport { Type } from \"typebox\";\nimport {\n\tformatPage,\n\tgetPage,\n\tlistPages,\n\tresolvePage,\n\tresolvePageForNavigation,\n\ttextResult,\n\twithCdp,\n} from \"./cdp-client.js\";\nimport { renderScreenshotResult, renderTextResult, renderToolCall, withStatus } from \"./render.js\";\nimport { state } from \"./runtime.js\";\nimport { formatScreenshotText, saveScreenshot, throwIfAborted } from \"./screenshot.js\";\nimport { CHROME_DEVTOOLS_TOOL_NAMES } from \"./tool-names.js\";\n\nexport const listPagesTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[0],\n\tlabel: \"Chrome DevTools: List Pages\",\n\tdescription: \"List Chrome tabs/pages from a running Chrome DevTools Protocol endpoint.\",\n\tparameters: Type.Object({}),\n\trenderCall: renderToolCall(\"list pages\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, _params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"list pages\", async () => {\n\t\t\tconst pages = await listPages();\n\t\t\treturn textResult(JSON.stringify(pages.map(formatPage), null, 2), { pages });\n\t\t});\n\t},\n});\n\nexport const selectPageTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[1],\n\tlabel: \"Chrome DevTools: Select Page\",\n\tdescription: \"Select the active Chrome page for later chrome_devtools_* tool calls.\",\n\tparameters: Type.Object({\n\t\tpageId: Type.String({ description: \"Page id from chrome_devtools_list_pages.\" }),\n\t}),\n\trenderCall: renderToolCall(\"select page\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"select page\", async () => {\n\t\t\tconst page = await getPage(params.pageId);\n\t\t\tstate.activePageId = page.id;\n\t\t\treturn textResult(`Selected page ${page.id}: ${page.title}\\n${page.url}`, {\n\t\t\t\tpage: formatPage(page),\n\t\t\t});\n\t\t});\n\t},\n});\n\nexport const navigateTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[2],\n\tlabel: \"Chrome DevTools: Navigate\",\n\tdescription:\n\t\t\"Navigate a Chrome page to a URL through Chrome DevTools Protocol, creating a page first if none is available.\",\n\tparameters: Type.Object({\n\t\turl: Type.String({ description: \"URL to navigate to.\" }),\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"navigate\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"navigate\", async () => {\n\t\t\tconst { created, page } = await resolvePageForNavigation(params.pageId);\n\t\t\tconst result = await withCdp(page, async (client) => {\n\t\t\t\tawait client.send(\"Page.enable\");\n\t\t\t\treturn client.send(\"Page.navigate\", { url: params.url });\n\t\t\t});\n\n\t\t\tstate.activePageId = page.id;\n\t\t\tconst action = created ? \"Created page and navigated\" : \"Navigated\";\n\t\t\treturn textResult(`${action} ${page.id} to ${params.url}`, {\n\t\t\t\tcreated,\n\t\t\t\tpage: formatPage(page),\n\t\t\t\tresult,\n\t\t\t});\n\t\t});\n\t},\n});\n\nexport const evaluateTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[3],\n\tlabel: \"Chrome DevTools: Evaluate\",\n\tdescription: \"Evaluate JavaScript in a Chrome page through Chrome DevTools Protocol.\",\n\tparameters: Type.Object({\n\t\texpression: Type.String({ description: \"JavaScript expression to evaluate.\" }),\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t\tawaitPromise: Type.Optional(\n\t\t\tType.Boolean({ description: \"Whether to await a returned Promise. Defaults to true.\" }),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"evaluate\"),\n\trenderResult: renderTextResult,\n\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"evaluate\", async () => {\n\t\t\tconst page = await resolvePage(params.pageId);\n\t\t\tconst result = await withCdp(page, (client) =>\n\t\t\t\tclient.send(\"Runtime.evaluate\", {\n\t\t\t\t\texpression: params.expression,\n\t\t\t\t\tawaitPromise: params.awaitPromise ?? true,\n\t\t\t\t\treturnByValue: true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tstate.activePageId = page.id;\n\t\t\treturn textResult(JSON.stringify(result, null, 2), { page: formatPage(page), result });\n\t\t});\n\t},\n});\n\nexport const screenshotTool = defineTool({\n\tname: CHROME_DEVTOOLS_TOOL_NAMES[4],\n\tlabel: \"Chrome DevTools: Screenshot\",\n\tdescription: \"Capture a PNG screenshot from a Chrome page through Chrome DevTools Protocol.\",\n\tparameters: Type.Object({\n\t\tpageId: Type.Optional(\n\t\t\tType.String({ description: \"Optional page id. Defaults to selected or first page.\" }),\n\t\t),\n\t\tfullPage: Type.Optional(\n\t\t\tType.Boolean({ description: \"Capture the full document, not just the viewport.\" }),\n\t\t),\n\t\tsavePath: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Screenshot is always saved as a PNG file. Optional output path; omitted defaults to a unique temp file. Relative paths resolve from the current working directory. A single leading @ is stripped to match Pi file-mention paths. Existing regular files are replaced.\",\n\t\t\t}),\n\t\t),\n\t}),\n\trenderCall: renderToolCall(\"screenshot\"),\n\trenderResult: renderScreenshotResult,\n\tasync execute(_toolCallId, params, signal, _onUpdate, ctx) {\n\t\treturn withStatus(ctx, \"screenshot\", async () => {\n\t\t\tconst page = await resolvePage(params.pageId);\n\t\t\tconst result = await withCdp(page, async (client) => {\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tawait client.send(\"Page.enable\");\n\n\t\t\t\tif (!params.fullPage) {\n\t\t\t\t\treturn client.send<{ data: string }>(\"Page.captureScreenshot\", { format: \"png\" });\n\t\t\t\t}\n\n\t\t\t\tconst metrics = await client.send<{\n\t\t\t\t\tcontentSize: { x: number; y: number; width: number; height: number };\n\t\t\t\t}>(\"Page.getLayoutMetrics\");\n\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\treturn client.send<{ data: string }>(\"Page.captureScreenshot\", {\n\t\t\t\t\tcaptureBeyondViewport: true,\n\t\t\t\t\tformat: \"png\",\n\t\t\t\t\tclip: {\n\t\t\t\t\t\tx: metrics.contentSize.x,\n\t\t\t\t\t\ty: metrics.contentSize.y,\n\t\t\t\t\t\twidth: metrics.contentSize.width,\n\t\t\t\t\t\theight: metrics.contentSize.height,\n\t\t\t\t\t\tscale: 1,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tstate.activePageId = page.id;\n\t\t\tconst savedScreenshot = await saveScreenshot(result.data, params.savePath, ctx.cwd, signal);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: formatScreenshotText(page, savedScreenshot),\n\t\t\t\t\t},\n\t\t\t\t\t{ type: \"image\", data: result.data, mimeType: \"image/png\" },\n\t\t\t\t],\n\t\t\t\tdetails: {\n\t\t\t\t\tpage: formatPage(page),\n\t\t\t\t\tbytes: savedScreenshot.bytes,\n\t\t\t\t\tsavedPath: savedScreenshot.savedPath,\n\t\t\t\t\tisDefaultPath: savedScreenshot.isDefaultPath,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t},\n});\n", "import {\n\tdevToolsEndpoint,\n\tensureDevToolsEndpoint,\n\tfetchDevToolsJson,\n\tformatPageListItem,\n\tlaunchHint,\n\twithEndpointRetry,\n} from \"./browser-manager.js\";\nimport {\n\tDEFAULT_ENDPOINT_WAIT_MS,\n\tDEFAULT_TIMEOUT_MS,\n\ttype DevToolsPage,\n\tstate,\n} from \"./runtime.js\";\n\ninterface CdpResponse<T = unknown> {\n\tid: number;\n\tresult?: T;\n\terror?: { code: number; message: string; data?: unknown };\n}\n\nexport async function listPages(options: { waitMs?: number } = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs);\n\treturn withEndpointRetry(async () => {\n\t\tconst pages = await fetchDevToolsJson<DevToolsPage[]>(\"/json/list\");\n\t\treturn pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n\t}, waitMs);\n}\n\nexport async function getPage(pageId: string) {\n\tconst pages = await listPages();\n\treturn requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string) {\n\tconst pages = await listPages();\n\tif (pageId) return requirePage(pageId, pages);\n\n\tconst page = resolveDefaultPage(pages);\n\tif (!page) {\n\t\tthrow new Error(\n\t\t\t[\n\t\t\t\t`No Chrome pages found at ${devToolsEndpoint()}.`,\n\t\t\t\t\"Use chrome_devtools_navigate with a URL to create a page, or open a Chrome tab manually.\",\n\t\t\t\tlaunchHint(),\n\t\t\t].join(\"\\n\"),\n\t\t);\n\t}\n\n\treturn page;\n}\n\nexport async function resolvePageForNavigation(pageId?: string) {\n\tconst pages = await listPages();\n\tif (pageId) return { created: false, page: requirePage(pageId, pages) };\n\n\tconst page = resolveDefaultPage(pages);\n\tif (page) return { created: false, page };\n\n\treturn { created: true, page: await createPage(\"about:blank\") };\n}\n\nfunction resolveDefaultPage(pages: DevToolsPage[]) {\n\tif (!state.activePageId) return pages[0];\n\n\tconst activePage = pages.find((candidate) => candidate.id === state.activePageId);\n\tif (activePage) return activePage;\n\n\tstate.activePageId = undefined;\n\treturn pages[0];\n}\n\nfunction requirePage(pageId: string, pages: DevToolsPage[]) {\n\tconst page = pages.find((candidate) => candidate.id === pageId);\n\tif (page) return page;\n\n\tconst availablePages = pages.map(formatPageListItem).join(\"\\n\");\n\tthrow new Error(\n\t\t[\n\t\t\t`Chrome DevTools page not found: ${pageId}.`,\n\t\t\tavailablePages\n\t\t\t\t? `Available pages:\\n${availablePages}`\n\t\t\t\t: \"No inspectable Chrome pages are currently available.\",\n\t\t].join(\"\\n\"),\n\t);\n}\n\nexport async function createPage(url: string, options: { waitMs?: number } = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs);\n\tconst page = await withEndpointRetry(\n\t\t() =>\n\t\t\tfetchDevToolsJson<DevToolsPage>(`/json/new?${encodeURIComponent(url)}`, {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t}),\n\t\twaitMs,\n\t);\n\tif (page.type !== \"page\" || !page.webSocketDebuggerUrl) {\n\t\tthrow new Error(\"Chrome DevTools created a target that is not an inspectable page.\");\n\t}\n\n\treturn page;\n}\n\nexport function formatPage(page: DevToolsPage) {\n\treturn {\n\t\tid: page.id,\n\t\ttype: page.type,\n\t\ttitle: page.title,\n\t\turl: page.url,\n\t};\n}\n\nexport function textResult(text: string, details: unknown) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport async function withCdp<T>(page: DevToolsPage, callback: (client: CdpClient) => Promise<T>) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n\tconst client = await CdpClient.connect(page.webSocketDebuggerUrl);\n\ttry {\n\t\treturn await callback(client);\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nclass CdpClient {\n\t#nextId = 1;\n\t#pending = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (value: unknown) => void;\n\t\t\treject: (reason: unknown) => void;\n\t\t\ttimeout: NodeJS.Timeout;\n\t\t}\n\t>();\n\tprivate readonly socket: WebSocket;\n\n\tprivate constructor(socket: WebSocket) {\n\t\tthis.socket = socket;\n\t\tsocket.addEventListener(\"message\", (event) => {\n\t\t\tconst response = JSON.parse(String(event.data)) as CdpResponse;\n\t\t\tif (typeof response.id !== \"number\") return;\n\n\t\t\tconst pending = this.#pending.get(response.id);\n\t\t\tif (!pending) return;\n\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tthis.#pending.delete(response.id);\n\n\t\t\tif (response.error) {\n\t\t\t\tpending.reject(new Error(`CDP error ${response.error.code}: ${response.error.message}`));\n\t\t\t} else {\n\t\t\t\tpending.resolve(response.result);\n\t\t\t}\n\t\t});\n\n\t\tsocket.addEventListener(\"close\", () => {\n\t\t\tthis.rejectAll(new Error(\"Chrome DevTools WebSocket closed\"));\n\t\t});\n\n\t\tsocket.addEventListener(\"error\", () => {\n\t\t\tthis.rejectAll(new Error(\"Chrome DevTools WebSocket error\"));\n\t\t});\n\t}\n\n\tstatic connect(url: string) {\n\t\treturn new Promise<CdpClient>((resolve, reject) => {\n\t\t\tconst socket = new WebSocket(url);\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tsocket.close();\n\t\t\t\treject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n\t\t\t}, DEFAULT_TIMEOUT_MS);\n\n\t\t\tsocket.addEventListener(\"open\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tresolve(new CdpClient(socket));\n\t\t\t});\n\n\t\t\tsocket.addEventListener(\"error\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n\t\t\t});\n\t\t});\n\t}\n\n\tsend<T = unknown>(method: string, params?: Record<string, unknown>) {\n\t\tconst id = this.#nextId;\n\t\tthis.#nextId += 1;\n\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\treject(new Error(`Timed out waiting for CDP response: ${method}`));\n\t\t\t}, DEFAULT_TIMEOUT_MS);\n\n\t\t\tthis.#pending.set(id, { resolve: resolve as (value: unknown) => void, reject, timeout });\n\t\t\tthis.socket.send(JSON.stringify({ id, method, params: params ?? {} }));\n\t\t});\n\t}\n\n\tclose() {\n\t\tthis.socket.close();\n\t}\n\n\tprivate rejectAll(error: Error) {\n\t\tfor (const [id, pending] of this.#pending) {\n\t\t\tclearTimeout(pending.timeout);\n\t\t\tpending.reject(error);\n\t\t\tthis.#pending.delete(id);\n\t\t}\n\t}\n}\n", "import type { AgentToolResult, ToolRenderResultOptions } from \"@earendil-works/pi-coding-agent\";\n\nconst STATUS_KEY = \"chrome-devtools\";\ninterface StatusContext {\n\tui: { setStatus: (key: string, value: string | undefined) => void };\n}\ninterface RenderTheme {\n\tbold(text: string): string;\n\tfg(color: string, text: string): string;\n}\ninterface RenderComponent {\n\tinvalidate(): void;\n\trender(width: number): string[];\n}\n\nexport function renderToolCall(action: string) {\n\treturn () => new PiTextComponent(`Chrome DevTools: ${action}`);\n}\n\nexport function renderTextResult(\n\tresult: AgentToolResult<unknown>,\n\toptions: ToolRenderResultOptions,\n\ttheme: RenderTheme,\n) {\n\tconst output = formatCollapsibleOutput(textContent(result), options);\n\treturn new PiTextComponent(output.text, theme, output.color);\n}\n\nexport function renderScreenshotResult(\n\tresult: AgentToolResult<unknown>,\n\toptions: ToolRenderResultOptions,\n\ttheme: RenderTheme,\n): RenderComponent {\n\tconst output = formatCollapsibleOutput(screenshotTextContent(result), options);\n\treturn new PiTextComponent(output.text, theme, output.color);\n}\n\nfunction textContent(result: AgentToolResult<unknown>) {\n\treturn result.content\n\t\t.flatMap((content) => (content.type === \"text\" ? [content.text] : []))\n\t\t.join(\"\\n\");\n}\n\nfunction screenshotTextContent(result: AgentToolResult<unknown>) {\n\tconst text = textContent(result);\n\tif (text.trim()) return text;\n\n\tconst details = result.details as { savedPath?: unknown; bytes?: unknown } | undefined;\n\tif (typeof details?.savedPath !== \"string\") return text;\n\tconst bytes = typeof details.bytes === \"number\" ? ` (${details.bytes} bytes)` : \"\";\n\treturn `Saved screenshot to ${details.savedPath}${bytes}`;\n}\n\nfunction formatCollapsibleOutput(\n\ttext: string,\n\toptions: ToolRenderResultOptions,\n): { text: string; color?: string } {\n\tif (options.isPartial) return { text: \"Running...\", color: \"warning\" };\n\tif (options.expanded) return { text, color: \"toolOutput\" };\n\n\treturn { text: \"\" };\n}\n\nclass PiTextComponent implements RenderComponent {\n\tprivate text: string;\n\tprivate readonly theme?: RenderTheme;\n\tprivate readonly color?: string;\n\n\tconstructor(text = \"\", theme?: RenderTheme, color?: string) {\n\t\tthis.text = text;\n\t\tthis.theme = theme;\n\t\tthis.color = color;\n\t}\n\n\tsetText(text: string) {\n\t\tthis.text = text;\n\t}\n\n\tinvalidate() {\n\t\t// Stateless renderer: no cached layout to invalidate.\n\t}\n\n\trender(width: number) {\n\t\tif (!this.text.trim()) return [];\n\t\treturn this.text\n\t\t\t.replace(/\\t/g, \" \")\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.map((line) => {\n\t\t\t\tconst truncatedLine = truncateLine(line, Math.max(1, width));\n\t\t\t\treturn this.theme && this.color ? this.theme.fg(this.color, truncatedLine) : truncatedLine;\n\t\t\t});\n\t}\n}\n\nfunction truncateLine(line: string, maxWidth: number) {\n\treturn Array.from(line).slice(0, maxWidth).join(\"\");\n}\n\nexport async function withStatus<T>(\n\tctx: StatusContext,\n\tstatus: string,\n\tcallback: () => Promise<T>,\n) {\n\tctx.ui.setStatus(STATUS_KEY, status);\n\ttry {\n\t\treturn await callback();\n\t} finally {\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { lstat, mkdir, realpath, rename, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport { withFileMutationQueue } from \"@earendil-works/pi-coding-agent\";\nimport type { DevToolsPage } from \"./runtime.js\";\n\nfunction unique<T>(values: T[]) {\n\treturn Array.from(new Set(values));\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n\nexport interface ResolvedScreenshotPath {\n\tpath: string;\n\tallowedRoots: string[];\n\tisDefault: boolean;\n}\nexport interface ScreenshotSaveResult {\n\tsavedPath: string;\n\tbytes: number;\n\tisDefaultPath: boolean;\n}\n\nexport async function saveScreenshot(\n\tbase64Png: string,\n\tsavePath: string | undefined,\n\tcwd: string,\n\tsignal: AbortSignal | undefined,\n): Promise<ScreenshotSaveResult> {\n\tconst resolvedPath = resolveScreenshotPath(savePath, cwd);\n\tconst pngBytes = Buffer.from(base64Png, \"base64\");\n\n\tawait withFileMutationQueue(resolvedPath.path, async () => {\n\t\tthrowIfAborted(signal);\n\t\tawait ensureSafeScreenshotParent(resolvedPath);\n\t\tawait assertSafeScreenshotTargetPath(resolvedPath);\n\t\tawait writeScreenshotFileSafely(resolvedPath, pngBytes, signal);\n\t});\n\n\treturn {\n\t\tsavedPath: resolvedPath.path,\n\t\tbytes: pngBytes.byteLength,\n\t\tisDefaultPath: resolvedPath.isDefault,\n\t};\n}\n\nexport function resolveScreenshotPath(\n\tsavePath: string | undefined,\n\tcwd: string,\n): ResolvedScreenshotPath {\n\tconst cwdRoot = resolve(cwd);\n\tconst tempRoot = resolve(tmpdir());\n\n\tif (savePath === undefined) {\n\t\treturn {\n\t\t\tpath: join(tempRoot, `pi-chrome-devtools-screenshot-${randomUUID()}.png`),\n\t\t\tallowedRoots: [tempRoot],\n\t\t\tisDefault: true,\n\t\t};\n\t}\n\n\tconst normalizedPath = stripLeadingAtPath(savePath);\n\tif (!normalizedPath.trim()) {\n\t\tthrow new Error(\"Screenshot savePath must not be empty.\");\n\t}\n\tif (normalizedPath.includes(\"\\0\")) {\n\t\tthrow new Error(\"Screenshot savePath must not contain NUL bytes.\");\n\t}\n\tif (hasParentPathSegment(normalizedPath)) {\n\t\tthrow new Error(\"Screenshot savePath must not contain '..' path segments.\");\n\t}\n\n\tconst isAbsolutePath = isAbsolute(normalizedPath);\n\tconst path = isAbsolutePath ? resolve(normalizedPath) : resolve(cwdRoot, normalizedPath);\n\tconst allowedRoots = isAbsolutePath ? unique([cwdRoot, tempRoot]) : [cwdRoot];\n\tif (!allowedRoots.some((root) => isPathInsideRoot(path, root))) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath must be relative to the current working directory, or an absolute path inside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n\n\treturn { path, allowedRoots, isDefault: false };\n}\n\nfunction stripLeadingAtPath(path: string) {\n\treturn path.startsWith(\"@\") ? path.slice(1) : path;\n}\n\nexport function hasParentPathSegment(path: string) {\n\treturn path.split(/[\\\\/]+/).some((part) => part === \"..\");\n}\n\nasync function ensureSafeScreenshotParent(resolvedPath: ResolvedScreenshotPath) {\n\tconst parentPath = dirname(resolvedPath.path);\n\tconst rootPath = selectAllowedRoot(parentPath, resolvedPath.allowedRoots);\n\tif (!rootPath) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath parent must stay inside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n\n\tconst realRootPath = await realpath(rootPath);\n\tlet currentPath = rootPath;\n\tconst parentSegments = relative(rootPath, parentPath)\n\t\t.split(/[\\\\/]+/)\n\t\t.filter((part) => part.length > 0);\n\n\tfor (const segment of parentSegments) {\n\t\tcurrentPath = join(currentPath, segment);\n\t\tawait ensureSafeDirectorySegment(currentPath, realRootPath);\n\t}\n}\n\nexport function selectAllowedRoot(path: string, roots: readonly string[]) {\n\tconst matchingRoots = roots.filter((root) => isPathInsideRoot(path, root));\n\tmatchingRoots.sort(\n\t\t(left, right) =>\n\t\t\tnormalizePathForComparison(resolve(right)).length -\n\t\t\tnormalizePathForComparison(resolve(left)).length,\n\t);\n\treturn matchingRoots[0];\n}\n\nasync function ensureSafeDirectorySegment(path: string, realRootPath: string) {\n\tconst existingDirectory = await lstat(path).catch(async (error: unknown) => {\n\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\tawait mkdir(path).catch((mkdirError: unknown) => {\n\t\t\tif (!isNodeError(mkdirError) || mkdirError.code !== \"EEXIST\") throw mkdirError;\n\t\t});\n\t\treturn lstat(path);\n\t});\n\n\tif (existingDirectory.isSymbolicLink()) {\n\t\tthrow new Error(\"Screenshot savePath parent directories must not contain symbolic links.\");\n\t}\n\tif (!existingDirectory.isDirectory()) {\n\t\tthrow new Error(\"Screenshot savePath parent must be a directory.\");\n\t}\n\tawait assertPathWithinRealRoot(path, realRootPath);\n}\n\nasync function assertSafeScreenshotTargetPath(resolvedPath: ResolvedScreenshotPath) {\n\tconst existingTarget = await lstat(resolvedPath.path).catch((error: unknown) => {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return undefined;\n\t\tthrow error;\n\t});\n\tif (existingTarget?.isSymbolicLink()) {\n\t\tthrow new Error(\"Screenshot savePath must not point to a symbolic link.\");\n\t}\n\tif (existingTarget?.isDirectory()) {\n\t\tthrow new Error(\"Screenshot savePath must point to a file, not a directory.\");\n\t}\n\tif (existingTarget && !existingTarget.isFile()) {\n\t\tthrow new Error(\"Screenshot savePath may only replace regular files.\");\n\t}\n\n\tconst realAllowedRoots = await Promise.all(resolvedPath.allowedRoots.map(realpathOrResolvedPath));\n\tconst realParent = await realpath(dirname(resolvedPath.path));\n\tconst realTargetPath = join(realParent, basename(resolvedPath.path));\n\tif (!realAllowedRoots.some((root) => isPathInsideRoot(realTargetPath, root))) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath resolves outside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n}\n\nasync function assertPathWithinRealRoot(path: string, realRootPath: string) {\n\tconst realPath = await realpath(path);\n\tif (!isPathInsideRoot(realPath, realRootPath)) {\n\t\tthrow new Error(\n\t\t\t\"Screenshot savePath parent resolves outside the current working directory or OS temp directory.\",\n\t\t);\n\t}\n}\n\nasync function writeScreenshotFileSafely(\n\tresolvedPath: ResolvedScreenshotPath,\n\tpngBytes: Buffer,\n\tsignal: AbortSignal | undefined,\n) {\n\tconst tempFile = join(\n\t\tdirname(resolvedPath.path),\n\t\t`.${basename(resolvedPath.path)}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`,\n\t);\n\ttry {\n\t\tawait writeFile(tempFile, pngBytes, { flag: \"wx\", signal });\n\t\tthrowIfAborted(signal);\n\t\tawait replaceScreenshotFile(resolvedPath, tempFile, signal);\n\t} catch (error) {\n\t\tawait rm(tempFile, { force: true }).catch(() => undefined);\n\t\tthrow error;\n\t}\n}\n\nasync function replaceScreenshotFile(\n\tresolvedPath: ResolvedScreenshotPath,\n\ttempFile: string,\n\tsignal: AbortSignal | undefined,\n) {\n\ttry {\n\t\tawait rename(tempFile, resolvedPath.path);\n\t\treturn;\n\t} catch (error) {\n\t\tif (!shouldRetryRenameAfterRemovingDestination(error)) throw error;\n\t}\n\n\t// Some Windows filesystems reject renaming over an existing file. Revalidate before\n\t// removing the destination so the fallback still refuses directories and symlinks.\n\tawait assertSafeScreenshotTargetPath(resolvedPath);\n\tthrowIfAborted(signal);\n\tawait rm(resolvedPath.path, { force: true });\n\tawait rename(tempFile, resolvedPath.path);\n}\n\nfunction shouldRetryRenameAfterRemovingDestination(error: unknown) {\n\treturn (\n\t\tprocess.platform === \"win32\" &&\n\t\tisNodeError(error) &&\n\t\t[\"EACCES\", \"EEXIST\", \"EPERM\"].includes(error.code ?? \"\")\n\t);\n}\n\nasync function realpathOrResolvedPath(path: string) {\n\treturn realpath(path).catch(() => resolve(path));\n}\n\nexport function isPathInsideRoot(path: string, root: string) {\n\tconst normalizedPath = normalizePathForComparison(resolve(path));\n\tconst normalizedRoot = normalizePathForComparison(resolve(root));\n\tif (normalizedPath === normalizedRoot) return true;\n\tconst rootWithSeparator = normalizedRoot.endsWith(sep)\n\t\t? normalizedRoot\n\t\t: `${normalizedRoot}${sep}`;\n\treturn normalizedPath.startsWith(rootWithSeparator);\n}\n\nfunction normalizePathForComparison(path: string) {\n\treturn process.platform === \"win32\" ? path.toLowerCase() : path;\n}\n\nexport function throwIfAborted(signal: AbortSignal | undefined) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error ? signal.reason : new Error(\"Screenshot capture cancelled.\");\n}\n\nexport function formatScreenshotText(page: DevToolsPage, screenshot: ScreenshotSaveResult) {\n\tconst pathLabel = screenshot.isDefaultPath ? \"Saved to temp file\" : \"Saved to\";\n\treturn [\n\t\t`Captured PNG screenshot from ${page.title || page.url || page.id}.`,\n\t\t`${pathLabel}: ${screenshot.savedPath}`,\n\t\t`Bytes: ${screenshot.bytes}`,\n\t\t`Use read({ path: ${JSON.stringify(screenshot.savedPath)} }) to inspect the saved screenshot if inline image content is not available.`,\n\t].join(\"\\n\");\n}\n", "import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { shutdownManagedBrowser } from \"./browser-manager.js\";\nimport {\n\tavailableChromeDevtoolsTools,\n\tconfigureChromeDevtoolsToolExposure,\n\tcreateChromeDevtoolsLoadTool,\n\tinitializeAvailableChromeDevtoolsTools,\n\trequireEagerChromeDevtoolsToolExposure,\n\tsupportsNativeDeferredToolLoading,\n} from \"./lazy-tools.js\";\nimport { applyRuntimeBrowserSettings, state } from \"./runtime.js\";\nimport { loadSettings, waitForSettingsWrites } from \"./settings.js\";\nimport {\n\tallChromeDevtoolsTools,\n\tbuildCommandGuide,\n\tbuildQuickstartMessage,\n\tbuildToolStatusMessage,\n\tsanitizeChromeDevtoolsDisplay,\n\tupdateChromeDevtoolsTools,\n\twaitForChromeDevtoolsSettings,\n} from \"./tool-selector.js\";\nimport {\n\tevaluateTool,\n\tlistPagesTool,\n\tnavigateTool,\n\tscreenshotTool,\n\tselectPageTool,\n} from \"./tools.js\";\n\ntype CommandAction =\n\t| \"menu\"\n\t| \"help\"\n\t| \"quickstart\"\n\t| \"status\"\n\t| \"settings\"\n\t| \"tools\"\n\t| \"enable\"\n\t| \"disable\";\ntype CommandContext = ExtensionCommandContext;\nconst STATUS_KEY = \"chrome-devtools\";\nconst COMMAND_COMPLETIONS = [\n\t{ value: \"help\", label: \"help\", description: \"Show command usage\" },\n\t{ value: \"quickstart\", label: \"quickstart\", description: \"Show endpoint and launch help\" },\n\t{ value: \"status\", label: \"status\", description: \"Show tool and settings status\" },\n\t{ value: \"settings\", label: \"settings\", description: \"Edit browser connection settings\" },\n\t{ value: \"tools\", label: \"tools\", description: \"Choose available Chrome DevTools tools\" },\n\t{ value: \"toggle\", label: \"toggle\", description: \"Alias for tools\" },\n\t{ value: \"select\", label: \"select\", description: \"Compatibility alias for tools\" },\n\t{ value: \"enable\", label: \"enable\", description: \"Make all Chrome DevTools tools available\" },\n\t{ value: \"on\", label: \"on\", description: \"Compatibility alias for enable\" },\n\t{ value: \"disable\", label: \"disable\", description: \"Make all Chrome DevTools tools unavailable\" },\n\t{ value: \"off\", label: \"off\", description: \"Compatibility alias for disable\" },\n];\nexport default function chromeDevtools(pi: ExtensionAPI) {\n\tpi.registerTool(listPagesTool);\n\tpi.registerTool(selectPageTool);\n\tpi.registerTool(navigateTool);\n\tpi.registerTool(evaluateTool);\n\tpi.registerTool(screenshotTool);\n\tpi.registerTool(createChromeDevtoolsLoadTool(pi));\n\n\tpi.registerCommand(\"chrome-devtools\", {\n\t\tdescription: \"Open Chrome DevTools help and tool controls\",\n\t\tgetArgumentCompletions: (prefix) => commandCompletions(prefix),\n\t\thandler: async (args, ctx) => {\n\t\t\tinitializeAvailableChromeDevtoolsTools(pi);\n\t\t\tconst generation = state.sessionGeneration;\n\t\t\tawait handleChromeDevtoolsCommand(pi, args, ctx, generation);\n\t\t},\n\t});\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tconst generation = ++state.sessionGeneration;\n\t\tinitializeAvailableChromeDevtoolsTools(pi);\n\t\treplaceSessionController(\"Chrome DevTools session replaced\");\n\t\tstate.shuttingDown = false;\n\t\tstate.settingsNotice = undefined;\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\tawait shutdownManagedBrowser();\n\t\tif (generation !== state.sessionGeneration) return;\n\t\tstate.activePageId = undefined;\n\t\tstate.lastLaunchAttempt = undefined;\n\t\tconst projectTrusted = ctx.isProjectTrusted();\n\t\tconst settings = await loadSettings({ cwd: ctx.cwd, projectTrusted });\n\t\tif (generation !== state.sessionGeneration) return;\n\t\tapplyRuntimeBrowserSettings(settings.effectiveBrowser, settings.paths, projectTrusted);\n\t\tstate.settingsNotice = settings.notice;\n\t\tfor (const warning of settings.warnings) {\n\t\t\tctx.ui.notify(sanitizeChromeDevtoolsDisplay(warning), \"warning\");\n\t\t}\n\t\tconst availableTools =\n\t\t\tsettings.kind === \"loaded\" && settings.settings.tools\n\t\t\t\t? settings.settings.tools\n\t\t\t\t: availableChromeDevtoolsTools(pi);\n\t\tconfigureChromeDevtoolsToolExposure(pi, availableTools, ctx.model);\n\t});\n\n\tpi.on(\"model_select\", (event) => {\n\t\tif (!supportsNativeDeferredToolLoading(event.model)) {\n\t\t\trequireEagerChromeDevtoolsToolExposure(pi);\n\t\t}\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tstate.sessionGeneration += 1;\n\t\treplaceSessionController(\"Chrome DevTools session shut down\");\n\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\tconst browserShutdown = shutdownManagedBrowser(undefined, { cancelLaunch: true });\n\t\tawait waitForChromeDevtoolsSettings();\n\t\tawait waitForSettingsWrites();\n\t\tawait browserShutdown;\n\t});\n}\n\nasync function handleChromeDevtoolsCommand(\n\tpi: ExtensionAPI,\n\targs: string,\n\tctx: CommandContext,\n\tgeneration: number,\n) {\n\tconst command = parseCommand(args);\n\tswitch (command) {\n\t\tcase \"menu\":\n\t\t\tawait showMenu(pi, ctx, generation);\n\t\t\treturn;\n\t\tcase \"help\":\n\t\t\trequireObservableUi(ctx, \"help\");\n\t\t\tctx.ui.notify(buildCommandGuide(), \"info\");\n\t\t\treturn;\n\t\tcase \"quickstart\":\n\t\t\trequireObservableUi(ctx, \"quickstart\");\n\t\t\tctx.ui.notify(buildQuickstartMessage(), \"info\");\n\t\t\treturn;\n\t\tcase \"status\": {\n\t\t\trequireObservableUi(ctx, \"status\");\n\t\t\tconst status = await buildToolStatusMessage(pi);\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tctx.ui.notify(status, \"info\");\n\t\t\treturn;\n\t\t}\n\t\tcase \"settings\": {\n\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\tthrow new Error(\"/chrome-devtools settings requires TUI or RPC mode\");\n\t\t\t}\n\t\t\tconst { showChromeDevtoolsBrowserSettings } = await import(\"./browser-settings-menu.js\");\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tawait showChromeDevtoolsBrowserSettings(ctx, generation);\n\t\t\treturn;\n\t\t}\n\t\tcase \"tools\": {\n\t\t\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\t\t\tthrow new Error(\"/chrome-devtools tools requires TUI or RPC mode\");\n\t\t\t}\n\t\t\tconst { showChromeDevtoolsToolWorkflow } = await import(\"./menu.js\");\n\t\t\tif (generation !== state.sessionGeneration) return;\n\t\t\tawait showChromeDevtoolsToolWorkflow(pi, ctx, generation);\n\t\t\treturn;\n\t\t}\n\t\tcase \"enable\":\n\t\t\tawait updateChromeDevtoolsTools(pi, ctx, allChromeDevtoolsTools(), \"made all available\");\n\t\t\treturn;\n\t\tcase \"disable\":\n\t\t\tawait updateChromeDevtoolsTools(pi, ctx, [], \"made all unavailable\");\n\t\t\treturn;\n\t}\n\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(`Unknown /chrome-devtools command: ${args.trim()}`);\n\t}\n\tctx.ui.notify(\n\t\t`Unknown /chrome-devtools command: ${args.trim()}\n\n${buildCommandGuide()}`,\n\t\t\"warning\",\n\t);\n}\n\nfunction requireObservableUi(ctx: CommandContext, route: string) {\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(`/chrome-devtools ${route} requires TUI or RPC mode`);\n\t}\n}\n\nasync function showMenu(pi: ExtensionAPI, ctx: CommandContext, generation: number) {\n\tif (!ctx.hasUI || (ctx.mode !== \"tui\" && ctx.mode !== \"rpc\")) {\n\t\tthrow new Error(\"/chrome-devtools menu requires TUI or RPC mode; use a direct subcommand\");\n\t}\n\tconst { showChromeDevtoolsMenu } = await import(\"./menu.js\");\n\tif (generation !== state.sessionGeneration) return;\n\tawait showChromeDevtoolsMenu(pi, ctx, generation);\n}\n\nfunction replaceSessionController(reason: string) {\n\tstate.sessionController.abort(new DOMException(reason, \"AbortError\"));\n\tstate.sessionController = new AbortController();\n}\n\nexport function parseCommand(args: string): CommandAction | \"unknown\" {\n\tconst command = args.trim().toLowerCase();\n\tif (!command) return \"menu\";\n\tif (command === \"help\") return \"help\";\n\tif (command === \"quickstart\") return \"quickstart\";\n\tif (command === \"status\") return \"status\";\n\tif (command === \"settings\") return \"settings\";\n\tif (command === \"tools\" || command === \"select\" || command === \"toggle\") return \"tools\";\n\tif (command === \"enable\" || command === \"on\") return \"enable\";\n\tif (command === \"disable\" || command === \"off\") return \"disable\";\n\treturn \"unknown\";\n}\n\nexport function commandCompletions(prefix: string) {\n\tconst normalized = prefix.trimStart().toLowerCase();\n\tif (/\\s/.test(normalized)) return null;\n\n\tconst matches = COMMAND_COMPLETIONS.filter((completion) =>\n\t\tcompletion.value.startsWith(normalized),\n\t);\n\treturn matches.length > 0 ? matches : null;\n}\n\nexport {\n\tformatHostForUrl,\n\tisLocalDevToolsHost,\n\tquoteCommandPart,\n} from \"./browser-manager.js\";\nexport { CHROME_DEVTOOLS_LOAD_TOOL_NAME } from \"./lazy-tools.js\";\nexport { parseConfiguredPort } from \"./runtime.js\";\nexport {\n\thasParentPathSegment,\n\tisPathInsideRoot,\n\tresolveScreenshotPath,\n\tselectAllowedRoot,\n} from \"./screenshot.js\";\nexport { normalizeChromeDevtoolsSettings } from \"./settings.js\";\nexport {\n\torderedChromeDevtoolsTools,\n\tsanitizeChromeDevtoolsDisplay,\n} from \"./tool-selector.js\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resolve", "STATUS_KEY"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-chrome-devtools",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.3",
|
|
4
4
|
"description": "Pi extension that exposes Chrome DevTools Protocol tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
"typebox": "*"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@biomejs/biome": "2.5.
|
|
43
|
-
"@earendil-works/pi-coding-agent": "0.84.
|
|
44
|
-
"esbuild": "0.28.
|
|
45
|
-
"typebox": "1.3.
|
|
42
|
+
"@biomejs/biome": "2.5.10",
|
|
43
|
+
"@earendil-works/pi-coding-agent": "0.84.3",
|
|
44
|
+
"esbuild": "0.28.2",
|
|
45
|
+
"typebox": "1.3.18",
|
|
46
46
|
"typescript": "7.0.2"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@narumitw/pi-tui-kit": "^0.
|
|
49
|
+
"@narumitw/pi-tui-kit": "^0.58.0"
|
|
50
50
|
},
|
|
51
51
|
"repository": {
|
|
52
52
|
"type": "git",
|