@narumitw/pi-chrome-devtools 0.52.3 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +62 -9
  2. package/dist/chunks/{browser-settings-menu-VWCNG4HB.js → browser-settings-menu-N5O65I7S.js} +81 -7
  3. package/dist/chunks/browser-settings-menu-N5O65I7S.js.map +7 -0
  4. package/dist/chunks/chunk-B7B63PWB.js +465 -0
  5. package/dist/chunks/chunk-B7B63PWB.js.map +7 -0
  6. package/dist/chunks/{chunk-RH6KESL3.js → chunk-GVBXT3FB.js} +369 -514
  7. package/dist/chunks/chunk-GVBXT3FB.js.map +7 -0
  8. package/dist/chunks/chunk-RTECHAEZ.js +373 -0
  9. package/dist/chunks/chunk-RTECHAEZ.js.map +7 -0
  10. package/dist/chunks/{menu-PLD3S3EO.js → menu-UBHW6UP2.js} +72 -39
  11. package/dist/chunks/menu-UBHW6UP2.js.map +7 -0
  12. package/dist/chunks/tools-V7OR5KJ3.js +945 -0
  13. package/dist/chunks/tools-V7OR5KJ3.js.map +7 -0
  14. package/dist/index.ts +158 -195
  15. package/dist/index.ts.map +4 -4
  16. package/package.json +4 -3
  17. package/src/browser-manager.ts +282 -109
  18. package/src/browser-settings-menu.ts +98 -4
  19. package/src/cdp-client.ts +329 -83
  20. package/src/chrome-devtools.ts +51 -11
  21. package/src/lazy-tools.ts +37 -4
  22. package/src/menu.ts +80 -39
  23. package/src/render.ts +12 -1
  24. package/src/runtime.ts +92 -0
  25. package/src/settings.ts +47 -10
  26. package/src/tool-names.ts +16 -1
  27. package/src/tool-selector.ts +67 -30
  28. package/src/tools.ts +86 -10
  29. package/src/webmcp/discovery.ts +235 -0
  30. package/src/webmcp/policy.ts +402 -0
  31. package/src/webmcp/protocol.ts +414 -0
  32. package/src/webmcp/tools.ts +190 -0
  33. package/dist/chunks/browser-settings-menu-VWCNG4HB.js.map +0 -7
  34. package/dist/chunks/chunk-RH6KESL3.js.map +0 -7
  35. package/dist/chunks/menu-PLD3S3EO.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/cdp-client.ts"],
