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
|
@@ -71,6 +71,8 @@ The `shadow-claw-pages` web component handles rendering the UI and displaying fi
|
|
|
71
71
|
### Navigation & URL State Synchronization
|
|
72
72
|
|
|
73
73
|
- **URL Sync & App Route Validation**: Selecting or reordering pages dispatches navigation events (`shadow-claw-navigate`) and updates browser URL history via `history.pushState()`, preserving active page state across refreshes. Same-origin link navigation uses `isPossibleAppRoute(pathname)` to validate internal routes against top-level valid pages (`VALID_PAGES`) and static route manifests; same-origin links pointing to non-app paths (such as external demo applications or static deployments) bypass SPA router interception and fall back to native browser navigation (`window.open`).
|
|
74
|
+
- **Root Pretty Path Resolution**: `src/storage/staticRouting.ts` supports mapping root paths (`/` and `/index.html`) directly to page definitions (e.g. `/pages/main/index.html`) via `"prettyPath": "/"`, and reverse-resolves root page routes back to `"/"`.
|
|
75
|
+
- **In-Feed Scroll & Navigation Guarding**: `replaceState` navigations with state flags (`inFeedScroll: true`, `scrollSpy: true`, or `suppressRouter: true` in history or Navigation API destination state) are bypassed by the router in `getRoute` and `popstateListener`, preventing unnecessary page resets and view thrashing during scroll-driven URL synchronization.
|
|
74
76
|
- **Ebook-Style Pagination**: Includes Previous (`[data-pages-prev]`) and Next (`[data-pages-next]`) page controls. Navigation buttons are dynamically enabled/disabled and set to `hidden` (`display: none !important`) based on current page index to avoid layout shifts.
|
|
75
77
|
- **Keyboard & Gesture Navigation**: Supports `ArrowLeft` and `ArrowRight` keyboard navigation for page turning, with strict focus guards to prevent interference when typing in inputs or content-editable regions. Swipe gestures are fully supported via touch and mouse drag interactions, including swipe passthrough from sandboxed iframe previews via `postMessage`.
|
|
76
78
|
- **Accessibility Announcements**: Uses an `aria-live` announcer to provide immediate screen reader feedback (`Navigated to page: [Title]`) when the active page changes.
|
|
@@ -130,24 +132,29 @@ Applications pre-rendered with Declarative Shadow DOM (DSD) shell via `src/cli/p
|
|
|
130
132
|
- When navigating to pages not embedded in the initial HTML or stored in local storage, `shadow-claw-pages` and `getStaticPageContent()` dynamically fetch individual markdown files from `static-main/` or fallback to `static-main-manifest.json`.
|
|
131
133
|
- **Pretty Paths & Sub-Routes**:
|
|
132
134
|
- Configured via `routes.json` (normally `pages/routes.json`) to map markdown page sources to clean URL paths (e.g. `/2026/06/30/on-developing-loops/`). Candidate locations include `pages/resources/`, `pages/deps/`, `resources/`, `deps/`, `pages/`, and the project root.
|
|
133
|
-
- Supports recursive nested `subRoutes` entries matching child URL hierarchies.
|
|
135
|
+
- Supports recursive nested `subRoutes` entries matching child URL hierarchies, as well as root pretty path mapping (`"prettyPath": "/"`).
|
|
134
136
|
- The pre-render pipeline generates dedicated physical `index.html` files with page-specific DSD templates.
|
|
135
137
|
- If no `routes.json` exists, pretty-path generation is skipped without failing the build.
|
|
136
138
|
- **Static Routing Manifest**:
|
|
137
139
|
- Embedded via `#shadow-claw-static-routing` JSON script tags or fetched via `static-routing.json` (`src/storage/staticRouting.ts`), allowing client-side router (`app-routes.ts`) and pages component to resolve routes asynchronously (`resolvePrettyPathToRouteAsync`, `parseRouteFromUrlAsync`) across Node.js, Electron, and GitHub Pages.
|
|
138
140
|
- **Server Middleware Fallbacks**:
|
|
139
|
-
- Express server includes static file middleware serving fallback content from `pages/main` for `/files/main/`, `/static-main/`, and `/pages/`, alongside SPA redirect fallback middleware for clean URL reloads.
|
|
141
|
+
- Express server includes static file middleware serving fallback content from `pages/main` for `/files/main/`, `/static-main/`, and `/pages/`, alongside SPA redirect fallback middleware for clean URL reloads, serving `index.html` for app routes even when matching directories exist on disk.
|
|
140
142
|
- **DSD Shell Override**:
|
|
141
143
|
- Enabled via the "Override pre-rendered content" toggle in Settings (`CONFIG_KEYS.OVERRIDE_PRERENDER_SKELETON`). Hides the initial DSD shell on boot, showing the skeleton loader until hydration finishes.
|
|
142
144
|
- **Declarative Configuration (`shadow-claw.config.json`)**:
|
|
143
145
|
- Template repositories and content publishers can declaratively brand and customize the site shell without editing ShadowClaw source files. The canonical location is `shadow-claw.config.json` in the project root (legacy `site-config.json` is also supported for backward compatibility):
|
|
144
146
|
- **`site`**: `title`, `description`, `themeColor`, `lang`.
|
|
145
147
|
- **`branding`**: `titleText`, `siteUrl`, `repoUrl`, `repoLabel`, `faviconPath`, `appleTouchIconPath`, `logoSlotHtml`.
|
|
146
|
-
- **`sidebar`**: `pagesHidden`, `chatHidden`, `tasksHidden`, `filesHidden`, `defaultPage` (`"pages"` | `"chat"` | `"tasks"` | `"files"`).
|
|
148
|
+
- **`sidebar`**: `pagesHidden`, `chatHidden`, `tasksHidden`, `filesHidden`, `defaultPage` (`"pages"` | `"chat"` | `"tasks"` | `"files"`), `slotHtml` (raw HTML string), `slotPath` (path to a custom sidebar HTML file), `sections` (array of declarative sidebar sections with `title`, `headerHref`, `items: [{ title, label, href, target, rel, active }]`, or `html`).
|
|
147
149
|
- **`pages`**: `sortOrder` (`"asc"` | `"desc"`), `defaultPinnedPage`.
|
|
148
150
|
- **`theme`**: `stylesheet` (custom theme CSS stylesheet injected into head).
|
|
149
151
|
- **`settings`**: `assistantName` (pre-seeds the default assistant name), `defaultToolsProfile` (pre-seeds the default tool profile e.g. `"__builtin_default"` or `"none"`), `enabledTools` (pre-seeds default enabled built-in tool array).
|
|
150
152
|
- **`cacheDir`** / **`server.cacheDir`**: Custom directory for storing cache, control tokens, and SQLite databases.
|
|
153
|
+
- **Slotted Sidebar & Custom Sections**:
|
|
154
|
+
- The root `<shadow-claw>` web component exposes named slots for custom navigation: `slot="sidebar-nav"`, `slot="sidebar"`, `slot="sidebar-content"`, and `slot="sidebar-footer"`.
|
|
155
|
+
- `applySiteConfig` discovers sidebar markup from `sidebar.slotHtml`, `sidebar.sections`, or auto-discovered candidate files (`pages/main/sidebar.html`, `pages/sidebar.html`, `sidebar.html`, `resources/sidebar.html`), patching the markup directly into `<shadow-claw>` light DOM.
|
|
156
|
+
- Slotted links (`.sidebar-link`, `[slot^="sidebar"] a`) automatically synchronize active classes (`.active`) and `aria-current="page"` via `syncSlottedSidebarActiveLinks` on route changes, `popstate`, and Navigation API `navigate`.
|
|
157
|
+
- On mobile viewports (<896px), clicking any slotted sidebar link automatically closes the navigation drawer.
|
|
151
158
|
- **Build-Time Application**: `src/cli/site-config/apply.ts` patches `index.html`, `manifest.json`, `sitemap.xml` / `sitemap.txt`, and copies custom theme stylesheets into the build distribution. Stylesheets under `pages/resources/`, `pages/deps/`, `resources/`, `deps/`, `pages/assets/`, or `pages/main/assets/` are flattened to the distribution root and have that prefix removed from the generated `href`; other paths, such as `pages/main/theme.css`, retain their path.
|
|
152
159
|
- **Branding Asset Precedence**: For `faviconPath` and `appleTouchIconPath`, content-specific locations under `pages/` and its supported resource/dependency paths are checked before bare repository-root defaults, so a published site's branding assets are not shadowed by ShadowClaw's built-in assets.
|
|
153
160
|
- **DSD Shell Navigation Visibility**: `src/cli/prerender/dsd-shell/prerender-dsd-shell.ts` applies `hidden` and `aria-hidden` attributes to sidebar navigation items at build time, preventing layout shift on first paint.
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Theming, Stylesheets & Layout Customization
|
|
2
|
+
|
|
3
|
+
> Architecture, configuration, and styling patterns for theming ShadowClaw sites, customizing layout tokens, and styling slotted components across light and shadow DOM boundaries.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
ShadowClaw provides a layered theming and templating system designed for both standalone AI assistant deployments and published static documentation hubs or personal sites. The styling architecture operates across two distinct DOM domains:
|
|
10
|
+
|
|
11
|
+
1. **Shadow DOM (Component Internals)**:
|
|
12
|
+
- Built-in web components (`<shadow-claw>`, `<shadow-claw-pages>`, `<shadow-claw-chat>`, `<shadow-claw-dialog>`, etc.) render inside open Shadow Roots with pre-rendered Declarative Shadow DOM (DSD) templates.
|
|
13
|
+
- These components are insulated from external CSS rules, but inherit and reflect global **CSS Custom Properties** (`--shadow-claw-*`).
|
|
14
|
+
2. **Light DOM (Slotted Content & Custom Shell)**:
|
|
15
|
+
- Slotted elements injected into named slots (`slot="sidebar"`, `slot="sidebar-nav"`, `slot="sidebar-content"`, `slot="sidebar-footer"`, `slot="header-actions-logo"`, `slot="logo"`) live directly in the host page's Light DOM.
|
|
16
|
+
- These elements are styled using standard CSS selectors defined in the site's custom stylesheet (`theme.stylesheet`).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Configuration (`shadow-claw.config.json`)
|
|
21
|
+
|
|
22
|
+
Custom theming is declared in the root configuration file (`shadow-claw.config.json` or legacy `site-config.json`):
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"theme": {
|
|
27
|
+
"stylesheet": "pages/main/theme.css"
|
|
28
|
+
},
|
|
29
|
+
"sidebar": {
|
|
30
|
+
"pagesHidden": true,
|
|
31
|
+
"chatHidden": true,
|
|
32
|
+
"tasksHidden": true,
|
|
33
|
+
"filesHidden": true,
|
|
34
|
+
"defaultPage": "pages"
|
|
35
|
+
},
|
|
36
|
+
"branding": {
|
|
37
|
+
"titleText": "My Custom Site",
|
|
38
|
+
"faviconPath": "pages/resources/favicon.ico",
|
|
39
|
+
"appleTouchIconPath": "pages/resources/icon-192x192.png"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### `theme.stylesheet`
|
|
45
|
+
|
|
46
|
+
- **Build-Time Processing**: When `theme.stylesheet` is defined:
|
|
47
|
+
- `src/cli/site-config/apply.ts` locates the source stylesheet.
|
|
48
|
+
- The stylesheet is copied into the distribution directory (`dist/public/`).
|
|
49
|
+
- An HTML link tag (`<link rel="stylesheet" href="..." />`) is injected immediately before the closing `</head>` in `dist/public/index.html` and across all pre-rendered pretty path `index.html` files.
|
|
50
|
+
- **Path Resolution & Asset Flattening**:
|
|
51
|
+
- Stylesheets located in resource folders (`pages/resources/`, `pages/deps/`, `resources/`, `deps/`, `pages/assets/`, or `pages/main/assets/`) are flattened to the root of the distribution directory, and their href prefix is automatically resolved.
|
|
52
|
+
- Custom paths such as `pages/main/theme.css` retain their posix path relative to `<base href="/">`.
|
|
53
|
+
- External stylesheets starting with `http://`, `https://`, or `//` are preserved verbatim.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## CSS Custom Properties (Theme Tokens)
|
|
58
|
+
|
|
59
|
+
ShadowClaw exposes CSS variables across several functional categories:
|
|
60
|
+
|
|
61
|
+
### 1. Layout & Shell Visibility Overrides
|
|
62
|
+
|
|
63
|
+
These tokens allow a custom site to selectively hide or reconfigure default built-in chrome without modifying core component templates:
|
|
64
|
+
|
|
65
|
+
| CSS Custom Property | Default | Purpose / Usage |
|
|
66
|
+
| :----------------------------------------------- | :------- | :------------------------------------------------------------------------------------------ |
|
|
67
|
+
| `--shadow-claw-sidebar-footer-display` | `block` | Set to `none` to hide the default sidebar footer containing the Settings button. |
|
|
68
|
+
| `--shadow-claw-header-main-toggle-display` | `block` | Set to `none` to hide the top-left main app drawer / hamburger toggle button in the header. |
|
|
69
|
+
| `--shadow-claw-page-header-display` | `flex` | Set to `none` to hide the `<shadow-claw-page-header>` component entirely. |
|
|
70
|
+
| `--shadow-claw-pages-dropdown-container-display` | `flex` | Set to `none` to hide the page navigation dropdown / breadcrumb selector. |
|
|
71
|
+
| `--shadow-claw-article-header-margin-bottom` | `1.5rem` | Controls the bottom margin beneath markdown article headers. |
|
|
72
|
+
|
|
73
|
+
### 2. Design Tokens (Colors, Typography & Radii)
|
|
74
|
+
|
|
75
|
+
Defined globally in `index.css`:
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
:root {
|
|
79
|
+
/* Fonts */
|
|
80
|
+
--shadow-claw-font-sans:
|
|
81
|
+
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
82
|
+
--shadow-claw-font-mono: "Fira Code", "Courier New", monospace;
|
|
83
|
+
|
|
84
|
+
/* Colors (Light Mode) */
|
|
85
|
+
--shadow-claw-bg-primary: #f8fafc;
|
|
86
|
+
--shadow-claw-bg-secondary: #f1f5f9;
|
|
87
|
+
--shadow-claw-bg-tertiary: #e2e8f0;
|
|
88
|
+
--shadow-claw-border-color: #e2e8f0;
|
|
89
|
+
--shadow-claw-text-primary: #0f172a;
|
|
90
|
+
--shadow-claw-text-secondary: #475569;
|
|
91
|
+
--shadow-claw-text-tertiary: #64748b;
|
|
92
|
+
--shadow-claw-link: #1e40af;
|
|
93
|
+
--shadow-claw-link-hover: #334155;
|
|
94
|
+
--shadow-claw-accent-primary: #334155;
|
|
95
|
+
--shadow-claw-accent-hover: #1e293b;
|
|
96
|
+
|
|
97
|
+
/* Border Radii */
|
|
98
|
+
--shadow-claw-radius-s: 0.5rem;
|
|
99
|
+
--shadow-claw-radius-m: 0.75rem;
|
|
100
|
+
--shadow-claw-radius-l: 1.25rem;
|
|
101
|
+
--shadow-claw-radius-pill: 62.5rem;
|
|
102
|
+
|
|
103
|
+
/* Transitions */
|
|
104
|
+
--shadow-claw-duration-min: 150ms;
|
|
105
|
+
--shadow-claw-duration-regular: 300ms;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
In dark mode (`html.dark-mode`), variables automatically adapt or can be overridden via `@media (prefers-color-scheme: dark)` or `html.dark-mode` selectors.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Slotted Navigation & Viewport Containment
|
|
114
|
+
|
|
115
|
+
### Slotted Sidebar Elements
|
|
116
|
+
|
|
117
|
+
Custom sidebars can be supplied via `pages/main/sidebar.html`, `sidebar.slotHtml`, or declarative `sidebar.sections` in `shadow-claw.config.json`. These render into the light DOM within `<shadow-claw>`:
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<div slot="sidebar" class="sidebar-custom-sections">
|
|
121
|
+
<section class="sidebar-section">
|
|
122
|
+
<div class="sidebar-section-header"><span>Projects</span></div>
|
|
123
|
+
<div class="sidebar-item">
|
|
124
|
+
<a href="/project-a" class="sidebar-link">Project A</a>
|
|
125
|
+
</div>
|
|
126
|
+
</section>
|
|
127
|
+
</div>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Viewport Scroll Containment
|
|
131
|
+
|
|
132
|
+
To prevent dual scrollbars when using a custom slotted sidebar alongside scrollable main content, enforce viewport containment on the outer document:
|
|
133
|
+
|
|
134
|
+
```css
|
|
135
|
+
/* Prevent the outer SPA window from producing a secondary scrollbar */
|
|
136
|
+
html:has(shadow-claw),
|
|
137
|
+
body:has(shadow-claw) {
|
|
138
|
+
height: 100%;
|
|
139
|
+
height: 100dvh;
|
|
140
|
+
overflow: hidden;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Ensure the slotted sidebar container scrolls independently */
|
|
144
|
+
.sidebar-custom-sections {
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
gap: 0.5rem;
|
|
148
|
+
max-height: calc(100vh - 4rem);
|
|
149
|
+
max-height: calc(100dvh - 4rem);
|
|
150
|
+
overflow-y: auto;
|
|
151
|
+
padding: 0.5rem;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Active Link Synchronization
|
|
156
|
+
|
|
157
|
+
Slotted anchor elements (`.sidebar-link`, `[slot^="sidebar"] a`) automatically synchronize `.active` classes and `aria-current="page"` via `syncSlottedSidebarActiveLinks` on:
|
|
158
|
+
|
|
159
|
+
- History API events (`pushState`, `replaceState`, `popstate`).
|
|
160
|
+
- Modern Navigation API transitions (`navigate`).
|
|
161
|
+
- Route changes dispatched by the client-side router (`app-routes.ts`).
|
|
162
|
+
|
|
163
|
+
On viewports narrower than `896px` (mobile drawer), clicking any slotted link automatically collapses the navigation drawer.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Sandboxed Preview Iframe Theme Sync
|
|
168
|
+
|
|
169
|
+
When viewing markdown documents or HTML files in the Pages preview or File Viewer, content renders inside a sandboxed iframe. ShadowClaw ensures styling consistency across the iframe boundary via `src/ui/iframe-theme.ts`:
|
|
170
|
+
|
|
171
|
+
1. **Automatic Stylesheet Inclusion**:
|
|
172
|
+
- `getIframeThemeStylesheetLink(siteConfig)` inspects the active site configuration and injects the configured `theme.stylesheet` into the iframe's `<head>`.
|
|
173
|
+
2. **Computed CSS Property Reflection**:
|
|
174
|
+
- `getIframeThemeStyleHtml()` reads all computed `--*` CSS custom properties from `document.documentElement` and mirrors them into the iframe's `:root` style block.
|
|
175
|
+
3. **Color Scheme & Class Mirroring**:
|
|
176
|
+
- The iframe root receives the matching `.dark-mode` or `.light-mode` class and `color-scheme: dark | light` to prevent Flash of Unstyled Content (FOUC).
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Complete Theming Example
|
|
181
|
+
|
|
182
|
+
Below is a complete, working `pages/main/theme.css` example implementing custom layout tokens, viewport containment, and slotted sidebar styling:
|
|
183
|
+
|
|
184
|
+
```css
|
|
185
|
+
:root {
|
|
186
|
+
/* Hide unwanted built-in shell elements */
|
|
187
|
+
--shadow-claw-header-main-toggle-display: none;
|
|
188
|
+
--shadow-claw-page-header-display: none;
|
|
189
|
+
--shadow-claw-pages-dropdown-container-display: none;
|
|
190
|
+
--shadow-claw-sidebar-footer-display: none;
|
|
191
|
+
|
|
192
|
+
/* Custom Spacing */
|
|
193
|
+
--shadow-claw-article-header-margin-bottom: 1.5rem;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* Contain the outer viewport */
|
|
197
|
+
html:has(shadow-claw),
|
|
198
|
+
body:has(shadow-claw) {
|
|
199
|
+
height: 100%;
|
|
200
|
+
height: 100dvh;
|
|
201
|
+
overflow: hidden;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Slotted Sidebar Scroll & Layout */
|
|
205
|
+
.sidebar-custom-sections {
|
|
206
|
+
--shadow-claw-radius-m: var(--shadow-claw-radius-s, 0.375rem);
|
|
207
|
+
display: flex;
|
|
208
|
+
flex-direction: column;
|
|
209
|
+
gap: 0.5rem;
|
|
210
|
+
max-height: calc(100vh - 4rem);
|
|
211
|
+
max-height: calc(100dvh - 4rem);
|
|
212
|
+
overflow-y: auto;
|
|
213
|
+
padding: 0.5rem;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.sidebar-section {
|
|
217
|
+
display: flex;
|
|
218
|
+
flex-direction: column;
|
|
219
|
+
gap: 0.125rem;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.sidebar-section-header {
|
|
223
|
+
color: var(--shadow-claw-text-secondary, #888);
|
|
224
|
+
font-size: var(--shadow-claw-font-size-sm, 0.875rem);
|
|
225
|
+
font-weight: 500;
|
|
226
|
+
padding: 0.25rem 0.5rem;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.sidebar-link {
|
|
230
|
+
color: var(--shadow-claw-text-primary);
|
|
231
|
+
text-decoration: none;
|
|
232
|
+
padding: 0.375rem 0.5rem;
|
|
233
|
+
border-radius: var(--shadow-claw-radius-s, 0.375rem);
|
|
234
|
+
transition: background-color var(--shadow-claw-duration-min) ease;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.sidebar-link:hover,
|
|
238
|
+
.sidebar-link.active {
|
|
239
|
+
background-color: var(--shadow-claw-bg-secondary);
|
|
240
|
+
color: var(--shadow-claw-link);
|
|
241
|
+
}
|
|
242
|
+
```
|
|
@@ -143,7 +143,32 @@ Executes a tool on a WebMCP `ModelContext` instance with backwards compatibility
|
|
|
143
143
|
1. Accepts an optional JavaScript object directly or a JSON string.
|
|
144
144
|
2. Calls `modelContext.executeTool(tool, inputObject, options)` first.
|
|
145
145
|
3. If the host environment rejects with an error starting with `"Failed to parse input"` (Chrome < 155 / `@mcp-b/webmcp-polyfill`) or a WebIDL `TypeError`, it retries with `JSON.stringify(inputObject)`.
|
|
146
|
-
|
|
146
|
+
|
|
147
|
+
### `getWebMcpEventTarget(type?): WebMcpEventTarget | null`
|
|
148
|
+
|
|
149
|
+
Resolves the appropriate `EventTarget` for WebMCP lifecycle events (`toolactivated` and `toolcancel`) with backwards compatibility across Chrome versions:
|
|
150
|
+
|
|
151
|
+
- **Chrome 156.0.8076.0+ (PR #245):** Returns `document.modelContext` when `ontoolactivated` or `ontoolcancel` exists on `document.modelContext`.
|
|
152
|
+
- **Chrome < 156:** Falls back to `window` where legacy event handlers resided.
|
|
153
|
+
- **Older Canary (< 152):** Checks `navigator.modelContext` if `document.modelContext` is not defined.
|
|
154
|
+
- **Node.js / Headless / Workers:** Safely returns `null` without throwing `ReferenceError`.
|
|
155
|
+
|
|
156
|
+
### `addWebMcpEventListener(type, listener, options?): () => void`
|
|
157
|
+
|
|
158
|
+
Safely registers a listener for WebMCP lifecycle events (`toolactivated`, `toolcancel`) with graceful degradation, event payload normalization, and automatic unsubscription:
|
|
159
|
+
|
|
160
|
+
- Automatically extracts and normalizes `toolName` whether passed on `event.toolName` (`ToolActivatedEvent` / `ToolCancelEvent`) or legacy `event.detail.toolName`.
|
|
161
|
+
- Returns an idempotent unsubscribe cleanup function `() => void`.
|
|
162
|
+
- Supports standard `AddEventListenerOptions` including `{ signal }` for `AbortSignal`-driven unsubscription.
|
|
163
|
+
- Supports `{ listenBoth: true }` to listen across both `document.modelContext` and `window` with tick-level deduplication during migration periods.
|
|
164
|
+
|
|
165
|
+
### `onWebMcpToolActivated(listener, options?): () => void`
|
|
166
|
+
|
|
167
|
+
Convenience helper to subscribe to tool execution start events (`toolactivated`). Returns an unsubscribe cleanup function.
|
|
168
|
+
|
|
169
|
+
### `onWebMcpToolCancel(listener, options?): () => void`
|
|
170
|
+
|
|
171
|
+
Convenience helper to subscribe to tool execution cancel events (`toolcancel`). Returns an unsubscribe cleanup function.
|
|
147
172
|
|
|
148
173
|
### `unregisterWebMcpTools(): void`
|
|
149
174
|
|
|
@@ -367,6 +392,69 @@ Internally, `executeWebMcpTool()`:
|
|
|
367
392
|
2. If `executeTool` rejects with an error starting with `"Failed to parse input"` or a `TypeError`, it transparently retries with `JSON.stringify(inputObject)`.
|
|
368
393
|
3. Propagates all other application or execution errors without retrying.
|
|
369
394
|
|
|
395
|
+
### Tool Lifecycle Events & Backward Compatibility (PR #245 / Chrome 156+)
|
|
396
|
+
|
|
397
|
+
Starting in Chrome 156.0.8076.0 (PR #245, superseding PR #146), the `ontoolactivated` and `ontoolcancel` event handler properties and lifecycle events moved from `window` to `document.modelContext`.
|
|
398
|
+
|
|
399
|
+
The WebMCP specification introduces dedicated event interfaces:
|
|
400
|
+
|
|
401
|
+
- `ToolActivatedEvent`: Dispatched when tool execution starts, exposing `readonly attribute DOMString toolName`.
|
|
402
|
+
- `ToolCancelEvent`: Dispatched when tool execution is cancelled, exposing `readonly attribute DOMString toolName`.
|
|
403
|
+
|
|
404
|
+
#### Backward Compatibility & Degradation Strategy
|
|
405
|
+
|
|
406
|
+
Because Chrome updates unevenly across user environments, enterprise installs, channels (Stable vs Dev vs Canary), and runtime shells (Electron, PWA, headless agents), ShadowClaw implements a robust target detection and subscription layer:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
import {
|
|
410
|
+
getWebMcpEventTarget,
|
|
411
|
+
addWebMcpEventListener,
|
|
412
|
+
onWebMcpToolActivated,
|
|
413
|
+
onWebMcpToolCancel,
|
|
414
|
+
} from "./webmcp.js";
|
|
415
|
+
|
|
416
|
+
// 1. Subscribe to tool execution start
|
|
417
|
+
const unsubscribeActivated = onWebMcpToolActivated(({ toolName }) => {
|
|
418
|
+
console.log(`Tool "${toolName}" started execution.`);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// 2. Subscribe to tool execution cancellation
|
|
422
|
+
const unsubscribeCancel = onWebMcpToolCancel(({ toolName }) => {
|
|
423
|
+
console.log(`Tool "${toolName}" execution is cancelled.`);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Clean up listeners when needed
|
|
427
|
+
unsubscribeActivated();
|
|
428
|
+
unsubscribeCancel();
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### Why ShadowClaw's Implementation is More Robust
|
|
432
|
+
|
|
433
|
+
While the canonical Chrome preview compat snippet checks:
|
|
434
|
+
|
|
435
|
+
```js
|
|
436
|
+
const targetFor = (type, listener, options) =>
|
|
437
|
+
(`on${type}` in (document.modelContext ?? {})
|
|
438
|
+
? document.modelContext
|
|
439
|
+
: window
|
|
440
|
+
).addEventListener(type, listener, options);
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
ShadowClaw's `getWebMcpEventTarget()` and `addWebMcpEventListener()` add essential production safeguards:
|
|
444
|
+
|
|
445
|
+
1. **Environment Safety:** Safely guards against `ReferenceError` when `document` or `window` are undefined (such as in Node.js headless CLI agents, background tasks, or Web Workers).
|
|
446
|
+
2. **Capability Verification:** Verifies that the resolved target actually implements `addEventListener` (guarding against partial mocks, older polyfills, or non-EventTarget objects).
|
|
447
|
+
3. **Multi-tier Fallback Chain:**
|
|
448
|
+
- Checks `document.modelContext` (Chrome 156+).
|
|
449
|
+
- Falls back to `navigator.modelContext` (retained for older Canary builds < 152).
|
|
450
|
+
- Falls back to `window` (Chrome < 156 legacy event location).
|
|
451
|
+
- Returns `null` cleanly in non-browser environments without throwing.
|
|
452
|
+
4. **Idempotent Cleanup:** Returns an unsubscription callback `() => void` to prevent memory leaks and dangling listeners.
|
|
453
|
+
5. **AbortSignal Support:** Accepts standard `AddEventListenerOptions` including `{ signal }` to automatically unsubscribe when an `AbortController` triggers.
|
|
454
|
+
6. **Payload Normalization:** Safely resolves `toolName` whether delivered directly via `ToolActivatedEvent` / `ToolCancelEvent` (`event.toolName`) or through legacy/custom event payloads (`event.detail.toolName`).
|
|
455
|
+
7. **Optional Dual-Coverage with Deduplication:** Allows `{ listenBoth: true }` to listen across both `modelContext` and `window` during migration/testing phases while deduplicating duplicate firings within the same tick.
|
|
456
|
+
8. **Orchestrator Event Bus Integration:** `syncWebMcpRegistration()` automatically binds WebMCP lifecycle events to `orchestrator.events`, emitting `"webmcp-tool-activated"` and `"webmcp-tool-cancel"` and cleaning up listeners during unregistration.
|
|
457
|
+
|
|
370
458
|
### Tool Querying & Graceful Degradation (`getWebMcpTools`)
|
|
371
459
|
|
|
372
460
|
ShadowClaw provides `getWebMcpTools()` to safely query registered WebMCP tools across different browser environments:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./getGroupDir-
|
|
1
|
+
import{t as e}from"./getGroupDir-CeSr4fzS.js";import{p as t}from"./tools-sOLCHTj8.js";async function n(n,r,i){let a=await e(n,r),{dirs:o,filename:s}=t(i),c=a;for(let e of o)c=await c.getDirectoryHandle(e);let l=await(await c.getFileHandle(s)).getFile(),u=URL.createObjectURL(l),d=document.createElement(`a`);d.href=u,d.download=s,document.body.appendChild(d),d.click(),document.body.removeChild(d),URL.revokeObjectURL(u)}export{n as t};
|
|
@@ -429,8 +429,9 @@ export const TIME_MINUTES_ONE = 60000;
|
|
|
429
429
|
- For Provider Help dialogs, mock provider errors to trigger the dialogs and verify the contextual instructions and links.
|
|
430
430
|
- **Remote MCP Testing**: Verify tool discovery, execution, and automatic OAuth reconnection flows by mocking streamable HTTP responses and OAuth failure modes.
|
|
431
431
|
- **Proxy Security Testing**: Verify that the `/proxy` endpoint rejects non-HTTP/S schemes (`file:`, `ftp:`, etc.) with `400` and blocks private/loopback IP targets (`localhost`, `127.*`, `10.*`, `192.168.*`, `169.254.*`) with `403`. Use the unit tests in `src/server/utils/proxy-helpers.test.ts` for scheme and SSRF guard coverage; E2E tests should verify that the authenticated service-worker format (body-based JSON with `Content-Type: application/json`) is still allowed to reach local tool servers.
|
|
432
|
-
- **Page Navigation Testing**: When testing pages or file viewer navigation, ensure keyboard events (`ArrowLeft`/`ArrowRight`) are properly guarded and do not trigger when the active element is an input or content-editable. Swipe gestures can be simulated using mouse events (`mousedown`, `mousemove`, `mouseup`) or touch events; ensure drag/text-selection does not trigger a false swipe. Assert that same-origin links are validated via `isPossibleAppRoute` so non-app routes (e.g. standalone demo subpaths) bypass SPA navigation and trigger native browser navigation (`window.open`).
|
|
433
|
-
- **Sidebar Visibility & Fallback Testing**: When verifying sidebar toggle controls, assert that hiding the currently active view triggers automatic navigation to the next available visible view (`getDefaultSidebarPage`).
|
|
432
|
+
- **Page Navigation Testing**: When testing pages or file viewer navigation, ensure keyboard events (`ArrowLeft`/`ArrowRight`) are properly guarded and do not trigger when the active element is an input or content-editable. Swipe gestures can be simulated using mouse events (`mousedown`, `mousemove`, `mouseup`) or touch events; ensure drag/text-selection does not trigger a false swipe. Assert that same-origin links are validated via `isPossibleAppRoute` so non-app routes (e.g. standalone demo subpaths) bypass SPA navigation and trigger native browser navigation (`window.open`). Verify root pretty path resolution (mapping `/` and `/index.html` to `{ page: "pages", groupId: "br:main", path: "index.html" }` and resolving `{ page: "pages" }` back to `/`), and assert that in-feed scroll / scroll-spy `replaceState` navigations with `inFeedScroll: true`, `scrollSpy: true`, or `suppressRouter: true` do not trigger router route changes or re-renders.
|
|
433
|
+
- **Sidebar Visibility & Fallback Testing**: When verifying sidebar toggle controls, assert that hiding the currently active view triggers automatic navigation to the next available visible view (`getDefaultSidebarPage`). For custom slotted sidebar links (`[slot="sidebar"]`, `[slot="sidebar-nav"]`, etc.), assert that link elements accurately reflect `.active` classes and `aria-current="page"` across route navigations, and clicking slotted links on mobile viewports (<896px) auto-closes the sidebar drawer.
|
|
434
|
+
- **Theming & Stylesheet Testing**: When testing custom themed deployments or template sites (`theme.stylesheet`), assert that `<link rel="stylesheet">` tags are placed before `</head>` in the document head without corrupting inlined scripts. Verify that layout tokens (e.g. `--shadow-claw-sidebar-footer-display: none;`, `--shadow-claw-header-main-toggle-display: none;`) correctly apply to shadow DOM elements, slotted `.sidebar-custom-sections` elements scroll independently within `max-height: calc(100dvh - 4rem)`, and preview iframes correctly load the custom stylesheet and inherit computed `--*` CSS custom properties.
|
|
434
435
|
- **Custom Element Guard Testing**: When testing custom elements in E2E or unit suites, verify that registering unapproved custom element tags throws a security error and DOM injection of unapproved custom element tags results in immediate removal by the DOM mutation guard. For custom element script descriptors (`customElements.scripts`), verify that object entries (`{ src, hasInit }`) are correctly parsed alongside legacy URLs, and `init()` is executed exclusively when `hasInit: true`.
|
|
435
436
|
- **Sandboxed Iframe & Storage Proxy Testing**: Verify preview iframe navigation and storage bridges in `file-viewer-preview-bridge.js` and `iframe-storage-bridge.js`. Assert that link clicks and programmatic navigation (`location.href`, `location.assign()`, `location.replace()`) relay navigation messages to the parent frame via `postMessage`, rebuilding the iframe `srcdoc` with injected `location.search` parameters before custom element scripts execute. Assert that `IndexedDB` and `localStorage` CRUD operations are proxied via `shadow-claw-storage-proxy` to parent storage, `showOpenFilePicker` and `showSaveFilePicker` degrade gracefully to input/download triggers, ServiceWorker/caches getters are trapped without `SecurityError` rejections, and `IframeBroadcastProxy` relays BroadcastChannel messages while suppressing command echo feedback loops via `isRelayingCommandFromParent`.
|
|
436
437
|
- **Peer & Room File Sharing Testing**: When verifying file actions in `<shadow-claw-files>` and `<shadow-claw-file-viewer>`, ensure tests assert that peer transfer options (`.files__send-peer`, `.modal-share-dropdown`) appear strictly when the conversation is a peer (`peer:...`) or room (`room:...`), and remain hidden in non-peer conversations. Verify that clicking peer transfer options correctly calls the underlying channel/store methods, shows typing indicators during transfer, and renders the sent attachment in the local chat stream.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as e,it as t,tt as n,v as r}from"./orchestrator-
|
|
1
|
+
import{W as e,it as t,tt as n,v as r}from"./orchestrator-BVnC4Vtt.js";function i(i,a){globalThis.__SHADOWCLAW_E2E__={isReady(){return i.ready},getDb(){return a.db},getActiveGroupId(){return i.activeGroupId},async createConversation(e){let t=a.db;if(!t)throw Error(`[E2E Bridge] DB not ready`);return i.createConversation(t,e)},async switchConversation(e){let t=a.db;if(!t)throw Error(`[E2E Bridge] DB not ready`);await i.switchConversation(t,e)},async loadTasks(){let e=a.db;if(!e)throw Error(`[E2E Bridge] DB not ready`);await i.loadTasks(e)},async configureProvider(o,s,c,l){let u=i.orchestrator,d=a.db;if(!u||!d)throw Error(`[E2E Bridge] Orchestrator or DB not ready`);await t(u,d,o,{loadApiKeyForProvider:u.loadApiKeyForProvider.bind(u),getApiKeyForHeaders:()=>e(u)}),await u.setApiKey(d,s),await n(u,d,c),await r(u,d,l)}}}function a(){return globalThis.__SHADOWCLAW_E2E_ENABLE__===!0}export{a as n,i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./config-
|
|
1
|
+
import{o as e}from"./config-Dewnqegf.js";import{t}from"./dist-B9m1QM9v.js";import{pn as n}from"./orchestrator-BVnC4Vtt.js";import{t as r}from"./getGroupDir-CeSr4fzS.js";import{f as i,p as a}from"./tools-sOLCHTj8.js";async function o(e,t,n){let i=await r(e,t),{dirs:o,filename:s}=a(n),c=i;for(let e of o)c=await c.getDirectoryHandle(e);return await(await c.getFileHandle(s)).getFile()}const s=new class{_file;constructor(){this._file=new t.State(null)}closeFile(){this._file.set(null)}get file(){return this._file.get()}getFile(){return this.file}getPreviewBinaryMimeType(e){return{"3gp":`video/3gpp`,"7z":`application/x-7z-compressed`,aac:`audio/aac`,apng:`image/apng`,avi:`video/x-msvideo`,avif:`image/avif`,bin:`application/octet-stream`,bmp:`image/bmp`,db:`application/vnd.sqlite3`,dll:`application/octet-stream`,dmg:`application/octet-stream`,dylib:`application/octet-stream`,exe:`application/vnd.microsoft.portable-executable`,flac:`audio/flac`,flv:`video/x-flv`,gif:`image/gif`,gz:`application/gzip`,heic:`image/heic`,heif:`image/heif`,ico:`image/x-icon`,iso:`application/octet-stream`,jpeg:`image/jpeg`,jpg:`image/jpeg`,m4a:`audio/mp4`,m4v:`video/mp4`,mkv:`video/x-matroska`,mov:`video/mp4`,mp3:`audio/mpeg`,mp4:`video/mp4`,oga:`audio/ogg`,ogg:`audio/ogg`,ogv:`video/ogg`,png:`image/png`,rar:`application/vnd.rar`,so:`application/octet-stream`,sqlite:`application/vnd.sqlite3`,sqlite3:`application/vnd.sqlite3`,tar:`application/x-tar`,tif:`image/tiff`,tiff:`image/tiff`,wasm:`application/wasm`,wav:`audio/wav`,weba:`audio/webm`,webm:`video/webm`,webp:`image/webp`,wmv:`video/x-ms-wmv`,zip:`application/zip`}[e.toLowerCase().split(`.`).pop()||``]||``}async openFile(t,r,a=e){try{let e=r.split(`/`).pop()||r,s=/\.pdf$/i.test(e),c=this.getPreviewBinaryMimeType(e);if(s){let i=await n(t,a,r);this._file.set({name:e,path:r,groupId:a,content:``,kind:`pdf`,binaryContent:i,mimeType:`application/pdf`});return}if(c){let n=await o(t,a,r);this._file.set({name:e,path:r,groupId:a,content:``,kind:`binary`,binaryContent:null,nativeFile:n,mimeType:c});return}let l=await i(t,a,r);this._file.set({name:e,path:r,groupId:a,content:l,kind:`text`,binaryContent:null,mimeType:`text/plain`})}catch(e){throw console.error(`Failed to open file:`,r,e),e}}};export{s as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-aKtaBQYM.js";import{r as t,x as n}from"./config-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-aKtaBQYM.js";import{r as t,x as n}from"./config-Dewnqegf.js";import{a as r}from"./app-routes-C6-H2zPH.js";import{t as i}from"./txPromise-C2iYogHX.js";import{t as a}from"./getConfig-4saf0Tkq.js";import{r as o}from"./headless-BbtDA5cs.js";import{t as s}from"./memoryStorage-ykv-Ri-y.js";async function c(e,...t){let n=e;for(let e of t){let t=await n.getDirectoryHandle(e,{create:!0});if(typeof n.isSameEntry==`function`&&await n.isSameEntry(t))throw Error(`Directory navigation failed: "${e}" resolved to the same directory as its parent. The stored directory handle may be stale — try re-selecting the storage folder.`);n=t}return n}function l(e,t){return i(e,`config`,`readwrite`,e=>e.delete(t)).then(()=>void 0)}let u=null;async function d(e,t){try{return await e.entries().next(),`granted`}catch{return t}}function f(){let e=r();return e?`${n}-${e}`:n}async function p(){try{if(typeof navigator<`u`&&navigator.storage&&typeof navigator.storage.getDirectory==`function`){let e=await navigator.storage.getDirectory(),t=f();return await e.getDirectoryHandle(t,{create:!0})}}catch(e){console.warn(`OPFS is unavailable (e.g. Firefox Private Browsing). Using in-memory storage fallback:`,e)}return s()}function m(e){if(!e||typeof e!=`object`)return!1;let t=globalThis.FileSystemDirectoryHandle;return t!==void 0&&e instanceof t||typeof e.getDirectoryHandle==`function`&&typeof e.getFileHandle==`function`}async function h(e){if(u)return u;try{let n=await a(e,t.STORAGE_HANDLE);if(m(n)){let e=n;if(typeof e.queryPermission==`function`&&await e.queryPermission({mode:`readwrite`})!==`granted`&&typeof e.requestPermission==`function`)try{await e.requestPermission({mode:`readwrite`})}catch{}return e}}catch(e){console.warn(`Failed to retrieve local storage handle from DB:`,e)}return p()}function g(e){u=e}function _(){u=null}function v(e){return e instanceof DOMException&&e.name===`InvalidStateError`}async function y(e){await l(e,t.STORAGE_HANDLE),u=null}async function b(e){if(u)try{let e=await u.queryPermission({mode:`readwrite`});return{type:`local`,permission:e===`granted`?`granted`:await d(u,e),name:u.name}}catch{console.warn(`Getting storage status failed for explicit storage root.`)}try{let n=await a(e,t.STORAGE_HANDLE);if(m(n)){let e=n,t=await e.queryPermission({mode:`readwrite`});return{type:`local`,permission:t===`granted`?`granted`:await d(e,t),name:e.name}}}catch(e){console.warn(`Failed to check storage status:`,e)}return{type:`opfs`,permission:`granted`,name:`OPFS`}}var x=e({getGroupDir:()=>S});async function S(e,t){let n=await h(e);return o()?n:c(n,`groups`,t.replace(/:/g,`-`))}export{b as a,y as c,h as i,g as l,x as n,_ as o,f as r,v as s,S as t};
|