shadow-claw 1.40.1 → 1.41.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.well-known/mcp/server-card.json +1 -1
- package/.well-known/mcp.json +1 -1
- package/README.md +2 -1
- package/dist/cli/build/build.js +1 -1
- package/dist/cli/{chunk-Bfz2NYgD.js → chunk-0IeC97mU.js} +7 -7
- package/dist/cli/chunk-3oLxlxPn.js +1 -0
- package/dist/cli/chunk-63s8NnIS.js +93 -0
- package/dist/cli/{chunk-BXg4-9Rq2.js → chunk-8CrZyP1b2.js} +1 -1
- package/dist/cli/{chunk-BP5Hg6CM.js → chunk-B--ueArB.js} +1 -1
- package/dist/cli/chunk-BATVgkFY.js +17 -0
- package/dist/cli/chunk-BIh7rXlJ2.js +1 -0
- package/dist/cli/{chunk-Drr0VSGA2.js → chunk-BKnTOLLS2.js} +1 -1
- package/dist/cli/{chunk-C5PuRV08.js → chunk-BLMC1Bxv.js} +1 -1
- package/dist/cli/{chunk-B2tNSlFy2.js → chunk-BOigzz2U2.js} +1 -1
- package/dist/cli/{chunk-DOf3DZdR.js → chunk-BOzn335y.js} +1 -1
- package/dist/cli/chunk-BjOeVLb42.js +1 -0
- package/dist/cli/{chunk-DqTx0rRp2.js → chunk-Bjqh5_SU2.js} +1 -1
- package/dist/cli/chunk-BqWBd_jF2.js +1 -0
- package/dist/cli/{chunk-DIbSoQmd2.js → chunk-C6FFByBU2.js} +2 -2
- package/dist/cli/{chunk-Drq18VZe.js → chunk-C9-aL3rF.js} +1 -1
- package/dist/cli/{chunk-BUhqHeEA2.js → chunk-C9czddEh2.js} +2 -2
- package/dist/cli/chunk-CCx8WOwz2.js +1 -0
- package/dist/cli/{chunk-BkMSjVJb.js → chunk-CK6ejMig.js} +1 -1
- package/dist/cli/chunk-CUUERioR2.js +1 -0
- package/dist/cli/chunk-CXAobnJd.js +1 -0
- package/dist/cli/chunk-CY1X0pOF2.js +1 -0
- package/dist/cli/chunk-CZvvgLVv.js +1 -0
- package/dist/cli/chunk-CbcwbfJB.js +1 -0
- package/dist/cli/{chunk-quilB3TV2.js → chunk-Ci9OJGcd2.js} +1 -1
- package/dist/cli/chunk-Cj9wl0qx.js +1 -0
- package/dist/cli/{chunk-3gRhOmGo2.js → chunk-CjJsVrKI2.js} +1 -1
- package/dist/cli/{chunk-CmEfzm-_.js → chunk-ClPZ4Rea.js} +1 -1
- package/dist/cli/chunk-Cmdxoq9q.js +13 -0
- package/dist/cli/{chunk-WMPAfIvV2.js → chunk-DHJCGRuG2.js} +1 -1
- package/dist/cli/{chunk-C7Y2xIk4.js → chunk-DKVkYTV9.js} +1 -1
- package/dist/cli/chunk-DR2XtWRo.js +1 -0
- package/dist/cli/{chunk-BiVJVh_S.js → chunk-DUlIqkaX.js} +7 -7
- package/dist/cli/{chunk-CkpueGaZ2.js → chunk-DjWle8FF2.js} +1 -1
- package/dist/cli/{chunk-CSvHmNOk.js → chunk-DmRXVLfy.js} +1 -1
- package/dist/cli/{chunk-BT1xXZn72.js → chunk-HlSiTC-u2.js} +1 -1
- package/dist/cli/{chunk-da0bsiOn.js → chunk-P4JSeFBI.js} +1 -1
- package/dist/cli/chunk-UcNbHaRQ.js +1 -0
- package/dist/cli/{chunk-BXFHFbEd.js → chunk-UweLmfQS.js} +1 -1
- package/dist/cli/{chunk-CGiXWHTi2.js → chunk-gwpxl-0W2.js} +1 -1
- package/dist/cli/{chunk-NH8koEis2.js → chunk-nmDhxXH_2.js} +1 -1
- package/dist/cli/chunk-p0n_c-I2.js +1 -0
- package/dist/cli/{chunk-D7xP72La.js → chunk-q7r4FosZ.js} +1 -1
- package/dist/cli/cli.js +1 -1
- package/dist/cli/prerender/dsd-shell/prerender-dsd-shell.js +1 -1
- package/dist/electron/main.cjs +1 -1
- package/dist/headless-agent.js +1 -1
- package/dist/lib/{app-routes-BAEMLu9g.js → app-routes-CKkiX12g.js} +7 -2
- package/dist/lib/app-routes-CKkiX12g.js.map +1 -0
- package/dist/lib/components/index.js +26 -26
- package/dist/lib/components/settings/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/settings/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/settings/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/settings/shadow-claw-git.js +1 -1
- package/dist/lib/components/settings/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/settings/shadow-claw-llm.js +1 -1
- package/dist/lib/components/settings/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/settings/shadow-claw-networking.js +1 -1
- package/dist/lib/components/settings/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/settings/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/settings/shadow-claw-storage.js +1 -1
- package/dist/lib/components/settings/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/settings/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw/utils/syncSlottedSidebarActiveLinks.d.ts +10 -0
- package/dist/lib/components/shadow-claw-a2ui.js +1 -1
- package/dist/lib/components/shadow-claw-accounts.js +1 -1
- package/dist/lib/components/shadow-claw-channel-config.js +1 -1
- package/dist/lib/components/shadow-claw-channels.js +1 -1
- package/dist/lib/components/shadow-claw-chat.js +1 -1
- package/dist/lib/components/shadow-claw-control-plane.js +1 -1
- package/dist/lib/components/shadow-claw-conversations.js +1 -1
- package/dist/lib/components/shadow-claw-file-viewer.js +1 -1
- package/dist/lib/components/shadow-claw-files.js +1 -1
- package/dist/lib/components/shadow-claw-git.js +1 -1
- package/dist/lib/components/shadow-claw-integrations.js +1 -1
- package/dist/lib/components/shadow-claw-llm.js +1 -1
- package/dist/lib/components/shadow-claw-mcp-remote.js +1 -1
- package/dist/lib/components/shadow-claw-networking.js +1 -1
- package/dist/lib/components/shadow-claw-notifications.js +1 -1
- package/dist/lib/components/shadow-claw-page-header.js +1 -1
- package/dist/lib/components/shadow-claw-pages.js +1 -1
- package/dist/lib/components/shadow-claw-peerjs.js +1 -1
- package/dist/lib/components/shadow-claw-settings.js +1 -1
- package/dist/lib/components/shadow-claw-storage.js +1 -1
- package/dist/lib/components/shadow-claw-task-server.js +1 -1
- package/dist/lib/components/shadow-claw-tasks.js +1 -1
- package/dist/lib/components/shadow-claw-terminal.js +1 -1
- package/dist/lib/components/shadow-claw-tools.js +1 -1
- package/dist/lib/components/shadow-claw-webvm.js +1 -1
- package/dist/lib/components/shadow-claw.js +1 -1
- package/dist/lib/{config-CPHDmyTx.js → config-DZkF9LiO.js} +2 -2
- package/dist/lib/{config-CPHDmyTx.js.map → config-DZkF9LiO.js.map} +1 -1
- package/dist/lib/{configurePeerJs-BsJoycQd.js → configurePeerJs-B3IE9BY2.js} +3 -3
- package/dist/lib/{configurePeerJs-BsJoycQd.js.map → configurePeerJs-B3IE9BY2.js.map} +1 -1
- package/dist/lib/{connections-BdIru7bF.js → connections-CalJGWvZ.js} +2 -2
- package/dist/lib/{connections-BdIru7bF.js.map → connections-CalJGWvZ.js.map} +1 -1
- package/dist/lib/{downloadGroupFile-Dn0KsMlV.js → downloadGroupFile-DDE1fIhJ.js} +2 -2
- package/dist/lib/{downloadGroupFile-Dn0KsMlV.js.map → downloadGroupFile-DDE1fIhJ.js.map} +1 -1
- package/dist/lib/{file-viewer-BYrXXu-X.js → file-viewer-Bll2EoGc.js} +5 -5
- package/dist/lib/{file-viewer-BYrXXu-X.js.map → file-viewer-Bll2EoGc.js.map} +1 -1
- package/dist/lib/{getGroupDir-DF-RZO8X.js → getGroupDir-MHv7Lvmp.js} +4 -4
- package/dist/lib/{getGroupDir-DF-RZO8X.js.map → getGroupDir-MHv7Lvmp.js.map} +1 -1
- package/dist/lib/{git-s_0cgKm1.js → git-Bv_M3dgw.js} +3 -3
- package/dist/lib/{git-s_0cgKm1.js.map → git-Bv_M3dgw.js.map} +1 -1
- package/dist/lib/{iframe-sanitizer-DFdda1jJ.js → iframe-sanitizer-C7ZGDjEI.js} +2 -2
- package/dist/lib/{iframe-sanitizer-DFdda1jJ.js.map → iframe-sanitizer-C7ZGDjEI.js.map} +1 -1
- package/dist/lib/{iframe-storage-proxy-qrhZmQyO.js → iframe-storage-proxy-CR8ZYHPd.js} +2 -2
- package/dist/lib/{iframe-storage-proxy-qrhZmQyO.js.map → iframe-storage-proxy-CR8ZYHPd.js.map} +1 -1
- package/dist/lib/index.js +27 -27
- package/dist/lib/{initChatSplitResize-DuNlwCuI.js → initChatSplitResize-DiKTI-wk.js} +2 -2
- package/dist/lib/{initChatSplitResize-DuNlwCuI.js.map → initChatSplitResize-DiKTI-wk.js.map} +1 -1
- package/dist/lib/{initControlPlane-D4UZ4EhV.js → initControlPlane-CzjtQ4aM.js} +15 -15
- package/dist/lib/{initControlPlane-D4UZ4EhV.js.map → initControlPlane-CzjtQ4aM.js.map} +1 -1
- package/dist/lib/{markdown-CRRwbN9h.js → markdown-k8wA9LKy.js} +4 -4
- package/dist/lib/{markdown-CRRwbN9h.js.map → markdown-k8wA9LKy.js.map} +1 -1
- package/dist/lib/{mcp-reconnect-COdZ-cea.js → mcp-reconnect-CGIdfZnS.js} +2 -2
- package/dist/lib/{mcp-reconnect-COdZ-cea.js.map → mcp-reconnect-CGIdfZnS.js.map} +1 -1
- package/dist/lib/{memoryStorage-BsMe2FOQ.js → memoryStorage-DL-Bo3dh.js} +2 -2
- package/dist/lib/{memoryStorage-BsMe2FOQ.js.map → memoryStorage-DL-Bo3dh.js.map} +1 -1
- package/dist/lib/{orchestrator-D9f5fDCb.js → orchestrator-DKHCoikY.js} +11 -11
- package/dist/lib/{orchestrator-D9f5fDCb.js.map → orchestrator-DKHCoikY.js.map} +1 -1
- package/dist/lib/{orchestrator-CMN43L0F.js → orchestrator-Dn1ZOz9B.js} +12 -12
- package/dist/lib/{orchestrator-CMN43L0F.js.map → orchestrator-Dn1ZOz9B.js.map} +1 -1
- package/dist/lib/{peerjs-6u8KtenE.js → peerjs-BK41iBvP.js} +7 -7
- package/dist/lib/{peerjs-6u8KtenE.js.map → peerjs-BK41iBvP.js.map} +1 -1
- package/dist/lib/{push-client-DCnB2-OU.js → push-client-DKgVFD2Z.js} +3 -3
- package/dist/lib/{push-client-DCnB2-OU.js.map → push-client-DKgVFD2Z.js.map} +1 -1
- package/dist/lib/{readGroupFileBytes-nKNJ6sbl.js → readGroupFileBytes-CgU_UfGv.js} +2 -2
- package/dist/lib/{readGroupFileBytes-nKNJ6sbl.js.map → readGroupFileBytes-CgU_UfGv.js.map} +1 -1
- package/dist/lib/{shadow-claw-4x3LqlII.js → shadow-claw-CtCj5Rn_.js} +121 -16
- package/dist/lib/shadow-claw-CtCj5Rn_.js.map +1 -0
- package/dist/lib/{shadow-claw-a2ui-Dipe8nY2.js → shadow-claw-a2ui-CvK5w940.js} +2 -2
- package/dist/lib/{shadow-claw-a2ui-Dipe8nY2.js.map → shadow-claw-a2ui-CvK5w940.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-BgCkz3Zv.js → shadow-claw-accounts-Br3XdHro.js} +3 -3
- package/dist/lib/{shadow-claw-accounts-BgCkz3Zv.js.map → shadow-claw-accounts-Br3XdHro.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-CIm_Bxd2.js → shadow-claw-channel-config-Da2dN19M.js} +3 -3
- package/dist/lib/{shadow-claw-channel-config-CIm_Bxd2.js.map → shadow-claw-channel-config-Da2dN19M.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-CaceK52s.js → shadow-claw-channels-BofYHgz8.js} +3 -3
- package/dist/lib/{shadow-claw-channels-CaceK52s.js.map → shadow-claw-channels-BofYHgz8.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-BD18-mAR.js → shadow-claw-chat-Dw32DPV2.js} +12 -12
- package/dist/lib/{shadow-claw-chat-BD18-mAR.js.map → shadow-claw-chat-Dw32DPV2.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-U6LsfRPm.js → shadow-claw-control-plane-CwFotFDh.js} +7 -7
- package/dist/lib/{shadow-claw-control-plane-U6LsfRPm.js.map → shadow-claw-control-plane-CwFotFDh.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-CDsza_oB.js → shadow-claw-conversations-0UXge23k.js} +5 -5
- package/dist/lib/{shadow-claw-conversations-CDsza_oB.js.map → shadow-claw-conversations-0UXge23k.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-CuDhkVcL.js → shadow-claw-file-viewer-CAsn9NxH.js} +10 -10
- package/dist/lib/{shadow-claw-file-viewer-CuDhkVcL.js.map → shadow-claw-file-viewer-CAsn9NxH.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-BI0P3m8a.js → shadow-claw-files-xGGhsHNH.js} +9 -9
- package/dist/lib/{shadow-claw-files-BI0P3m8a.js.map → shadow-claw-files-xGGhsHNH.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-xRApLEMN.js → shadow-claw-git-B606hcMU.js} +6 -6
- package/dist/lib/{shadow-claw-git-xRApLEMN.js.map → shadow-claw-git-B606hcMU.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-B2e1Nfg1.js → shadow-claw-integrations-Bwq5cba1.js} +4 -4
- package/dist/lib/{shadow-claw-integrations-B2e1Nfg1.js.map → shadow-claw-integrations-Bwq5cba1.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-Bc2mWuGb.js → shadow-claw-llm-BgpcMBIy.js} +6 -6
- package/dist/lib/{shadow-claw-llm-Bc2mWuGb.js.map → shadow-claw-llm-BgpcMBIy.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-D_Bh3aeC.js → shadow-claw-mcp-remote-DvQCA-Bk.js} +4 -4
- package/dist/lib/{shadow-claw-mcp-remote-D_Bh3aeC.js.map → shadow-claw-mcp-remote-DvQCA-Bk.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-F5W3n5ci.js → shadow-claw-networking-Cxvf9c7E.js} +2 -2
- package/dist/lib/{shadow-claw-networking-F5W3n5ci.js.map → shadow-claw-networking-Cxvf9c7E.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-lvMt9WJ1.js → shadow-claw-notifications-CGVcFYBy.js} +3 -3
- package/dist/lib/{shadow-claw-notifications-lvMt9WJ1.js.map → shadow-claw-notifications-CGVcFYBy.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-6gq6EMqX.js → shadow-claw-page-header-DAYz3I_o.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-6gq6EMqX.js.map → shadow-claw-page-header-DAYz3I_o.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-Bo8_z2S-.js → shadow-claw-pages-BLeEZb9k.js} +24 -12
- package/dist/lib/shadow-claw-pages-BLeEZb9k.js.map +1 -0
- package/dist/lib/{shadow-claw-peerjs-DRTLCVDQ.js → shadow-claw-peerjs-BcFnbK74.js} +3 -3
- package/dist/lib/{shadow-claw-peerjs-DRTLCVDQ.js.map → shadow-claw-peerjs-BcFnbK74.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-D00B4p4L.js → shadow-claw-settings-B7o0Z4hu.js} +9 -9
- package/dist/lib/{shadow-claw-settings-D00B4p4L.js.map → shadow-claw-settings-B7o0Z4hu.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-DgMe7-Zo.js → shadow-claw-storage-afMVqB7E.js} +5 -5
- package/dist/lib/{shadow-claw-storage-DgMe7-Zo.js.map → shadow-claw-storage-afMVqB7E.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-D103YOuI.js → shadow-claw-task-server-B9-MQjl6.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-D103YOuI.js.map → shadow-claw-task-server-B9-MQjl6.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-6OhALkq1.js → shadow-claw-tasks-Dc4BC-t-.js} +8 -8
- package/dist/lib/{shadow-claw-tasks-6OhALkq1.js.map → shadow-claw-tasks-Dc4BC-t-.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-BGtxA1qD.js → shadow-claw-terminal-BINcTdsk.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-BGtxA1qD.js.map → shadow-claw-terminal-BINcTdsk.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-OeIwAnnd.js → shadow-claw-tools-BjFgXNLR.js} +7 -7
- package/dist/lib/{shadow-claw-tools-OeIwAnnd.js.map → shadow-claw-tools-BjFgXNLR.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-gVFZ197u.js → shadow-claw-webvm-Xe3ByMDw.js} +3 -3
- package/dist/lib/{shadow-claw-webvm-gVFZ197u.js.map → shadow-claw-webvm-Xe3ByMDw.js.map} +1 -1
- package/dist/lib/subsystems/mcp/webmcp.d.ts +64 -0
- package/dist/lib/{syncWebMcpRegistration-Bbph0XZl.js → syncWebMcpRegistration-D7alChz0.js} +21 -6
- package/dist/lib/syncWebMcpRegistration-D7alChz0.js.map +1 -0
- package/dist/lib/{tools-D0OlSzMD.js → tools-Cmhpk3X8.js} +4 -4
- package/dist/lib/{tools-D0OlSzMD.js.map → tools-Cmhpk3X8.js.map} +1 -1
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/namespacedStorage.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/{utils-DYdrO2KI.js → utils-CzgKe_XZ.js} +4 -4
- package/dist/lib/{utils-DYdrO2KI.js.map → utils-CzgKe_XZ.js.map} +1 -1
- package/dist/lib/{webmcp-D2bocsgh.js → webmcp-oEP9YpR2.js} +119 -3
- package/dist/lib/{webmcp-D2bocsgh.js.map → webmcp-oEP9YpR2.js.map} +1 -1
- package/dist/public/.well-known/mcp/server-card.json +1 -1
- package/dist/public/.well-known/mcp.json +1 -1
- package/dist/public/AGENTS.md +8 -2
- package/dist/public/README.md +2 -1
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/app-routes-C6-H2zPH.js +1 -0
- package/dist/public/components/shadow-claw/shadow-claw.css +1 -1
- package/dist/public/components/shadow-claw/shadow-claw.html +1 -1
- package/dist/public/components/shadow-claw-pages/shadow-claw-pages.css +1 -1
- package/dist/public/{config-D4lVqMs8.js → config-Dewnqegf.js} +1 -1
- package/dist/public/{configurePeerJs-DDOAVSaH.js → configurePeerJs-CaPU2sN5.js} +1 -1
- package/dist/public/{connections-CiukjGiH.js → connections-CwE7jE9l.js} +1 -1
- package/dist/public/{custom-element-security-piU2U-Ec.js → custom-element-security-DLgHMf5R.js} +1 -1
- package/dist/public/docs/README.md +1 -0
- package/dist/public/docs/example/article/index.html +4 -4
- package/dist/public/docs/guides/publishing-to-github-pages.md +95 -6
- package/dist/public/docs/publishing/index.html +4 -4
- package/dist/public/docs/skill-creator/index.html +4 -4
- package/dist/public/docs/subsystems/pages.md +10 -3
- package/dist/public/docs/subsystems/theming.md +242 -0
- package/dist/public/docs/subsystems/webmcp.md +89 -1
- package/dist/public/{downloadGroupFile-BiZQYY-O.js → downloadGroupFile-ChWHuap_.js} +1 -1
- package/dist/public/e2e/README.md +3 -2
- package/dist/public/{e2e-bridge-CybB810Q.js → e2e-bridge-BkaldjV2.js} +1 -1
- package/dist/public/{file-viewer-DLUBvOVD.js → file-viewer-Df4qUJCn.js} +1 -1
- package/dist/public/{getGroupDir-CLz5c8cg.js → getGroupDir-CeSr4fzS.js} +1 -1
- package/dist/public/{git-Ba8AeviI.js → git-Bscc1tK-.js} +2 -2
- package/dist/public/{iframe-sanitizer-CKOO7cxp.js → iframe-sanitizer-BVdkQsor.js} +1 -1
- package/dist/public/{iframe-storage-proxy-BvRiccH0.js → iframe-storage-proxy-Cg8aFw7o.js} +1 -1
- package/dist/public/index.css +1 -1
- package/dist/public/index.html +4 -4
- package/dist/public/index.js +1 -1
- package/dist/public/{initChatSplitResize-osJXM2gu.js → initChatSplitResize-C3Rp1LeZ.js} +1 -1
- package/dist/public/{initControlPlane-CNggzsRw.js → initControlPlane-C1pnzG16.js} +1 -1
- package/dist/public/llms.txt +2 -2
- package/dist/public/main/index.html +4 -4
- package/dist/public/main/memory/index.html +4 -4
- package/dist/public/{markdown-CZA-Ye2Q.js → markdown-D3A902nT.js} +1 -1
- package/dist/public/{mcp-reconnect-BK1bYBdC.js → mcp-reconnect-BJWxQBm_.js} +1 -1
- package/dist/public/{memoryStorage-Bew1X8Uy.js → memoryStorage-ykv-Ri-y.js} +1 -1
- package/dist/public/{orchestrator-D6tel2Zp.js → orchestrator-BVnC4Vtt.js} +2 -2
- package/dist/public/{orchestrator-Dc_Q73La.js → orchestrator-CQcc7OFA.js} +2 -2
- package/dist/public/{peerjs-CYs1F7sq.js → peerjs-CYC2cI1Y.js} +1 -1
- package/dist/public/{push-client-_HUyJlFJ.js → push-client-BJrnOULM.js} +1 -1
- package/dist/public/service-worker/fetch-proxy.js +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/{shadow-claw-Dabb2AEp.js → shadow-claw-WwfOu-tu.js} +33 -3
- package/dist/public/{shadow-claw-accounts-BqGrm47Z.js → shadow-claw-accounts-BFZxrPsH.js} +1 -1
- package/dist/public/{shadow-claw-channels-Ci2UPaaA.js → shadow-claw-channels-C0w0c1EF.js} +1 -1
- package/dist/public/{shadow-claw-chat-BxR6cBYQ.js → shadow-claw-chat-DIJ0A-QN.js} +1 -1
- package/dist/public/{shadow-claw-control-plane-C1A-CZ9H.js → shadow-claw-control-plane-DZoxUd-1.js} +2 -2
- package/dist/public/{shadow-claw-conversations-DcwG05-H.js → shadow-claw-conversations-DMyG_5zj.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-CDs1QGXk.js → shadow-claw-file-viewer-DYgZjZb9.js} +1 -1
- package/dist/public/{shadow-claw-files-B774Xz1d.js → shadow-claw-files-DIOUdKJr.js} +1 -1
- package/dist/public/{shadow-claw-git-CTIPP0vs.js → shadow-claw-git-if5S0QJr.js} +2 -2
- package/dist/public/{shadow-claw-integrations-CjtkA6l0.js → shadow-claw-integrations-BQt4hcWe.js} +1 -1
- package/dist/public/{shadow-claw-llm-DfmITHde.js → shadow-claw-llm-9uf1KFA0.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BPuV22So.js → shadow-claw-mcp-remote-COpNIzJd.js} +1 -1
- package/dist/public/{shadow-claw-networking-DEMMygy0.js → shadow-claw-networking-AOVRUn6B.js} +1 -1
- package/dist/public/{shadow-claw-notifications-B9Xhcj1P.js → shadow-claw-notifications-CKB-W1TA.js} +1 -1
- package/dist/public/{shadow-claw-page-header-CAXokjQy.js → shadow-claw-page-header-D4LmUigA.js} +1 -1
- package/dist/public/{shadow-claw-pages-BRQw8bTm.js → shadow-claw-pages-BpHRY4vH.js} +12 -3
- package/dist/public/{shadow-claw-settings-BGrDNyqh.js → shadow-claw-settings-CE-aUo_J.js} +3 -3
- package/dist/public/{shadow-claw-storage-DK3pf11w.js → shadow-claw-storage-CFKC-Y3V.js} +1 -1
- package/dist/public/{shadow-claw-task-server-CMp5Vjza.js → shadow-claw-task-server-B_ZjqK4B.js} +1 -1
- package/dist/public/{shadow-claw-tasks-BO8aXM2B.js → shadow-claw-tasks-CGsEv48K.js} +1 -1
- package/dist/public/{shadow-claw-terminal-BSeTuyDa.js → shadow-claw-terminal-DcaS7cPH.js} +1 -1
- package/dist/public/{shadow-claw-tools-Bj6DLZ-2.js → shadow-claw-tools-Cnu9hKy0.js} +1 -1
- package/dist/public/{shadow-claw-webvm-M7d5RH8H.js → shadow-claw-webvm-BB8SFvJ8.js} +1 -1
- package/dist/public/syncWebMcpRegistration-D2Zx4oA1.js +1 -0
- package/dist/public/theme-init.js +1 -1
- package/dist/public/{tools-nysPKnGT.js → tools-sOLCHTj8.js} +1 -1
- package/dist/public/{webmcp-Bo3KTgRb.js → webmcp-YFt6vM1_.js} +1 -1
- package/dist/server.js +188 -188
- package/package.json +1 -1
- package/src/cli/build/build.ts +18 -11
- package/src/cli/prerender/dsd-shell/prerender-dsd-shell.test.ts +4 -1
- package/src/cli/prerender/dsd-shell/prerender-dsd-shell.ts +13 -1
- package/src/cli/prerender/pretty-paths/prerender-pretty-paths.ts +22 -0
- package/src/cli/prerender/utils/insert-before-closing-head.test.ts +34 -1
- package/src/cli/prerender/utils/insert-before-closing-head.ts +20 -6
- package/src/cli/site-config/apply.test.ts +90 -0
- package/src/cli/site-config/apply.ts +189 -22
- package/src/components/shadow-claw/shadow-claw.css +26 -0
- package/src/components/shadow-claw/shadow-claw.html +4 -0
- package/src/components/shadow-claw/utils/applyRoute.ts +3 -0
- package/src/components/shadow-claw/utils/bindEventListeners.test.ts +6 -0
- package/src/components/shadow-claw/utils/bindEventListeners.ts +30 -1
- package/src/components/shadow-claw/utils/getRoute.test.ts +52 -0
- package/src/components/shadow-claw/utils/getRoute.ts +18 -0
- package/src/components/shadow-claw/utils/navigateToRoute.test.ts +21 -0
- package/src/components/shadow-claw/utils/navigateToRoute.ts +10 -0
- package/src/components/shadow-claw/utils/sidebarVisibility.ts +12 -4
- package/src/components/shadow-claw/utils/syncSlottedSidebarActiveLinks.test.ts +93 -0
- package/src/components/shadow-claw/utils/syncSlottedSidebarActiveLinks.ts +100 -0
- package/src/components/shadow-claw-pages/shadow-claw-pages.css +10 -1
- package/src/components/shadow-claw-pages/utils/removePreviewIframe.ts +3 -0
- package/src/core/orchestrator/utils/syncWebMcpRegistration.test.ts +52 -0
- package/src/core/orchestrator/utils/syncWebMcpRegistration.ts +28 -1
- package/src/server/middleware/static-files.test.ts +36 -0
- package/src/server/middleware/static-files.ts +14 -6
- package/src/storage/staticRouting.test.ts +36 -0
- package/src/storage/staticRouting.ts +31 -3
- package/src/subsystems/mcp/webmcp.test.ts +255 -0
- package/src/subsystems/mcp/webmcp.ts +253 -0
- package/dist/cli/chunk-00GAzVPl2.js +0 -1
- package/dist/cli/chunk-2hnFoNNC.js +0 -1
- package/dist/cli/chunk-BKQL4nzF2.js +0 -1
- package/dist/cli/chunk-BQ4K3fqj2.js +0 -1
- package/dist/cli/chunk-BVCGo6uf2.js +0 -1
- package/dist/cli/chunk-Bc9nRNyN.js +0 -11
- package/dist/cli/chunk-BcTH_-FL.js +0 -1
- package/dist/cli/chunk-BmD_sPRt.js +0 -1
- package/dist/cli/chunk-BsxNqqer.js +0 -1
- package/dist/cli/chunk-CCcF5T-c.js +0 -1
- package/dist/cli/chunk-CFhvwUeL.js +0 -91
- package/dist/cli/chunk-CwWtvULn.js +0 -1
- package/dist/cli/chunk-DID5VvOG.js +0 -17
- package/dist/cli/chunk-Drf-hXIR2.js +0 -1
- package/dist/cli/chunk-Dt5HNYVi.js +0 -1
- package/dist/cli/chunk-DwZQi9Ax.js +0 -1
- package/dist/cli/chunk-m9ZX7TyF2.js +0 -1
- package/dist/lib/app-routes-BAEMLu9g.js.map +0 -1
- package/dist/lib/shadow-claw-4x3LqlII.js.map +0 -1
- package/dist/lib/shadow-claw-pages-Bo8_z2S-.js.map +0 -1
- package/dist/lib/syncWebMcpRegistration-Bbph0XZl.js.map +0 -1
- package/dist/public/app-routes-BMQ4HFaM.js +0 -1
- package/dist/public/syncWebMcpRegistration-4bT0YUyZ.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-tools-OeIwAnnd.js","names":["shadowClawToolsStyles","shadowClawToolsTemplate"],"sources":["../../src/components/shadow-claw-tools/shadow-claw-tools.ts"],"sourcesContent":["import { getAvailableProviders, getProvider } from \"../../config/config.js\";\nimport { effect } from \"../../core/effect.js\";\n\nimport { getDb, ShadowClawDatabase } from \"../../db/db.js\";\nimport { getWebMcpMode } from \"../../subsystems/mcp/webmcp.js\";\n\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { toolsStore } from \"../../stores/tools.js\";\n\nimport { TOOL_DEFINITIONS } from \"../../subsystems/tools/tools.js\";\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { ulid } from \"../../utils/ulid.js\";\n\nimport type { Orchestrator } from \"../../core/orchestrator/orchestrator.js\";\nimport type { RemoteManifest } from \"../../subsystems/tools/remote/types.js\";\nimport {\n setWebMcpMode,\n setWebMcpToolsEnabled,\n} from \"../../core/orchestrator/utils/syncWebMcpRegistration.js\";\n\nimport \"../common/shadow-claw-page-header-action-button/shadow-claw-page-header-action-button.js\";\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawToolsStyles from \"./shadow-claw-tools.css\" with { type: \"css\" };\nimport shadowClawToolsTemplate from \"./shadow-claw-tools.html\" with { type: \"html\" };\n\nconst BUILTIN_TOOL_NAMES = new Set(TOOL_DEFINITIONS.map((t) => t.name));\n\nconst elementName = \"shadow-claw-tools\";\nexport class ShadowClawTools extends ShadowClawElement {\n static styles = shadowClawToolsStyles;\n static template = shadowClawToolsTemplate;\n currentRemoteManifest: RemoteManifest | null = null;\n\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n\n await toolsStore.refreshDeclarativeTools(db);\n this.setupEffects(db);\n this.bindEventListeners(db);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n bindEventListeners(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n // Back button\n root.querySelector(\".tools__back-btn\")?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate-back\", { bubbles: true, composed: true }),\n );\n });\n\n // Add tool button\n root.querySelector(\".tools__add-btn\")?.addEventListener(\"click\", () => {\n const dialog = root.querySelector(\"dialog\");\n if (dialog) {\n const form = root.querySelector(\n \".tools__dialog-form\",\n ) as HTMLFormElement | null;\n form?.reset();\n dialog.showModal();\n }\n });\n\n // Backup\n root.querySelector(\".tools__backup-btn\")?.addEventListener(\"click\", () => {\n this.handleBackup();\n });\n\n // Restore\n const restoreInput = root.querySelector(\".tools__hidden-restore\");\n root.querySelector(\".tools__restore-btn\")?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.click();\n }\n });\n restoreInput?.addEventListener(\"change\", (e) => {\n if (e.target instanceof HTMLInputElement) {\n this.handleRestore(db, e.target);\n }\n });\n\n // Select all / none\n root\n .querySelector(\".tools__select-all-btn\")\n ?.addEventListener(\"click\", () => {\n const allNames = toolsStore.allTools.map((t) => t.name);\n toolsStore.setAllEnabled(db, allNames);\n const declNames = toolsStore.declarativeTools.map((t) => t.name);\n toolsStore.setAllDeclarativeEnabled(db, declNames);\n showInfo(\"All tools enabled\");\n });\n\n root\n .querySelector(\".tools__select-none-btn\")\n ?.addEventListener(\"click\", () => {\n toolsStore.setAllEnabled(db, []);\n toolsStore.setAllDeclarativeEnabled(db, []);\n showInfo(\"All tools disabled\");\n });\n\n // WebMCP toggle listener\n const webMcpToggle = root.querySelector(\n \".tools__webmcp-toggle\",\n ) as HTMLInputElement | null;\n if (webMcpToggle) {\n webMcpToggle.addEventListener(\"change\", async () => {\n const orchestrator =\n this.orchestrator ?? orchestratorStore.orchestrator;\n if (!orchestrator) {\n webMcpToggle.checked = false;\n showError(\"Orchestrator is not ready\");\n\n return;\n }\n\n const next = webMcpToggle.checked;\n try {\n await setWebMcpToolsEnabled(orchestrator, db, next, { orchestrator });\n showInfo(\n next\n ? \"WebMCP tool registration enabled\"\n : \"WebMCP tool registration disabled\",\n );\n } catch (err) {\n webMcpToggle.checked = !next;\n showError(\n `Failed to update WebMCP setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Shared full internet access toggle listener\n const internetAccessToggle = root.querySelector(\n \".tools__internet-access-toggle\",\n ) as HTMLInputElement | null;\n if (internetAccessToggle) {\n internetAccessToggle.addEventListener(\"change\", async () => {\n const next = internetAccessToggle.checked;\n try {\n await orchestratorStore.setVMBashFullInternetAccess(db, next);\n showInfo(\n next\n ? \"Full internet access enabled for Bash and JavaScript tools\"\n : \"Full internet access disabled for Bash and JavaScript tools\",\n );\n } catch (err) {\n internetAccessToggle.checked = !next;\n showError(\n `Failed to update internet access setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Web Search toggle\n const webSearchUseProxyToggle = root.querySelector(\n \".tools__websearch-proxy-toggle\",\n ) as HTMLInputElement | null;\n webSearchUseProxyToggle?.addEventListener(\"change\", async () => {\n try {\n await toolsStore.setWebSearchUseProxy(\n db,\n webSearchUseProxyToggle.checked,\n );\n showInfo(\n webSearchUseProxyToggle.checked\n ? \"Web Search local proxy enabled\"\n : \"Web Search local proxy disabled\",\n );\n } catch (err) {\n webSearchUseProxyToggle.checked = !webSearchUseProxyToggle.checked;\n showError(\n `Failed to update Web Search proxy setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // Search Files save button\n root\n .querySelector(\".tools__save-searchfiles-btn\")\n ?.addEventListener(\"click\", async () => {\n const maxFileBytesInput = root.querySelector(\n \".tools__searchfiles-max-file-bytes-input\",\n ) as HTMLInputElement | null;\n const maxFilesVisitedInput = root.querySelector(\n \".tools__searchfiles-max-files-visited-input\",\n ) as HTMLInputElement | null;\n const skipDirsInput = root.querySelector(\n \".tools__searchfiles-skip-dirs-input\",\n ) as HTMLInputElement | null;\n\n const maxFileBytes = parseInt(maxFileBytesInput?.value || \"\", 10);\n const maxFilesVisited = parseInt(maxFilesVisitedInput?.value || \"\", 10);\n const skipDirs = skipDirsInput?.value ?? \"\";\n\n try {\n if (!isNaN(maxFileBytes) && maxFileBytes > 0) {\n await toolsStore.setSearchFilesMaxFileBytes(db, maxFileBytes);\n }\n if (!isNaN(maxFilesVisited) && maxFilesVisited > 0) {\n await toolsStore.setSearchFilesMaxFilesVisited(db, maxFilesVisited);\n }\n await toolsStore.setSearchFilesSkipDirs(db, skipDirs);\n showSuccess(\"Search Files settings saved\");\n } catch (err) {\n showError(\n `Failed to save Search Files settings: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // Web Search save button\n root\n .querySelector(\".tools__save-websearch-btn\")\n ?.addEventListener(\"click\", async () => {\n const proxyUrlInput = root.querySelector(\n \".tools__websearch-proxy-url-input\",\n ) as HTMLInputElement | null;\n const searchUrlInput = root.querySelector(\n \".tools__websearch-url-input\",\n ) as HTMLInputElement | null;\n\n const proxyUrl = proxyUrlInput?.value.trim() || \"/proxy\";\n const searchUrl =\n searchUrlInput?.value.trim() ||\n \"https://html.duckduckgo.com/html/?q={query}\";\n\n try {\n await toolsStore.setWebSearchProxyUrl(db, proxyUrl);\n await toolsStore.setWebSearchUrl(db, searchUrl);\n showSuccess(\"Web Search settings saved\");\n } catch (err) {\n showError(\n `Failed to save Web Search settings: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // WebMCP mode selector\n const webMcpModeSelect = root.querySelector(\n \".tools__webmcp-mode\",\n ) as HTMLSelectElement | null;\n if (webMcpModeSelect) {\n webMcpModeSelect.addEventListener(\"change\", async () => {\n const orchestrator =\n this.orchestrator ?? orchestratorStore.orchestrator;\n if (!orchestrator) {\n return;\n }\n\n const mode = webMcpModeSelect.value as \"polyfill\" | \"native\";\n try {\n await setWebMcpMode(orchestrator, db, mode, { orchestrator });\n showInfo(`WebMCP mode set to ${mode}`);\n } catch (err) {\n showError(\n `Failed to update WebMCP mode: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Save prompt\n root\n .querySelector(\".tools__save-prompt-btn\")\n ?.addEventListener(\"click\", () => {\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (textarea instanceof HTMLTextAreaElement) {\n toolsStore.setSystemPromptOverride(db, textarea.value);\n showSuccess(\"System prompt override saved\");\n }\n });\n\n // Clear prompt\n root\n .querySelector(\".tools__clear-prompt-btn\")\n ?.addEventListener(\"click\", () => {\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (textarea instanceof HTMLTextAreaElement) {\n textarea.value = \"\";\n toolsStore.setSystemPromptOverride(db, \"\");\n showSuccess(\"System prompt override cleared\");\n }\n });\n\n // Dialog controls — Add Tool\n const dialog = root.querySelector(\n \".tools__dialog\",\n ) as HTMLDialogElement | null;\n const closeBtn = dialog?.querySelector(\".tools__dialog-close\");\n const cancelBtn = dialog?.querySelector(\".tools__btn-cancel\");\n const form = root.querySelector(\n \".tools__dialog-form\",\n ) as HTMLFormElement | null;\n\n closeBtn?.addEventListener(\"click\", () => dialog?.close());\n cancelBtn?.addEventListener(\"click\", () => dialog?.close());\n\n dialog?.addEventListener(\"click\", (e) => {\n if (e.target === dialog) {\n dialog.close();\n }\n });\n\n form?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (form) {\n this.handleAddTool(db, form);\n }\n });\n\n // Dialog controls — Clone Tool\n const cloneDialog = root.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n const cloneCloseBtn = root.querySelector(\".tools__clone-dialog-close\");\n const cloneCancelBtn = root.querySelector(\".tools__clone-cancel-btn\");\n const cloneForm = root.querySelector(\n \".tools__clone-dialog-form\",\n ) as HTMLFormElement | null;\n\n cloneCloseBtn?.addEventListener(\"click\", () => cloneDialog?.close());\n cloneCancelBtn?.addEventListener(\"click\", () => cloneDialog?.close());\n cloneDialog?.addEventListener(\"click\", (e) => {\n if (e.target === cloneDialog) {\n cloneDialog.close();\n }\n });\n\n cloneForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (cloneForm) {\n this.handleCloneTool(db, cloneForm);\n }\n });\n\n // Dialog controls — Profile\n const profileDialog = root.querySelector(\n \".tools__profile-dialog\",\n ) as HTMLDialogElement | null;\n const profileCloseBtn = root.querySelector(\".tools__profile-dialog-close\");\n const profileCancelBtn = root.querySelector(\".tools__profile-cancel-btn\");\n const profileForm = root.querySelector(\n \".tools__profile-dialog-form\",\n ) as HTMLFormElement | null;\n\n profileCloseBtn?.addEventListener(\"click\", () => profileDialog?.close());\n profileCancelBtn?.addEventListener(\"click\", () => profileDialog?.close());\n profileDialog?.addEventListener(\"click\", (e) => {\n if (e.target === profileDialog) {\n profileDialog.close();\n }\n });\n\n profileForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (profileForm) {\n this.handleSaveProfile(db, profileForm);\n }\n });\n\n // Profile select\n const profileSelect = root.querySelector(\".tools__profile-select\");\n profileSelect?.addEventListener(\"change\", (e) => {\n const select = e.target as HTMLSelectElement;\n const value = select.value;\n if (value) {\n toolsStore.activateProfile(db, value);\n showInfo(\"Profile activated\");\n } else {\n toolsStore.deactivateProfile(db);\n showInfo(\"Profile deactivated\");\n }\n });\n\n // Profile new button → open dialog\n root\n .querySelector(\".tools__profile-new-btn\")\n ?.addEventListener(\"click\", () => {\n if (profileDialog && profileForm) {\n profileForm.reset();\n // Populate provider dropdown\n const providerSelect = profileForm.querySelector(\n '[name=\"providerId\"]',\n );\n if (providerSelect) {\n providerSelect.replaceChildren();\n const defaultOption = document.createElement(\"option\");\n defaultOption.value = \"\";\n defaultOption.textContent = \"— Any provider —\";\n providerSelect.append(defaultOption);\n for (const pid of getAvailableProviders()) {\n const p = getProvider(pid);\n if (p) {\n const opt = document.createElement(\"option\");\n opt.value = pid;\n opt.textContent = p.name;\n providerSelect.appendChild(opt);\n }\n }\n }\n\n (profileDialog as HTMLDialogElement).showModal();\n }\n });\n\n // Profile save (overwrite active)\n root\n .querySelector(\".tools__profile-save-btn\")\n ?.addEventListener(\"click\", async () => {\n const activeId = toolsStore.activeProfileId;\n if (activeId) {\n await toolsStore.saveToActiveProfile(db);\n showSuccess(\"Profile saved\");\n } else {\n // No active profile — open new profile dialog\n root\n .querySelector(\".tools__profile-new-btn\")\n ?.dispatchEvent(new Event(\"click\"));\n }\n });\n\n // Profile delete\n root\n .querySelector(\".tools__profile-delete-btn\")\n ?.addEventListener(\"click\", async () => {\n const activeId = toolsStore.activeProfileId;\n if (!activeId) {\n showInfo(\"No profile selected\");\n\n return;\n }\n\n if (activeId.startsWith(\"__builtin_\")) {\n showInfo(\"Built-in profiles cannot be deleted\");\n\n return;\n }\n\n await toolsStore.deleteProfile(db, activeId);\n showSuccess(\"Profile deleted\");\n });\n\n // Dialog controls — Import\n const importDialog = root.querySelector(\n \".tools__import-dialog\",\n ) as HTMLDialogElement | null;\n const importCloseBtn = root.querySelector(\".tools__import-dialog-close\");\n const importCancelBtn = root.querySelector(\".tools__import-cancel-btn\");\n const importForm = root.querySelector(\n \".tools__import-dialog-form\",\n ) as HTMLFormElement | null;\n const importFetchBtn = root.querySelector(\".tools__import-fetch-btn\");\n\n root.querySelector(\".tools__import-btn\")?.addEventListener(\"click\", () => {\n if (importDialog && importForm) {\n importForm.reset();\n this.resetImportDialogState();\n importDialog.showModal();\n }\n });\n\n importCloseBtn?.addEventListener(\"click\", () => importDialog?.close());\n importCancelBtn?.addEventListener(\"click\", () => importDialog?.close());\n importDialog?.addEventListener(\"click\", (e) => {\n if (e.target === importDialog) {\n importDialog.close();\n }\n });\n\n root.querySelectorAll(\".tools__preset-btn\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n const url = (btn as HTMLElement).dataset.url;\n const input = root.querySelector(\n \".tools__import-url-input\",\n ) as HTMLInputElement | null;\n if (input && url) {\n input.value = url;\n this.handleFetchSite(db, url);\n }\n });\n });\n\n importFetchBtn?.addEventListener(\"click\", () => {\n const input = root.querySelector(\n \".tools__import-url-input\",\n ) as HTMLInputElement | null;\n if (input && input.value.trim()) {\n this.handleFetchSite(db, input.value.trim());\n }\n });\n\n importForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (importForm) {\n this.handleImportSubmit(db, importForm);\n }\n });\n }\n\n handleBackup() {\n const json = toolsStore.exportBackup();\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `shadowclaw-tools-${Date.now()}.json`;\n a.click();\n URL.revokeObjectURL(url);\n showSuccess(\"Tools config exported\");\n }\n\n /**\n * Open the clone tool dialog for a given source tool.\n */\n openCloneDialog(sourceToolName: string) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const cloneDialog = root.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n const cloneForm = root.querySelector(\n \".tools__clone-dialog-form\",\n ) as HTMLFormElement | null;\n if (!cloneDialog || !cloneForm) {\n return;\n }\n\n cloneForm.reset();\n const sourceInput = cloneForm.querySelector(\n '[name=\"source\"]',\n ) as HTMLInputElement | null;\n if (sourceInput) {\n sourceInput.value = sourceToolName;\n }\n\n cloneDialog.showModal();\n }\n\n renderImportCatalog(manifest: RemoteManifest) {\n const root = this.shadowRoot;\n if (!root) return;\n\n const catalog = root.querySelector(\".tools__import-catalog\");\n if (!catalog) return;\n catalog.replaceChildren();\n\n // 1. Render Tools\n const tools = manifest.tools || [];\n if (tools.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `🛠️ Tools (${tools.length})`;\n category.appendChild(header);\n\n for (const tool of tools) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importTool\";\n checkbox.value = tool.name;\n checkbox.checked = true;\n checkbox.id = `import_tool_${tool.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = tool.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge tools__item-badge--declarative\";\n badge.textContent = tool.executionType || \"declarative\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (tool.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = tool.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n\n // 2. Render Skills\n const skills = manifest.skills || [];\n if (skills.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `🧠 Agent Skills (${skills.length})`;\n category.appendChild(header);\n\n for (const skill of skills) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importSkill\";\n checkbox.value = skill.name;\n checkbox.checked = true;\n checkbox.id = `import_skill_${skill.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = skill.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"skill\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (skill.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = skill.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n\n // 3. Render Scripts\n const scripts = manifest.scripts || [];\n if (scripts.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `📜 Companion Scripts (${scripts.length})`;\n category.appendChild(header);\n\n for (const script of scripts) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importScript\";\n checkbox.value = script.name;\n checkbox.checked = true;\n checkbox.id = `import_script_${script.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = script.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"script\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (script.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = script.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n }\n\n resetImportDialogState() {\n this.currentRemoteManifest = null;\n const root = this.shadowRoot;\n if (!root) return;\n\n const statusEl = root.querySelector(\n \".tools__import-manifest-status\",\n ) as HTMLElement | null;\n if (statusEl) statusEl.hidden = true;\n\n const siteName = root.querySelector(\".tools__import-site-name\");\n if (siteName) siteName.textContent = \"\";\n\n const siteDesc = root.querySelector(\".tools__import-site-desc\");\n if (siteDesc) siteDesc.textContent = \"\";\n\n const catalog = root.querySelector(\".tools__import-catalog\");\n if (catalog) catalog.replaceChildren();\n\n const submitBtn = root.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) submitBtn.disabled = true;\n }\n\n setupEffects(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n // Reactive re-render on tool store changes\n this.addCleanup(\n effect(() => {\n toolsStore.enabledToolNames;\n toolsStore.customTools;\n toolsStore.declarativeTools;\n toolsStore.declarativeToolNamesEnabled;\n toolsStore.systemPromptOverride;\n toolsStore.profiles;\n toolsStore.activeProfileId;\n this.updateToolList(db);\n }),\n );\n\n // WebMCP opt-in toggle\n const webMcpToggle = root.querySelector(\n \".tools__webmcp-toggle\",\n ) as HTMLInputElement | null;\n const internetAccessToggle = root.querySelector(\n \".tools__internet-access-toggle\",\n ) as HTMLInputElement | null;\n const webMcpModeSelect = root.querySelector(\n \".tools__webmcp-mode\",\n ) as HTMLSelectElement | null;\n\n if (webMcpToggle) {\n // Sync checked state and mode when orchestrator becomes available\n this.addCleanup(\n effect(() => {\n if (orchestratorStore.ready) {\n this.orchestrator = orchestratorStore.orchestrator;\n webMcpToggle.checked =\n this.orchestrator?.webMcpToolsEnabled === true;\n if (webMcpModeSelect && this.orchestrator) {\n webMcpModeSelect.value = getWebMcpMode() || \"polyfill\";\n }\n }\n }),\n );\n }\n\n if (internetAccessToggle) {\n this.addCleanup(\n effect(() => {\n internetAccessToggle.checked =\n orchestratorStore.vmBashFullInternetAccess;\n }),\n );\n }\n\n // Web Search reactive effects\n const webSearchProxyToggle = root.querySelector(\n \".tools__websearch-proxy-toggle\",\n ) as HTMLInputElement | null;\n const webSearchProxyUrlInput = root.querySelector(\n \".tools__websearch-proxy-url-input\",\n ) as HTMLInputElement | null;\n const webSearchUrlInput = root.querySelector(\n \".tools__websearch-url-input\",\n ) as HTMLInputElement | null;\n\n if (webSearchProxyToggle) {\n this.addCleanup(\n effect(() => {\n webSearchProxyToggle.checked = toolsStore.webSearchUseProxy;\n }),\n );\n }\n\n if (webSearchProxyUrlInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== webSearchProxyUrlInput &&\n !webSearchProxyUrlInput.matches(\":focus\")\n ) {\n webSearchProxyUrlInput.value = toolsStore.webSearchProxyUrl;\n }\n }),\n );\n }\n\n if (webSearchUrlInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== webSearchUrlInput &&\n !webSearchUrlInput.matches(\":focus\")\n ) {\n webSearchUrlInput.value = toolsStore.webSearchUrl;\n }\n }),\n );\n }\n\n // Search Files reactive effects\n const searchFilesMaxFileBytesInput = root.querySelector(\n \".tools__searchfiles-max-file-bytes-input\",\n ) as HTMLInputElement | null;\n const searchFilesMaxFilesVisitedInput = root.querySelector(\n \".tools__searchfiles-max-files-visited-input\",\n ) as HTMLInputElement | null;\n const searchFilesSkipDirsInput = root.querySelector(\n \".tools__searchfiles-skip-dirs-input\",\n ) as HTMLInputElement | null;\n\n if (searchFilesMaxFileBytesInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesMaxFileBytesInput &&\n !searchFilesMaxFileBytesInput.matches(\":focus\")\n ) {\n searchFilesMaxFileBytesInput.value = String(\n toolsStore.searchFilesMaxFileBytes,\n );\n }\n }),\n );\n }\n\n if (searchFilesMaxFilesVisitedInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesMaxFilesVisitedInput &&\n !searchFilesMaxFilesVisitedInput.matches(\":focus\")\n ) {\n searchFilesMaxFilesVisitedInput.value = String(\n toolsStore.searchFilesMaxFilesVisited,\n );\n }\n }),\n );\n }\n\n if (searchFilesSkipDirsInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesSkipDirsInput &&\n !searchFilesSkipDirsInput.matches(\":focus\")\n ) {\n searchFilesSkipDirsInput.value = toolsStore.searchFilesSkipDirs;\n }\n }),\n );\n }\n }\n\n /** Update the profile dropdown to reflect current state. */\n updateProfileSelector() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const select = root.querySelector(\".tools__profile-select\");\n if (!select) {\n return;\n }\n\n const profiles = toolsStore.profiles;\n const activeId = toolsStore.activeProfileId;\n\n // Preserve selection\n select.replaceChildren();\n const defaultOption = document.createElement(\"option\");\n defaultOption.value = \"\";\n defaultOption.textContent = \"— No profile (manual config) —\";\n select.append(defaultOption);\n for (const p of profiles) {\n const opt = document.createElement(\"option\");\n opt.value = p.id;\n const isBuiltin = p.id.startsWith(\"__builtin_\");\n const providerLabel = p.providerId\n ? getProvider(p.providerId)?.name || p.providerId\n : \"any\";\n const modelLabel = p.model || \"any\";\n opt.textContent = isBuiltin\n ? `⚡ ${p.name} (${providerLabel})`\n : `${p.name} (${providerLabel} / ${modelLabel})`;\n if (p.id === activeId) {\n opt.selected = true;\n }\n\n select.appendChild(opt);\n }\n\n // Disable delete button for built-in profiles\n const deleteBtn = root.querySelector(\n \".tools__profile-delete-btn\",\n ) as HTMLButtonElement | null;\n if (deleteBtn) {\n const isBuiltinActive = activeId?.startsWith(\"__builtin_\");\n deleteBtn.disabled = !!isBuiltinActive;\n deleteBtn.title = isBuiltinActive\n ? \"Built-in profiles cannot be deleted\"\n : \"\";\n }\n }\n\n updateToolList(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tools__list\");\n if (!list) {\n return;\n }\n\n const enabled = toolsStore.enabledToolNames;\n const allTools = toolsStore.allTools;\n const declarativeTools = toolsStore.declarativeTools;\n\n const existingCheckboxes = list.querySelectorAll<HTMLInputElement>(\n \".tools__item-checkbox[data-tool]\",\n );\n const existingToolNames = Array.from(existingCheckboxes).map(\n (cb) => cb.getAttribute(\"data-tool\") || \"\",\n );\n const targetToolNames = [\n ...allTools.map((t) => t.name),\n ...declarativeTools.map((t) => t.name),\n ];\n\n const isSameStructure =\n existingToolNames.length === targetToolNames.length &&\n existingToolNames.every((name, i) => name === targetToolNames[i]);\n\n if (isSameStructure) {\n for (const cb of existingCheckboxes) {\n const toolName = cb.getAttribute(\"data-tool\");\n if (!toolName) continue;\n const isDeclarative = declarativeTools.some((t) => t.name === toolName);\n const isChecked = isDeclarative\n ? toolsStore.isDeclarativeToolEnabled(toolName)\n : enabled.has(toolName);\n if (cb.checked !== isChecked) {\n cb.checked = isChecked;\n }\n }\n } else {\n list.replaceChildren();\n\n for (const tool of allTools) {\n const isCustom = !BUILTIN_TOOL_NAMES.has(tool.name);\n const isChecked = enabled.has(tool.name);\n const brief = tool.description.split(\". \")[0];\n\n const item = document.createElement(\"div\");\n item.className = \"tools__item\";\n item.setAttribute(\"role\", \"listitem\");\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"tools__item-checkbox\";\n checkbox.setAttribute(\"data-tool\", tool.name);\n checkbox.setAttribute(\"aria-label\", `Enable ${tool.name}`);\n checkbox.checked = isChecked;\n\n const info = document.createElement(\"div\");\n info.className = \"tools__item-info\";\n\n const name = document.createElement(\"div\");\n name.className = \"tools__item-name\";\n name.textContent = tool.name;\n\n const desc = document.createElement(\"div\");\n desc.className = \"tools__item-desc\";\n desc.setAttribute(\"title\", tool.description);\n desc.textContent = brief;\n info.append(name, desc);\n\n const cloneBtn = document.createElement(\"button\");\n cloneBtn.className = \"tools__item-clone\";\n cloneBtn.setAttribute(\"data-clone\", tool.name);\n cloneBtn.setAttribute(\"aria-label\", `Clone ${tool.name}`);\n cloneBtn.setAttribute(\"title\", \"Clone tool\");\n cloneBtn.textContent = \"📋\";\n\n item.append(checkbox, info);\n\n if (isCustom) {\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"custom\";\n item.append(badge);\n }\n\n item.append(cloneBtn);\n\n let deleteBtn: HTMLButtonElement | null = null;\n if (isCustom) {\n deleteBtn = document.createElement(\"button\");\n deleteBtn.className = \"tools__item-delete\";\n deleteBtn.setAttribute(\"data-delete\", tool.name);\n deleteBtn.setAttribute(\"aria-label\", `Delete ${tool.name}`);\n deleteBtn.textContent = \"🗑️\";\n item.append(deleteBtn);\n }\n\n // Toggle\n checkbox?.addEventListener(\"change\", () => {\n toolsStore.setToolEnabled(db, tool.name, checkbox.checked);\n });\n\n // Clone\n cloneBtn?.addEventListener(\"click\", () => {\n this.openCloneDialog(tool.name);\n });\n\n // Delete custom tool\n deleteBtn?.addEventListener(\"click\", () => {\n toolsStore.removeCustomTool(db, tool.name);\n showInfo(`Removed custom tool: ${tool.name}`);\n });\n\n list.appendChild(item);\n }\n\n for (const tool of declarativeTools) {\n const isChecked = toolsStore.isDeclarativeToolEnabled(tool.name);\n const brief = tool.description.split(\". \")[0];\n\n const item = document.createElement(\"div\");\n item.className = \"tools__item\";\n item.setAttribute(\"role\", \"listitem\");\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"tools__item-checkbox\";\n checkbox.setAttribute(\"data-tool\", tool.name);\n checkbox.setAttribute(\"aria-label\", `Enable ${tool.name}`);\n checkbox.checked = isChecked;\n\n const info = document.createElement(\"div\");\n info.className = \"tools__item-info\";\n\n const name = document.createElement(\"div\");\n name.className = \"tools__item-name\";\n name.textContent = tool.name;\n\n const desc = document.createElement(\"div\");\n desc.className = \"tools__item-desc\";\n desc.setAttribute(\"title\", tool.description);\n desc.textContent = brief;\n info.append(name, desc);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge tools__item-badge--declarative\";\n badge.textContent = \"declarative\";\n item.append(checkbox, info, badge);\n\n checkbox.addEventListener(\"change\", () => {\n toolsStore.setDeclarativeToolEnabled(db, tool.name, checkbox.checked);\n });\n\n list.appendChild(item);\n }\n }\n\n // Update count\n const countEl = root.querySelector(\".tools__count\");\n if (countEl) {\n const enabledBuiltinCount = (toolsStore.enabledTools || []).length;\n const enabledDeclarativeCount = (toolsStore.enabledDeclarativeTools || [])\n .length;\n const totalEnabled = enabledBuiltinCount + enabledDeclarativeCount;\n const totalCount = allTools.length + declarativeTools.length;\n countEl.textContent = `${totalEnabled} of ${totalCount} enabled`;\n }\n\n // Update prompt textarea\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (\n textarea instanceof HTMLTextAreaElement &&\n document.activeElement !== textarea &&\n !textarea.matches(\":focus\")\n ) {\n textarea.value = toolsStore.systemPromptOverride;\n }\n\n // Update profile selector\n this.updateProfileSelector();\n }\n\n async handleAddTool(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const name = String(data.get(\"name\") || \"\").trim();\n const description = String(data.get(\"description\") || \"\").trim();\n const schemaStr = String(data.get(\"input_schema\") || \"\").trim();\n\n if (!name || !description) {\n showError(\"Name and description are required\");\n\n return;\n }\n\n // Check uniqueness\n if (toolsStore.allTools.some((t) => t.name === name)) {\n showError(`A tool named \"${name}\" already exists`);\n\n return;\n }\n\n let input_schema = { type: \"object\", properties: {} };\n if (schemaStr) {\n try {\n input_schema = JSON.parse(schemaStr);\n } catch {\n showError(\"Invalid JSON in input schema\");\n\n return;\n }\n }\n\n await toolsStore.addCustomTool(db, { name, description, input_schema });\n showSuccess(`Added custom tool: ${name}`);\n\n const dialog = this.shadowRoot?.querySelector(\n \".tools__dialog\",\n ) as HTMLDialogElement | null;\n dialog?.close();\n }\n\n async handleCloneTool(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const sourceToolName = String(data.get(\"source\") || \"\").trim();\n const newName = String(data.get(\"name\") || \"\").trim();\n const newDesc = String(data.get(\"description\") || \"\").trim();\n\n if (!sourceToolName || !newName) {\n showError(\"Source and new tool name are required\");\n\n return;\n }\n\n const ok = await toolsStore.cloneTool(\n db,\n sourceToolName,\n newName,\n newDesc || undefined,\n );\n if (!ok) {\n showError(\n `Clone failed: source not found or name \"${newName}\" already exists.`,\n );\n\n return;\n }\n\n showSuccess(`Cloned \"${sourceToolName}\" → \"${newName}\"`);\n const cloneDialog = this.shadowRoot?.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n cloneDialog?.close();\n }\n\n async handleFetchSite(_db: ShadowClawDatabase, url: string) {\n const root = this.shadowRoot;\n if (!root) return;\n\n const fetchBtn = root.querySelector(\n \".tools__import-fetch-btn\",\n ) as HTMLButtonElement | null;\n const origText = fetchBtn?.textContent || \"🔍 Fetch\";\n if (fetchBtn) {\n fetchBtn.disabled = true;\n fetchBtn.textContent = \"Fetching...\";\n }\n\n try {\n const resolved = await toolsStore.fetchRemoteDiscoveryManifest(url);\n this.currentRemoteManifest = resolved.manifest;\n\n const siteName = root.querySelector(\".tools__import-site-name\");\n if (siteName)\n siteName.textContent = resolved.manifest.name || \"Remote Site\";\n\n const siteDesc = root.querySelector(\".tools__import-site-desc\");\n if (siteDesc) {\n siteDesc.textContent =\n resolved.manifest.description || \"No description provided.\";\n }\n\n this.renderImportCatalog(resolved.manifest);\n\n const statusEl = root.querySelector(\n \".tools__import-manifest-status\",\n ) as HTMLElement | null;\n if (statusEl) statusEl.hidden = false;\n\n const submitBtn = root.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) submitBtn.disabled = false;\n\n showInfo(\n `Discovered ${(resolved.manifest.tools || []).length} tools, ${(resolved.manifest.skills || []).length} skills from ${resolved.manifest.name}`,\n );\n } catch (err) {\n this.resetImportDialogState();\n showError(\n `Failed to fetch site: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n if (fetchBtn) {\n fetchBtn.disabled = false;\n fetchBtn.textContent = origText;\n }\n }\n }\n\n async handleImportSubmit(db: ShadowClawDatabase, form: HTMLFormElement) {\n if (!this.currentRemoteManifest) {\n showError(\"No remote discovery manifest loaded.\");\n return;\n }\n\n const formData = new FormData(form);\n const toolNames = formData.getAll(\"importTool\").map(String);\n const skillNames = formData.getAll(\"importSkill\").map(String);\n const scriptNames = formData.getAll(\"importScript\").map(String);\n\n if (\n toolNames.length === 0 &&\n skillNames.length === 0 &&\n scriptNames.length === 0\n ) {\n showError(\"Please select at least one tool, skill, or script to import.\");\n return;\n }\n\n const autoEnable =\n (form.querySelector(\".tools__import-auto-enable\") as HTMLInputElement)\n ?.checked ?? true;\n const overwrite =\n (form.querySelector(\".tools__import-overwrite\") as HTMLInputElement)\n ?.checked ?? false;\n\n const submitBtn = form.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) {\n submitBtn.disabled = true;\n submitBtn.textContent = \"Importing...\";\n }\n\n try {\n const result = await toolsStore.importFromRemoteSite(\n db,\n this.currentRemoteManifest,\n { toolNames, skillNames, scriptNames },\n { autoEnable, overwrite },\n );\n\n const importedToolsCount = result.tools.filter(\n (t) => t.status === \"imported\",\n ).length;\n const importedSkillsCount = result.skills.filter(\n (s) => s.status === \"imported\",\n ).length;\n const importedScriptsCount = result.scripts.filter(\n (sc) => sc.status === \"imported\",\n ).length;\n\n const totalCount =\n importedToolsCount + importedSkillsCount + importedScriptsCount;\n\n showSuccess(\n `Successfully imported ${totalCount} items from ${this.currentRemoteManifest.name || \"site\"}!`,\n );\n\n const dialog = this.shadowRoot?.querySelector(\n \".tools__import-dialog\",\n ) as HTMLDialogElement | null;\n dialog?.close();\n } catch (err) {\n showError(\n `Import failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n if (submitBtn) {\n submitBtn.disabled = false;\n submitBtn.textContent = \"Import Selected\";\n }\n }\n }\n\n async handleRestore(db: ShadowClawDatabase, input: HTMLInputElement) {\n const file = input.files?.[0];\n if (!file) {\n return;\n }\n\n try {\n const text = await file.text();\n await toolsStore.importBackup(db, text);\n showSuccess(\"Tools config restored\");\n } catch (err) {\n showError(\n `Failed to restore: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n input.value = \"\";\n }\n\n async handleSaveProfile(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const name = String(data.get(\"name\") || \"\").trim();\n const providerId = String(data.get(\"providerId\") || \"\").trim();\n const model = String(data.get(\"model\") || \"\").trim();\n\n if (!name) {\n showError(\"Profile name is required\");\n\n return;\n }\n\n const profile = {\n id: ulid(),\n name,\n providerId: providerId || undefined,\n model: model || undefined,\n enabledToolNames: [...toolsStore.enabledToolNames],\n customTools: [...toolsStore.customTools],\n systemPromptOverride: toolsStore.systemPromptOverride,\n };\n\n await toolsStore.addProfile(db, profile);\n await toolsStore.activateProfile(db, profile.id);\n showSuccess(`Profile \"${name}\" created and activated`);\n\n const profileDialog = this.shadowRoot?.querySelector(\n \".tools__profile-dialog\",\n ) as HTMLDialogElement | null;\n profileDialog?.close();\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTools);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,qBAAqB,IAAI,IAAI,iBAAiB,KAAK,MAAM,EAAE,IAAI,CAAC;AAEtE,MAAM,cAAc;AACpB,IAAa,kBAAb,cAAqC,kBAAkB;CACrD,OAAO,SAASA;CAChB,OAAO,WAAWC;CAClB,wBAA+C;CAE/C,eAAoC;CAEpC,cAAc;EACZ,MAAM;CACR;CAEA,MAAM,oBAAoB;EACxB,MAAM,KAAK,MAAM,MAAM;EACvB,KAAK,eAAe,kBAAkB;EAEtC,MAAM,WAAW,wBAAwB,EAAE;EAC3C,KAAK,aAAa,EAAE;EACpB,KAAK,mBAAmB,EAAE;CAC5B;CAEA,uBAAuB;EACrB,MAAM,qBAAqB;CAC7B;CAEA,mBAAmB,IAAwB;EACzC,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAIF,KAAK,cAAc,kBAAkB,CAAC,EAAE,iBAAiB,eAAe;GACtE,KAAK,cACH,IAAI,YAAY,iBAAiB;IAAE,SAAS;IAAM,UAAU;GAAK,CAAC,CACpE;EACF,CAAC;EAGD,KAAK,cAAc,iBAAiB,CAAC,EAAE,iBAAiB,eAAe;GACrE,MAAM,SAAS,KAAK,cAAc,QAAQ;GAC1C,IAAI,QAAQ;IAIV,AAHa,KAAK,cAChB,qBAEC,CAAC,EAAE,MAAM;IACZ,OAAO,UAAU;GACnB;EACF,CAAC;EAGD,KAAK,cAAc,oBAAoB,CAAC,EAAE,iBAAiB,eAAe;GACxE,KAAK,aAAa;EACpB,CAAC;EAGD,MAAM,eAAe,KAAK,cAAc,wBAAwB;EAChE,KAAK,cAAc,qBAAqB,CAAC,EAAE,iBAAiB,eAAe;GACzE,IAAI,wBAAwB,kBAC1B,aAAa,MAAM;EAEvB,CAAC;EACD,cAAc,iBAAiB,WAAW,MAAM;GAC9C,IAAI,EAAE,kBAAkB,kBACtB,KAAK,cAAc,IAAI,EAAE,MAAM;EAEnC,CAAC;EAGD,KACG,cAAc,wBAAwB,CAAC,EACtC,iBAAiB,eAAe;GAChC,MAAM,WAAW,WAAW,SAAS,KAAK,MAAM,EAAE,IAAI;GACtD,WAAW,cAAc,IAAI,QAAQ;GACrC,MAAM,YAAY,WAAW,iBAAiB,KAAK,MAAM,EAAE,IAAI;GAC/D,WAAW,yBAAyB,IAAI,SAAS;GACjD,SAAS,mBAAmB;EAC9B,CAAC;EAEH,KACG,cAAc,yBAAyB,CAAC,EACvC,iBAAiB,eAAe;GAChC,WAAW,cAAc,IAAI,CAAC,CAAC;GAC/B,WAAW,yBAAyB,IAAI,CAAC,CAAC;GAC1C,SAAS,oBAAoB;EAC/B,CAAC;EAGH,MAAM,eAAe,KAAK,cACxB,uBACF;EACA,IAAI,cACF,aAAa,iBAAiB,UAAU,YAAY;GAClD,MAAM,eACJ,KAAK,gBAAgB,kBAAkB;GACzC,IAAI,CAAC,cAAc;IACjB,aAAa,UAAU;IACvB,UAAU,2BAA2B;IAErC;GACF;GAEA,MAAM,OAAO,aAAa;GAC1B,IAAI;IACF,MAAM,sBAAsB,cAAc,IAAI,MAAM,EAAE,aAAa,CAAC;IACpE,SACE,OACI,qCACA,mCACN;GACF,SAAS,KAAK;IACZ,aAAa,UAAU,CAAC;IACxB,UACE,oCACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAIH,MAAM,uBAAuB,KAAK,cAChC,gCACF;EACA,IAAI,sBACF,qBAAqB,iBAAiB,UAAU,YAAY;GAC1D,MAAM,OAAO,qBAAqB;GAClC,IAAI;IACF,MAAM,kBAAkB,4BAA4B,IAAI,IAAI;IAC5D,SACE,OACI,+DACA,6DACN;GACF,SAAS,KAAK;IACZ,qBAAqB,UAAU,CAAC;IAChC,UACE,6CACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAIH,MAAM,0BAA0B,KAAK,cACnC,gCACF;EACA,yBAAyB,iBAAiB,UAAU,YAAY;GAC9D,IAAI;IACF,MAAM,WAAW,qBACf,IACA,wBAAwB,OAC1B;IACA,SACE,wBAAwB,UACpB,mCACA,iCACN;GACF,SAAS,KAAK;IACZ,wBAAwB,UAAU,CAAC,wBAAwB;IAC3D,UACE,8CACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAGD,KACG,cAAc,8BAA8B,CAAC,EAC5C,iBAAiB,SAAS,YAAY;GACtC,MAAM,oBAAoB,KAAK,cAC7B,0CACF;GACA,MAAM,uBAAuB,KAAK,cAChC,6CACF;GACA,MAAM,gBAAgB,KAAK,cACzB,qCACF;GAEA,MAAM,eAAe,SAAS,mBAAmB,SAAS,IAAI,EAAE;GAChE,MAAM,kBAAkB,SAAS,sBAAsB,SAAS,IAAI,EAAE;GACtE,MAAM,WAAW,eAAe,SAAS;GAEzC,IAAI;IACF,IAAI,CAAC,MAAM,YAAY,KAAK,eAAe,GACzC,MAAM,WAAW,2BAA2B,IAAI,YAAY;IAE9D,IAAI,CAAC,MAAM,eAAe,KAAK,kBAAkB,GAC/C,MAAM,WAAW,8BAA8B,IAAI,eAAe;IAEpE,MAAM,WAAW,uBAAuB,IAAI,QAAQ;IACpD,YAAY,6BAA6B;GAC3C,SAAS,KAAK;IACZ,UACE,yCACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAGH,KACG,cAAc,4BAA4B,CAAC,EAC1C,iBAAiB,SAAS,YAAY;GACtC,MAAM,gBAAgB,KAAK,cACzB,mCACF;GACA,MAAM,iBAAiB,KAAK,cAC1B,6BACF;GAEA,MAAM,WAAW,eAAe,MAAM,KAAK,KAAK;GAChD,MAAM,YACJ,gBAAgB,MAAM,KAAK,KAC3B;GAEF,IAAI;IACF,MAAM,WAAW,qBAAqB,IAAI,QAAQ;IAClD,MAAM,WAAW,gBAAgB,IAAI,SAAS;IAC9C,YAAY,2BAA2B;GACzC,SAAS,KAAK;IACZ,UACE,uCACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAGH,MAAM,mBAAmB,KAAK,cAC5B,qBACF;EACA,IAAI,kBACF,iBAAiB,iBAAiB,UAAU,YAAY;GACtD,MAAM,eACJ,KAAK,gBAAgB,kBAAkB;GACzC,IAAI,CAAC,cACH;GAGF,MAAM,OAAO,iBAAiB;GAC9B,IAAI;IACF,MAAM,cAAc,cAAc,IAAI,MAAM,EAAE,aAAa,CAAC;IAC5D,SAAS,sBAAsB,MAAM;GACvC,SAAS,KAAK;IACZ,UACE,iCACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAEnD;GACF;EACF,CAAC;EAIH,KACG,cAAc,yBAAyB,CAAC,EACvC,iBAAiB,eAAe;GAChC,MAAM,WAAW,KAAK,cAAc,qBAAqB;GACzD,IAAI,oBAAoB,qBAAqB;IAC3C,WAAW,wBAAwB,IAAI,SAAS,KAAK;IACrD,YAAY,8BAA8B;GAC5C;EACF,CAAC;EAGH,KACG,cAAc,0BAA0B,CAAC,EACxC,iBAAiB,eAAe;GAChC,MAAM,WAAW,KAAK,cAAc,qBAAqB;GACzD,IAAI,oBAAoB,qBAAqB;IAC3C,SAAS,QAAQ;IACjB,WAAW,wBAAwB,IAAI,EAAE;IACzC,YAAY,gCAAgC;GAC9C;EACF,CAAC;EAGH,MAAM,SAAS,KAAK,cAClB,gBACF;EACA,MAAM,WAAW,QAAQ,cAAc,sBAAsB;EAC7D,MAAM,YAAY,QAAQ,cAAc,oBAAoB;EAC5D,MAAM,OAAO,KAAK,cAChB,qBACF;EAEA,UAAU,iBAAiB,eAAe,QAAQ,MAAM,CAAC;EACzD,WAAW,iBAAiB,eAAe,QAAQ,MAAM,CAAC;EAE1D,QAAQ,iBAAiB,UAAU,MAAM;GACvC,IAAI,EAAE,WAAW,QACf,OAAO,MAAM;EAEjB,CAAC;EAED,MAAM,iBAAiB,WAAW,MAAM;GACtC,EAAE,eAAe;GACjB,IAAI,MACF,KAAK,cAAc,IAAI,IAAI;EAE/B,CAAC;EAGD,MAAM,cAAc,KAAK,cACvB,sBACF;EACA,MAAM,gBAAgB,KAAK,cAAc,4BAA4B;EACrE,MAAM,iBAAiB,KAAK,cAAc,0BAA0B;EACpE,MAAM,YAAY,KAAK,cACrB,2BACF;EAEA,eAAe,iBAAiB,eAAe,aAAa,MAAM,CAAC;EACnE,gBAAgB,iBAAiB,eAAe,aAAa,MAAM,CAAC;EACpE,aAAa,iBAAiB,UAAU,MAAM;GAC5C,IAAI,EAAE,WAAW,aACf,YAAY,MAAM;EAEtB,CAAC;EAED,WAAW,iBAAiB,WAAW,MAAM;GAC3C,EAAE,eAAe;GACjB,IAAI,WACF,KAAK,gBAAgB,IAAI,SAAS;EAEtC,CAAC;EAGD,MAAM,gBAAgB,KAAK,cACzB,wBACF;EACA,MAAM,kBAAkB,KAAK,cAAc,8BAA8B;EACzE,MAAM,mBAAmB,KAAK,cAAc,4BAA4B;EACxE,MAAM,cAAc,KAAK,cACvB,6BACF;EAEA,iBAAiB,iBAAiB,eAAe,eAAe,MAAM,CAAC;EACvE,kBAAkB,iBAAiB,eAAe,eAAe,MAAM,CAAC;EACxE,eAAe,iBAAiB,UAAU,MAAM;GAC9C,IAAI,EAAE,WAAW,eACf,cAAc,MAAM;EAExB,CAAC;EAED,aAAa,iBAAiB,WAAW,MAAM;GAC7C,EAAE,eAAe;GACjB,IAAI,aACF,KAAK,kBAAkB,IAAI,WAAW;EAE1C,CAAC;EAID,AADsB,KAAK,cAAc,wBAC7B,CAAC,EAAE,iBAAiB,WAAW,MAAM;GAE/C,MAAM,QADS,EAAE,OACI;GACrB,IAAI,OAAO;IACT,WAAW,gBAAgB,IAAI,KAAK;IACpC,SAAS,mBAAmB;GAC9B,OAAO;IACL,WAAW,kBAAkB,EAAE;IAC/B,SAAS,qBAAqB;GAChC;EACF,CAAC;EAGD,KACG,cAAc,yBAAyB,CAAC,EACvC,iBAAiB,eAAe;GAChC,IAAI,iBAAiB,aAAa;IAChC,YAAY,MAAM;IAElB,MAAM,iBAAiB,YAAY,cACjC,uBACF;IACA,IAAI,gBAAgB;KAClB,eAAe,gBAAgB;KAC/B,MAAM,gBAAgB,SAAS,cAAc,QAAQ;KACrD,cAAc,QAAQ;KACtB,cAAc,cAAc;KAC5B,eAAe,OAAO,aAAa;KACnC,KAAK,MAAM,OAAO,sBAAsB,GAAG;MACzC,MAAM,IAAI,YAAY,GAAG;MACzB,IAAI,GAAG;OACL,MAAM,MAAM,SAAS,cAAc,QAAQ;OAC3C,IAAI,QAAQ;OACZ,IAAI,cAAc,EAAE;OACpB,eAAe,YAAY,GAAG;MAChC;KACF;IACF;IAEA,AAAC,cAAoC,UAAU;GACjD;EACF,CAAC;EAGH,KACG,cAAc,0BAA0B,CAAC,EACxC,iBAAiB,SAAS,YAAY;GAEtC,IADiB,WAAW,iBACd;IACZ,MAAM,WAAW,oBAAoB,EAAE;IACvC,YAAY,eAAe;GAC7B,OAEE,KACG,cAAc,yBAAyB,CAAC,EACvC,cAAc,IAAI,MAAM,OAAO,CAAC;EAExC,CAAC;EAGH,KACG,cAAc,4BAA4B,CAAC,EAC1C,iBAAiB,SAAS,YAAY;GACtC,MAAM,WAAW,WAAW;GAC5B,IAAI,CAAC,UAAU;IACb,SAAS,qBAAqB;IAE9B;GACF;GAEA,IAAI,SAAS,WAAW,YAAY,GAAG;IACrC,SAAS,qCAAqC;IAE9C;GACF;GAEA,MAAM,WAAW,cAAc,IAAI,QAAQ;GAC3C,YAAY,iBAAiB;EAC/B,CAAC;EAGH,MAAM,eAAe,KAAK,cACxB,uBACF;EACA,MAAM,iBAAiB,KAAK,cAAc,6BAA6B;EACvE,MAAM,kBAAkB,KAAK,cAAc,2BAA2B;EACtE,MAAM,aAAa,KAAK,cACtB,4BACF;EACA,MAAM,iBAAiB,KAAK,cAAc,0BAA0B;EAEpE,KAAK,cAAc,oBAAoB,CAAC,EAAE,iBAAiB,eAAe;GACxE,IAAI,gBAAgB,YAAY;IAC9B,WAAW,MAAM;IACjB,KAAK,uBAAuB;IAC5B,aAAa,UAAU;GACzB;EACF,CAAC;EAED,gBAAgB,iBAAiB,eAAe,cAAc,MAAM,CAAC;EACrE,iBAAiB,iBAAiB,eAAe,cAAc,MAAM,CAAC;EACtE,cAAc,iBAAiB,UAAU,MAAM;GAC7C,IAAI,EAAE,WAAW,cACf,aAAa,MAAM;EAEvB,CAAC;EAED,KAAK,iBAAiB,oBAAoB,CAAC,CAAC,SAAS,QAAQ;GAC3D,IAAI,iBAAiB,eAAe;IAClC,MAAM,MAAO,IAAoB,QAAQ;IACzC,MAAM,QAAQ,KAAK,cACjB,0BACF;IACA,IAAI,SAAS,KAAK;KAChB,MAAM,QAAQ;KACd,KAAK,gBAAgB,IAAI,GAAG;IAC9B;GACF,CAAC;EACH,CAAC;EAED,gBAAgB,iBAAiB,eAAe;GAC9C,MAAM,QAAQ,KAAK,cACjB,0BACF;GACA,IAAI,SAAS,MAAM,MAAM,KAAK,GAC5B,KAAK,gBAAgB,IAAI,MAAM,MAAM,KAAK,CAAC;EAE/C,CAAC;EAED,YAAY,iBAAiB,WAAW,MAAM;GAC5C,EAAE,eAAe;GACjB,IAAI,YACF,KAAK,mBAAmB,IAAI,UAAU;EAE1C,CAAC;CACH;CAEA,eAAe;EACb,MAAM,OAAO,WAAW,aAAa;EACrC,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,mBAAmB,CAAC;EAC1D,MAAM,MAAM,IAAI,gBAAgB,IAAI;EACpC,MAAM,IAAI,SAAS,cAAc,GAAG;EACpC,EAAE,OAAO;EACT,EAAE,WAAW,oBAAoB,KAAK,IAAI,EAAE;EAC5C,EAAE,MAAM;EACR,IAAI,gBAAgB,GAAG;EACvB,YAAY,uBAAuB;CACrC;;;;CAKA,gBAAgB,gBAAwB;EACtC,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,cAAc,KAAK,cACvB,sBACF;EACA,MAAM,YAAY,KAAK,cACrB,2BACF;EACA,IAAI,CAAC,eAAe,CAAC,WACnB;EAGF,UAAU,MAAM;EAChB,MAAM,cAAc,UAAU,cAC5B,mBACF;EACA,IAAI,aACF,YAAY,QAAQ;EAGtB,YAAY,UAAU;CACxB;CAEA,oBAAoB,UAA0B;EAC5C,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MAAM;EAEX,MAAM,UAAU,KAAK,cAAc,wBAAwB;EAC3D,IAAI,CAAC,SAAS;EACd,QAAQ,gBAAgB;EAGxB,MAAM,QAAQ,SAAS,SAAS,CAAC;EACjC,IAAI,MAAM,SAAS,GAAG;GACpB,MAAM,WAAW,SAAS,cAAc,KAAK;GAC7C,SAAS,YAAY;GAErB,MAAM,SAAS,SAAS,cAAc,KAAK;GAC3C,OAAO,YAAY;GACnB,OAAO,cAAc,cAAc,MAAM,OAAO;GAChD,SAAS,YAAY,MAAM;GAE3B,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IAEjB,MAAM,aAAa,SAAS,cAAc,KAAK;IAC/C,WAAW,YAAY;IAEvB,MAAM,WAAW,SAAS,cAAc,OAAO;IAC/C,SAAS,OAAO;IAChB,SAAS,OAAO;IAChB,SAAS,QAAQ,KAAK;IACtB,SAAS,UAAU;IACnB,SAAS,KAAK,eAAe,KAAK;IAClC,WAAW,YAAY,QAAQ;IAE/B,MAAM,aAAa,SAAS,cAAc,OAAO;IACjD,WAAW,UAAU,SAAS;IAC9B,WAAW,YAAY;IACvB,WAAW,cAAc,KAAK;IAC9B,WAAW,YAAY,UAAU;IAEjC,MAAM,QAAQ,SAAS,cAAc,MAAM;IAC3C,MAAM,YAAY;IAClB,MAAM,cAAc,KAAK,iBAAiB;IAC1C,WAAW,YAAY,KAAK;IAE5B,KAAK,YAAY,UAAU;IAE3B,IAAI,KAAK,aAAa;KACpB,MAAM,OAAO,SAAS,cAAc,KAAK;KACzC,KAAK,YAAY;KACjB,KAAK,cAAc,KAAK;KACxB,KAAK,YAAY,IAAI;IACvB;IAEA,SAAS,YAAY,IAAI;GAC3B;GAEA,QAAQ,YAAY,QAAQ;EAC9B;EAGA,MAAM,SAAS,SAAS,UAAU,CAAC;EACnC,IAAI,OAAO,SAAS,GAAG;GACrB,MAAM,WAAW,SAAS,cAAc,KAAK;GAC7C,SAAS,YAAY;GAErB,MAAM,SAAS,SAAS,cAAc,KAAK;GAC3C,OAAO,YAAY;GACnB,OAAO,cAAc,oBAAoB,OAAO,OAAO;GACvD,SAAS,YAAY,MAAM;GAE3B,KAAK,MAAM,SAAS,QAAQ;IAC1B,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IAEjB,MAAM,aAAa,SAAS,cAAc,KAAK;IAC/C,WAAW,YAAY;IAEvB,MAAM,WAAW,SAAS,cAAc,OAAO;IAC/C,SAAS,OAAO;IAChB,SAAS,OAAO;IAChB,SAAS,QAAQ,MAAM;IACvB,SAAS,UAAU;IACnB,SAAS,KAAK,gBAAgB,MAAM;IACpC,WAAW,YAAY,QAAQ;IAE/B,MAAM,aAAa,SAAS,cAAc,OAAO;IACjD,WAAW,UAAU,SAAS;IAC9B,WAAW,YAAY;IACvB,WAAW,cAAc,MAAM;IAC/B,WAAW,YAAY,UAAU;IAEjC,MAAM,QAAQ,SAAS,cAAc,MAAM;IAC3C,MAAM,YAAY;IAClB,MAAM,cAAc;IACpB,WAAW,YAAY,KAAK;IAE5B,KAAK,YAAY,UAAU;IAE3B,IAAI,MAAM,aAAa;KACrB,MAAM,OAAO,SAAS,cAAc,KAAK;KACzC,KAAK,YAAY;KACjB,KAAK,cAAc,MAAM;KACzB,KAAK,YAAY,IAAI;IACvB;IAEA,SAAS,YAAY,IAAI;GAC3B;GAEA,QAAQ,YAAY,QAAQ;EAC9B;EAGA,MAAM,UAAU,SAAS,WAAW,CAAC;EACrC,IAAI,QAAQ,SAAS,GAAG;GACtB,MAAM,WAAW,SAAS,cAAc,KAAK;GAC7C,SAAS,YAAY;GAErB,MAAM,SAAS,SAAS,cAAc,KAAK;GAC3C,OAAO,YAAY;GACnB,OAAO,cAAc,yBAAyB,QAAQ,OAAO;GAC7D,SAAS,YAAY,MAAM;GAE3B,KAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IAEjB,MAAM,aAAa,SAAS,cAAc,KAAK;IAC/C,WAAW,YAAY;IAEvB,MAAM,WAAW,SAAS,cAAc,OAAO;IAC/C,SAAS,OAAO;IAChB,SAAS,OAAO;IAChB,SAAS,QAAQ,OAAO;IACxB,SAAS,UAAU;IACnB,SAAS,KAAK,iBAAiB,OAAO;IACtC,WAAW,YAAY,QAAQ;IAE/B,MAAM,aAAa,SAAS,cAAc,OAAO;IACjD,WAAW,UAAU,SAAS;IAC9B,WAAW,YAAY;IACvB,WAAW,cAAc,OAAO;IAChC,WAAW,YAAY,UAAU;IAEjC,MAAM,QAAQ,SAAS,cAAc,MAAM;IAC3C,MAAM,YAAY;IAClB,MAAM,cAAc;IACpB,WAAW,YAAY,KAAK;IAE5B,KAAK,YAAY,UAAU;IAE3B,IAAI,OAAO,aAAa;KACtB,MAAM,OAAO,SAAS,cAAc,KAAK;KACzC,KAAK,YAAY;KACjB,KAAK,cAAc,OAAO;KAC1B,KAAK,YAAY,IAAI;IACvB;IAEA,SAAS,YAAY,IAAI;GAC3B;GAEA,QAAQ,YAAY,QAAQ;EAC9B;CACF;CAEA,yBAAyB;EACvB,KAAK,wBAAwB;EAC7B,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,KAAK,cACpB,gCACF;EACA,IAAI,UAAU,SAAS,SAAS;EAEhC,MAAM,WAAW,KAAK,cAAc,0BAA0B;EAC9D,IAAI,UAAU,SAAS,cAAc;EAErC,MAAM,WAAW,KAAK,cAAc,0BAA0B;EAC9D,IAAI,UAAU,SAAS,cAAc;EAErC,MAAM,UAAU,KAAK,cAAc,wBAAwB;EAC3D,IAAI,SAAS,QAAQ,gBAAgB;EAErC,MAAM,YAAY,KAAK,cACrB,2BACF;EACA,IAAI,WAAW,UAAU,WAAW;CACtC;CAEA,aAAa,IAAwB;EACnC,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAIF,KAAK,WACH,aAAa;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,KAAK,eAAe,EAAE;EACxB,CAAC,CACH;EAGA,MAAM,eAAe,KAAK,cACxB,uBACF;EACA,MAAM,uBAAuB,KAAK,cAChC,gCACF;EACA,MAAM,mBAAmB,KAAK,cAC5B,qBACF;EAEA,IAAI,cAEF,KAAK,WACH,aAAa;GACX,IAAI,kBAAkB,OAAO;IAC3B,KAAK,eAAe,kBAAkB;IACtC,aAAa,UACX,KAAK,cAAc,uBAAuB;IAC5C,IAAI,oBAAoB,KAAK,cAC3B,iBAAiB,QAAQ,cAAc,KAAK;GAEhD;EACF,CAAC,CACH;EAGF,IAAI,sBACF,KAAK,WACH,aAAa;GACX,qBAAqB,UACnB,kBAAkB;EACtB,CAAC,CACH;EAIF,MAAM,uBAAuB,KAAK,cAChC,gCACF;EACA,MAAM,yBAAyB,KAAK,cAClC,mCACF;EACA,MAAM,oBAAoB,KAAK,cAC7B,6BACF;EAEA,IAAI,sBACF,KAAK,WACH,aAAa;GACX,qBAAqB,UAAU,WAAW;EAC5C,CAAC,CACH;EAGF,IAAI,wBACF,KAAK,WACH,aAAa;GACX,IACE,SAAS,kBAAkB,0BAC3B,CAAC,uBAAuB,QAAQ,QAAQ,GAExC,uBAAuB,QAAQ,WAAW;EAE9C,CAAC,CACH;EAGF,IAAI,mBACF,KAAK,WACH,aAAa;GACX,IACE,SAAS,kBAAkB,qBAC3B,CAAC,kBAAkB,QAAQ,QAAQ,GAEnC,kBAAkB,QAAQ,WAAW;EAEzC,CAAC,CACH;EAIF,MAAM,+BAA+B,KAAK,cACxC,0CACF;EACA,MAAM,kCAAkC,KAAK,cAC3C,6CACF;EACA,MAAM,2BAA2B,KAAK,cACpC,qCACF;EAEA,IAAI,8BACF,KAAK,WACH,aAAa;GACX,IACE,SAAS,kBAAkB,gCAC3B,CAAC,6BAA6B,QAAQ,QAAQ,GAE9C,6BAA6B,QAAQ,OACnC,WAAW,uBACb;EAEJ,CAAC,CACH;EAGF,IAAI,iCACF,KAAK,WACH,aAAa;GACX,IACE,SAAS,kBAAkB,mCAC3B,CAAC,gCAAgC,QAAQ,QAAQ,GAEjD,gCAAgC,QAAQ,OACtC,WAAW,0BACb;EAEJ,CAAC,CACH;EAGF,IAAI,0BACF,KAAK,WACH,aAAa;GACX,IACE,SAAS,kBAAkB,4BAC3B,CAAC,yBAAyB,QAAQ,QAAQ,GAE1C,yBAAyB,QAAQ,WAAW;EAEhD,CAAC,CACH;CAEJ;;CAGA,wBAAwB;EACtB,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,SAAS,KAAK,cAAc,wBAAwB;EAC1D,IAAI,CAAC,QACH;EAGF,MAAM,WAAW,WAAW;EAC5B,MAAM,WAAW,WAAW;EAG5B,OAAO,gBAAgB;EACvB,MAAM,gBAAgB,SAAS,cAAc,QAAQ;EACrD,cAAc,QAAQ;EACtB,cAAc,cAAc;EAC5B,OAAO,OAAO,aAAa;EAC3B,KAAK,MAAM,KAAK,UAAU;GACxB,MAAM,MAAM,SAAS,cAAc,QAAQ;GAC3C,IAAI,QAAQ,EAAE;GACd,MAAM,YAAY,EAAE,GAAG,WAAW,YAAY;GAC9C,MAAM,gBAAgB,EAAE,aACpB,YAAY,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,aACrC;GACJ,MAAM,aAAa,EAAE,SAAS;GAC9B,IAAI,cAAc,YACd,KAAK,EAAE,KAAK,IAAI,cAAc,KAC9B,GAAG,EAAE,KAAK,IAAI,cAAc,KAAK,WAAW;GAChD,IAAI,EAAE,OAAO,UACX,IAAI,WAAW;GAGjB,OAAO,YAAY,GAAG;EACxB;EAGA,MAAM,YAAY,KAAK,cACrB,4BACF;EACA,IAAI,WAAW;GACb,MAAM,kBAAkB,UAAU,WAAW,YAAY;GACzD,UAAU,WAAW,CAAC,CAAC;GACvB,UAAU,QAAQ,kBACd,wCACA;EACN;CACF;CAEA,eAAe,IAAwB;EACrC,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,OAAO,KAAK,cAAc,cAAc;EAC9C,IAAI,CAAC,MACH;EAGF,MAAM,UAAU,WAAW;EAC3B,MAAM,WAAW,WAAW;EAC5B,MAAM,mBAAmB,WAAW;EAEpC,MAAM,qBAAqB,KAAK,iBAC9B,kCACF;EACA,MAAM,oBAAoB,MAAM,KAAK,kBAAkB,CAAC,CAAC,KACtD,OAAO,GAAG,aAAa,WAAW,KAAK,EAC1C;EACA,MAAM,kBAAkB,CACtB,GAAG,SAAS,KAAK,MAAM,EAAE,IAAI,GAC7B,GAAG,iBAAiB,KAAK,MAAM,EAAE,IAAI,CACvC;EAMA,IAHE,kBAAkB,WAAW,gBAAgB,UAC7C,kBAAkB,OAAO,MAAM,MAAM,SAAS,gBAAgB,EAAE,GAGhE,KAAK,MAAM,MAAM,oBAAoB;GACnC,MAAM,WAAW,GAAG,aAAa,WAAW;GAC5C,IAAI,CAAC,UAAU;GAEf,MAAM,YADgB,iBAAiB,MAAM,MAAM,EAAE,SAAS,QAChC,IAC1B,WAAW,yBAAyB,QAAQ,IAC5C,QAAQ,IAAI,QAAQ;GACxB,IAAI,GAAG,YAAY,WACjB,GAAG,UAAU;EAEjB;OACK;GACL,KAAK,gBAAgB;GAErB,KAAK,MAAM,QAAQ,UAAU;IAC3B,MAAM,WAAW,CAAC,mBAAmB,IAAI,KAAK,IAAI;IAClD,MAAM,YAAY,QAAQ,IAAI,KAAK,IAAI;IACvC,MAAM,QAAQ,KAAK,YAAY,MAAM,IAAI,CAAC,CAAC;IAE3C,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,aAAa,QAAQ,UAAU;IAEpC,MAAM,WAAW,SAAS,cAAc,OAAO;IAC/C,SAAS,OAAO;IAChB,SAAS,YAAY;IACrB,SAAS,aAAa,aAAa,KAAK,IAAI;IAC5C,SAAS,aAAa,cAAc,UAAU,KAAK,MAAM;IACzD,SAAS,UAAU;IAEnB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IAEjB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,cAAc,KAAK;IAExB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,aAAa,SAAS,KAAK,WAAW;IAC3C,KAAK,cAAc;IACnB,KAAK,OAAO,MAAM,IAAI;IAEtB,MAAM,WAAW,SAAS,cAAc,QAAQ;IAChD,SAAS,YAAY;IACrB,SAAS,aAAa,cAAc,KAAK,IAAI;IAC7C,SAAS,aAAa,cAAc,SAAS,KAAK,MAAM;IACxD,SAAS,aAAa,SAAS,YAAY;IAC3C,SAAS,cAAc;IAEvB,KAAK,OAAO,UAAU,IAAI;IAE1B,IAAI,UAAU;KACZ,MAAM,QAAQ,SAAS,cAAc,MAAM;KAC3C,MAAM,YAAY;KAClB,MAAM,cAAc;KACpB,KAAK,OAAO,KAAK;IACnB;IAEA,KAAK,OAAO,QAAQ;IAEpB,IAAI,YAAsC;IAC1C,IAAI,UAAU;KACZ,YAAY,SAAS,cAAc,QAAQ;KAC3C,UAAU,YAAY;KACtB,UAAU,aAAa,eAAe,KAAK,IAAI;KAC/C,UAAU,aAAa,cAAc,UAAU,KAAK,MAAM;KAC1D,UAAU,cAAc;KACxB,KAAK,OAAO,SAAS;IACvB;IAGA,UAAU,iBAAiB,gBAAgB;KACzC,WAAW,eAAe,IAAI,KAAK,MAAM,SAAS,OAAO;IAC3D,CAAC;IAGD,UAAU,iBAAiB,eAAe;KACxC,KAAK,gBAAgB,KAAK,IAAI;IAChC,CAAC;IAGD,WAAW,iBAAiB,eAAe;KACzC,WAAW,iBAAiB,IAAI,KAAK,IAAI;KACzC,SAAS,wBAAwB,KAAK,MAAM;IAC9C,CAAC;IAED,KAAK,YAAY,IAAI;GACvB;GAEA,KAAK,MAAM,QAAQ,kBAAkB;IACnC,MAAM,YAAY,WAAW,yBAAyB,KAAK,IAAI;IAC/D,MAAM,QAAQ,KAAK,YAAY,MAAM,IAAI,CAAC,CAAC;IAE3C,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,aAAa,QAAQ,UAAU;IAEpC,MAAM,WAAW,SAAS,cAAc,OAAO;IAC/C,SAAS,OAAO;IAChB,SAAS,YAAY;IACrB,SAAS,aAAa,aAAa,KAAK,IAAI;IAC5C,SAAS,aAAa,cAAc,UAAU,KAAK,MAAM;IACzD,SAAS,UAAU;IAEnB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IAEjB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,cAAc,KAAK;IAExB,MAAM,OAAO,SAAS,cAAc,KAAK;IACzC,KAAK,YAAY;IACjB,KAAK,aAAa,SAAS,KAAK,WAAW;IAC3C,KAAK,cAAc;IACnB,KAAK,OAAO,MAAM,IAAI;IAEtB,MAAM,QAAQ,SAAS,cAAc,MAAM;IAC3C,MAAM,YAAY;IAClB,MAAM,cAAc;IACpB,KAAK,OAAO,UAAU,MAAM,KAAK;IAEjC,SAAS,iBAAiB,gBAAgB;KACxC,WAAW,0BAA0B,IAAI,KAAK,MAAM,SAAS,OAAO;IACtE,CAAC;IAED,KAAK,YAAY,IAAI;GACvB;EACF;EAGA,MAAM,UAAU,KAAK,cAAc,eAAe;EAClD,IAAI,SAMF,QAAQ,cAAc,IALO,WAAW,gBAAgB,CAAC,EAAC,CAAE,UAC3B,WAAW,2BAA2B,CAAC,EAAC,CACtE,OAGmC,MADnB,SAAS,SAAS,iBAAiB,OACC;EAIzD,MAAM,WAAW,KAAK,cAAc,qBAAqB;EACzD,IACE,oBAAoB,uBACpB,SAAS,kBAAkB,YAC3B,CAAC,SAAS,QAAQ,QAAQ,GAE1B,SAAS,QAAQ,WAAW;EAI9B,KAAK,sBAAsB;CAC7B;CAEA,MAAM,cAAc,IAAwB,MAAuB;EACjE,MAAM,OAAO,IAAI,SAAS,IAAI;EAC9B,MAAM,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KAAK;EACjD,MAAM,cAAc,OAAO,KAAK,IAAI,aAAa,KAAK,EAAE,CAAC,CAAC,KAAK;EAC/D,MAAM,YAAY,OAAO,KAAK,IAAI,cAAc,KAAK,EAAE,CAAC,CAAC,KAAK;EAE9D,IAAI,CAAC,QAAQ,CAAC,aAAa;GACzB,UAAU,mCAAmC;GAE7C;EACF;EAGA,IAAI,WAAW,SAAS,MAAM,MAAM,EAAE,SAAS,IAAI,GAAG;GACpD,UAAU,iBAAiB,KAAK,iBAAiB;GAEjD;EACF;EAEA,IAAI,eAAe;GAAE,MAAM;GAAU,YAAY,CAAC;EAAE;EACpD,IAAI,WACF,IAAI;GACF,eAAe,KAAK,MAAM,SAAS;EACrC,QAAQ;GACN,UAAU,8BAA8B;GAExC;EACF;EAGF,MAAM,WAAW,cAAc,IAAI;GAAE;GAAM;GAAa;EAAa,CAAC;EACtE,YAAY,sBAAsB,MAAM;EAKxC,CAHe,KAAK,YAAY,cAC9B,gBACF,EACM,EAAE,MAAM;CAChB;CAEA,MAAM,gBAAgB,IAAwB,MAAuB;EACnE,MAAM,OAAO,IAAI,SAAS,IAAI;EAC9B,MAAM,iBAAiB,OAAO,KAAK,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,KAAK;EAC7D,MAAM,UAAU,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KAAK;EACpD,MAAM,UAAU,OAAO,KAAK,IAAI,aAAa,KAAK,EAAE,CAAC,CAAC,KAAK;EAE3D,IAAI,CAAC,kBAAkB,CAAC,SAAS;GAC/B,UAAU,uCAAuC;GAEjD;EACF;EAQA,IAAI,CAAC,MANY,WAAW,UAC1B,IACA,gBACA,SACA,WAAW,MACb,GACS;GACP,UACE,2CAA2C,QAAQ,kBACrD;GAEA;EACF;EAEA,YAAY,WAAW,eAAe,OAAO,QAAQ,EAAE;EAIvD,CAHoB,KAAK,YAAY,cACnC,sBACF,EACW,EAAE,MAAM;CACrB;CAEA,MAAM,gBAAgB,KAAyB,KAAa;EAC1D,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MAAM;EAEX,MAAM,WAAW,KAAK,cACpB,0BACF;EACA,MAAM,WAAW,UAAU,eAAe;EAC1C,IAAI,UAAU;GACZ,SAAS,WAAW;GACpB,SAAS,cAAc;EACzB;EAEA,IAAI;GACF,MAAM,WAAW,MAAM,WAAW,6BAA6B,GAAG;GAClE,KAAK,wBAAwB,SAAS;GAEtC,MAAM,WAAW,KAAK,cAAc,0BAA0B;GAC9D,IAAI,UACF,SAAS,cAAc,SAAS,SAAS,QAAQ;GAEnD,MAAM,WAAW,KAAK,cAAc,0BAA0B;GAC9D,IAAI,UACF,SAAS,cACP,SAAS,SAAS,eAAe;GAGrC,KAAK,oBAAoB,SAAS,QAAQ;GAE1C,MAAM,WAAW,KAAK,cACpB,gCACF;GACA,IAAI,UAAU,SAAS,SAAS;GAEhC,MAAM,YAAY,KAAK,cACrB,2BACF;GACA,IAAI,WAAW,UAAU,WAAW;GAEpC,SACE,eAAe,SAAS,SAAS,SAAS,CAAC,EAAC,CAAE,OAAO,WAAW,SAAS,SAAS,UAAU,CAAC,EAAC,CAAE,OAAO,eAAe,SAAS,SAAS,MAC1I;EACF,SAAS,KAAK;GACZ,KAAK,uBAAuB;GAC5B,UACE,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAC1E;EACF,UAAU;GACR,IAAI,UAAU;IACZ,SAAS,WAAW;IACpB,SAAS,cAAc;GACzB;EACF;CACF;CAEA,MAAM,mBAAmB,IAAwB,MAAuB;EACtE,IAAI,CAAC,KAAK,uBAAuB;GAC/B,UAAU,sCAAsC;GAChD;EACF;EAEA,MAAM,WAAW,IAAI,SAAS,IAAI;EAClC,MAAM,YAAY,SAAS,OAAO,YAAY,CAAC,CAAC,IAAI,MAAM;EAC1D,MAAM,aAAa,SAAS,OAAO,aAAa,CAAC,CAAC,IAAI,MAAM;EAC5D,MAAM,cAAc,SAAS,OAAO,cAAc,CAAC,CAAC,IAAI,MAAM;EAE9D,IACE,UAAU,WAAW,KACrB,WAAW,WAAW,KACtB,YAAY,WAAW,GACvB;GACA,UAAU,8DAA8D;GACxE;EACF;EAEA,MAAM,aACH,KAAK,cAAc,4BAA4B,CAAC,EAC7C,WAAW;EACjB,MAAM,YACH,KAAK,cAAc,0BAA0B,CAAC,EAC3C,WAAW;EAEjB,MAAM,YAAY,KAAK,cACrB,2BACF;EACA,IAAI,WAAW;GACb,UAAU,WAAW;GACrB,UAAU,cAAc;EAC1B;EAEA,IAAI;GACF,MAAM,SAAS,MAAM,WAAW,qBAC9B,IACA,KAAK,uBACL;IAAE;IAAW;IAAY;GAAY,GACrC;IAAE;IAAY;GAAU,CAC1B;GAEA,MAAM,qBAAqB,OAAO,MAAM,QACrC,MAAM,EAAE,WAAW,UACtB,CAAC,CAAC;GACF,MAAM,sBAAsB,OAAO,OAAO,QACvC,MAAM,EAAE,WAAW,UACtB,CAAC,CAAC;GACF,MAAM,uBAAuB,OAAO,QAAQ,QACzC,OAAO,GAAG,WAAW,UACxB,CAAC,CAAC;GAKF,YACE,yBAHA,qBAAqB,sBAAsB,qBAGP,cAAc,KAAK,sBAAsB,QAAQ,OAAO,EAC9F;GAKA,CAHe,KAAK,YAAY,cAC9B,uBACF,EACM,EAAE,MAAM;EAChB,SAAS,KAAK;GACZ,UACE,kBAAkB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GACnE;EACF,UAAU;GACR,IAAI,WAAW;IACb,UAAU,WAAW;IACrB,UAAU,cAAc;GAC1B;EACF;CACF;CAEA,MAAM,cAAc,IAAwB,OAAyB;EACnE,MAAM,OAAO,MAAM,QAAQ;EAC3B,IAAI,CAAC,MACH;EAGF,IAAI;GACF,MAAM,OAAO,MAAM,KAAK,KAAK;GAC7B,MAAM,WAAW,aAAa,IAAI,IAAI;GACtC,YAAY,uBAAuB;EACrC,SAAS,KAAK;GACZ,UACE,sBAAsB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GACvE;EACF;EAEA,MAAM,QAAQ;CAChB;CAEA,MAAM,kBAAkB,IAAwB,MAAuB;EACrE,MAAM,OAAO,IAAI,SAAS,IAAI;EAC9B,MAAM,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,KAAK;EACjD,MAAM,aAAa,OAAO,KAAK,IAAI,YAAY,KAAK,EAAE,CAAC,CAAC,KAAK;EAC7D,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,KAAK;EAEnD,IAAI,CAAC,MAAM;GACT,UAAU,0BAA0B;GAEpC;EACF;EAEA,MAAM,UAAU;GACd,IAAI,KAAK;GACT;GACA,YAAY,cAAc;GAC1B,OAAO,SAAS;GAChB,kBAAkB,CAAC,GAAG,WAAW,gBAAgB;GACjD,aAAa,CAAC,GAAG,WAAW,WAAW;GACvC,sBAAsB,WAAW;EACnC;EAEA,MAAM,WAAW,WAAW,IAAI,OAAO;EACvC,MAAM,WAAW,gBAAgB,IAAI,QAAQ,EAAE;EAC/C,YAAY,YAAY,KAAK,wBAAwB;EAKrD,CAHsB,KAAK,YAAY,cACrC,wBACF,EACa,EAAE,MAAM;CACvB;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,aAAa,eAAe"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-tools-BjFgXNLR.js","names":["shadowClawToolsStyles","shadowClawToolsTemplate"],"sources":["../../src/components/shadow-claw-tools/shadow-claw-tools.ts"],"sourcesContent":["import { getAvailableProviders, getProvider } from \"../../config/config.js\";\nimport { effect } from \"../../core/effect.js\";\n\nimport { getDb, ShadowClawDatabase } from \"../../db/db.js\";\nimport { getWebMcpMode } from \"../../subsystems/mcp/webmcp.js\";\n\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { toolsStore } from \"../../stores/tools.js\";\n\nimport { TOOL_DEFINITIONS } from \"../../subsystems/tools/tools.js\";\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { ulid } from \"../../utils/ulid.js\";\n\nimport type { Orchestrator } from \"../../core/orchestrator/orchestrator.js\";\nimport type { RemoteManifest } from \"../../subsystems/tools/remote/types.js\";\nimport {\n setWebMcpMode,\n setWebMcpToolsEnabled,\n} from \"../../core/orchestrator/utils/syncWebMcpRegistration.js\";\n\nimport \"../common/shadow-claw-page-header-action-button/shadow-claw-page-header-action-button.js\";\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawToolsStyles from \"./shadow-claw-tools.css\" with { type: \"css\" };\nimport shadowClawToolsTemplate from \"./shadow-claw-tools.html\" with { type: \"html\" };\n\nconst BUILTIN_TOOL_NAMES = new Set(TOOL_DEFINITIONS.map((t) => t.name));\n\nconst elementName = \"shadow-claw-tools\";\nexport class ShadowClawTools extends ShadowClawElement {\n static styles = shadowClawToolsStyles;\n static template = shadowClawToolsTemplate;\n currentRemoteManifest: RemoteManifest | null = null;\n\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n\n await toolsStore.refreshDeclarativeTools(db);\n this.setupEffects(db);\n this.bindEventListeners(db);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n bindEventListeners(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n // Back button\n root.querySelector(\".tools__back-btn\")?.addEventListener(\"click\", () => {\n this.dispatchEvent(\n new CustomEvent(\"navigate-back\", { bubbles: true, composed: true }),\n );\n });\n\n // Add tool button\n root.querySelector(\".tools__add-btn\")?.addEventListener(\"click\", () => {\n const dialog = root.querySelector(\"dialog\");\n if (dialog) {\n const form = root.querySelector(\n \".tools__dialog-form\",\n ) as HTMLFormElement | null;\n form?.reset();\n dialog.showModal();\n }\n });\n\n // Backup\n root.querySelector(\".tools__backup-btn\")?.addEventListener(\"click\", () => {\n this.handleBackup();\n });\n\n // Restore\n const restoreInput = root.querySelector(\".tools__hidden-restore\");\n root.querySelector(\".tools__restore-btn\")?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.click();\n }\n });\n restoreInput?.addEventListener(\"change\", (e) => {\n if (e.target instanceof HTMLInputElement) {\n this.handleRestore(db, e.target);\n }\n });\n\n // Select all / none\n root\n .querySelector(\".tools__select-all-btn\")\n ?.addEventListener(\"click\", () => {\n const allNames = toolsStore.allTools.map((t) => t.name);\n toolsStore.setAllEnabled(db, allNames);\n const declNames = toolsStore.declarativeTools.map((t) => t.name);\n toolsStore.setAllDeclarativeEnabled(db, declNames);\n showInfo(\"All tools enabled\");\n });\n\n root\n .querySelector(\".tools__select-none-btn\")\n ?.addEventListener(\"click\", () => {\n toolsStore.setAllEnabled(db, []);\n toolsStore.setAllDeclarativeEnabled(db, []);\n showInfo(\"All tools disabled\");\n });\n\n // WebMCP toggle listener\n const webMcpToggle = root.querySelector(\n \".tools__webmcp-toggle\",\n ) as HTMLInputElement | null;\n if (webMcpToggle) {\n webMcpToggle.addEventListener(\"change\", async () => {\n const orchestrator =\n this.orchestrator ?? orchestratorStore.orchestrator;\n if (!orchestrator) {\n webMcpToggle.checked = false;\n showError(\"Orchestrator is not ready\");\n\n return;\n }\n\n const next = webMcpToggle.checked;\n try {\n await setWebMcpToolsEnabled(orchestrator, db, next, { orchestrator });\n showInfo(\n next\n ? \"WebMCP tool registration enabled\"\n : \"WebMCP tool registration disabled\",\n );\n } catch (err) {\n webMcpToggle.checked = !next;\n showError(\n `Failed to update WebMCP setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Shared full internet access toggle listener\n const internetAccessToggle = root.querySelector(\n \".tools__internet-access-toggle\",\n ) as HTMLInputElement | null;\n if (internetAccessToggle) {\n internetAccessToggle.addEventListener(\"change\", async () => {\n const next = internetAccessToggle.checked;\n try {\n await orchestratorStore.setVMBashFullInternetAccess(db, next);\n showInfo(\n next\n ? \"Full internet access enabled for Bash and JavaScript tools\"\n : \"Full internet access disabled for Bash and JavaScript tools\",\n );\n } catch (err) {\n internetAccessToggle.checked = !next;\n showError(\n `Failed to update internet access setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Web Search toggle\n const webSearchUseProxyToggle = root.querySelector(\n \".tools__websearch-proxy-toggle\",\n ) as HTMLInputElement | null;\n webSearchUseProxyToggle?.addEventListener(\"change\", async () => {\n try {\n await toolsStore.setWebSearchUseProxy(\n db,\n webSearchUseProxyToggle.checked,\n );\n showInfo(\n webSearchUseProxyToggle.checked\n ? \"Web Search local proxy enabled\"\n : \"Web Search local proxy disabled\",\n );\n } catch (err) {\n webSearchUseProxyToggle.checked = !webSearchUseProxyToggle.checked;\n showError(\n `Failed to update Web Search proxy setting: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // Search Files save button\n root\n .querySelector(\".tools__save-searchfiles-btn\")\n ?.addEventListener(\"click\", async () => {\n const maxFileBytesInput = root.querySelector(\n \".tools__searchfiles-max-file-bytes-input\",\n ) as HTMLInputElement | null;\n const maxFilesVisitedInput = root.querySelector(\n \".tools__searchfiles-max-files-visited-input\",\n ) as HTMLInputElement | null;\n const skipDirsInput = root.querySelector(\n \".tools__searchfiles-skip-dirs-input\",\n ) as HTMLInputElement | null;\n\n const maxFileBytes = parseInt(maxFileBytesInput?.value || \"\", 10);\n const maxFilesVisited = parseInt(maxFilesVisitedInput?.value || \"\", 10);\n const skipDirs = skipDirsInput?.value ?? \"\";\n\n try {\n if (!isNaN(maxFileBytes) && maxFileBytes > 0) {\n await toolsStore.setSearchFilesMaxFileBytes(db, maxFileBytes);\n }\n if (!isNaN(maxFilesVisited) && maxFilesVisited > 0) {\n await toolsStore.setSearchFilesMaxFilesVisited(db, maxFilesVisited);\n }\n await toolsStore.setSearchFilesSkipDirs(db, skipDirs);\n showSuccess(\"Search Files settings saved\");\n } catch (err) {\n showError(\n `Failed to save Search Files settings: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // Web Search save button\n root\n .querySelector(\".tools__save-websearch-btn\")\n ?.addEventListener(\"click\", async () => {\n const proxyUrlInput = root.querySelector(\n \".tools__websearch-proxy-url-input\",\n ) as HTMLInputElement | null;\n const searchUrlInput = root.querySelector(\n \".tools__websearch-url-input\",\n ) as HTMLInputElement | null;\n\n const proxyUrl = proxyUrlInput?.value.trim() || \"/proxy\";\n const searchUrl =\n searchUrlInput?.value.trim() ||\n \"https://html.duckduckgo.com/html/?q={query}\";\n\n try {\n await toolsStore.setWebSearchProxyUrl(db, proxyUrl);\n await toolsStore.setWebSearchUrl(db, searchUrl);\n showSuccess(\"Web Search settings saved\");\n } catch (err) {\n showError(\n `Failed to save Web Search settings: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n\n // WebMCP mode selector\n const webMcpModeSelect = root.querySelector(\n \".tools__webmcp-mode\",\n ) as HTMLSelectElement | null;\n if (webMcpModeSelect) {\n webMcpModeSelect.addEventListener(\"change\", async () => {\n const orchestrator =\n this.orchestrator ?? orchestratorStore.orchestrator;\n if (!orchestrator) {\n return;\n }\n\n const mode = webMcpModeSelect.value as \"polyfill\" | \"native\";\n try {\n await setWebMcpMode(orchestrator, db, mode, { orchestrator });\n showInfo(`WebMCP mode set to ${mode}`);\n } catch (err) {\n showError(\n `Failed to update WebMCP mode: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n }\n\n // Save prompt\n root\n .querySelector(\".tools__save-prompt-btn\")\n ?.addEventListener(\"click\", () => {\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (textarea instanceof HTMLTextAreaElement) {\n toolsStore.setSystemPromptOverride(db, textarea.value);\n showSuccess(\"System prompt override saved\");\n }\n });\n\n // Clear prompt\n root\n .querySelector(\".tools__clear-prompt-btn\")\n ?.addEventListener(\"click\", () => {\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (textarea instanceof HTMLTextAreaElement) {\n textarea.value = \"\";\n toolsStore.setSystemPromptOverride(db, \"\");\n showSuccess(\"System prompt override cleared\");\n }\n });\n\n // Dialog controls — Add Tool\n const dialog = root.querySelector(\n \".tools__dialog\",\n ) as HTMLDialogElement | null;\n const closeBtn = dialog?.querySelector(\".tools__dialog-close\");\n const cancelBtn = dialog?.querySelector(\".tools__btn-cancel\");\n const form = root.querySelector(\n \".tools__dialog-form\",\n ) as HTMLFormElement | null;\n\n closeBtn?.addEventListener(\"click\", () => dialog?.close());\n cancelBtn?.addEventListener(\"click\", () => dialog?.close());\n\n dialog?.addEventListener(\"click\", (e) => {\n if (e.target === dialog) {\n dialog.close();\n }\n });\n\n form?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (form) {\n this.handleAddTool(db, form);\n }\n });\n\n // Dialog controls — Clone Tool\n const cloneDialog = root.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n const cloneCloseBtn = root.querySelector(\".tools__clone-dialog-close\");\n const cloneCancelBtn = root.querySelector(\".tools__clone-cancel-btn\");\n const cloneForm = root.querySelector(\n \".tools__clone-dialog-form\",\n ) as HTMLFormElement | null;\n\n cloneCloseBtn?.addEventListener(\"click\", () => cloneDialog?.close());\n cloneCancelBtn?.addEventListener(\"click\", () => cloneDialog?.close());\n cloneDialog?.addEventListener(\"click\", (e) => {\n if (e.target === cloneDialog) {\n cloneDialog.close();\n }\n });\n\n cloneForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (cloneForm) {\n this.handleCloneTool(db, cloneForm);\n }\n });\n\n // Dialog controls — Profile\n const profileDialog = root.querySelector(\n \".tools__profile-dialog\",\n ) as HTMLDialogElement | null;\n const profileCloseBtn = root.querySelector(\".tools__profile-dialog-close\");\n const profileCancelBtn = root.querySelector(\".tools__profile-cancel-btn\");\n const profileForm = root.querySelector(\n \".tools__profile-dialog-form\",\n ) as HTMLFormElement | null;\n\n profileCloseBtn?.addEventListener(\"click\", () => profileDialog?.close());\n profileCancelBtn?.addEventListener(\"click\", () => profileDialog?.close());\n profileDialog?.addEventListener(\"click\", (e) => {\n if (e.target === profileDialog) {\n profileDialog.close();\n }\n });\n\n profileForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (profileForm) {\n this.handleSaveProfile(db, profileForm);\n }\n });\n\n // Profile select\n const profileSelect = root.querySelector(\".tools__profile-select\");\n profileSelect?.addEventListener(\"change\", (e) => {\n const select = e.target as HTMLSelectElement;\n const value = select.value;\n if (value) {\n toolsStore.activateProfile(db, value);\n showInfo(\"Profile activated\");\n } else {\n toolsStore.deactivateProfile(db);\n showInfo(\"Profile deactivated\");\n }\n });\n\n // Profile new button → open dialog\n root\n .querySelector(\".tools__profile-new-btn\")\n ?.addEventListener(\"click\", () => {\n if (profileDialog && profileForm) {\n profileForm.reset();\n // Populate provider dropdown\n const providerSelect = profileForm.querySelector(\n '[name=\"providerId\"]',\n );\n if (providerSelect) {\n providerSelect.replaceChildren();\n const defaultOption = document.createElement(\"option\");\n defaultOption.value = \"\";\n defaultOption.textContent = \"— Any provider —\";\n providerSelect.append(defaultOption);\n for (const pid of getAvailableProviders()) {\n const p = getProvider(pid);\n if (p) {\n const opt = document.createElement(\"option\");\n opt.value = pid;\n opt.textContent = p.name;\n providerSelect.appendChild(opt);\n }\n }\n }\n\n (profileDialog as HTMLDialogElement).showModal();\n }\n });\n\n // Profile save (overwrite active)\n root\n .querySelector(\".tools__profile-save-btn\")\n ?.addEventListener(\"click\", async () => {\n const activeId = toolsStore.activeProfileId;\n if (activeId) {\n await toolsStore.saveToActiveProfile(db);\n showSuccess(\"Profile saved\");\n } else {\n // No active profile — open new profile dialog\n root\n .querySelector(\".tools__profile-new-btn\")\n ?.dispatchEvent(new Event(\"click\"));\n }\n });\n\n // Profile delete\n root\n .querySelector(\".tools__profile-delete-btn\")\n ?.addEventListener(\"click\", async () => {\n const activeId = toolsStore.activeProfileId;\n if (!activeId) {\n showInfo(\"No profile selected\");\n\n return;\n }\n\n if (activeId.startsWith(\"__builtin_\")) {\n showInfo(\"Built-in profiles cannot be deleted\");\n\n return;\n }\n\n await toolsStore.deleteProfile(db, activeId);\n showSuccess(\"Profile deleted\");\n });\n\n // Dialog controls — Import\n const importDialog = root.querySelector(\n \".tools__import-dialog\",\n ) as HTMLDialogElement | null;\n const importCloseBtn = root.querySelector(\".tools__import-dialog-close\");\n const importCancelBtn = root.querySelector(\".tools__import-cancel-btn\");\n const importForm = root.querySelector(\n \".tools__import-dialog-form\",\n ) as HTMLFormElement | null;\n const importFetchBtn = root.querySelector(\".tools__import-fetch-btn\");\n\n root.querySelector(\".tools__import-btn\")?.addEventListener(\"click\", () => {\n if (importDialog && importForm) {\n importForm.reset();\n this.resetImportDialogState();\n importDialog.showModal();\n }\n });\n\n importCloseBtn?.addEventListener(\"click\", () => importDialog?.close());\n importCancelBtn?.addEventListener(\"click\", () => importDialog?.close());\n importDialog?.addEventListener(\"click\", (e) => {\n if (e.target === importDialog) {\n importDialog.close();\n }\n });\n\n root.querySelectorAll(\".tools__preset-btn\").forEach((btn) => {\n btn.addEventListener(\"click\", () => {\n const url = (btn as HTMLElement).dataset.url;\n const input = root.querySelector(\n \".tools__import-url-input\",\n ) as HTMLInputElement | null;\n if (input && url) {\n input.value = url;\n this.handleFetchSite(db, url);\n }\n });\n });\n\n importFetchBtn?.addEventListener(\"click\", () => {\n const input = root.querySelector(\n \".tools__import-url-input\",\n ) as HTMLInputElement | null;\n if (input && input.value.trim()) {\n this.handleFetchSite(db, input.value.trim());\n }\n });\n\n importForm?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (importForm) {\n this.handleImportSubmit(db, importForm);\n }\n });\n }\n\n handleBackup() {\n const json = toolsStore.exportBackup();\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `shadowclaw-tools-${Date.now()}.json`;\n a.click();\n URL.revokeObjectURL(url);\n showSuccess(\"Tools config exported\");\n }\n\n /**\n * Open the clone tool dialog for a given source tool.\n */\n openCloneDialog(sourceToolName: string) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const cloneDialog = root.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n const cloneForm = root.querySelector(\n \".tools__clone-dialog-form\",\n ) as HTMLFormElement | null;\n if (!cloneDialog || !cloneForm) {\n return;\n }\n\n cloneForm.reset();\n const sourceInput = cloneForm.querySelector(\n '[name=\"source\"]',\n ) as HTMLInputElement | null;\n if (sourceInput) {\n sourceInput.value = sourceToolName;\n }\n\n cloneDialog.showModal();\n }\n\n renderImportCatalog(manifest: RemoteManifest) {\n const root = this.shadowRoot;\n if (!root) return;\n\n const catalog = root.querySelector(\".tools__import-catalog\");\n if (!catalog) return;\n catalog.replaceChildren();\n\n // 1. Render Tools\n const tools = manifest.tools || [];\n if (tools.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `🛠️ Tools (${tools.length})`;\n category.appendChild(header);\n\n for (const tool of tools) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importTool\";\n checkbox.value = tool.name;\n checkbox.checked = true;\n checkbox.id = `import_tool_${tool.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = tool.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge tools__item-badge--declarative\";\n badge.textContent = tool.executionType || \"declarative\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (tool.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = tool.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n\n // 2. Render Skills\n const skills = manifest.skills || [];\n if (skills.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `🧠 Agent Skills (${skills.length})`;\n category.appendChild(header);\n\n for (const skill of skills) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importSkill\";\n checkbox.value = skill.name;\n checkbox.checked = true;\n checkbox.id = `import_skill_${skill.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = skill.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"skill\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (skill.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = skill.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n\n // 3. Render Scripts\n const scripts = manifest.scripts || [];\n if (scripts.length > 0) {\n const category = document.createElement(\"div\");\n category.className = \"tools__import-category\";\n\n const header = document.createElement(\"div\");\n header.className = \"tools__import-category-header\";\n header.textContent = `📜 Companion Scripts (${scripts.length})`;\n category.appendChild(header);\n\n for (const script of scripts) {\n const item = document.createElement(\"div\");\n item.className = \"tools__import-item\";\n\n const itemHeader = document.createElement(\"div\");\n itemHeader.className = \"tools__import-item-header\";\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.name = \"importScript\";\n checkbox.value = script.name;\n checkbox.checked = true;\n checkbox.id = `import_script_${script.name}`;\n itemHeader.appendChild(checkbox);\n\n const titleLabel = document.createElement(\"label\");\n titleLabel.htmlFor = checkbox.id;\n titleLabel.className = \"tools__import-item-title\";\n titleLabel.textContent = script.name;\n itemHeader.appendChild(titleLabel);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"script\";\n itemHeader.appendChild(badge);\n\n item.appendChild(itemHeader);\n\n if (script.description) {\n const desc = document.createElement(\"div\");\n desc.className = \"tools__import-item-desc\";\n desc.textContent = script.description;\n item.appendChild(desc);\n }\n\n category.appendChild(item);\n }\n\n catalog.appendChild(category);\n }\n }\n\n resetImportDialogState() {\n this.currentRemoteManifest = null;\n const root = this.shadowRoot;\n if (!root) return;\n\n const statusEl = root.querySelector(\n \".tools__import-manifest-status\",\n ) as HTMLElement | null;\n if (statusEl) statusEl.hidden = true;\n\n const siteName = root.querySelector(\".tools__import-site-name\");\n if (siteName) siteName.textContent = \"\";\n\n const siteDesc = root.querySelector(\".tools__import-site-desc\");\n if (siteDesc) siteDesc.textContent = \"\";\n\n const catalog = root.querySelector(\".tools__import-catalog\");\n if (catalog) catalog.replaceChildren();\n\n const submitBtn = root.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) submitBtn.disabled = true;\n }\n\n setupEffects(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n // Reactive re-render on tool store changes\n this.addCleanup(\n effect(() => {\n toolsStore.enabledToolNames;\n toolsStore.customTools;\n toolsStore.declarativeTools;\n toolsStore.declarativeToolNamesEnabled;\n toolsStore.systemPromptOverride;\n toolsStore.profiles;\n toolsStore.activeProfileId;\n this.updateToolList(db);\n }),\n );\n\n // WebMCP opt-in toggle\n const webMcpToggle = root.querySelector(\n \".tools__webmcp-toggle\",\n ) as HTMLInputElement | null;\n const internetAccessToggle = root.querySelector(\n \".tools__internet-access-toggle\",\n ) as HTMLInputElement | null;\n const webMcpModeSelect = root.querySelector(\n \".tools__webmcp-mode\",\n ) as HTMLSelectElement | null;\n\n if (webMcpToggle) {\n // Sync checked state and mode when orchestrator becomes available\n this.addCleanup(\n effect(() => {\n if (orchestratorStore.ready) {\n this.orchestrator = orchestratorStore.orchestrator;\n webMcpToggle.checked =\n this.orchestrator?.webMcpToolsEnabled === true;\n if (webMcpModeSelect && this.orchestrator) {\n webMcpModeSelect.value = getWebMcpMode() || \"polyfill\";\n }\n }\n }),\n );\n }\n\n if (internetAccessToggle) {\n this.addCleanup(\n effect(() => {\n internetAccessToggle.checked =\n orchestratorStore.vmBashFullInternetAccess;\n }),\n );\n }\n\n // Web Search reactive effects\n const webSearchProxyToggle = root.querySelector(\n \".tools__websearch-proxy-toggle\",\n ) as HTMLInputElement | null;\n const webSearchProxyUrlInput = root.querySelector(\n \".tools__websearch-proxy-url-input\",\n ) as HTMLInputElement | null;\n const webSearchUrlInput = root.querySelector(\n \".tools__websearch-url-input\",\n ) as HTMLInputElement | null;\n\n if (webSearchProxyToggle) {\n this.addCleanup(\n effect(() => {\n webSearchProxyToggle.checked = toolsStore.webSearchUseProxy;\n }),\n );\n }\n\n if (webSearchProxyUrlInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== webSearchProxyUrlInput &&\n !webSearchProxyUrlInput.matches(\":focus\")\n ) {\n webSearchProxyUrlInput.value = toolsStore.webSearchProxyUrl;\n }\n }),\n );\n }\n\n if (webSearchUrlInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== webSearchUrlInput &&\n !webSearchUrlInput.matches(\":focus\")\n ) {\n webSearchUrlInput.value = toolsStore.webSearchUrl;\n }\n }),\n );\n }\n\n // Search Files reactive effects\n const searchFilesMaxFileBytesInput = root.querySelector(\n \".tools__searchfiles-max-file-bytes-input\",\n ) as HTMLInputElement | null;\n const searchFilesMaxFilesVisitedInput = root.querySelector(\n \".tools__searchfiles-max-files-visited-input\",\n ) as HTMLInputElement | null;\n const searchFilesSkipDirsInput = root.querySelector(\n \".tools__searchfiles-skip-dirs-input\",\n ) as HTMLInputElement | null;\n\n if (searchFilesMaxFileBytesInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesMaxFileBytesInput &&\n !searchFilesMaxFileBytesInput.matches(\":focus\")\n ) {\n searchFilesMaxFileBytesInput.value = String(\n toolsStore.searchFilesMaxFileBytes,\n );\n }\n }),\n );\n }\n\n if (searchFilesMaxFilesVisitedInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesMaxFilesVisitedInput &&\n !searchFilesMaxFilesVisitedInput.matches(\":focus\")\n ) {\n searchFilesMaxFilesVisitedInput.value = String(\n toolsStore.searchFilesMaxFilesVisited,\n );\n }\n }),\n );\n }\n\n if (searchFilesSkipDirsInput) {\n this.addCleanup(\n effect(() => {\n if (\n document.activeElement !== searchFilesSkipDirsInput &&\n !searchFilesSkipDirsInput.matches(\":focus\")\n ) {\n searchFilesSkipDirsInput.value = toolsStore.searchFilesSkipDirs;\n }\n }),\n );\n }\n }\n\n /** Update the profile dropdown to reflect current state. */\n updateProfileSelector() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const select = root.querySelector(\".tools__profile-select\");\n if (!select) {\n return;\n }\n\n const profiles = toolsStore.profiles;\n const activeId = toolsStore.activeProfileId;\n\n // Preserve selection\n select.replaceChildren();\n const defaultOption = document.createElement(\"option\");\n defaultOption.value = \"\";\n defaultOption.textContent = \"— No profile (manual config) —\";\n select.append(defaultOption);\n for (const p of profiles) {\n const opt = document.createElement(\"option\");\n opt.value = p.id;\n const isBuiltin = p.id.startsWith(\"__builtin_\");\n const providerLabel = p.providerId\n ? getProvider(p.providerId)?.name || p.providerId\n : \"any\";\n const modelLabel = p.model || \"any\";\n opt.textContent = isBuiltin\n ? `⚡ ${p.name} (${providerLabel})`\n : `${p.name} (${providerLabel} / ${modelLabel})`;\n if (p.id === activeId) {\n opt.selected = true;\n }\n\n select.appendChild(opt);\n }\n\n // Disable delete button for built-in profiles\n const deleteBtn = root.querySelector(\n \".tools__profile-delete-btn\",\n ) as HTMLButtonElement | null;\n if (deleteBtn) {\n const isBuiltinActive = activeId?.startsWith(\"__builtin_\");\n deleteBtn.disabled = !!isBuiltinActive;\n deleteBtn.title = isBuiltinActive\n ? \"Built-in profiles cannot be deleted\"\n : \"\";\n }\n }\n\n updateToolList(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tools__list\");\n if (!list) {\n return;\n }\n\n const enabled = toolsStore.enabledToolNames;\n const allTools = toolsStore.allTools;\n const declarativeTools = toolsStore.declarativeTools;\n\n const existingCheckboxes = list.querySelectorAll<HTMLInputElement>(\n \".tools__item-checkbox[data-tool]\",\n );\n const existingToolNames = Array.from(existingCheckboxes).map(\n (cb) => cb.getAttribute(\"data-tool\") || \"\",\n );\n const targetToolNames = [\n ...allTools.map((t) => t.name),\n ...declarativeTools.map((t) => t.name),\n ];\n\n const isSameStructure =\n existingToolNames.length === targetToolNames.length &&\n existingToolNames.every((name, i) => name === targetToolNames[i]);\n\n if (isSameStructure) {\n for (const cb of existingCheckboxes) {\n const toolName = cb.getAttribute(\"data-tool\");\n if (!toolName) continue;\n const isDeclarative = declarativeTools.some((t) => t.name === toolName);\n const isChecked = isDeclarative\n ? toolsStore.isDeclarativeToolEnabled(toolName)\n : enabled.has(toolName);\n if (cb.checked !== isChecked) {\n cb.checked = isChecked;\n }\n }\n } else {\n list.replaceChildren();\n\n for (const tool of allTools) {\n const isCustom = !BUILTIN_TOOL_NAMES.has(tool.name);\n const isChecked = enabled.has(tool.name);\n const brief = tool.description.split(\". \")[0];\n\n const item = document.createElement(\"div\");\n item.className = \"tools__item\";\n item.setAttribute(\"role\", \"listitem\");\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"tools__item-checkbox\";\n checkbox.setAttribute(\"data-tool\", tool.name);\n checkbox.setAttribute(\"aria-label\", `Enable ${tool.name}`);\n checkbox.checked = isChecked;\n\n const info = document.createElement(\"div\");\n info.className = \"tools__item-info\";\n\n const name = document.createElement(\"div\");\n name.className = \"tools__item-name\";\n name.textContent = tool.name;\n\n const desc = document.createElement(\"div\");\n desc.className = \"tools__item-desc\";\n desc.setAttribute(\"title\", tool.description);\n desc.textContent = brief;\n info.append(name, desc);\n\n const cloneBtn = document.createElement(\"button\");\n cloneBtn.className = \"tools__item-clone\";\n cloneBtn.setAttribute(\"data-clone\", tool.name);\n cloneBtn.setAttribute(\"aria-label\", `Clone ${tool.name}`);\n cloneBtn.setAttribute(\"title\", \"Clone tool\");\n cloneBtn.textContent = \"📋\";\n\n item.append(checkbox, info);\n\n if (isCustom) {\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge\";\n badge.textContent = \"custom\";\n item.append(badge);\n }\n\n item.append(cloneBtn);\n\n let deleteBtn: HTMLButtonElement | null = null;\n if (isCustom) {\n deleteBtn = document.createElement(\"button\");\n deleteBtn.className = \"tools__item-delete\";\n deleteBtn.setAttribute(\"data-delete\", tool.name);\n deleteBtn.setAttribute(\"aria-label\", `Delete ${tool.name}`);\n deleteBtn.textContent = \"🗑️\";\n item.append(deleteBtn);\n }\n\n // Toggle\n checkbox?.addEventListener(\"change\", () => {\n toolsStore.setToolEnabled(db, tool.name, checkbox.checked);\n });\n\n // Clone\n cloneBtn?.addEventListener(\"click\", () => {\n this.openCloneDialog(tool.name);\n });\n\n // Delete custom tool\n deleteBtn?.addEventListener(\"click\", () => {\n toolsStore.removeCustomTool(db, tool.name);\n showInfo(`Removed custom tool: ${tool.name}`);\n });\n\n list.appendChild(item);\n }\n\n for (const tool of declarativeTools) {\n const isChecked = toolsStore.isDeclarativeToolEnabled(tool.name);\n const brief = tool.description.split(\". \")[0];\n\n const item = document.createElement(\"div\");\n item.className = \"tools__item\";\n item.setAttribute(\"role\", \"listitem\");\n\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"tools__item-checkbox\";\n checkbox.setAttribute(\"data-tool\", tool.name);\n checkbox.setAttribute(\"aria-label\", `Enable ${tool.name}`);\n checkbox.checked = isChecked;\n\n const info = document.createElement(\"div\");\n info.className = \"tools__item-info\";\n\n const name = document.createElement(\"div\");\n name.className = \"tools__item-name\";\n name.textContent = tool.name;\n\n const desc = document.createElement(\"div\");\n desc.className = \"tools__item-desc\";\n desc.setAttribute(\"title\", tool.description);\n desc.textContent = brief;\n info.append(name, desc);\n\n const badge = document.createElement(\"span\");\n badge.className = \"tools__item-badge tools__item-badge--declarative\";\n badge.textContent = \"declarative\";\n item.append(checkbox, info, badge);\n\n checkbox.addEventListener(\"change\", () => {\n toolsStore.setDeclarativeToolEnabled(db, tool.name, checkbox.checked);\n });\n\n list.appendChild(item);\n }\n }\n\n // Update count\n const countEl = root.querySelector(\".tools__count\");\n if (countEl) {\n const enabledBuiltinCount = (toolsStore.enabledTools || []).length;\n const enabledDeclarativeCount = (toolsStore.enabledDeclarativeTools || [])\n .length;\n const totalEnabled = enabledBuiltinCount + enabledDeclarativeCount;\n const totalCount = allTools.length + declarativeTools.length;\n countEl.textContent = `${totalEnabled} of ${totalCount} enabled`;\n }\n\n // Update prompt textarea\n const textarea = root.querySelector(\".tools__prompt-area\");\n if (\n textarea instanceof HTMLTextAreaElement &&\n document.activeElement !== textarea &&\n !textarea.matches(\":focus\")\n ) {\n textarea.value = toolsStore.systemPromptOverride;\n }\n\n // Update profile selector\n this.updateProfileSelector();\n }\n\n async handleAddTool(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const name = String(data.get(\"name\") || \"\").trim();\n const description = String(data.get(\"description\") || \"\").trim();\n const schemaStr = String(data.get(\"input_schema\") || \"\").trim();\n\n if (!name || !description) {\n showError(\"Name and description are required\");\n\n return;\n }\n\n // Check uniqueness\n if (toolsStore.allTools.some((t) => t.name === name)) {\n showError(`A tool named \"${name}\" already exists`);\n\n return;\n }\n\n let input_schema = { type: \"object\", properties: {} };\n if (schemaStr) {\n try {\n input_schema = JSON.parse(schemaStr);\n } catch {\n showError(\"Invalid JSON in input schema\");\n\n return;\n }\n }\n\n await toolsStore.addCustomTool(db, { name, description, input_schema });\n showSuccess(`Added custom tool: ${name}`);\n\n const dialog = this.shadowRoot?.querySelector(\n \".tools__dialog\",\n ) as HTMLDialogElement | null;\n dialog?.close();\n }\n\n async handleCloneTool(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const sourceToolName = String(data.get(\"source\") || \"\").trim();\n const newName = String(data.get(\"name\") || \"\").trim();\n const newDesc = String(data.get(\"description\") || \"\").trim();\n\n if (!sourceToolName || !newName) {\n showError(\"Source and new tool name are required\");\n\n return;\n }\n\n const ok = await toolsStore.cloneTool(\n db,\n sourceToolName,\n newName,\n newDesc || undefined,\n );\n if (!ok) {\n showError(\n `Clone failed: source not found or name \"${newName}\" already exists.`,\n );\n\n return;\n }\n\n showSuccess(`Cloned \"${sourceToolName}\" → \"${newName}\"`);\n const cloneDialog = this.shadowRoot?.querySelector(\n \".tools__clone-dialog\",\n ) as HTMLDialogElement | null;\n cloneDialog?.close();\n }\n\n async handleFetchSite(_db: ShadowClawDatabase, url: string) {\n const root = this.shadowRoot;\n if (!root) return;\n\n const fetchBtn = root.querySelector(\n \".tools__import-fetch-btn\",\n ) as HTMLButtonElement | null;\n const origText = fetchBtn?.textContent || \"🔍 Fetch\";\n if (fetchBtn) {\n fetchBtn.disabled = true;\n fetchBtn.textContent = \"Fetching...\";\n }\n\n try {\n const resolved = await toolsStore.fetchRemoteDiscoveryManifest(url);\n this.currentRemoteManifest = resolved.manifest;\n\n const siteName = root.querySelector(\".tools__import-site-name\");\n if (siteName)\n siteName.textContent = resolved.manifest.name || \"Remote Site\";\n\n const siteDesc = root.querySelector(\".tools__import-site-desc\");\n if (siteDesc) {\n siteDesc.textContent =\n resolved.manifest.description || \"No description provided.\";\n }\n\n this.renderImportCatalog(resolved.manifest);\n\n const statusEl = root.querySelector(\n \".tools__import-manifest-status\",\n ) as HTMLElement | null;\n if (statusEl) statusEl.hidden = false;\n\n const submitBtn = root.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) submitBtn.disabled = false;\n\n showInfo(\n `Discovered ${(resolved.manifest.tools || []).length} tools, ${(resolved.manifest.skills || []).length} skills from ${resolved.manifest.name}`,\n );\n } catch (err) {\n this.resetImportDialogState();\n showError(\n `Failed to fetch site: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n if (fetchBtn) {\n fetchBtn.disabled = false;\n fetchBtn.textContent = origText;\n }\n }\n }\n\n async handleImportSubmit(db: ShadowClawDatabase, form: HTMLFormElement) {\n if (!this.currentRemoteManifest) {\n showError(\"No remote discovery manifest loaded.\");\n return;\n }\n\n const formData = new FormData(form);\n const toolNames = formData.getAll(\"importTool\").map(String);\n const skillNames = formData.getAll(\"importSkill\").map(String);\n const scriptNames = formData.getAll(\"importScript\").map(String);\n\n if (\n toolNames.length === 0 &&\n skillNames.length === 0 &&\n scriptNames.length === 0\n ) {\n showError(\"Please select at least one tool, skill, or script to import.\");\n return;\n }\n\n const autoEnable =\n (form.querySelector(\".tools__import-auto-enable\") as HTMLInputElement)\n ?.checked ?? true;\n const overwrite =\n (form.querySelector(\".tools__import-overwrite\") as HTMLInputElement)\n ?.checked ?? false;\n\n const submitBtn = form.querySelector(\n \".tools__import-submit-btn\",\n ) as HTMLButtonElement | null;\n if (submitBtn) {\n submitBtn.disabled = true;\n submitBtn.textContent = \"Importing...\";\n }\n\n try {\n const result = await toolsStore.importFromRemoteSite(\n db,\n this.currentRemoteManifest,\n { toolNames, skillNames, scriptNames },\n { autoEnable, overwrite },\n );\n\n const importedToolsCount = result.tools.filter(\n (t) => t.status === \"imported\",\n ).length;\n const importedSkillsCount = result.skills.filter(\n (s) => s.status === \"imported\",\n ).length;\n const importedScriptsCount = result.scripts.filter(\n (sc) => sc.status === \"imported\",\n ).length;\n\n const totalCount =\n importedToolsCount + importedSkillsCount + importedScriptsCount;\n\n showSuccess(\n `Successfully imported ${totalCount} items from ${this.currentRemoteManifest.name || \"site\"}!`,\n );\n\n const dialog = this.shadowRoot?.querySelector(\n \".tools__import-dialog\",\n ) as HTMLDialogElement | null;\n dialog?.close();\n } catch (err) {\n showError(\n `Import failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n if (submitBtn) {\n submitBtn.disabled = false;\n submitBtn.textContent = \"Import Selected\";\n }\n }\n }\n\n async handleRestore(db: ShadowClawDatabase, input: HTMLInputElement) {\n const file = input.files?.[0];\n if (!file) {\n return;\n }\n\n try {\n const text = await file.text();\n await toolsStore.importBackup(db, text);\n showSuccess(\"Tools config restored\");\n } catch (err) {\n showError(\n `Failed to restore: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n input.value = \"\";\n }\n\n async handleSaveProfile(db: ShadowClawDatabase, form: HTMLFormElement) {\n const data = new FormData(form);\n const name = String(data.get(\"name\") || \"\").trim();\n const providerId = String(data.get(\"providerId\") || \"\").trim();\n const model = String(data.get(\"model\") || \"\").trim();\n\n if (!name) {\n showError(\"Profile name is required\");\n\n return;\n }\n\n const profile = {\n id: ulid(),\n name,\n providerId: providerId || undefined,\n model: model || undefined,\n enabledToolNames: [...toolsStore.enabledToolNames],\n customTools: [...toolsStore.customTools],\n systemPromptOverride: toolsStore.systemPromptOverride,\n };\n\n await toolsStore.addProfile(db, profile);\n await toolsStore.activateProfile(db, profile.id);\n showSuccess(`Profile \"${name}\" created and activated`);\n\n const profileDialog = this.shadowRoot?.querySelector(\n \".tools__profile-dialog\",\n ) as HTMLDialogElement | null;\n profileDialog?.close();\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTools);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
2
|
import { r as getDb } from "./txPromise-DdeRXi7G.js";
|
|
3
|
-
import { f as DEFAULT_VM_BOOT_HOST, n as BASH_MAX_TIMEOUT_SEC, r as CONFIG_KEYS } from "./config-
|
|
3
|
+
import { f as DEFAULT_VM_BOOT_HOST, n as BASH_MAX_TIMEOUT_SEC, r as CONFIG_KEYS } from "./config-DZkF9LiO.js";
|
|
4
4
|
import { t as getConfig } from "./getConfig-B7JdRqIY.js";
|
|
5
|
-
import { E as setVMNetworkRelayURL, T as setVMBootMode, t as orchestratorStore, v as setVMBashTimeout, w as setVMBootHost } from "./orchestrator-
|
|
5
|
+
import { E as setVMNetworkRelayURL, T as setVMBootMode, t as orchestratorStore, v as setVMBashTimeout, w as setVMBootHost } from "./orchestrator-DKHCoikY.js";
|
|
6
6
|
import { a as showSuccess, r as showError, s as showWarning } from "./toast-DZ6r7_YI.js";
|
|
7
7
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
8
8
|
|
|
@@ -344,4 +344,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
344
344
|
|
|
345
345
|
//#endregion
|
|
346
346
|
export { ShadowClawWebvm as t };
|
|
347
|
-
//# sourceMappingURL=shadow-claw-webvm-
|
|
347
|
+
//# sourceMappingURL=shadow-claw-webvm-Xe3ByMDw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-webvm-gVFZ197u.js","names":["shadowClawWebvmStyles","shadowClawWebvmTemplate"],"sources":["../../src/components/settings/shadow-claw-webvm/shadow-claw-webvm.ts"],"sourcesContent":["import {\n BASH_DEFAULT_TIMEOUT_SEC,\n BASH_MAX_TIMEOUT_SEC,\n CONFIG_KEYS,\n DEFAULT_VM_BOOT_HOST,\n} from \"../../../config/config.js\";\n\nimport { effect } from \"../../../core/effect.js\";\n\nimport {\n setVMBootHost,\n setVMBootMode,\n setVMNetworkRelayURL,\n} from \"../../../core/orchestrator/utils/operations/vm.js\";\n\nimport { setVMBashTimeout } from \"../../../core/orchestrator/utils/settings.js\";\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawWebvmStyles from \"./shadow-claw-webvm.css\" with { type: \"css\" };\nimport shadowClawWebvmTemplate from \"./shadow-claw-webvm.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-webvm\";\n\n/**\n * Settings sub-component for WebVM configuration:\n * boot mode, bash timeout, boot host, network relay URL.\n */\nexport class ShadowClawWebvm extends ShadowClawElement {\n static styles = shadowClawWebvmStyles;\n static template = shadowClawWebvmTemplate;\n\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.bindEventListeners();\n this.setupEffects();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-vm-boot-mode\"]')\n ?.addEventListener(\"click\", () => this.saveVMBootMode());\n\n root\n .querySelector('[data-action=\"save-vm-bash-timeout\"]')\n ?.addEventListener(\"click\", () => this.saveVMBashTimeout());\n\n root\n .querySelector('[data-action=\"save-vm-boot-host\"]')\n ?.addEventListener(\"click\", () => this.saveVMBootHost());\n\n root\n .querySelector('[data-action=\"save-vm-network-relay-url\"]')\n ?.addEventListener(\"click\", () => this.saveVMNetworkRelayURL());\n }\n\n /**\n * Set up reactive effects.\n */\n setupEffects() {\n effect(() => {\n if (orchestratorStore.ready) {\n void (async () => {\n this.db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n await this.render();\n })();\n }\n });\n }\n\n /**\n * Load and populate all WebVM settings fields.\n */\n async render() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n // Boot mode\n const vmBootModeSelect = root.querySelector(\n '[data-setting=\"vm-boot-mode-select\"]',\n ) as HTMLSelectElement | null;\n const vmBootMode = await getConfig(this.db, CONFIG_KEYS.VM_BOOT_MODE);\n const normalizedVMBootMode =\n vmBootMode === \"disabled\" ||\n vmBootMode === \"9p\" ||\n vmBootMode === \"ext2\" ||\n vmBootMode === \"auto\"\n ? vmBootMode\n : \"disabled\";\n if (vmBootModeSelect) {\n vmBootModeSelect.value = normalizedVMBootMode;\n }\n\n // Bash timeout\n const vmBashTimeoutInput = root.querySelector(\n '[data-setting=\"vm-bash-timeout-input\"]',\n ) as HTMLInputElement | null;\n const vmBashTimeoutRaw = await getConfig(\n this.db,\n CONFIG_KEYS.VM_BASH_TIMEOUT_SEC,\n );\n const vmBashTimeoutParsed = Number(vmBashTimeoutRaw);\n const normalizedVMBashTimeout = Number.isFinite(vmBashTimeoutParsed)\n ? Math.min(\n Math.max(Math.floor(vmBashTimeoutParsed), 1),\n BASH_MAX_TIMEOUT_SEC,\n )\n : BASH_DEFAULT_TIMEOUT_SEC;\n if (vmBashTimeoutInput) {\n vmBashTimeoutInput.value = String(normalizedVMBashTimeout);\n }\n\n // Boot host\n const vmBootHostInput = root.querySelector(\n '[data-setting=\"vm-boot-host-input\"]',\n ) as HTMLInputElement | null;\n const vmBootHostRaw = await getConfig(this.db, CONFIG_KEYS.VM_BOOT_HOST);\n if (vmBootHostInput) {\n vmBootHostInput.value =\n typeof vmBootHostRaw === \"string\"\n ? vmBootHostRaw.trim()\n : DEFAULT_VM_BOOT_HOST;\n }\n\n // Network relay URL\n const vmNetworkRelayURLInput = root.querySelector(\n '[data-setting=\"vm-network-relay-url-input\"]',\n ) as HTMLInputElement | null;\n const vmNetworkRelayURLRaw = await getConfig(\n this.db,\n CONFIG_KEYS.VM_NETWORK_RELAY_URL,\n );\n if (vmNetworkRelayURLInput && typeof vmNetworkRelayURLRaw === \"string\") {\n vmNetworkRelayURLInput.value = vmNetworkRelayURLRaw.trim();\n }\n } catch (e) {\n console.warn(\"Could not load WebVM settings:\", e);\n }\n }\n\n /**\n * Save default bash timeout.\n */\n async saveVMBashTimeout() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-bash-timeout-input\"]',\n ) as HTMLInputElement | null;\n const parsed = Number(input?.value);\n\n if (!Number.isFinite(parsed)) {\n showWarning(\"Please enter a valid timeout in seconds\", 3000);\n\n return;\n }\n\n const normalized = Math.min(\n Math.max(Math.floor(parsed), 1),\n BASH_MAX_TIMEOUT_SEC,\n );\n if (input) {\n input.value = String(normalized);\n }\n\n try {\n await setVMBashTimeout(this.orchestrator, this.db, normalized);\n showSuccess(\"WebVM bash timeout saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM bash timeout: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save boot host URL.\n */\n async saveVMBootHost() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-boot-host-input\"]',\n ) as HTMLInputElement | null;\n const value = input?.value?.trim() || \"\";\n\n if (value) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new Error(\"Boot host must use http:// or https://\");\n }\n } catch {\n showWarning(\"Please enter a valid HTTP(S) boot host URL\", 3500);\n\n return;\n }\n }\n\n try {\n await setVMBootHost(this.orchestrator, this.db, value);\n showSuccess(\"WebVM boot host saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM boot host: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save VM boot mode.\n */\n async saveVMBootMode() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const select = root.querySelector(\n '[data-setting=\"vm-boot-mode-select\"]',\n ) as HTMLSelectElement | null;\n const selected = select?.value || \"disabled\";\n const mode =\n selected === \"disabled\" ||\n selected === \"9p\" ||\n selected === \"ext2\" ||\n selected === \"auto\"\n ? selected\n : \"disabled\";\n\n try {\n await setVMBootMode(this.orchestrator, this.db, mode);\n showSuccess(\"WebVM boot mode saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM mode: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save network relay URL.\n */\n async saveVMNetworkRelayURL() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-network-relay-url-input\"]',\n ) as HTMLInputElement | null;\n const value = input?.value?.trim() || \"\";\n\n if (value) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol !== \"ws:\" && parsed.protocol !== \"wss:\") {\n throw new Error(\"Relay URL must use ws:// or wss://\");\n }\n } catch {\n showWarning(\"Please enter a valid ws:// or wss:// relay URL\", 3500);\n\n return;\n }\n }\n\n if (input) {\n input.value = value;\n }\n\n try {\n await setVMNetworkRelayURL(this.orchestrator, this.db, value);\n showSuccess(\"WebVM relay URL saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM relay URL: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawWebvm);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-webvm-Xe3ByMDw.js","names":["shadowClawWebvmStyles","shadowClawWebvmTemplate"],"sources":["../../src/components/settings/shadow-claw-webvm/shadow-claw-webvm.ts"],"sourcesContent":["import {\n BASH_DEFAULT_TIMEOUT_SEC,\n BASH_MAX_TIMEOUT_SEC,\n CONFIG_KEYS,\n DEFAULT_VM_BOOT_HOST,\n} from \"../../../config/config.js\";\n\nimport { effect } from \"../../../core/effect.js\";\n\nimport {\n setVMBootHost,\n setVMBootMode,\n setVMNetworkRelayURL,\n} from \"../../../core/orchestrator/utils/operations/vm.js\";\n\nimport { setVMBashTimeout } from \"../../../core/orchestrator/utils/settings.js\";\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/getConfig.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawWebvmStyles from \"./shadow-claw-webvm.css\" with { type: \"css\" };\nimport shadowClawWebvmTemplate from \"./shadow-claw-webvm.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-webvm\";\n\n/**\n * Settings sub-component for WebVM configuration:\n * boot mode, bash timeout, boot host, network relay URL.\n */\nexport class ShadowClawWebvm extends ShadowClawElement {\n static styles = shadowClawWebvmStyles;\n static template = shadowClawWebvmTemplate;\n\n db: ShadowClawDatabase | null = null;\n orchestrator: Orchestrator | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.bindEventListeners();\n this.setupEffects();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-vm-boot-mode\"]')\n ?.addEventListener(\"click\", () => this.saveVMBootMode());\n\n root\n .querySelector('[data-action=\"save-vm-bash-timeout\"]')\n ?.addEventListener(\"click\", () => this.saveVMBashTimeout());\n\n root\n .querySelector('[data-action=\"save-vm-boot-host\"]')\n ?.addEventListener(\"click\", () => this.saveVMBootHost());\n\n root\n .querySelector('[data-action=\"save-vm-network-relay-url\"]')\n ?.addEventListener(\"click\", () => this.saveVMNetworkRelayURL());\n }\n\n /**\n * Set up reactive effects.\n */\n setupEffects() {\n effect(() => {\n if (orchestratorStore.ready) {\n void (async () => {\n this.db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n await this.render();\n })();\n }\n });\n }\n\n /**\n * Load and populate all WebVM settings fields.\n */\n async render() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n // Boot mode\n const vmBootModeSelect = root.querySelector(\n '[data-setting=\"vm-boot-mode-select\"]',\n ) as HTMLSelectElement | null;\n const vmBootMode = await getConfig(this.db, CONFIG_KEYS.VM_BOOT_MODE);\n const normalizedVMBootMode =\n vmBootMode === \"disabled\" ||\n vmBootMode === \"9p\" ||\n vmBootMode === \"ext2\" ||\n vmBootMode === \"auto\"\n ? vmBootMode\n : \"disabled\";\n if (vmBootModeSelect) {\n vmBootModeSelect.value = normalizedVMBootMode;\n }\n\n // Bash timeout\n const vmBashTimeoutInput = root.querySelector(\n '[data-setting=\"vm-bash-timeout-input\"]',\n ) as HTMLInputElement | null;\n const vmBashTimeoutRaw = await getConfig(\n this.db,\n CONFIG_KEYS.VM_BASH_TIMEOUT_SEC,\n );\n const vmBashTimeoutParsed = Number(vmBashTimeoutRaw);\n const normalizedVMBashTimeout = Number.isFinite(vmBashTimeoutParsed)\n ? Math.min(\n Math.max(Math.floor(vmBashTimeoutParsed), 1),\n BASH_MAX_TIMEOUT_SEC,\n )\n : BASH_DEFAULT_TIMEOUT_SEC;\n if (vmBashTimeoutInput) {\n vmBashTimeoutInput.value = String(normalizedVMBashTimeout);\n }\n\n // Boot host\n const vmBootHostInput = root.querySelector(\n '[data-setting=\"vm-boot-host-input\"]',\n ) as HTMLInputElement | null;\n const vmBootHostRaw = await getConfig(this.db, CONFIG_KEYS.VM_BOOT_HOST);\n if (vmBootHostInput) {\n vmBootHostInput.value =\n typeof vmBootHostRaw === \"string\"\n ? vmBootHostRaw.trim()\n : DEFAULT_VM_BOOT_HOST;\n }\n\n // Network relay URL\n const vmNetworkRelayURLInput = root.querySelector(\n '[data-setting=\"vm-network-relay-url-input\"]',\n ) as HTMLInputElement | null;\n const vmNetworkRelayURLRaw = await getConfig(\n this.db,\n CONFIG_KEYS.VM_NETWORK_RELAY_URL,\n );\n if (vmNetworkRelayURLInput && typeof vmNetworkRelayURLRaw === \"string\") {\n vmNetworkRelayURLInput.value = vmNetworkRelayURLRaw.trim();\n }\n } catch (e) {\n console.warn(\"Could not load WebVM settings:\", e);\n }\n }\n\n /**\n * Save default bash timeout.\n */\n async saveVMBashTimeout() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-bash-timeout-input\"]',\n ) as HTMLInputElement | null;\n const parsed = Number(input?.value);\n\n if (!Number.isFinite(parsed)) {\n showWarning(\"Please enter a valid timeout in seconds\", 3000);\n\n return;\n }\n\n const normalized = Math.min(\n Math.max(Math.floor(parsed), 1),\n BASH_MAX_TIMEOUT_SEC,\n );\n if (input) {\n input.value = String(normalized);\n }\n\n try {\n await setVMBashTimeout(this.orchestrator, this.db, normalized);\n showSuccess(\"WebVM bash timeout saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM bash timeout: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save boot host URL.\n */\n async saveVMBootHost() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-boot-host-input\"]',\n ) as HTMLInputElement | null;\n const value = input?.value?.trim() || \"\";\n\n if (value) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new Error(\"Boot host must use http:// or https://\");\n }\n } catch {\n showWarning(\"Please enter a valid HTTP(S) boot host URL\", 3500);\n\n return;\n }\n }\n\n try {\n await setVMBootHost(this.orchestrator, this.db, value);\n showSuccess(\"WebVM boot host saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM boot host: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save VM boot mode.\n */\n async saveVMBootMode() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const select = root.querySelector(\n '[data-setting=\"vm-boot-mode-select\"]',\n ) as HTMLSelectElement | null;\n const selected = select?.value || \"disabled\";\n const mode =\n selected === \"disabled\" ||\n selected === \"9p\" ||\n selected === \"ext2\" ||\n selected === \"auto\"\n ? selected\n : \"disabled\";\n\n try {\n await setVMBootMode(this.orchestrator, this.db, mode);\n showSuccess(\"WebVM boot mode saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM mode: \" + errorMsg, 6000);\n }\n }\n\n /**\n * Save network relay URL.\n */\n async saveVMNetworkRelayURL() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"vm-network-relay-url-input\"]',\n ) as HTMLInputElement | null;\n const value = input?.value?.trim() || \"\";\n\n if (value) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol !== \"ws:\" && parsed.protocol !== \"wss:\") {\n throw new Error(\"Relay URL must use ws:// or wss://\");\n }\n } catch {\n showWarning(\"Please enter a valid ws:// or wss:// relay URL\", 3500);\n\n return;\n }\n }\n\n if (input) {\n input.value = value;\n }\n\n try {\n await setVMNetworkRelayURL(this.orchestrator, this.db, value);\n showSuccess(\"WebVM relay URL saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving WebVM relay URL: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawWebvm);\n}\n"],"mappings":"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"}
|
|
@@ -86,6 +86,70 @@ export declare function executeWebMcpTool(modelContext: any, tool: any, input?:
|
|
|
86
86
|
* https://chromewebstore.google.com/detail/model-context-tool-inspec/gbpdfapgefenggkahomfgkhfehlcenpd
|
|
87
87
|
*/
|
|
88
88
|
export declare function isWebMcpSupported(): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Event fired when a tool execution begins (PR #245 / Chrome 156+).
|
|
91
|
+
* Dispatched on `document.modelContext` in Chrome 156+, or `window` in Chrome < 156.
|
|
92
|
+
*/
|
|
93
|
+
export interface WebMcpToolActivatedEvent extends Event {
|
|
94
|
+
readonly toolName: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Event fired when a tool execution is cancelled (PR #245 / Chrome 156+).
|
|
98
|
+
* Dispatched on `document.modelContext` in Chrome 156+, or `window` in Chrome < 156.
|
|
99
|
+
*/
|
|
100
|
+
export interface WebMcpToolCancelEvent extends Event {
|
|
101
|
+
readonly toolName: string;
|
|
102
|
+
}
|
|
103
|
+
export type WebMcpEventTarget = EventTarget & {
|
|
104
|
+
addEventListener: (type: string, listener: any, options?: any) => void;
|
|
105
|
+
removeEventListener: (type: string, listener: any, options?: any) => void;
|
|
106
|
+
};
|
|
107
|
+
export interface WebMcpEventListenerOptions extends AddEventListenerOptions {
|
|
108
|
+
/**
|
|
109
|
+
* If true, also attaches a fallback listener to window when modelContext is selected
|
|
110
|
+
* (or vice versa), deduplicating events by toolName within the same tick if both fire.
|
|
111
|
+
*/
|
|
112
|
+
listenBoth?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolves the appropriate EventTarget for WebMCP lifecycle events
|
|
116
|
+
* (`toolactivated` and `toolcancel`) with backwards compatibility.
|
|
117
|
+
*
|
|
118
|
+
* Starting in Chrome 156.0.8076.0 (PR #245), `ontoolactivated` and `ontoolcancel`
|
|
119
|
+
* event handler properties and lifecycle events moved from `window` to `document.modelContext`.
|
|
120
|
+
* In Chrome < 156, these events were fired on `window`.
|
|
121
|
+
*
|
|
122
|
+
* This function practices robust feature detection and graceful degradation:
|
|
123
|
+
* 1. Safely checks for existence of `document` and `window` to avoid ReferenceErrors
|
|
124
|
+
* in non-DOM / headless / Node.js environments.
|
|
125
|
+
* 2. Checks if `on${type}` is present in `document.modelContext` (or `navigator.modelContext`).
|
|
126
|
+
* If present and it supports `addEventListener`, `modelContext` is returned.
|
|
127
|
+
* 3. Checks if `on${type}` is present in `window`. If present and `window` supports
|
|
128
|
+
* `addEventListener`, `window` is returned (legacy Chrome < 156 path).
|
|
129
|
+
* 4. Fallback: If neither has `on${type}` (e.g. polyfill, synthetic mock, or uninitialized prototype),
|
|
130
|
+
* prefers `modelContext` if it supports `addEventListener`, otherwise falls back to `window`.
|
|
131
|
+
* 5. Returns `null` if no valid EventTarget is found.
|
|
132
|
+
*/
|
|
133
|
+
export declare function getWebMcpEventTarget(type?: "toolactivated" | "toolcancel" | string): WebMcpEventTarget | null;
|
|
134
|
+
/**
|
|
135
|
+
* Safely registers a listener for WebMCP lifecycle events (`toolactivated`, `toolcancel`)
|
|
136
|
+
* with graceful degradation, event payload normalization, and automatic unsubscription.
|
|
137
|
+
*
|
|
138
|
+
* Returns an idempotent unsubscribe cleanup function.
|
|
139
|
+
*/
|
|
140
|
+
export declare function addWebMcpEventListener<T extends "toolactivated" | "toolcancel" | string = "toolactivated" | "toolcancel">(type: T, listener: (event: T extends "toolactivated" ? WebMcpToolActivatedEvent : T extends "toolcancel" ? WebMcpToolCancelEvent : Event & {
|
|
141
|
+
toolName?: string;
|
|
142
|
+
}) => void, options?: boolean | WebMcpEventListenerOptions): () => void;
|
|
143
|
+
/**
|
|
144
|
+
* Convenience helper to subscribe to tool execution start events (`toolactivated`).
|
|
145
|
+
* Returns an unsubscribe cleanup function.
|
|
146
|
+
*/
|
|
147
|
+
export declare function onWebMcpToolActivated(listener: (event: WebMcpToolActivatedEvent) => void, options?: boolean | WebMcpEventListenerOptions): () => void;
|
|
148
|
+
/**
|
|
149
|
+
* Convenience helper to subscribe to tool execution cancel events (`toolcancel`).
|
|
150
|
+
* Returns an unsubscribe cleanup function.
|
|
151
|
+
*/
|
|
152
|
+
export declare function onWebMcpToolCancel(listener: (event: WebMcpToolCancelEvent) => void, options?: boolean | WebMcpEventListenerOptions): () => void;
|
|
89
153
|
/**
|
|
90
154
|
* Consequential tools that perform high-stakes, irreversible, or external real-world actions
|
|
91
155
|
* (such as deleting data, executing arbitrary system commands, or transmitting live communications).
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { r as CONFIG_KEYS } from "./config-
|
|
2
|
-
import { t as toolsStore } from "./tools-
|
|
3
|
-
import { Mt as discoverSkills, O as handleWorkerMessage, t as orchestratorStore } from "./orchestrator-
|
|
1
|
+
import { r as CONFIG_KEYS } from "./config-DZkF9LiO.js";
|
|
2
|
+
import { t as toolsStore } from "./tools-Cmhpk3X8.js";
|
|
3
|
+
import { Mt as discoverSkills, O as handleWorkerMessage, t as orchestratorStore } from "./orchestrator-DKHCoikY.js";
|
|
4
4
|
import { t as setConfig } from "./setConfig-CmvLryM3.js";
|
|
5
5
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
6
|
-
import { i as
|
|
6
|
+
import { a as setWebMcpMode$1, i as registerWebMcpTools, n as onWebMcpToolActivated, o as unregisterWebMcpTools, r as onWebMcpToolCancel } from "./webmcp-oEP9YpR2.js";
|
|
7
7
|
|
|
8
8
|
//#region src/subsystems/skills/tool.ts
|
|
9
9
|
const activate_skill = {
|
|
@@ -30,7 +30,13 @@ function syncWebMcpRegistration(orchestrator, db) {
|
|
|
30
30
|
unregisterWebMcpTools();
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
const unsubscribeActivated = onWebMcpToolActivated((event) => {
|
|
34
|
+
orchestrator.events?.emit("webmcp-tool-activated", { toolName: event.toolName });
|
|
35
|
+
});
|
|
36
|
+
const unsubscribeCancel = onWebMcpToolCancel((event) => {
|
|
37
|
+
orchestrator.events?.emit("webmcp-tool-cancel", { toolName: event.toolName });
|
|
38
|
+
});
|
|
39
|
+
const disposeEffect = effect(() => {
|
|
34
40
|
const activeGroupId = orchestratorStore.activeGroupId;
|
|
35
41
|
const allTools = toolsStore.allTools;
|
|
36
42
|
const globalTools = toolsStore.enabledTools;
|
|
@@ -59,6 +65,15 @@ function syncWebMcpRegistration(orchestrator, db) {
|
|
|
59
65
|
console.error("WebMCP registration failed:", err);
|
|
60
66
|
});
|
|
61
67
|
});
|
|
68
|
+
orchestrator.webMcpEffectCleanup = () => {
|
|
69
|
+
try {
|
|
70
|
+
unsubscribeActivated();
|
|
71
|
+
} catch {}
|
|
72
|
+
try {
|
|
73
|
+
unsubscribeCancel();
|
|
74
|
+
} catch {}
|
|
75
|
+
if (typeof disposeEffect === "function") disposeEffect();
|
|
76
|
+
};
|
|
62
77
|
}
|
|
63
78
|
async function setWebMcpMode(_state, db, mode, syncDeps) {
|
|
64
79
|
unregisterWebMcpTools();
|
|
@@ -74,4 +89,4 @@ async function setWebMcpToolsEnabled(state, db, enabled, syncDeps) {
|
|
|
74
89
|
|
|
75
90
|
//#endregion
|
|
76
91
|
export { activate_skill as i, setWebMcpToolsEnabled as n, syncWebMcpRegistration as r, setWebMcpMode as t };
|
|
77
|
-
//# sourceMappingURL=syncWebMcpRegistration-
|
|
92
|
+
//# sourceMappingURL=syncWebMcpRegistration-D7alChz0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncWebMcpRegistration-D7alChz0.js","names":[],"sources":["../../src/subsystems/skills/tool.ts","../../src/core/orchestrator/utils/syncWebMcpRegistration.ts"],"sourcesContent":["import type { ToolDefinition } from \"../../subsystems/tools/types.js\";\n\nexport const activate_skill: ToolDefinition = {\n name: \"activate_skill\",\n description:\n \"Load the full instructions for a workspace skill when its description matches the current task.\",\n input_schema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description: \"The exact skill name from the available skills catalog.\",\n },\n },\n required: [\"name\"],\n },\n};\n","import { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { toolsStore } from \"../../../stores/tools.js\";\n\nimport {\n setWebMcpMode as applyWebMcpMode,\n registerWebMcpTools,\n unregisterWebMcpTools,\n onWebMcpToolActivated,\n onWebMcpToolCancel,\n} from \"../../../subsystems/mcp/webmcp.js\";\n\nimport { effect } from \"../../effect.js\";\nimport { handleWorkerMessage } from \"./handleWorkerMessage.js\";\n\nimport { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { setConfig } from \"../../../db/setConfig.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/db.js\";\nimport type { DeclarativeToolDefinition } from \"../../../subsystems/tools/declarative.js\";\nimport type { SkillRecord } from \"../../../subsystems/skills/types.js\";\nimport type { WebMcpMode } from \"../../../subsystems/mcp/webmcp.js\";\nimport type { OrchestratorState } from \"../orchestrator-state.js\";\nimport type { Orchestrator } from \"../orchestrator.js\";\n\nimport { discoverSkills } from \"../../../subsystems/skills/discoverSkills.js\";\nimport { activate_skill } from \"../../../subsystems/skills/tool.js\";\n\nexport function syncWebMcpRegistration(\n orchestrator: Orchestrator,\n db: ShadowClawDatabase,\n): void {\n if (typeof orchestrator.webMcpEffectCleanup === \"function\") {\n orchestrator.webMcpEffectCleanup();\n orchestrator.webMcpEffectCleanup = null;\n }\n\n if (!orchestrator.webMcpToolsEnabled) {\n unregisterWebMcpTools();\n\n return;\n }\n\n // Subscribe to WebMCP lifecycle events (PR #245 / Chrome 156+ with backwards compatibility).\n const unsubscribeActivated = onWebMcpToolActivated((event) => {\n orchestrator.events?.emit(\"webmcp-tool-activated\", {\n toolName: event.toolName,\n });\n });\n\n const unsubscribeCancel = onWebMcpToolCancel((event) => {\n orchestrator.events?.emit(\"webmcp-tool-cancel\", {\n toolName: event.toolName,\n });\n });\n\n // Register WebMCP tools and re-register when tool config changes.\n // This effect runs once immediately to perform the initial registration.\n // We intentionally do NOT call isWebMcpSupported() here — that accesses\n // the browser's modelContext API which can crash Chrome Canary's\n // early-preview renderer. Instead, registerWebMcpTools handles feature detection\n // internally and skips modelContext access entirely when 0 tools are\n // passed.\n const disposeEffect = effect(() => {\n // Access signals to establish tracking.\n const activeGroupId = orchestratorStore.activeGroupId;\n const allTools = toolsStore.allTools;\n const globalTools = toolsStore.enabledTools;\n void toolsStore.declarativeTools;\n void toolsStore.declarativeToolNamesEnabled;\n const groups = orchestratorStore.groups;\n const group = groups.find((g) => g.groupId === activeGroupId);\n\n // Serialize WebMCP registration calls to prevent overlapping unregister/register cycles.\n orchestrator.webMcpRegistrationLock = orchestrator.webMcpRegistrationLock\n .then(async () => {\n unregisterWebMcpTools();\n // Small delay to allow the browser's ModelContext to process the unregistrations.\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n let declarativeTools: DeclarativeToolDefinition[] = [];\n try {\n declarativeTools = await toolsStore.refreshDeclarativeTools(\n db,\n activeGroupId,\n );\n } catch {\n // Ignore OPFS load errors\n }\n\n const enabledDeclarativeTools = declarativeTools.filter((dt) =>\n toolsStore.isDeclarativeToolEnabled(dt.name),\n );\n\n const candidateTools = [...allTools, ...declarativeTools];\n let tools =\n group?.toolTags && group.toolTags.length > 0\n ? candidateTools.filter((t) => group.toolTags!.includes(t.name))\n : [...globalTools, ...enabledDeclarativeTools];\n\n let skillDiscovery: { skills: SkillRecord[] } = { skills: [] };\n try {\n skillDiscovery = await discoverSkills(db, activeGroupId);\n } catch {\n // Ignore OPFS load errors\n }\n\n if (\n skillDiscovery.skills.length > 0 &&\n !tools.some((t) => t.name === activate_skill.name)\n ) {\n tools = [...tools, activate_skill];\n }\n\n await registerWebMcpTools(\n orchestrator.agentWorker,\n async (msg) => {\n await handleWorkerMessage(orchestrator, db, msg);\n },\n activeGroupId,\n tools,\n );\n })\n .catch((err) => {\n console.error(\"WebMCP registration failed:\", err);\n });\n });\n\n orchestrator.webMcpEffectCleanup = () => {\n try {\n unsubscribeActivated();\n } catch {}\n try {\n unsubscribeCancel();\n } catch {}\n if (typeof disposeEffect === \"function\") {\n disposeEffect();\n }\n };\n}\nexport async function setWebMcpMode(\n _state: Pick<\n OrchestratorState,\n \"webMcpToolsEnabled\" | \"webMcpRegistrationLock\"\n > & {\n webMcpEffectCleanup: (() => void) | null;\n agentWorker: Worker | null;\n },\n db: ShadowClawDatabase,\n mode: WebMcpMode,\n syncDeps: { orchestrator: Orchestrator },\n): Promise<void> {\n // Unregister with old mode, switch, re-register with new mode.\n unregisterWebMcpTools();\n applyWebMcpMode(mode);\n\n await setConfig(db, CONFIG_KEYS.WEBMCP_MODE, mode);\n\n syncWebMcpRegistration(syncDeps.orchestrator, db);\n}\n\nexport async function setWebMcpToolsEnabled(\n state: Pick<OrchestratorState, \"webMcpToolsEnabled\">,\n db: ShadowClawDatabase,\n enabled: boolean,\n syncDeps: { orchestrator: Orchestrator },\n): Promise<void> {\n state.webMcpToolsEnabled = !!enabled;\n\n await setConfig(\n db,\n CONFIG_KEYS.WEBMCP_TOOLS_ENABLED,\n state.webMcpToolsEnabled ? \"true\" : \"false\",\n );\n\n syncWebMcpRegistration(syncDeps.orchestrator, db);\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,iBAAiC;CAC5C,MAAM;CACN,aACE;CACF,cAAc;EACZ,MAAM;EACN,YAAY,EACV,MAAM;GACJ,MAAM;GACN,aAAa;EACf,EACF;EACA,UAAU,CAAC,MAAM;CACnB;AACF;;;;ACWA,SAAgB,uBACd,cACA,IACM;CACN,IAAI,OAAO,aAAa,wBAAwB,YAAY;EAC1D,aAAa,oBAAoB;EACjC,aAAa,sBAAsB;CACrC;CAEA,IAAI,CAAC,aAAa,oBAAoB;EACpC,sBAAsB;EAEtB;CACF;CAGA,MAAM,uBAAuB,uBAAuB,UAAU;EAC5D,aAAa,QAAQ,KAAK,yBAAyB,EACjD,UAAU,MAAM,SAClB,CAAC;CACH,CAAC;CAED,MAAM,oBAAoB,oBAAoB,UAAU;EACtD,aAAa,QAAQ,KAAK,sBAAsB,EAC9C,UAAU,MAAM,SAClB,CAAC;CACH,CAAC;CASD,MAAM,gBAAgB,aAAa;EAEjC,MAAM,gBAAgB,kBAAkB;EACxC,MAAM,WAAW,WAAW;EAC5B,MAAM,cAAc,WAAW;EAC/B,AAAK,WAAW;EAChB,AAAK,WAAW;EAEhB,MAAM,QADS,kBAAkB,OACZ,MAAM,MAAM,EAAE,YAAY,aAAa;EAG5D,aAAa,yBAAyB,aAAa,uBAChD,KAAK,YAAY;GAChB,sBAAsB;GAEtB,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,CAAC,CAAC;GAErD,IAAI,mBAAgD,CAAC;GACrD,IAAI;IACF,mBAAmB,MAAM,WAAW,wBAClC,IACA,aACF;GACF,QAAQ,CAER;GAEA,MAAM,0BAA0B,iBAAiB,QAAQ,OACvD,WAAW,yBAAyB,GAAG,IAAI,CAC7C;GAEA,MAAM,iBAAiB,CAAC,GAAG,UAAU,GAAG,gBAAgB;GACxD,IAAI,QACF,OAAO,YAAY,MAAM,SAAS,SAAS,IACvC,eAAe,QAAQ,MAAM,MAAM,SAAU,SAAS,EAAE,IAAI,CAAC,IAC7D,CAAC,GAAG,aAAa,GAAG,uBAAuB;GAEjD,IAAI,iBAA4C,EAAE,QAAQ,CAAC,EAAE;GAC7D,IAAI;IACF,iBAAiB,MAAM,eAAe,IAAI,aAAa;GACzD,QAAQ,CAER;GAEA,IACE,eAAe,OAAO,SAAS,KAC/B,CAAC,MAAM,MAAM,MAAM,EAAE,SAAS,eAAe,IAAI,GAEjD,QAAQ,CAAC,GAAG,OAAO,cAAc;GAGnC,MAAM,oBACJ,aAAa,aACb,OAAO,QAAQ;IACb,MAAM,oBAAoB,cAAc,IAAI,GAAG;GACjD,GACA,eACA,KACF;EACF,CAAC,CAAC,CACD,OAAO,QAAQ;GACd,QAAQ,MAAM,+BAA+B,GAAG;EAClD,CAAC;CACL,CAAC;CAED,aAAa,4BAA4B;EACvC,IAAI;GACF,qBAAqB;EACvB,QAAQ,CAAC;EACT,IAAI;GACF,kBAAkB;EACpB,QAAQ,CAAC;EACT,IAAI,OAAO,kBAAkB,YAC3B,cAAc;CAElB;AACF;AACA,eAAsB,cACpB,QAOA,IACA,MACA,UACe;CAEf,sBAAsB;CACtB,gBAAgB,IAAI;CAEpB,MAAM,UAAU,IAAI,YAAY,aAAa,IAAI;CAEjD,uBAAuB,SAAS,cAAc,EAAE;AAClD;AAEA,eAAsB,sBACpB,OACA,IACA,SACA,UACe;CACf,MAAM,qBAAqB,CAAC,CAAC;CAE7B,MAAM,UACJ,IACA,YAAY,sBACZ,MAAM,qBAAqB,SAAS,OACtC;CAEA,uBAAuB,SAAS,cAAc,EAAE;AAClD"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { i as __toESM, n as __exportAll, t as __commonJSMin } from "./rolldown-runtime-DZ8SGSJo.js";
|
|
2
2
|
import { t as Signal } from "./dist-Bxg3C_zy.js";
|
|
3
|
-
import { a as getStorageStatus, o as invalidateStorageRoot, r as getOpfsRootDirName, s as isStaleHandleError, t as getGroupDir } from "./getGroupDir-
|
|
4
|
-
import { o as DEFAULT_GROUP_ID, r as CONFIG_KEYS } from "./config-
|
|
3
|
+
import { a as getStorageStatus, o as invalidateStorageRoot, r as getOpfsRootDirName, s as isStaleHandleError, t as getGroupDir } from "./getGroupDir-MHv7Lvmp.js";
|
|
4
|
+
import { o as DEFAULT_GROUP_ID, r as CONFIG_KEYS } from "./config-DZkF9LiO.js";
|
|
5
5
|
import { t as getConfig } from "./getConfig-B7JdRqIY.js";
|
|
6
6
|
import { t as parsePath } from "./parsePath-rArsS7VY.js";
|
|
7
7
|
import { t as setConfig } from "./setConfig-CmvLryM3.js";
|
|
8
8
|
import { t as TOOL_DEFINITIONS } from "./tools-BQpz4Hkp.js";
|
|
9
9
|
import "./tools-d8Wgmt5f.js";
|
|
10
|
-
import { S as toTrustedScriptUrl, n as computeSha256 } from "./utils-
|
|
10
|
+
import { S as toTrustedScriptUrl, n as computeSha256 } from "./utils-CzgKe_XZ.js";
|
|
11
11
|
import { t as require_buffer } from "./buffer-BEXn271X.js";
|
|
12
12
|
|
|
13
13
|
//#region src/storage/readGroupFile.ts
|
|
@@ -9391,4 +9391,4 @@ const toolsStore = new ToolsStore();
|
|
|
9391
9391
|
|
|
9392
9392
|
//#endregion
|
|
9393
9393
|
export { groupFileExists as a, writeOpfsPathViaWorker as c, DEFAULT_BUILTIN_PROFILE as d, readGroupFile as f, require_gray_matter as i, findDeclarativeTool as l, tools_exports as n, writeGroupFile as o, parseSkill as r, writeFileHandle as s, toolsStore as t, loadDeclarativeTools as u };
|
|
9394
|
-
//# sourceMappingURL=tools-
|
|
9394
|
+
//# sourceMappingURL=tools-Cmhpk3X8.js.map
|