4
+ "sourcesContent": ["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\terror?: { code: number; data?: unknown; message: string };\n\tid: number;\n\tresult?: T;\n}\n\ninterface CdpEvent {\n\tmethod: string;\n\tparams?: unknown;\n}\n\ninterface PendingRequest {\n\tcleanup: () => void;\n\treject: (reason: unknown) => void;\n\tresolve: (value: unknown) => void;\n}\n\ninterface EventWaiter<T = unknown> {\n\tcleanup: () => void;\n\tmethod: string;\n\tpredicate: (params: unknown) => params is T;\n\treject: (reason: unknown) => void;\n\tresolve: (params: T) => void;\n}\n\nexport type CdpWebSocketConstructor = new (url: string | URL) => WebSocket;\n\nexport interface CdpOperationOptions {\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}\n\nexport interface CdpConnectOptions extends CdpOperationOptions {\n\twebSocketConstructor?: CdpWebSocketConstructor;\n}\n\nconst MAX_BUFFERED_EVENTS_PER_METHOD = 32;\nconst MAX_CDP_MESSAGE_BYTES = 8 * 1024 * 1024;\n\ninterface PageOperationOptions {\n\tsessionOwner?: object;\n\tsignal?: AbortSignal;\n\twaitMs?: number;\n}\n\nexport async function listPages(options: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\treturn withEndpointRetry(\n\t\tasync () => {\n\t\t\tconst pages = await fetchDevToolsJson<DevToolsPage[]>(\n\t\t\t\t\"/json/list\",\n\t\t\t\t{ signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t);\n\t\t\treturn pages.filter((page) => page.type === \"page\" && page.webSocketDebuggerUrl);\n\t\t},\n\t\twaitMs,\n\t\toptions.signal,\n\t);\n}\n\nexport async function getPage(pageId: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\n\treturn requirePage(pageId, pages);\n}\n\nexport async function resolvePage(pageId?: string, options: PageOperationOptions = {}) {\n\tconst pages = await listPages(options);\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(options.sessionOwner)}.`,\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(\n\tpageId?: string,\n\toptions: PageOperationOptions = {},\n) {\n\tconst pages = await listPages(options);\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\", options) };\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: PageOperationOptions = {}) {\n\tconst waitMs = options.waitMs ?? DEFAULT_ENDPOINT_WAIT_MS;\n\tawait ensureDevToolsEndpoint(waitMs, options.signal, options.sessionOwner);\n\tconst page = await withEndpointRetry(\n\t\t() =>\n\t\t\tfetchDevToolsJson<DevToolsPage>(\n\t\t\t\t`/json/new?${encodeURIComponent(url)}`,\n\t\t\t\t{ method: \"PUT\", signal: options.signal },\n\t\t\t\toptions.sessionOwner,\n\t\t\t),\n\t\twaitMs,\n\t\toptions.signal,\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<T>(text: string, details: T) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport async function withCdp<T>(\n\tpage: DevToolsPage,\n\tcallback: (client: CdpClient) => Promise<T>,\n\toptions: CdpConnectOptions = {},\n) {\n\tif (!page.webSocketDebuggerUrl) throw new Error(`Page has no webSocketDebuggerUrl: ${page.id}`);\n\n\tconst client = await CdpClient.connect(page.webSocketDebuggerUrl, options);\n\ttry {\n\t\treturn await callback(client);\n\t} finally {\n\t\tclient.close();\n\t}\n}\n\nexport class CdpClient {\n\t#closed = false;\n\t#eventBuffers = new Map<string, unknown[]>();\n\t#eventWaiters = new Set<EventWaiter>();\n\t#nextId = 1;\n\t#pending = new Map<number, PendingRequest>();\n\treadonly #socket: WebSocket;\n\n\tprivate constructor(socket: WebSocket) {\n\t\tthis.#socket = socket;\n\t\tsocket.addEventListener(\"message\", this.onMessage);\n\t\tsocket.addEventListener(\"close\", this.onClose);\n\t\tsocket.addEventListener(\"error\", this.onError);\n\t}\n\n\tstatic connect(url: string, options: CdpConnectOptions = {}) {\n\t\tconst timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\t\tconst WebSocketImplementation = options.webSocketConstructor ?? WebSocket;\n\t\toptions.signal?.throwIfAborted();\n\t\treturn new Promise<CdpClient>((resolve, reject) => {\n\t\t\tconst socket = new WebSocketImplementation(url);\n\t\t\tlet settled = false;\n\t\t\tconst settle = (callback: () => void) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tsocket.removeEventListener(\"open\", onOpen);\n\t\t\t\tsocket.removeEventListener(\"error\", onConnectError);\n\t\t\t\tcallback();\n\t\t\t};\n\t\t\tconst onOpen = () => settle(() => resolve(new CdpClient(socket)));\n\t\t\tconst onConnectError = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(new Error(`Failed to connect to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t});\n\t\t\tconst onAbort = () =>\n\t\t\t\tsettle(() => {\n\t\t\t\t\tsocket.close();\n\t\t\t\t\treject(options.signal?.reason ?? abortError(\"Chrome DevTools connection aborted\"));\n\t\t\t\t});\n\t\t\tconst timeout = setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tsettle(() => {\n\t\t\t\t\t\tsocket.close();\n\t\t\t\t\t\treject(new Error(`Timed out connecting to Chrome DevTools WebSocket: ${url}`));\n\t\t\t\t\t}),\n\t\t\t\ttimeoutMs,\n\t\t\t);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tsocket.addEventListener(\"open\", onOpen, { once: true });\n\t\t\tsocket.addEventListener(\"error\", onConnectError, { once: true });\n\t\t});\n\t}\n\n\tsend<T = unknown>(\n\t\tmethod: string,\n\t\tparams: Record<string, unknown> = {},\n\t\toptions: CdpOperationOptions = {},\n\t) {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst id = this.#nextId;\n\t\tthis.#nextId += 1;\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP command aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP response: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tthis.#pending.set(id, {\n\t\t\t\tcleanup,\n\t\t\t\treject,\n\t\t\t\tresolve: resolve as (value: unknown) => void,\n\t\t\t});\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\ttry {\n\t\t\t\tthis.#socket.send(JSON.stringify({ id, method, params }));\n\t\t\t} catch (error) {\n\t\t\t\tthis.#pending.delete(id);\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t}\n\t\t});\n\t}\n\n\twaitForEvent<T>(\n\t\tmethod: string,\n\t\tpredicate: (params: unknown) => params is T,\n\t\toptions: CdpOperationOptions = {},\n\t): Promise<T> {\n\t\tthis.throwIfClosed();\n\t\toptions.signal?.throwIfAborted();\n\t\tconst buffered = this.#eventBuffers.get(method) ?? [];\n\t\tfor (const [index, params] of buffered.entries()) {\n\t\t\tif (!predicate(params)) continue;\n\t\t\tbuffered.splice(index, 1);\n\t\t\tif (buffered.length === 0) this.#eventBuffers.delete(method);\n\t\t\treturn Promise.resolve(params);\n\t\t}\n\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst waiter = {} as EventWaiter<T>;\n\t\t\tconst onAbort = () => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\tcleanup();\n\t\t\t\treject(options.signal?.reason ?? abortError(`CDP event wait aborted: ${method}`));\n\t\t\t};\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.#eventWaiters.delete(waiter as EventWaiter);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(new Error(`Timed out waiting for CDP event: ${method}`));\n\t\t\t}, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\t\t\tconst cleanup = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\t};\n\t\t\tObject.assign(waiter, { cleanup, method, predicate, reject, resolve });\n\t\t\tthis.#eventWaiters.add(waiter as EventWaiter);\n\t\t\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t});\n\t}\n\n\tclose(reason: unknown = new Error(\"Chrome DevTools WebSocket closed\")) {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#socket.removeEventListener(\"message\", this.onMessage);\n\t\tthis.#socket.removeEventListener(\"close\", this.onClose);\n\t\tthis.#socket.removeEventListener(\"error\", this.onError);\n\t\tthis.rejectAll(reason);\n\t\tthis.#eventBuffers.clear();\n\t\ttry {\n\t\t\tthis.#socket.close();\n\t\t} catch {\n\t\t\t// The transport is already unusable; pending work has still been rejected.\n\t\t}\n\t}\n\n\tprivate readonly onClose = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket closed\"));\n\t};\n\n\tprivate readonly onError = () => {\n\t\tthis.close(new Error(\"Chrome DevTools WebSocket error\"));\n\t};\n\n\tprivate readonly onMessage = (event: MessageEvent) => {\n\t\tif (typeof event.data !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent an unsupported binary message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tevent.data.length > MAX_CDP_MESSAGE_BYTES ||\n\t\t\tBuffer.byteLength(event.data, \"utf8\") > MAX_CDP_MESSAGE_BYTES\n\t\t) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket message exceeds the 8 MB limit\"));\n\t\t\treturn;\n\t\t}\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(event.data) as unknown;\n\t\t} catch {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent malformed JSON\"));\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecord(payload)) {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed message\"));\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.id === \"number\") {\n\t\t\tthis.handleResponse(payload as unknown as CdpResponse);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof payload.method !== \"string\") {\n\t\t\tthis.close(new Error(\"Chrome DevTools WebSocket sent a malformed event\"));\n\t\t\treturn;\n\t\t}\n\t\tthis.handleEvent(payload as unknown as CdpEvent);\n\t};\n\n\tprivate handleResponse(response: CdpResponse) {\n\t\tconst pending = this.#pending.get(response.id);\n\t\tif (!pending) return;\n\t\tthis.#pending.delete(response.id);\n\t\tpending.cleanup();\n\t\tif (response.error) {\n\t\t\tpending.reject(\n\t\t\t\tnew Error(\n\t\t\t\t\t`CDP error ${response.error.code}: ${response.error.message}${\n\t\t\t\t\t\tresponse.error.data === undefined ? \"\" : ` (${safeJson(response.error.data)})`\n\t\t\t\t\t}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tpending.resolve(response.result);\n\t}\n\n\tprivate handleEvent(event: CdpEvent) {\n\t\tif (event.method === \"Inspector.detached\" || event.method === \"Target.detachedFromTarget\") {\n\t\t\tthis.close(new Error(`Chrome DevTools target detached: ${safeJson(event.params)}`));\n\t\t\treturn;\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tif (waiter.method !== event.method) continue;\n\t\t\tlet matched: boolean;\n\t\t\ttry {\n\t\t\t\tmatched = waiter.predicate(event.params);\n\t\t\t} catch (error) {\n\t\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\t\twaiter.cleanup();\n\t\t\t\twaiter.reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!matched) continue;\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.resolve(event.params);\n\t\t\treturn;\n\t\t}\n\t\tconst buffer = this.#eventBuffers.get(event.method) ?? [];\n\t\tbuffer.push(event.params);\n\t\tif (buffer.length > MAX_BUFFERED_EVENTS_PER_METHOD) {\n\t\t\tthis.close(\n\t\t\t\tnew Error(\n\t\t\t\t\t`Chrome DevTools WebSocket buffered more than ${MAX_BUFFERED_EVENTS_PER_METHOD} ${event.method} events`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.#eventBuffers.set(event.method, buffer);\n\t}\n\n\tprivate rejectAll(reason: unknown) {\n\t\tfor (const [id, pending] of this.#pending) {\n\t\t\tthis.#pending.delete(id);\n\t\t\tpending.cleanup();\n\t\t\tpending.reject(reason);\n\t\t}\n\t\tfor (const waiter of this.#eventWaiters) {\n\t\t\tthis.#eventWaiters.delete(waiter);\n\t\t\twaiter.cleanup();\n\t\t\twaiter.reject(reason);\n\t\t}\n\t}\n\n\tprivate throwIfClosed() {\n\t\tif (this.#closed) throw new Error(\"Chrome DevTools WebSocket is closed\");\n\t}\n}\n\nfunction abortError(message: string) {\n\treturn new DOMException(message, \"AbortError\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown) {\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAmDA,IAAM,iCAAiC;AACvC,IAAM,wBAAwB,IAAI,OAAO;AAQzC,eAAsB,UAAU,UAAgC,CAAC,GAAG;AACnE,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,uBAAuB,QAAQ,QAAQ,QAAQ,QAAQ,YAAY;AACzE,SAAO;AAAA,IACN,YAAY;AACX,YAAM,QAAQ,MAAM;AAAA,QACnB;AAAA,QACA,EAAE,QAAQ,QAAQ,OAAO;AAAA,QACzB,QAAQ;AAAA,MACT;AACA,aAAO,MAAM,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,oBAAoB;AAAA,IAChF;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACT;AACD;AAEA,eAAsB,QAAQ,QAAgB,UAAgC,CAAC,GAAG;AACjF,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,SAAO,YAAY,QAAQ,KAAK;AACjC;AAEA,eAAsB,YAAY,QAAiB,UAAgC,CAAC,GAAG;AACtF,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,MAAI,OAAQ,QAAO,YAAY,QAAQ,KAAK;AAE5C,QAAM,OAAO,mBAAmB,KAAK;AACrC,MAAI,CAAC,MAAM;AACV,UAAM,IAAI;AAAA,MACT;AAAA,QACC,4BAA4B,iBAAiB,QAAQ,YAAY,CAAC;AAAA,QAClE;AAAA,QACA,WAAW;AAAA,MACZ,EAAE,KAAK,IAAI;AAAA,IACZ;AAAA,EACD;AAEA,SAAO;AACR;AAEA,eAAsB,yBACrB,QACA,UAAgC,CAAC,GAChC;AACD,QAAM,QAAQ,MAAM,UAAU,OAAO;AACrC,MAAI,OAAQ,QAAO,EAAE,SAAS,OAAO,MAAM,YAAY,QAAQ,KAAK,EAAE;AAEtE,QAAM,OAAO,mBAAmB,KAAK;AACrC,MAAI,KAAM,QAAO,EAAE,SAAS,OAAO,KAAK;AAExC,SAAO,EAAE,SAAS,MAAM,MAAM,MAAM,WAAW,eAAe,OAAO,EAAE;AACxE;AAEA,SAAS,mBAAmB,OAAuB;AAClD,MAAI,CAAC,MAAM,aAAc,QAAO,MAAM,CAAC;AAEvC,QAAM,aAAa,MAAM,KAAK,CAAC,cAAc,UAAU,OAAO,MAAM,YAAY;AAChF,MAAI,WAAY,QAAO;AAEvB,QAAM,eAAe;AACrB,SAAO,MAAM,CAAC;AACf;AAEA,SAAS,YAAY,QAAgB,OAAuB;AAC3D,QAAM,OAAO,MAAM,KAAK,CAAC,cAAc,UAAU,OAAO,MAAM;AAC9D,MAAI,KAAM,QAAO;AAEjB,QAAM,iBAAiB,MAAM,IAAI,kBAAkB,EAAE,KAAK,IAAI;AAC9D,QAAM,IAAI;AAAA,IACT;AAAA,MACC,mCAAmC,MAAM;AAAA,MACzC,iBACG;AAAA,EAAqB,cAAc,KACnC;AAAA,IACJ,EAAE,KAAK,IAAI;AAAA,EACZ;AACD;AAEA,eAAsB,WAAW,KAAa,UAAgC,CAAC,GAAG;AACjF,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,uBAAuB,QAAQ,QAAQ,QAAQ,QAAQ,YAAY;AACzE,QAAM,OAAO,MAAM;AAAA,IAClB,MACC;AAAA,MACC,aAAa,mBAAmB,GAAG,CAAC;AAAA,MACpC,EAAE,QAAQ,OAAO,QAAQ,QAAQ,OAAO;AAAA,MACxC,QAAQ;AAAA,IACT;AAAA,IACD;AAAA,IACA,QAAQ;AAAA,EACT;AACA,MAAI,KAAK,SAAS,UAAU,CAAC,KAAK,sBAAsB;AACvD,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACpF;AAEA,SAAO;AACR;AAEO,SAAS,WAAW,MAAoB;AAC9C,SAAO;AAAA,IACN,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,KAAK,KAAK;AAAA,EACX;AACD;AAEO,SAAS,WAAc,MAAc,SAAY;AACvD,SAAO;AAAA,IACN,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,IACzC;AAAA,EACD;AACD;AAEA,eAAsB,QACrB,MACA,UACA,UAA6B,CAAC,GAC7B;AACD,MAAI,CAAC,KAAK,qBAAsB,OAAM,IAAI,MAAM,qCAAqC,KAAK,EAAE,EAAE;AAE9F,QAAM,SAAS,MAAM,UAAU,QAAQ,KAAK,sBAAsB,OAAO;AACzE,MAAI;AACH,WAAO,MAAM,SAAS,MAAM;AAAA,EAC7B,UAAE;AACD,WAAO,MAAM;AAAA,EACd;AACD;AAEO,IAAM,YAAN,MAAM,WAAU;AAAA,EACtB,UAAU;AAAA,EACV,gBAAgB,oBAAI,IAAuB;AAAA,EAC3C,gBAAgB,oBAAI,IAAiB;AAAA,EACrC,UAAU;AAAA,EACV,WAAW,oBAAI,IAA4B;AAAA,EAClC;AAAA,EAED,YAAY,QAAmB;AACtC,SAAK,UAAU;AACf,WAAO,iBAAiB,WAAW,KAAK,SAAS;AACjD,WAAO,iBAAiB,SAAS,KAAK,OAAO;AAC7C,WAAO,iBAAiB,SAAS,KAAK,OAAO;AAAA,EAC9C;AAAA,EAEA,OAAO,QAAQ,KAAa,UAA6B,CAAC,GAAG;AAC5D,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,0BAA0B,QAAQ,wBAAwB;AAChE,YAAQ,QAAQ,eAAe;AAC/B,WAAO,IAAI,QAAmB,CAAC,SAAS,WAAW;AAClD,YAAM,SAAS,IAAI,wBAAwB,GAAG;AAC9C,UAAI,UAAU;AACd,YAAM,SAAS,CAAC,aAAyB;AACxC,YAAI,QAAS;AACb,kBAAU;AACV,qBAAa,OAAO;AACpB,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,eAAO,oBAAoB,QAAQ,MAAM;AACzC,eAAO,oBAAoB,SAAS,cAAc;AAClD,iBAAS;AAAA,MACV;AACA,YAAM,SAAS,MAAM,OAAO,MAAM,QAAQ,IAAI,WAAU,MAAM,CAAC,CAAC;AAChE,YAAM,iBAAiB,MACtB,OAAO,MAAM;AACZ,eAAO,MAAM;AACb,eAAO,IAAI,MAAM,mDAAmD,GAAG,EAAE,CAAC;AAAA,MAC3E,CAAC;AACF,YAAM,UAAU,MACf,OAAO,MAAM;AACZ,eAAO,MAAM;AACb,eAAO,QAAQ,QAAQ,UAAU,WAAW,oCAAoC,CAAC;AAAA,MAClF,CAAC;AACF,YAAM,UAAU;AAAA,QACf,MACC,OAAO,MAAM;AACZ,iBAAO,MAAM;AACb,iBAAO,IAAI,MAAM,sDAAsD,GAAG,EAAE,CAAC;AAAA,QAC9E,CAAC;AAAA,QACF;AAAA,MACD;AACA,cAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACjE,aAAO,iBAAiB,QAAQ,QAAQ,EAAE,MAAM,KAAK,CAAC;AACtD,aAAO,iBAAiB,SAAS,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAAA,IAChE,CAAC;AAAA,EACF;AAAA,EAEA,KACC,QACA,SAAkC,CAAC,GACnC,UAA+B,CAAC,GAC/B;AACD,SAAK,cAAc;AACnB,YAAQ,QAAQ,eAAe;AAC/B,UAAM,KAAK,KAAK;AAChB,SAAK,WAAW;AAChB,WAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AAC1C,YAAM,UAAU,MAAM;AACrB,aAAK,SAAS,OAAO,EAAE;AACvB,gBAAQ;AACR,eAAO,QAAQ,QAAQ,UAAU,WAAW,wBAAwB,MAAM,EAAE,CAAC;AAAA,MAC9E;AACA,YAAM,UAAU,WAAW,MAAM;AAChC,aAAK,SAAS,OAAO,EAAE;AACvB,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,eAAO,IAAI,MAAM,uCAAuC,MAAM,EAAE,CAAC;AAAA,MAClE,GAAG,QAAQ,aAAa,kBAAkB;AAC1C,YAAM,UAAU,MAAM;AACrB,qBAAa,OAAO;AACpB,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AAAA,MACrD;AACA,WAAK,SAAS,IAAI,IAAI;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AACD,cAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACjE,UAAI;AACH,aAAK,QAAQ,KAAK,KAAK,UAAU,EAAE,IAAI,QAAQ,OAAO,CAAC,CAAC;AAAA,MACzD,SAAS,OAAO;AACf,aAAK,SAAS,OAAO,EAAE;AACvB,gBAAQ;AACR,eAAO,KAAK;AAAA,MACb;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,aACC,QACA,WACA,UAA+B,CAAC,GACnB;AACb,SAAK,cAAc;AACnB,YAAQ,QAAQ,eAAe;AAC/B,UAAM,WAAW,KAAK,cAAc,IAAI,MAAM,KAAK,CAAC;AACpD,eAAW,CAAC,OAAO,MAAM,KAAK,SAAS,QAAQ,GAAG;AACjD,UAAI,CAAC,UAAU,MAAM,EAAG;AACxB,eAAS,OAAO,OAAO,CAAC;AACxB,UAAI,SAAS,WAAW,EAAG,MAAK,cAAc,OAAO,MAAM;AAC3D,aAAO,QAAQ,QAAQ,MAAM;AAAA,IAC9B;AAEA,WAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AAC1C,YAAM,SAAS,CAAC;AAChB,YAAM,UAAU,MAAM;AACrB,aAAK,cAAc,OAAO,MAAqB;AAC/C,gBAAQ;AACR,eAAO,QAAQ,QAAQ,UAAU,WAAW,2BAA2B,MAAM,EAAE,CAAC;AAAA,MACjF;AACA,YAAM,UAAU,WAAW,MAAM;AAChC,aAAK,cAAc,OAAO,MAAqB;AAC/C,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,eAAO,IAAI,MAAM,oCAAoC,MAAM,EAAE,CAAC;AAAA,MAC/D,GAAG,QAAQ,aAAa,kBAAkB;AAC1C,YAAM,UAAU,MAAM;AACrB,qBAAa,OAAO;AACpB,gBAAQ,QAAQ,oBAAoB,SAAS,OAAO;AAAA,MACrD;AACA,aAAO,OAAO,QAAQ,EAAE,SAAS,QAAQ,WAAW,QAAQ,QAAQ,CAAC;AACrE,WAAK,cAAc,IAAI,MAAqB;AAC5C,cAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IAClE,CAAC;AAAA,EACF;AAAA,EAEA,MAAM,SAAkB,IAAI,MAAM,kCAAkC,GAAG;AACtE,QAAI,KAAK,QAAS;AAClB,SAAK,UAAU;AACf,SAAK,QAAQ,oBAAoB,WAAW,KAAK,SAAS;AAC1D,SAAK,QAAQ,oBAAoB,SAAS,KAAK,OAAO;AACtD,SAAK,QAAQ,oBAAoB,SAAS,KAAK,OAAO;AACtD,SAAK,UAAU,MAAM;AACrB,SAAK,cAAc,MAAM;AACzB,QAAI;AACH,WAAK,QAAQ,MAAM;AAAA,IACpB,QAAQ;AAAA,IAER;AAAA,EACD;AAAA,EAEiB,UAAU,MAAM;AAChC,SAAK,MAAM,IAAI,MAAM,kCAAkC,CAAC;AAAA,EACzD;AAAA,EAEiB,UAAU,MAAM;AAChC,SAAK,MAAM,IAAI,MAAM,iCAAiC,CAAC;AAAA,EACxD;AAAA,EAEiB,YAAY,CAAC,UAAwB;AACrD,QAAI,OAAO,MAAM,SAAS,UAAU;AACnC,WAAK,MAAM,IAAI,MAAM,8DAA8D,CAAC;AACpF;AAAA,IACD;AACA,QACC,MAAM,KAAK,SAAS,yBACpB,OAAO,WAAW,MAAM,MAAM,MAAM,IAAI,uBACvC;AACD,WAAK,MAAM,IAAI,MAAM,0DAA0D,CAAC;AAChF;AAAA,IACD;AACA,QAAI;AACJ,QAAI;AACH,gBAAU,KAAK,MAAM,MAAM,IAAI;AAAA,IAChC,QAAQ;AACP,WAAK,MAAM,IAAI,MAAM,+CAA+C,CAAC;AACrE;AAAA,IACD;AACA,QAAI,CAAC,SAAS,OAAO,GAAG;AACvB,WAAK,MAAM,IAAI,MAAM,oDAAoD,CAAC;AAC1E;AAAA,IACD;AACA,QAAI,OAAO,QAAQ,OAAO,UAAU;AACnC,WAAK,eAAe,OAAiC;AACrD;AAAA,IACD;AACA,QAAI,OAAO,QAAQ,WAAW,UAAU;AACvC,WAAK,MAAM,IAAI,MAAM,kDAAkD,CAAC;AACxE;AAAA,IACD;AACA,SAAK,YAAY,OAA8B;AAAA,EAChD;AAAA,EAEQ,eAAe,UAAuB;AAC7C,UAAM,UAAU,KAAK,SAAS,IAAI,SAAS,EAAE;AAC7C,QAAI,CAAC,QAAS;AACd,SAAK,SAAS,OAAO,SAAS,EAAE;AAChC,YAAQ,QAAQ;AAChB,QAAI,SAAS,OAAO;AACnB,cAAQ;AAAA,QACP,IAAI;AAAA,UACH,aAAa,SAAS,MAAM,IAAI,KAAK,SAAS,MAAM,OAAO,GAC1D,SAAS,MAAM,SAAS,SAAY,KAAK,KAAK,SAAS,SAAS,MAAM,IAAI,CAAC,GAC5E;AAAA,QACD;AAAA,MACD;AACA;AAAA,IACD;AACA,YAAQ,QAAQ,SAAS,MAAM;AAAA,EAChC;AAAA,EAEQ,YAAY,OAAiB;AACpC,QAAI,MAAM,WAAW,wBAAwB,MAAM,WAAW,6BAA6B;AAC1F,WAAK,MAAM,IAAI,MAAM,oCAAoC,SAAS,MAAM,MAAM,CAAC,EAAE,CAAC;AAClF;AAAA,IACD;AACA,eAAW,UAAU,KAAK,eAAe;AACxC,UAAI,OAAO,WAAW,MAAM,OAAQ;AACpC,UAAI;AACJ,UAAI;AACH,kBAAU,OAAO,UAAU,MAAM,MAAM;AAAA,MACxC,SAAS,OAAO;AACf,aAAK,cAAc,OAAO,MAAM;AAChC,eAAO,QAAQ;AACf,eAAO,OAAO,KAAK;AACnB;AAAA,MACD;AACA,UAAI,CAAC,QAAS;AACd,WAAK,cAAc,OAAO,MAAM;AAChC,aAAO,QAAQ;AACf,aAAO,QAAQ,MAAM,MAAM;AAC3B;AAAA,IACD;AACA,UAAM,SAAS,KAAK,cAAc,IAAI,MAAM,MAAM,KAAK,CAAC;AACxD,WAAO,KAAK,MAAM,MAAM;AACxB,QAAI,OAAO,SAAS,gCAAgC;AACnD,WAAK;AAAA,QACJ,IAAI;AAAA,UACH,gDAAgD,8BAA8B,IAAI,MAAM,MAAM;AAAA,QAC/F;AAAA,MACD;AACA;AAAA,IACD;AACA,SAAK,cAAc,IAAI,MAAM,QAAQ,MAAM;AAAA,EAC5C;AAAA,EAEQ,UAAU,QAAiB;AAClC,eAAW,CAAC,IAAI,OAAO,KAAK,KAAK,UAAU;AAC1C,WAAK,SAAS,OAAO,EAAE;AACvB,cAAQ,QAAQ;AAChB,cAAQ,OAAO,MAAM;AAAA,IACtB;AACA,eAAW,UAAU,KAAK,eAAe;AACxC,WAAK,cAAc,OAAO,MAAM;AAChC,aAAO,QAAQ;AACf,aAAO,OAAO,MAAM;AAAA,IACrB;AAAA,EACD;AAAA,EAEQ,gBAAgB;AACvB,QAAI,KAAK,QAAS,OAAM,IAAI,MAAM,qCAAqC;AAAA,EACxE;AACD;AAEA,SAAS,WAAW,SAAiB;AACpC,SAAO,IAAI,aAAa,SAAS,YAAY;AAC9C;AAEA,SAAS,SAAS,OAAkD;AACnE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,SAAS,OAAgB;AACjC,MAAI;AACH,WAAO,KAAK,UAAU,KAAK;AAAA,EAC5B,QAAQ;AACP,WAAO,OAAO,KAAK;AAAA,EACpB;AACD;",
6
+ "names": []
7
+ }
@@ -1,18 +1,23 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- the generated entry uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
- CHROME_DEVTOOLS_TOOL_NAMES,
5
4
  availableChromeDevtoolsTools,
6
- browserLifecycleState,
7
5
  buildBrowserStatusMessage,
8
6
  buildCommandGuide,
7
+ sanitizeChromeDevtoolsDisplay,
8
+ setSelectedChromeDevtoolsTools
9
+ } from "./chunk-B7B63PWB.js";
10
+ import {
11
+ CHROME_DEVTOOLS_TOOL_NAMES,
12
+ CORE_CHROME_DEVTOOLS_TOOL_NAMES,
13
+ browserLifecycleState,
9
14
  devToolsEndpoint,
15
+ launchAttemptLines,
10
16
  launchModeLabel,
11
17
  loadSettings,
12
- sanitizeChromeDevtoolsDisplay,
13
- setSelectedChromeDevtoolsTools,
14
- state
15
- } from "./chunk-RH6KESL3.js";
18
+ state,
19
+ webMcpEnabled
20
+ } from "./chunk-GVBXT3FB.js";
16
21
 
17
22
  // src/menu.ts
18
23
  import { defineMenu, runMenu, runTask } from "@narumitw/pi-tui-kit";
@@ -36,6 +41,14 @@ var TOOL_PRESENTATION = {
36
41
  chrome_devtools_screenshot: {
37
42
  label: "Capture a screenshot",
38
43
  description: "Save a PNG of the selected page (chrome_devtools_screenshot)."
44
+ },
45
+ chrome_devtools_webmcp_list_tools: {
46
+ label: "List page WebMCP tools \xB7 Experimental",
47
+ description: "Discover page-provided WebMCP capabilities (chrome_devtools_webmcp_list_tools)."
48
+ },
49
+ chrome_devtools_webmcp_call_tool: {
50
+ label: "Call a page WebMCP tool \xB7 Experimental",
51
+ description: "Invoke a listed page tool after confirmation (chrome_devtools_webmcp_call_tool)."
39
52
  }
40
53
  };
41
54
  async function showChromeDevtoolsMenu(pi, ctx, generation) {
@@ -49,7 +62,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
49
62
  main: ({ state: current }) => ({
50
63
  kind: "actions",
51
64
  title: "Chrome DevTools",
52
- lines: mainStateLines(current),
65
+ lines: mainStateLines(current, ctx.sessionManager),
53
66
  items: [
54
67
  {
55
68
  id: "tools",
@@ -61,8 +74,8 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
61
74
  },
62
75
  {
63
76
  id: "bulk",
64
- label: current.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length ? "Make all browser tools unavailable\u2026" : "Make all browser tools available\u2026",
65
- description: current.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length ? "Preview 0 of 5; other active tools stay enabled." : "Preview 5 of 5; other active tools stay enabled.",
77
+ label: current.activeTools.length === availableCatalogNames(ctx.sessionManager).length ? "Make all browser tools unavailable\u2026" : "Make all browser tools available\u2026",
78
+ description: current.activeTools.length === availableCatalogNames(ctx.sessionManager).length ? `Preview 0 of ${availableCatalogNames(ctx.sessionManager).length}; other active tools stay enabled.` : `Preview ${availableCatalogNames(ctx.sessionManager).length} of ${availableCatalogNames(ctx.sessionManager).length}; other active tools stay enabled.`,
66
79
  disabled: Boolean(current.mutationBlockedReason),
67
80
  disabledReason: current.mutationBlockedReason,
68
81
  action: "bulk"
@@ -91,7 +104,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
91
104
  browserStatus: () => ({
92
105
  kind: "review",
93
106
  title: "Browser status",
94
- content: buildBrowserStatusMessage(),
107
+ content: buildBrowserStatusMessage(ctx.sessionManager),
95
108
  format: { kind: "text" },
96
109
  viewportSize: "adaptive",
97
110
  hint: "back"
@@ -99,7 +112,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
99
112
  help: () => ({
100
113
  kind: "review",
101
114
  title: "Chrome DevTools help",
102
- content: buildCommandGuide(),
115
+ content: buildCommandGuide(ctx.sessionManager),
103
116
  format: { kind: "text" },
104
117
  viewportSize: "adaptive",
105
118
  hint: "back"
@@ -114,7 +127,7 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
114
127
  return result?.closeParent ? { kind: "close" } : { kind: "stay" };
115
128
  },
116
129
  bulk: async ({ state: current }) => {
117
- const selectedTools = current.activeTools.length === CHROME_DEVTOOLS_TOOL_NAMES.length ? [] : [...CHROME_DEVTOOLS_TOOL_NAMES];
130
+ const selectedTools = current.activeTools.length === availableCatalogNames(ctx.sessionManager).length ? [] : availableCatalogNames(ctx.sessionManager);
118
131
  const result = await showChromeDevtoolsToolWorkflow(pi, ctx, generation, {
119
132
  snapshot: current,
120
133
  initialDraft: selectedTools,
@@ -123,11 +136,14 @@ async function showChromeDevtoolsMenu(pi, ctx, generation) {
123
136
  if (result?.applied && isCurrent()) updateSnapshotAfterApply(current, result.selectedTools);
124
137
  return result?.closeParent ? { kind: "close" } : { kind: "stay" };
125
138
  },
126
- settings: async () => {
127
- const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-VWCNG4HB.js");
139
+ settings: async ({ state: current }) => {
140
+ const { showChromeDevtoolsBrowserSettings } = await import("./browser-settings-menu-N5O65I7S.js");
128
141
  if (!isCurrent()) return { kind: "stay" };
129
- const result = await showChromeDevtoolsBrowserSettings(ctx, generation);
142
+ const result = await showChromeDevtoolsBrowserSettings(pi, ctx, generation);
130
143
  if (!isCurrent()) return { kind: "stay" };
144
+ const refreshed = await loadChromeDevtoolsMenuSnapshot(pi, ctx);
145
+ if (!isCurrent()) return { kind: "stay" };
146
+ Object.assign(current, refreshed);
131
147
  return result.closeParent ? { kind: "close" } : { kind: "stay" };
132
148
  }
133
149
  }
@@ -160,9 +176,9 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
160
176
  screens: {
161
177
  tools: ({ state: current }) => ({
162
178
  kind: "multiSelect",
163
- title: `Browser tools (${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length})`,
164
- lines: toolDraftLines(current),
165
- items: CHROME_DEVTOOLS_TOOL_NAMES.map((toolName) => ({
179
+ title: `Browser tools (${current.draft.size}/${availableCatalogNames(ctx.sessionManager).length})`,
180
+ lines: toolDraftLines(current, ctx.sessionManager),
181
+ items: availableCatalogNames(ctx.sessionManager).map((toolName) => ({
166
182
  id: toolName,
167
183
  label: TOOL_PRESENTATION[toolName].label,
168
184
  description: TOOL_PRESENTATION[toolName].description,
@@ -202,10 +218,10 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
202
218
  kind: "review",
203
219
  title: "Review tool changes",
204
220
  lines: [
205
- `Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
206
- `Proposed availability: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`
221
+ `Currently available: ${current.accepted.size}/${availableCatalogNames(ctx.sessionManager).length}`,
222
+ `Proposed availability: ${current.draft.size}/${availableCatalogNames(ctx.sessionManager).length}`
207
223
  ],
208
- content: buildToolReview(current),
224
+ content: buildToolReview(current, ctx.sessionManager),
209
225
  format: { kind: "text" },
210
226
  viewportSize: "adaptive",
211
227
  ...current.mutationBlockedReason || setsEqual(current.accepted, current.draft) ? {} : {
@@ -227,7 +243,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
227
243
  return { kind: "stay" };
228
244
  },
229
245
  selectAll: ({ state: current }) => {
230
- current.draft = new Set(CHROME_DEVTOOLS_TOOL_NAMES);
246
+ current.draft = new Set(availableCatalogNames(ctx.sessionManager));
231
247
  return { kind: "stay" };
232
248
  },
233
249
  selectNone: ({ state: current }) => {
@@ -257,7 +273,7 @@ async function showChromeDevtoolsToolWorkflow(pi, ctx, generation, options = {})
257
273
  current.draft = new Set(selectedTools);
258
274
  current.applied = true;
259
275
  ctx.ui.notify(
260
- `Saved: ${selectedTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} browser tools available.`,
276
+ `Saved: ${selectedTools.length} of ${availableCatalogNames(ctx.sessionManager).length} browser tools available.`,
261
277
  "info"
262
278
  );
263
279
  return { kind: "close" };
@@ -297,6 +313,13 @@ async function loadSnapshotWithFeedback(pi, ctx, generation) {
297
313
  });
298
314
  return result.kind === "completed" ? result.value : void 0;
299
315
  }
316
+ async function loadChromeDevtoolsMenuSnapshot(pi, ctx) {
317
+ const settings = await loadSettings({
318
+ cwd: ctx.cwd,
319
+ projectTrusted: ctx.isProjectTrusted()
320
+ });
321
+ return buildMenuSnapshot(pi, settings);
322
+ }
300
323
  function buildMenuSnapshot(pi, settings) {
301
324
  const activeTools = activeChromeTools(pi);
302
325
  const persistedTools = settings.kind === "loaded" && settings.settings.tools ? orderedTools(new Set(settings.settings.tools)) : void 0;
@@ -311,41 +334,47 @@ function buildMenuSnapshot(pi, settings) {
311
334
  ...settingsWarning ? { settingsWarning } : {}
312
335
  };
313
336
  }
314
- function mainStateLines(snapshot) {
337
+ function mainStateLines(snapshot, owner) {
338
+ const launchError = launchAttemptLines(owner).find(
339
+ (line) => line.startsWith("Last launch error:")
340
+ );
315
341
  return sanitizeLines([
316
- `Tool catalog: ${snapshot.activeTools.length} of ${CHROME_DEVTOOLS_TOOL_NAMES.length} available \xB7 ${snapshot.persistenceLabel}`,
317
- `Browser: ${browserLifecycleSummary()}`,
318
- `Endpoint: ${devToolsEndpoint()}`,
342
+ `Tool catalog: ${snapshot.activeTools.length} of ${availableCatalogNames(owner).length} available \xB7 ${snapshot.persistenceLabel}`,
343
+ `WebMCP: ${webMcpEnabled(owner) ? "enabled \xB7 experimental \xB7 confirmation required for every call" : "disabled \xB7 experimental"}`,
344
+ `Browser: ${browserLifecycleSummary(owner)}`,
345
+ `Endpoint: ${devToolsEndpoint(owner)}`,
319
346
  ...snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : [],
320
- ...state.lastLaunchAttempt?.lastError ? [`Launch warning: ${state.lastLaunchAttempt.lastError}`] : []
347
+ ...launchError ? [`Launch warning: ${launchError.slice("Last launch error: ".length)}`] : []
321
348
  ]);
322
349
  }
323
- function browserLifecycleSummary() {
324
- const lifecycle = browserLifecycleState();
350
+ function browserLifecycleSummary(owner) {
351
+ const lifecycle = browserLifecycleState(owner);
325
352
  if (lifecycle === "starting") return "starting managed browser";
326
353
  if (lifecycle === "running") return "managed browser running";
327
354
  if (lifecycle === "exited") return "managed browser exited \xB7 open Browser status to recover";
328
355
  if (lifecycle === "failed") return "last launch failed \xB7 open Browser status to recover";
329
- const launchMode = launchModeLabel();
356
+ const launchMode = launchModeLabel(owner);
330
357
  return launchMode.startsWith("attach first") ? "not started \xB7 attaches or launches on first use" : `not started \xB7 ${launchMode}`;
331
358
  }
332
- function toolDraftLines(current) {
359
+ function toolDraftLines(current, owner) {
333
360
  if (current.mutationBlockedReason)
334
361
  return sanitizeLines([`Unavailable: ${current.mutationBlockedReason}`]);
335
362
  const changes = symmetricDifferenceSize(current.accepted, current.draft);
336
363
  return [
337
- `Currently available: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
364
+ `Currently available: ${current.accepted.size}/${availableCatalogNames(owner).length}`,
338
365
  changes === 0 ? "No unapplied changes \xB7 Escape cancels" : `${changes} unapplied ${changes === 1 ? "change" : "changes"} \xB7 Escape cancels`,
366
+ `WebMCP gateways: ${webMcpEnabled(owner) ? "available for selection \xB7 experimental" : "hidden while experimental WebMCP is disabled"}`,
339
367
  "Changes are not applied until Review changes and Apply tool changes."
340
368
  ];
341
369
  }
342
- function buildToolReview(current) {
343
- const available = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => current.draft.has(name));
344
- const unavailable = CHROME_DEVTOOLS_TOOL_NAMES.filter((name) => !current.draft.has(name));
370
+ function buildToolReview(current, owner) {
371
+ const catalog = availableCatalogNames(owner);
372
+ const available = catalog.filter((name) => current.draft.has(name));
373
+ const unavailable = catalog.filter((name) => !current.draft.has(name));
345
374
  return sanitizeChromeDevtoolsDisplay(
346
375
  [
347
- `Current available browser tools: ${current.accepted.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
348
- `Proposed available browser tools: ${current.draft.size}/${CHROME_DEVTOOLS_TOOL_NAMES.length}`,
376
+ `Current available browser tools: ${current.accepted.size}/${catalog.length}`,
377
+ `Proposed available browser tools: ${current.draft.size}/${catalog.length}`,
349
378
  "",
350
379
  "Available after apply:",
351
380
  ...available.length > 0 ? available.map((name) => ` - ${TOOL_PRESENTATION[name].label} (${name})`) : [" - none"],
@@ -388,11 +417,15 @@ function arraysEqual(left, right) {
388
417
  function sanitizeLines(lines) {
389
418
  return sanitizeChromeDevtoolsDisplay(lines.join("\n")).split("\n");
390
419
  }
420
+ function availableCatalogNames(owner) {
421
+ return webMcpEnabled(owner) ? [...CHROME_DEVTOOLS_TOOL_NAMES] : [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];
422
+ }
391
423
  function formatError(error) {
392
424
  return error instanceof Error ? error.message : String(error);
393
425
  }
394
426
  export {
427
+ loadChromeDevtoolsMenuSnapshot,
395
428
  showChromeDevtoolsMenu,
396
429
  showChromeDevtoolsToolWorkflow
397
430
  };
398
- //# sourceMappingURL=menu-PLD3S3EO.js.map
431
+ //# sourceMappingURL=menu-UBHW6UP2.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/menu.ts"],
4
+ "sourcesContent": ["import type { ExtensionAPI, ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport { defineMenu, runMenu, runTask } from \"@narumitw/pi-tui-kit\";\nimport {\n\tbrowserLifecycleState,\n\tdevToolsEndpoint,\n\tlaunchAttemptLines,\n\tlaunchModeLabel,\n} from \"./browser-manager.js\";\nimport { availableChromeDevtoolsTools } from \"./lazy-tools.js\";\nimport { state, webMcpEnabled } from \"./runtime.js\";\nimport { loadSettings, type SettingsLoadResult } from \"./settings.js\";\nimport {\n\tCHROME_DEVTOOLS_TOOL_NAMES,\n\ttype ChromeDevToolsToolName,\n\tCORE_CHROME_DEVTOOLS_TOOL_NAMES,\n} 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\tchrome_devtools_webmcp_list_tools: {\n\t\tlabel: \"List page WebMCP tools \u00B7 Experimental\",\n\t\tdescription: \"Discover page-provided WebMCP capabilities (chrome_devtools_webmcp_list_tools).\",\n\t},\n\tchrome_devtools_webmcp_call_tool: {\n\t\tlabel: \"Call a page WebMCP tool \u00B7 Experimental\",\n\t\tdescription: \"Invoke a listed page tool after confirmation (chrome_devtools_webmcp_call_tool).\",\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, ctx.sessionManager),\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 === availableCatalogNames(ctx.sessionManager).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 === availableCatalogNames(ctx.sessionManager).length\n\t\t\t\t\t\t\t\t? `Preview 0 of ${availableCatalogNames(ctx.sessionManager).length}; other active tools stay enabled.`\n\t\t\t\t\t\t\t\t: `Preview ${availableCatalogNames(ctx.sessionManager).length} of ${availableCatalogNames(ctx.sessionManager).length}; 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(ctx.sessionManager),\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(ctx.sessionManager),\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 === availableCatalogNames(ctx.sessionManager).length\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: availableCatalogNames(ctx.sessionManager);\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 ({ state: current }) => {\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(pi, ctx, generation);\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\tconst refreshed = await loadChromeDevtoolsMenuSnapshot(pi, ctx);\n\t\t\t\tif (!isCurrent()) return { kind: \"stay\" };\n\t\t\t\tObject.assign(current, refreshed);\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}/${availableCatalogNames(ctx.sessionManager).length})`,\n\t\t\t\tlines: toolDraftLines(current, ctx.sessionManager),\n\t\t\t\titems: availableCatalogNames(ctx.sessionManager).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}/${availableCatalogNames(ctx.sessionManager).length}`,\n\t\t\t\t\t`Proposed availability: ${current.draft.size}/${availableCatalogNames(ctx.sessionManager).length}`,\n\t\t\t\t],\n\t\t\t\tcontent: buildToolReview(current, ctx.sessionManager),\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(availableCatalogNames(ctx.sessionManager));\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 ${availableCatalogNames(ctx.sessionManager).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\nexport async function loadChromeDevtoolsMenuSnapshot(\n\tpi: ExtensionAPI,\n\tctx: ExtensionCommandContext,\n) {\n\tconst settings = await loadSettings({\n\t\tcwd: ctx.cwd,\n\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t});\n\treturn buildMenuSnapshot(pi, settings);\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, owner: object) {\n\tconst launchError = launchAttemptLines(owner).find((line) =>\n\t\tline.startsWith(\"Last launch error:\"),\n\t);\n\treturn sanitizeLines([\n\t\t`Tool catalog: ${snapshot.activeTools.length} of ${availableCatalogNames(owner).length} available \u00B7 ${snapshot.persistenceLabel}`,\n\t\t`WebMCP: ${webMcpEnabled(owner) ? \"enabled \u00B7 experimental \u00B7 confirmation required for every call\" : \"disabled \u00B7 experimental\"}`,\n\t\t`Browser: ${browserLifecycleSummary(owner)}`,\n\t\t`Endpoint: ${devToolsEndpoint(owner)}`,\n\t\t...(snapshot.settingsWarning ? [`Settings warning: ${snapshot.settingsWarning}`] : []),\n\t\t...(launchError ? [`Launch warning: ${launchError.slice(\"Last launch error: \".length)}`] : []),\n\t]);\n}\n\nfunction browserLifecycleSummary(owner: object) {\n\tconst lifecycle = browserLifecycleState(owner);\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(owner);\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, owner: object) {\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}/${availableCatalogNames(owner).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`WebMCP gateways: ${webMcpEnabled(owner) ? \"available for selection \u00B7 experimental\" : \"hidden while experimental WebMCP is disabled\"}`,\n\t\t\"Changes are not applied until Review changes and Apply tool changes.\",\n\t];\n}\n\nfunction buildToolReview(current: ToolWorkflowState, owner: object) {\n\tconst catalog = availableCatalogNames(owner);\n\tconst available = catalog.filter((name) => current.draft.has(name));\n\tconst unavailable = catalog.filter((name) => !current.draft.has(name));\n\treturn sanitizeChromeDevtoolsDisplay(\n\t\t[\n\t\t\t`Current available browser tools: ${current.accepted.size}/${catalog.length}`,\n\t\t\t`Proposed available browser tools: ${current.draft.size}/${catalog.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 availableCatalogNames(owner: object): ChromeDevToolsToolName[] {\n\treturn webMcpEnabled(owner)\n\t\t? [...CHROME_DEVTOOLS_TOOL_NAMES]\n\t\t: [...CORE_CHROME_DEVTOOLS_TOOL_NAMES];\n}\n\nfunction formatError(error: unknown) {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }