shadow-claw 1.59.6 → 1.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.well-known/mcp/server-card.json +1 -1
- package/.well-known/mcp.json +1 -1
- package/README.md +6 -2
- package/dist/cli/build/build.js +1 -1
- package/dist/cli/chunk-3C5izdQW.js +1 -0
- package/dist/cli/chunk-B-75h9gX.js +1 -0
- package/dist/cli/{chunk-C9o6lXP3.js → chunk-B7Kn-otm.js} +1 -1
- package/dist/cli/{chunk-YX32FcN7.js → chunk-BBczgswQ.js} +1 -1
- package/dist/cli/{chunk-DcNxjqH6.js → chunk-BE-lYWcn.js} +1 -1
- package/dist/cli/{chunk-DJqHK-qS.js → chunk-BECr0WxI.js} +11 -11
- package/dist/cli/chunk-BEz1PD1_.js +1 -0
- package/dist/cli/chunk-BLzI1Fp2.js +1 -0
- package/dist/cli/{chunk-yiVdvGCJ.js → chunk-BVSC1MNQ.js} +11 -11
- package/dist/cli/{chunk-CX2itile.js → chunk-BdWcep6o.js} +1 -1
- package/dist/cli/{chunk-DLde6nuO.js → chunk-BfTpnSS4.js} +1 -1
- package/dist/cli/{chunk-D2_eAO83.js → chunk-BgvqTf7w.js} +1 -1
- package/dist/cli/chunk-BwsJfUT3.js +1 -0
- package/dist/cli/{chunk--PFY91kE.js → chunk-C9b4b7c_.js} +1 -1
- package/dist/cli/{chunk-D3y7h9Xe.js → chunk-CAw9XYFe.js} +1 -1
- package/dist/cli/chunk-CFCcbFs2.js +396 -0
- package/dist/cli/{chunk-Cnjb8Usu.js → chunk-CTarF4FC.js} +1 -1
- package/dist/cli/{chunk-DM4xsTry.js → chunk-Cbq5hpjb.js} +4 -4
- package/dist/cli/chunk-CjTjKy_v.js +310 -0
- package/dist/cli/chunk-Cjyu4cr_.js +36 -0
- package/dist/cli/{chunk-DUGZPka_.js → chunk-ClMKygjZ.js} +1 -1
- package/dist/cli/chunk-Cppnq1KF.js +1 -0
- package/dist/cli/{chunk-DvemF16v.js → chunk-D9QCNFMO.js} +1 -1
- package/dist/cli/chunk-DB21BMqt.js +7 -0
- package/dist/cli/{chunk-_Vo-o_e3.js → chunk-DHoIWvCc.js} +1 -1
- package/dist/cli/chunk-DZEN9T5y.js +1 -0
- package/dist/cli/{chunk-5rLO4DWS.js → chunk-Dl14OyYO.js} +9 -9
- package/dist/cli/chunk-Dl_vv0dI.js +1 -0
- package/dist/cli/chunk-Dpmfhlyl.js +1 -0
- package/dist/cli/{chunk-BrR1DOBS.js → chunk-Du7Xtucq.js} +1 -1
- package/dist/cli/{chunk-Bc_weULz.js → chunk-DxcDFUi_.js} +1 -1
- package/dist/cli/{chunk-Dt7-hzJU.js → chunk-DyyEWbV7.js} +1 -1
- package/dist/cli/chunk-N0x3mXU0.js +1 -0
- package/dist/cli/{chunk-CGoE4llV.js → chunk-V-w0Bata.js} +1 -1
- package/dist/cli/{chunk-C8DBACtx.js → chunk-ZxDxSSn-.js} +1 -1
- package/dist/cli/chunk-lPvFUkd5.js +7 -0
- package/dist/cli/{chunk-Ctg5L55n.js → chunk-n5s-sCdU.js} +1 -1
- package/dist/cli/{chunk-Dw8GndPD.js → chunk-nD9VPVMq.js} +1 -1
- package/dist/cli/{chunk-Cq_kQohv.js → chunk-rFuy8aS_.js} +1 -1
- package/dist/cli/{chunk-Bq38OubR.js → chunk-wjM6JXWa.js} +1 -1
- package/dist/cli/{chunk-3wTukVof.js → chunk-zcES9rut.js} +1 -1
- package/dist/cli/cli.js +3 -3
- package/dist/headless-agent.js +2 -2
- package/dist/lib/{app-routes-DJdIjp2V.js → app-routes-BXiRvlNl.js} +7 -25
- package/dist/lib/{app-routes-DJdIjp2V.js.map → app-routes-BXiRvlNl.js.map} +1 -1
- package/dist/lib/{attachment-capabilities-Dbb-4ZP5.js → attachment-capabilities-BjkEPip8.js} +2 -2
- package/dist/lib/{attachment-capabilities-Dbb-4ZP5.js.map → attachment-capabilities-BjkEPip8.js.map} +1 -1
- package/dist/lib/{channel-Dlru5ofR.js → channel-DB77spML.js} +3 -3
- package/dist/lib/{channel-Dlru5ofR.js.map → channel-DB77spML.js.map} +1 -1
- package/dist/lib/{chat-template-BuuLY8l7.js → chat-template-DPEKGJhB.js} +2 -2
- package/dist/lib/{chat-template-BuuLY8l7.js.map → chat-template-DPEKGJhB.js.map} +1 -1
- package/dist/lib/{compact-context-BtR55YPU.js → compact-context-Q9t9aL1e.js} +19 -19
- package/dist/lib/{compact-context-BtR55YPU.js.map → compact-context-Q9t9aL1e.js.map} +1 -1
- package/dist/lib/components/common/shadow-claw-provider-model-picker.js +1 -1
- package/dist/lib/components/index.js +27 -27
- 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-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-provider-model-picker.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-DxNI3TlW.js → config-BrHR97zt.js} +2 -2
- package/dist/lib/{config-DxNI3TlW.js.map → config-BrHR97zt.js.map} +1 -1
- package/dist/lib/{configure-peer-js-ChDhOZU4.js → configure-peer-js-CgFiwoxY.js} +3 -3
- package/dist/lib/{configure-peer-js-ChDhOZU4.js.map → configure-peer-js-CgFiwoxY.js.map} +1 -1
- package/dist/lib/{connections-DC4NZkJE.js → connections-C1FWsBsE.js} +2 -2
- package/dist/lib/{connections-DC4NZkJE.js.map → connections-C1FWsBsE.js.map} +1 -1
- package/dist/lib/content/build-attachment-content-blocks.d.ts +2 -0
- package/dist/lib/{credentials-5vpz0XPk.js → credentials-CZbngHXW.js} +2 -2
- package/dist/lib/{credentials-5vpz0XPk.js.map → credentials-CZbngHXW.js.map} +1 -1
- package/dist/lib/{discover-skills-CD0sKvAI.js → discover-skills-CXyaWHKi.js} +13 -13
- package/dist/lib/{discover-skills-CD0sKvAI.js.map → discover-skills-CXyaWHKi.js.map} +1 -1
- package/dist/lib/{download-group-file-Dk3qaxhJ.js → download-group-file-D0wgg10Q.js} +2 -2
- package/dist/lib/{download-group-file-Dk3qaxhJ.js.map → download-group-file-D0wgg10Q.js.map} +1 -1
- package/dist/lib/{file-viewer-B4pRW-_G.js → file-viewer-DOfvX6yy.js} +5 -5
- package/dist/lib/{file-viewer-B4pRW-_G.js.map → file-viewer-DOfvX6yy.js.map} +1 -1
- package/dist/lib/{get-or-create-subscriber-id-HCcgDEPz.js → get-or-create-subscriber-id-wyzaML7Z.js} +2 -2
- package/dist/lib/{get-or-create-subscriber-id-HCcgDEPz.js.map → get-or-create-subscriber-id-wyzaML7Z.js.map} +1 -1
- package/dist/lib/{git-B3Q1euc5.js → git-CogDRlEz.js} +5 -5
- package/dist/lib/{git-B3Q1euc5.js.map → git-CogDRlEz.js.map} +1 -1
- package/dist/lib/{iframe-bridge-scripts-D8iuFhUk.js → iframe-bridge-scripts-Dx825LLG.js} +2 -2
- package/dist/lib/{iframe-bridge-scripts-D8iuFhUk.js.map → iframe-bridge-scripts-Dx825LLG.js.map} +1 -1
- package/dist/lib/index.js +28 -28
- package/dist/lib/{init-chat-split-resize-B0ODULx9.js → init-chat-split-resize-Cc0bd2z9.js} +2 -2
- package/dist/lib/{init-chat-split-resize-B0ODULx9.js.map → init-chat-split-resize-Cc0bd2z9.js.map} +1 -1
- package/dist/lib/{init-control-plane-C1FRRmjC.js → init-control-plane-CEGdzgWX.js} +15 -15
- package/dist/lib/{init-control-plane-C1FRRmjC.js.map → init-control-plane-CEGdzgWX.js.map} +1 -1
- package/dist/lib/{invoke-agent-CzN7sVh-.js → invoke-agent-cac3gCsj.js} +11 -11
- package/dist/lib/{invoke-agent-CzN7sVh-.js.map → invoke-agent-cac3gCsj.js.map} +1 -1
- package/dist/lib/{markdown-mbNo7cV3.js → markdown--6vTAPEH.js} +2 -2
- package/dist/lib/{markdown-mbNo7cV3.js.map → markdown--6vTAPEH.js.map} +1 -1
- package/dist/lib/{mcp-reconnect-3T7yWGEY.js → mcp-reconnect-BeqQvNWO.js} +3 -3
- package/dist/lib/{mcp-reconnect-3T7yWGEY.js.map → mcp-reconnect-BeqQvNWO.js.map} +1 -1
- package/dist/lib/{model-ranking-DGNSWYwN.js → model-ranking-BhsJV7vb.js} +2 -2
- package/dist/lib/{model-ranking-DGNSWYwN.js.map → model-ranking-BhsJV7vb.js.map} +1 -1
- package/dist/lib/{move-group-entry-NMTJ59M9.js → move-group-entry-D8dptMg0.js} +5 -5
- package/dist/lib/{move-group-entry-NMTJ59M9.js.map → move-group-entry-D8dptMg0.js.map} +1 -1
- package/dist/lib/{orchestrator-B8FV1V7x.js → orchestrator-BBAwy9Nm.js} +24 -24
- package/dist/lib/{orchestrator-B8FV1V7x.js.map → orchestrator-BBAwy9Nm.js.map} +1 -1
- package/dist/lib/{orchestrator-i_QJ-o22.js → orchestrator-cRBe3lhq.js} +11 -11
- package/dist/lib/orchestrator-cRBe3lhq.js.map +1 -0
- package/dist/lib/{parse-path-DPCn-HwI.js → parse-path-BOHQP_IQ.js} +3 -3
- package/dist/lib/{parse-path-DPCn-HwI.js.map → parse-path-BOHQP_IQ.js.map} +1 -1
- package/dist/lib/{peerjs-z5zeioPV.js → peerjs-BLg8aGUj.js} +8 -8
- package/dist/lib/{peerjs-z5zeioPV.js.map → peerjs-BLg8aGUj.js.map} +1 -1
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js → process-peer-query-param-BnsVnxzH.js} +5 -5
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js.map → process-peer-query-param-BnsVnxzH.js.map} +1 -1
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js → process-pending-shared-payloads-DBZfZOOa.js} +4 -4
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js.map → process-pending-shared-payloads-DBZfZOOa.js.map} +1 -1
- package/dist/lib/{process-room-query-param-C3FFGGn6.js → process-room-query-param-B8EYg_-r.js} +4 -4
- package/dist/lib/{process-room-query-param-C3FFGGn6.js.map → process-room-query-param-B8EYg_-r.js.map} +1 -1
- package/dist/lib/{provider-DcQZypu5.js → provider-BC9KPI14.js} +3 -3
- package/dist/lib/{provider-DcQZypu5.js.map → provider-BC9KPI14.js.map} +1 -1
- package/dist/lib/{push-client-Cx5rMs6J.js → push-client-CAm6UMvE.js} +5 -5
- package/dist/lib/{push-client-Cx5rMs6J.js.map → push-client-CAm6UMvE.js.map} +1 -1
- package/dist/lib/{read-group-file-bytes-CXOG_YyM.js → read-group-file-bytes-UQIk1eJG.js} +2 -2
- package/dist/lib/{read-group-file-bytes-CXOG_YyM.js.map → read-group-file-bytes-UQIk1eJG.js.map} +1 -1
- package/dist/lib/{rooms-CwlkYLDU.js → rooms-Dzphx3rK.js} +2 -2
- package/dist/lib/{rooms-CwlkYLDU.js.map → rooms-Dzphx3rK.js.map} +1 -1
- package/dist/lib/{shadow-claw-DoQ7fgl5.js → shadow-claw-CGl8tXtG.js} +17 -20
- package/dist/lib/shadow-claw-CGl8tXtG.js.map +1 -0
- package/dist/lib/{shadow-claw-a2ui-Br6qJMs1.js → shadow-claw-a2ui-lG0vQbW8.js} +2 -2
- package/dist/lib/{shadow-claw-a2ui-Br6qJMs1.js.map → shadow-claw-a2ui-lG0vQbW8.js.map} +1 -1
- package/dist/lib/{shadow-claw-accounts-BTDILfWw.js → shadow-claw-accounts-CkqyCxwp.js} +3 -3
- package/dist/lib/{shadow-claw-accounts-BTDILfWw.js.map → shadow-claw-accounts-CkqyCxwp.js.map} +1 -1
- package/dist/lib/{shadow-claw-channel-config-IKiL34tI.js → shadow-claw-channel-config-BNIWCdsL.js} +4 -4
- package/dist/lib/{shadow-claw-channel-config-IKiL34tI.js.map → shadow-claw-channel-config-BNIWCdsL.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js → shadow-claw-channels-C2QSn4Ew.js} +3 -3
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js.map → shadow-claw-channels-C2QSn4Ew.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js → shadow-claw-chat-Wx3y9y6c.js} +15 -15
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js.map → shadow-claw-chat-Wx3y9y6c.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js → shadow-claw-control-plane-D5E4cFGu.js} +7 -7
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js.map → shadow-claw-control-plane-D5E4cFGu.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js → shadow-claw-conversations-BtDv7GRW.js} +7 -7
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js.map → shadow-claw-conversations-BtDv7GRW.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js → shadow-claw-file-viewer-CG40kwWV.js} +10 -10
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js.map → shadow-claw-file-viewer-CG40kwWV.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-DN7irmE1.js → shadow-claw-files-BOUULrlX.js} +11 -11
- package/dist/lib/{shadow-claw-files-DN7irmE1.js.map → shadow-claw-files-BOUULrlX.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-D-1oIh65.js → shadow-claw-git-BeHV73_9.js} +6 -6
- package/dist/lib/{shadow-claw-git-D-1oIh65.js.map → shadow-claw-git-BeHV73_9.js.map} +1 -1
- package/dist/lib/{shadow-claw-integrations-CZjnm7cM.js → shadow-claw-integrations-RZZ-m-Id.js} +4 -4
- package/dist/lib/{shadow-claw-integrations-CZjnm7cM.js.map → shadow-claw-integrations-RZZ-m-Id.js.map} +1 -1
- package/dist/lib/{shadow-claw-llm-4Gefh5FN.js → shadow-claw-llm-KONyWKZM.js} +9 -9
- package/dist/lib/{shadow-claw-llm-4Gefh5FN.js.map → shadow-claw-llm-KONyWKZM.js.map} +1 -1
- package/dist/lib/{shadow-claw-mcp-remote-B9ssb3YV.js → shadow-claw-mcp-remote-BKFROurv.js} +4 -4
- package/dist/lib/{shadow-claw-mcp-remote-B9ssb3YV.js.map → shadow-claw-mcp-remote-BKFROurv.js.map} +1 -1
- package/dist/lib/{shadow-claw-networking-BN5BB4hb.js → shadow-claw-networking-Diy3JJkc.js} +2 -2
- package/dist/lib/{shadow-claw-networking-BN5BB4hb.js.map → shadow-claw-networking-Diy3JJkc.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js → shadow-claw-notifications-C-upPa-4.js} +3 -3
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js.map → shadow-claw-notifications-C-upPa-4.js.map} +1 -1
- package/dist/lib/{shadow-claw-page-header-DMGO-TSe.js → shadow-claw-page-header-C_Qr3xZM.js} +2 -2
- package/dist/lib/{shadow-claw-page-header-DMGO-TSe.js.map → shadow-claw-page-header-C_Qr3xZM.js.map} +1 -1
- package/dist/lib/{shadow-claw-pages-BiRM6qiA.js → shadow-claw-pages-CfAjUKgd.js} +11 -11
- package/dist/lib/{shadow-claw-pages-BiRM6qiA.js.map → shadow-claw-pages-CfAjUKgd.js.map} +1 -1
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js → shadow-claw-peerjs-t4YibS9s.js} +6 -6
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js.map → shadow-claw-peerjs-t4YibS9s.js.map} +1 -1
- package/dist/lib/{shadow-claw-provider-model-picker-BXYXEobD.js → shadow-claw-provider-model-picker-B-Ct4yW-.js} +2 -2
- package/dist/lib/{shadow-claw-provider-model-picker-BXYXEobD.js.map → shadow-claw-provider-model-picker-B-Ct4yW-.js.map} +1 -1
- package/dist/lib/{shadow-claw-settings-CcT5EK08.js → shadow-claw-settings-Cg5V0e9g.js} +7 -7
- package/dist/lib/{shadow-claw-settings-CcT5EK08.js.map → shadow-claw-settings-Cg5V0e9g.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js → shadow-claw-storage-C7tCnsSG.js} +5 -5
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js.map → shadow-claw-storage-C7tCnsSG.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js → shadow-claw-task-server-BObsRdf8.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js.map → shadow-claw-task-server-BObsRdf8.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js → shadow-claw-tasks-B2EEqrcY.js} +9 -9
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js.map → shadow-claw-tasks-B2EEqrcY.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js → shadow-claw-terminal-DSHfO2b9.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js.map → shadow-claw-terminal-DSHfO2b9.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js → shadow-claw-tools-DwPBADua.js} +7 -7
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js.map → shadow-claw-tools-DwPBADua.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js → shadow-claw-webvm-CY4qGaMB.js} +3 -3
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js.map → shadow-claw-webvm-CY4qGaMB.js.map} +1 -1
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js → sync-web-mcp-registration-BiOZvW-R.js} +6 -6
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js.map → sync-web-mcp-registration-BiOZvW-R.js.map} +1 -1
- package/dist/lib/{system-prompt-DT_KeYaL.js → system-prompt-CxJ3Nx4c.js} +9 -8
- package/dist/lib/system-prompt-CxJ3Nx4c.js.map +1 -0
- package/dist/lib/{tools-Beuyh8y1.js → tools-B8OJ4sMF.js} +4 -4
- package/dist/lib/{tools-Beuyh8y1.js.map → tools-B8OJ4sMF.js.map} +1 -1
- package/dist/lib/{transformers-DydnReu4.js → transformers-BMURofG6.js} +2 -2
- package/dist/lib/{transformers-DydnReu4.js.map → transformers-BMURofG6.js.map} +1 -1
- package/dist/lib/{trusted-types-CfwZl_rr.js → trusted-types-HwsGS5Nj.js} +19 -17
- package/dist/lib/{trusted-types-CfwZl_rr.js.map → trusted-types-HwsGS5Nj.js.map} +1 -1
- package/dist/lib/{upload-group-file-BbBzjTcN.js → upload-group-file-CJpoNjEb.js} +3 -3
- package/dist/lib/{upload-group-file-BbBzjTcN.js.map → upload-group-file-CJpoNjEb.js.map} +1 -1
- package/dist/lib/utils/index.js +1 -1
- package/dist/lib/utils/namespaced-storage.js +1 -1
- package/dist/lib/utils/runtime-assets.js +1 -1
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/{webmcp-DCfAFiIO.js → webmcp-BoMTvgmX.js} +3 -3
- package/dist/lib/{webmcp-DCfAFiIO.js.map → webmcp-BoMTvgmX.js.map} +1 -1
- package/dist/lib/{write-group-file-bytes-Ccn-VFUU.js → write-group-file-bytes-CNT7DqOZ.js} +3 -3
- package/dist/lib/{write-group-file-bytes-Ccn-VFUU.js.map → write-group-file-bytes-CNT7DqOZ.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 +3 -1
- package/dist/public/README.md +6 -2
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/attachment-capabilities-AdwXt3--.js +1 -0
- package/dist/public/{channel-BylT3rJC.js → channel-DIpDQekL.js} +1 -1
- package/dist/public/{chat-template-DPHJy7tr.js → chat-template-CXKs8lFR.js} +1 -1
- package/dist/public/compact-context-BQ2ZXoAc.js +5 -0
- package/dist/public/{compact-context-BINQh64w.js → compact-context-dHitmPsV.js} +2 -2
- package/dist/public/config-C16fFWtP.js +1 -0
- package/dist/public/{configure-peer-js-DChhcOfe.js → configure-peer-js-DV1rqvFX.js} +1 -1
- package/dist/public/{connections-CHaw0VqP.js → connections-Dxwj8yK_.js} +1 -1
- package/dist/public/{create-model-cache-fetch-DQebkoPL.js → create-model-cache-fetch-B0mSCEk6.js} +1 -1
- package/dist/public/{credentials-CgVqS119.js → credentials-CJUQ5Ep2.js} +1 -1
- package/dist/public/{custom-element-security-kiDhPfb8.js → custom-element-security-B2daIE5r.js} +2 -2
- package/dist/public/{discover-skills-Cvmx5I9V.js → discover-skills-BWJB8HUA.js} +6 -6
- package/dist/public/docs/architecture/overview.md +1 -1
- package/dist/public/docs/example/article/index.html +29 -30
- package/dist/public/docs/example/article.html +29 -30
- package/dist/public/docs/publishing/index.html +29 -30
- package/dist/public/docs/publishing.html +29 -30
- package/dist/public/docs/skill-creator/index.html +29 -30
- package/dist/public/docs/skill-creator.html +29 -30
- package/dist/public/docs/subsystems/attachment-capabilities.md +14 -1
- package/dist/public/docs/subsystems/cli.md +95 -51
- package/dist/public/docs/subsystems/pages.md +5 -0
- package/dist/public/{download-group-file-BapoRgfU.js → download-group-file-BkMH-JKi.js} +1 -1
- package/dist/public/e2e/README.md +1 -1
- package/dist/public/{e2e-bridge-C0g8vZKr.js → e2e-bridge-lP2qqiv3.js} +1 -1
- package/dist/public/get-group-dir-D--BiEyk.js +1 -0
- package/dist/public/{get-or-create-subscriber-id-GvRZYXwA.js → get-or-create-subscriber-id-jVHnQfbr.js} +1 -1
- package/dist/public/{git-CaAAZfVd.js → git-DjmQ16rm.js} +2 -2
- package/dist/public/{iframe-bridge-scripts-BnqtKhE4.js → iframe-bridge-scripts-CO0izGjW.js} +1 -1
- package/dist/public/index.html +29 -30
- package/dist/public/index.js +1 -1
- package/dist/public/{init-chat-split-resize-Btonoy8u.js → init-chat-split-resize-C8AqCCiK.js} +1 -1
- package/dist/public/init-control-plane-Ctz7FI8M.js +1 -0
- package/dist/public/{invoke-agent-B3Osw6K7.js → invoke-agent-C_geruwq.js} +1 -1
- package/dist/public/llms.txt +1 -1
- package/dist/public/main/index.html +29 -30
- package/dist/public/main/memory/index.html +29 -30
- package/dist/public/main/memory.html +29 -30
- package/dist/public/main.html +29 -30
- package/dist/public/{markdown-CPbU4r1U.js → markdown-CDSb5Hrl.js} +1 -1
- package/dist/public/{mcp-reconnect-CzROVsXG.js → mcp-reconnect-iPZPihwX.js} +1 -1
- package/dist/public/{memory-storage-BkoMlxOr.js → memory-storage-2m7KZ-aP.js} +1 -1
- package/dist/public/{model-ranking-CK0iBo3Z.js → model-ranking-BgOSaNIy.js} +1 -1
- package/dist/public/{move-group-entry-CTxoq7lw.js → move-group-entry-QQ9Hkk54.js} +1 -1
- package/dist/public/{orchestrator-BrDjQbGf.js → orchestrator-C1kaTltu.js} +2 -2
- package/dist/public/orchestrator-Li1UAsv7.js +63 -0
- package/dist/public/{peerjs-CgF4Iz5W.js → peerjs-DbBryE-9.js} +1 -1
- package/dist/public/{process-peer-query-param-BL2k0Hu-.js → process-peer-query-param-DQIgr3KL.js} +1 -1
- package/dist/public/{process-pending-shared-payloads-C1AgGvn8.js → process-pending-shared-payloads-Ctb-TFqB.js} +1 -1
- package/dist/public/{process-room-query-param-DM0QCq3_.js → process-room-query-param-F-XnIVoZ.js} +1 -1
- package/dist/public/provider-YPZmsuHR.js +1 -0
- package/dist/public/{push-client-DJEOz7bi.js → push-client-DRx9Eggz.js} +1 -1
- package/dist/public/{rooms-C6LXIJl4.js → rooms-BurBI7is.js} +1 -1
- package/dist/public/service-worker/init.js +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/shadow-claw-Bg9AQ5x_.js +1176 -0
- package/dist/public/{shadow-claw-accounts--4hd_oCz.js → shadow-claw-accounts-B3mjYI0M.js} +1 -1
- package/dist/public/{shadow-claw-card-IbNlZAdK.js → shadow-claw-card-tcXRS1GF.js} +1 -1
- package/dist/public/{shadow-claw-channels-Vq_pPGa2.js → shadow-claw-channels-BiSfLvWv.js} +1 -1
- package/dist/public/{shadow-claw-chat-D7_GS25e.js → shadow-claw-chat-N5jMsXZZ.js} +3 -3
- package/dist/public/{shadow-claw-control-plane-WTMEV8_p.js → shadow-claw-control-plane-DFVe_Xdq.js} +2 -2
- package/dist/public/{shadow-claw-conversations-CLQgU1IT.js → shadow-claw-conversations-wAR06_ya.js} +1 -1
- package/dist/public/{shadow-claw-empty-state-D4CrFGsN.js → shadow-claw-empty-state-CnPm3NVM.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-BhqiqLWQ.js → shadow-claw-file-viewer-sZN_FCDW.js} +4 -4
- package/dist/public/{shadow-claw-files-senDiG9l.js → shadow-claw-files-CnvkCbd4.js} +2 -2
- package/dist/public/{shadow-claw-git-DOOCqY23.js → shadow-claw-git-BBHfClGk.js} +2 -2
- package/dist/public/{shadow-claw-integrations-Bsvc3Agq.js → shadow-claw-integrations-DvdBqzRJ.js} +1 -1
- package/dist/public/{shadow-claw-llm-actYICAk.js → shadow-claw-llm-YfohG519.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BYUgrK3v.js → shadow-claw-mcp-remote-BAVbf5pi.js} +1 -1
- package/dist/public/{shadow-claw-networking-Dk3p5Ny_.js → shadow-claw-networking-CZ4LWPW7.js} +1 -1
- package/dist/public/{shadow-claw-notifications-CzPAlay8.js → shadow-claw-notifications-BHwyREkG.js} +1 -1
- package/dist/public/{shadow-claw-page-header-CjJpVkyL.js → shadow-claw-page-header-De6Qf6eY.js} +1 -1
- package/dist/public/{shadow-claw-page-header-action-button-2DH5O1TD.js → shadow-claw-page-header-action-button-FSOhTc9z.js} +1 -1
- package/dist/public/{shadow-claw-pages-3r5I-wI8.js → shadow-claw-pages-D_oPyDca.js} +6 -6
- package/dist/public/{shadow-claw-pdf-viewer-BiCEwsoY.js → shadow-claw-pdf-viewer-CrU4wqRq.js} +1 -1
- package/dist/public/{shadow-claw-settings-DgB9RSZN.js → shadow-claw-settings-DkUhvxVr.js} +2 -2
- package/dist/public/{shadow-claw-storage-JB_43nd8.js → shadow-claw-storage-D0o56Tjw.js} +1 -1
- package/dist/public/{shadow-claw-task-server-oi5UIxdA.js → shadow-claw-task-server-4rkroO9K.js} +1 -1
- package/dist/public/{shadow-claw-tasks-CnyiOt81.js → shadow-claw-tasks-BdP7lmvu.js} +3 -3
- package/dist/public/{shadow-claw-terminal-BC3RynHt.js → shadow-claw-terminal-DVHX7Fsu.js} +1 -1
- package/dist/public/{shadow-claw-toast-YjG--2Za.js → shadow-claw-toast-B9Y9tSkW.js} +1 -1
- package/dist/public/{shadow-claw-tools-Bbwk4vlT.js → shadow-claw-tools-BwwY53Lr.js} +1 -1
- package/dist/public/{shadow-claw-webvm-HZqzl2H5.js → shadow-claw-webvm-CXGdkCNM.js} +1 -1
- package/dist/public/{sync-web-mcp-registration-BaH2nAP0.js → sync-web-mcp-registration-DVK_IhXZ.js} +1 -1
- package/dist/public/{system-prompt-Dck3N8T0.js → system-prompt-BmswoQwF.js} +2 -2
- package/dist/public/{tools-DHA1dK2I.js → tools-D-52Zmfc.js} +1 -1
- package/dist/public/{transformers-C-DuTM2K.js → transformers-CQ9ss9rD.js} +1 -1
- package/dist/public/{upload-group-file-Cejr3zo1.js → upload-group-file-A8kB7lvO.js} +1 -1
- package/dist/public/{webmcp-CMRtu57-.js → webmcp-DIUZjVF5.js} +1 -1
- package/dist/public/{workbox-92eae37e.js → workbox-e4022e15.js} +1 -1
- package/dist/public/{write-group-file-CmJuVQNO.js → write-group-file-R67DjJ-q.js} +1 -1
- package/dist/public/{write-group-file-bytes-Cejr3zo1.js → write-group-file-bytes-A8kB7lvO.js} +1 -1
- package/dist/public/{zip-reader-CuQ13eLe.js → zip-reader-JHoTbATw.js} +1 -1
- package/dist/server.js +6 -6
- package/package.json +1 -1
- package/dist/cli/chunk-2gZFafgY.js +0 -1
- package/dist/cli/chunk-BFziiMKt.js +0 -7
- package/dist/cli/chunk-BM3llsxb.js +0 -1
- package/dist/cli/chunk-BUNoeMKY.js +0 -36
- package/dist/cli/chunk-Bj5qFsDi.js +0 -7
- package/dist/cli/chunk-Bj95zm-y.js +0 -1
- package/dist/cli/chunk-BpyP-esT.js +0 -1
- package/dist/cli/chunk-CX696s3_.js +0 -1
- package/dist/cli/chunk-DRxCrCAA.js +0 -139
- package/dist/cli/chunk-DjbCHa0h.js +0 -1
- package/dist/cli/chunk-Ds5-K-9o.js +0 -1
- package/dist/cli/chunk-DsQhAF31.js +0 -1
- package/dist/cli/chunk-VM-dECyG.js +0 -1
- package/dist/cli/chunk-gvNsvav0.js +0 -225
- package/dist/cli/chunk-heu2xRw1.js +0 -1
- package/dist/lib/orchestrator-i_QJ-o22.js.map +0 -1
- package/dist/lib/shadow-claw-DoQ7fgl5.js.map +0 -1
- package/dist/lib/system-prompt-DT_KeYaL.js.map +0 -1
- package/dist/public/app-routes-V_-URXc5.js +0 -1
- package/dist/public/attachment-capabilities-B6ibLwQB.js +0 -1
- package/dist/public/compact-context-CX4H8V57.js +0 -5
- package/dist/public/config-C-YdSFZB.js +0 -1
- package/dist/public/get-group-dir-DL44kvqW.js +0 -1
- package/dist/public/init-control-plane-BoJijVtf.js +0 -1
- package/dist/public/orchestrator-CaUpEVkQ.js +0 -63
- package/dist/public/provider-DNIL4-Hw.js +0 -1
- package/dist/public/shadow-claw-DdgeYPg5.js +0 -1176
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as applyBasePath } from "./app-routes-BXiRvlNl.js";
|
|
2
2
|
import { getSiteConfig } from "./utils/site-config.js";
|
|
3
3
|
|
|
4
4
|
//#region src/ui/iframe-theme.ts
|
|
@@ -367,4 +367,4 @@ function safeInlineScript(code) {
|
|
|
367
367
|
|
|
368
368
|
//#endregion
|
|
369
369
|
export { iframeStorageDelete as a, iframeStorageSet as c, getIframeThemeStyleHtml as d, getIframeThemeStylesheetLink as f, iframeStorageClear as i, IframeBroadcastProxy as l, IFRAME_STORAGE_BRIDGE_SCRIPT as n, iframeStorageGet as o, safeInlineScript as r, iframeStorageGetAll as s, FILE_VIEWER_PREVIEW_BRIDGE_SCRIPT as t, getIframeHtmlClass as u };
|
|
370
|
-
//# sourceMappingURL=iframe-bridge-scripts-
|
|
370
|
+
//# sourceMappingURL=iframe-bridge-scripts-Dx825LLG.js.map
|
package/dist/lib/{iframe-bridge-scripts-D8iuFhUk.js.map → iframe-bridge-scripts-Dx825LLG.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframe-bridge-scripts-D8iuFhUk.js","names":[],"sources":["../../src/ui/iframe-theme.ts","../../src/components/shadow-claw-pages/utils/iframe-broadcast-proxy.ts","../../src/components/shadow-claw-pages/utils/iframe-storage-proxy.ts","../../src/components/shadow-claw-file-viewer/utils/iframe-bridge-scripts.ts"],"sourcesContent":["import { applyBasePath } from \"../core/app-routes.js\";\nimport { getSiteConfig } from \"../utils/site-config.js\";\n\n/**\n * Prefixes whose contents are flattened into the distribution root.\n */\nconst FLATTENED_STYLESHEET_PREFIXES = [\n \"pages/resources/\",\n \"pages/deps/\",\n \"resources/\",\n \"deps/\",\n \"pages/assets/\",\n \"pages/main/assets/\",\n];\n\n/**\n * Resolves a configured theme.stylesheet path to its actual distribution path.\n */\nexport function resolveThemeStylesheetHref(stylesheet: string): string {\n for (const prefix of FLATTENED_STYLESHEET_PREFIXES) {\n if (stylesheet.startsWith(prefix)) {\n return stylesheet.slice(prefix.length).replace(/^\\/+/, \"\");\n }\n }\n return stylesheet.replace(/^\\/+/, \"\");\n}\n\n/**\n * Generates an optional `<style>` or `<link rel=\"stylesheet\">` tag for the preview iframe\n * when an inline theme or theme stylesheet is configured.\n * When neither is configured, returns an empty string to avoid 404 requests.\n */\nexport function getIframeThemeStylesheetLink(siteConfig?: unknown): string {\n let config = siteConfig;\n if (!config && typeof document !== \"undefined\") {\n config = getSiteConfig();\n }\n\n let inlineThemeStyleText: string | undefined;\n if (typeof document !== \"undefined\") {\n let styleElementId = \"shadow-claw-theme\";\n if (config && typeof config === \"object\") {\n const customId = (config as { theme?: { styleElement?: unknown } }).theme\n ?.styleElement;\n if (typeof customId === \"string\" && customId.trim()) {\n styleElementId = customId.trim();\n }\n }\n const inlineStyle =\n document.getElementById(styleElementId) ||\n document.querySelector(\"style[data-shadow-claw-theme]\");\n if (inlineStyle?.textContent) {\n inlineThemeStyleText = inlineStyle.textContent;\n }\n }\n\n let stylesheet: string | undefined;\n if (config && typeof config === \"object\") {\n const rawTheme = (config as { theme?: { stylesheet?: unknown } }).theme;\n if (\n typeof rawTheme?.stylesheet === \"string\" &&\n rawTheme.stylesheet.trim()\n ) {\n stylesheet = rawTheme.stylesheet.trim();\n }\n }\n\n let result = \"\";\n if (inlineThemeStyleText) {\n result += `<style data-theme-style=\"true\">${inlineThemeStyleText}</style>`;\n }\n\n if (!stylesheet) {\n return result;\n }\n\n const isExternal =\n stylesheet.startsWith(\"http://\") ||\n stylesheet.startsWith(\"https://\") ||\n stylesheet.startsWith(\"//\");\n\n if (isExternal) {\n return `${result}<link rel=\"stylesheet\" href=\"${stylesheet}\">`;\n }\n\n // Runtime links must be site-root absolute (with the deployment base path):\n // srcdoc preview iframes set `<base href=\"/<base>/files/<group>/...\">`, so a\n // relative href would resolve under the file route and 404.\n const resolvedHref = resolveThemeStylesheetHref(stylesheet).replace(\n /^\\/+/,\n \"\",\n );\n return `${result}<link rel=\"stylesheet\" href=\"${applyBasePath(`/${resolvedHref}`)}\">`;\n}\n\n/**\n * Generates the CSS style block and html root class for sandboxed preview iframes\n * (file viewer and pages HTML preview) to synchronize theme CSS variables,\n * fonts, link styling, and dark/light mode color-scheme without FOUC.\n */\nexport function getIframeThemeStyleHtml(): string {\n const isDark =\n typeof document !== \"undefined\" &&\n document.documentElement.classList.contains(\"dark-mode\");\n const customProperties: string[] = [];\n\n if (typeof document !== \"undefined\") {\n const styles = getComputedStyle(document.documentElement);\n for (let i = 0; i < styles.length; i++) {\n const prop = styles[i];\n if (prop.startsWith(\"--\")) {\n customProperties.push(`${prop}: ${styles.getPropertyValue(prop)};`);\n }\n }\n }\n\n return [\n \"<style>\",\n \" :root {\",\n ` color-scheme: ${isDark ? \"dark\" : \"light\"};`,\n ` overflow: hidden;`,\n ` line-height: 1.5;`,\n ` ${customProperties.join(\"\\n \")}`,\n \" }\",\n \" * {\",\n \" scrollbar-width: thin;\",\n \" scrollbar-color: var(--shadow-claw-border-color) transparent;\",\n \" }\",\n \" ::-webkit-scrollbar {\",\n \" height: 0.5rem;\",\n \" width: 0.5rem;\",\n \" }\",\n \" ::-webkit-scrollbar-track {\",\n \" background: transparent;\",\n \" }\",\n \" ::-webkit-scrollbar-thumb {\",\n \" background: var(--shadow-claw-border-color);\",\n \" border-radius: 0.25rem;\",\n \" }\",\n \" ::-webkit-scrollbar-thumb:hover {\",\n \" background: var(--shadow-claw-text-tertiary);\",\n \" }\",\n \" body {\",\n \" color: var(--shadow-claw-text-primary);\",\n \" background-color: var(--shadow-claw-bg-primary);\",\n \" font-family: var(--shadow-claw-font-sans);\",\n \" margin: 0;\",\n \" }\",\n \" pre, code, kbd, samp {\",\n \" font-family: var(--shadow-claw-font-mono);\",\n \" }\",\n \" a {\",\n \" color: var(--shadow-claw-link);\",\n \" text-decoration: underline;\",\n \" text-underline-offset: 0.125rem;\",\n \" }\",\n \" a:hover {\",\n \" color: var(--shadow-claw-link-hover);\",\n \" }\",\n \" img {\",\n \" max-width: 100%;\",\n \" height: auto;\",\n \" }\",\n \" ul {\",\n \" line-height: 1.5;\",\n \" }\",\n \" article {\",\n \" padding: 1rem 1.5rem 1rem 1rem;\",\n \" }\",\n \" article > h1, article > h2 {\",\n \" margin-top: 0;\",\n \" }\",\n \"</style>\",\n ].join(\"\\n\");\n}\n\nexport function getIframeHtmlClass(): string {\n const isDark =\n typeof document !== \"undefined\" &&\n document.documentElement.classList.contains(\"dark-mode\");\n\n return isDark ? \"dark-mode\" : \"light-mode\";\n}\n","/**\n * iframe-broadcast-proxy.ts\n *\n * Parent-side BroadcastChannel proxy for sandboxed iframes.\n * When allow-same-origin is omitted from preview iframes, the iframe operates\n * under an opaque (null) origin. Browser BroadcastChannel instances are partitioned\n * by origin, preventing direct communication between parent/worker tools and the iframe.\n *\n * This proxy is completely AGNOSTIC and generic. It dynamically tracks BroadcastChannels\n * instantiated on the parent origin and extracts channel names declaratively from tool\n * definitions registered via site-config/toolsStore.\n */\n\nexport class IframeBroadcastProxy {\n private commandChannels: Map<string, BroadcastChannel> = new Map();\n private originalBroadcastChannel: typeof BroadcastChannel | null = null;\n\n constructor(private getTargetWindow: () => WindowProxy | null) {\n if (typeof BroadcastChannel !== \"undefined\") {\n this.patchParentBroadcastChannel();\n }\n }\n\n /**\n * Automatically intercept BroadcastChannel creation on parent window to\n * dynamically track and forward any channel used by tools or parent scripts.\n */\n private patchParentBroadcastChannel(): void {\n if ((globalThis as any)._shadowClawParentBcPatched) {\n return;\n }\n (globalThis as any)._shadowClawParentBcPatched = true;\n\n const self = this;\n const NativeBc = globalThis.BroadcastChannel;\n this.originalBroadcastChannel = NativeBc;\n\n const WrappedBc = function (this: BroadcastChannel, channelName: string) {\n const instance = new NativeBc(channelName);\n self.registerChannel(channelName);\n return instance;\n } as any;\n\n WrappedBc.prototype = NativeBc.prototype;\n globalThis.BroadcastChannel = WrappedBc;\n }\n\n /**\n * Declaratively scan tool execution code definitions for BroadcastChannel names\n * and register them automatically.\n */\n public registerChannelsFromTools(\n tools: Array<{ execution?: { code?: string }; code?: string }>,\n ): void {\n if (!Array.isArray(tools)) return;\n\n const bcRegex = /new\\s+BroadcastChannel\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/g;\n for (const tool of tools) {\n const code = tool.execution?.code || tool.code || \"\";\n if (!code) continue;\n\n let match: RegExpExecArray | null;\n bcRegex.lastIndex = 0;\n while ((match = bcRegex.exec(code)) !== null) {\n if (match[1]) {\n this.registerChannel(match[1]);\n }\n }\n }\n }\n\n /**\n * Register a channel name to forward parent messages to the sandboxed iframe.\n */\n public registerChannel(channelName: string): void {\n if (\n typeof BroadcastChannel === \"undefined\" ||\n !channelName ||\n channelName.endsWith(\"-results\") ||\n this.commandChannels.has(channelName)\n ) {\n return;\n }\n this.listenOnCommandChannel(channelName);\n }\n\n private listenOnCommandChannel(channelName: string): void {\n try {\n const NativeBc =\n this.originalBroadcastChannel || globalThis.BroadcastChannel;\n const bc = new NativeBc(channelName);\n bc.onmessage = (evt) => {\n const target = this.getTargetWindow();\n if (target) {\n target.postMessage(\n {\n type: \"shadow-claw-broadcast-command\",\n channel: channelName,\n payload: evt.data,\n },\n \"*\",\n );\n }\n };\n this.commandChannels.set(channelName, bc);\n } catch (e) {\n console.warn(\n `[IframeBroadcastProxy] Failed to listen on channel ${channelName}:`,\n e,\n );\n }\n }\n\n /**\n * Handle incoming broadcast result/message from the sandboxed iframe and relay it\n * to the parent-origin BroadcastChannel.\n */\n public handleResultFromIframe(\n sourceWindow: WindowProxy,\n channelName: string,\n payload: unknown,\n ): boolean {\n const target = this.getTargetWindow();\n if (target && sourceWindow !== target) {\n return false;\n }\n\n if (channelName) {\n try {\n const NativeBc =\n this.originalBroadcastChannel || globalThis.BroadcastChannel;\n const resBc = new NativeBc(channelName);\n resBc.postMessage(payload);\n resBc.close();\n return true;\n } catch (e) {\n console.warn(\n `[IframeBroadcastProxy] Failed to relay result for channel ${channelName}:`,\n e,\n );\n }\n }\n return false;\n }\n\n public dispose(): void {\n for (const bc of this.commandChannels.values()) {\n try {\n bc.close();\n } catch (e) {}\n }\n this.commandChannels.clear();\n }\n}\n","/**\n * iframe-storage-proxy.ts\n *\n * Parent-side storage implementation for the iframe storage bridge.\n * Provides a namespaced IndexedDB key-value store that the parent frame\n * uses to proxy storage operations on behalf of sandboxed iframes that\n * lack direct storage access due to opaque-origin isolation.\n *\n * Each page gets its own namespace to prevent cross-page data leakage.\n */\n\nconst DB_NAME = \"shadow-claw-iframe-storage\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"kv\";\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDb(): Promise<IDBDatabase> {\n if (dbPromise) {\n return dbPromise;\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n dbPromise = null;\n reject(request.error);\n };\n });\n\n return dbPromise;\n}\n\n/**\n * Build a composite key from a namespace and item key.\n */\nfunction compositeKey(namespace: string, key: string): string {\n return `${namespace}\\0${key}`;\n}\n\n/**\n * Set a value in the namespaced store.\n */\nexport async function iframeStorageSet(\n namespace: string,\n key: string,\n value: unknown,\n): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(value, compositeKey(namespace, key));\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Get a single value from the namespaced store.\n */\nexport async function iframeStorageGet(\n namespace: string,\n key: string,\n): Promise<unknown> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(compositeKey(namespace, key));\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\n/**\n * Get all values for a namespace as a key-value object.\n */\nexport async function iframeStorageGetAll(\n namespace: string,\n): Promise<Record<string, unknown>> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const result: Record<string, unknown> = {};\n const prefix = `${namespace}\\0`;\n const cursorReq = store.openCursor();\n\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (!cursor) {\n resolve(result);\n return;\n }\n const cursorKey =\n typeof cursor.key === \"string\" ? cursor.key : String(cursor.key);\n if (cursorKey.startsWith(prefix)) {\n result[cursorKey.slice(prefix.length)] = cursor.value;\n }\n cursor.continue();\n };\n\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n}\n\n/**\n * Delete a single value from the namespaced store.\n */\nexport async function iframeStorageDelete(\n namespace: string,\n key: string,\n): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(compositeKey(namespace, key));\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Clear all values for a namespace.\n */\nexport async function iframeStorageClear(namespace: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const prefix = `${namespace}\\0`;\n const cursorReq = store.openCursor();\n\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (!cursor) {\n resolve();\n return;\n }\n const cursorKey =\n typeof cursor.key === \"string\" ? cursor.key : String(cursor.key);\n if (cursorKey.startsWith(prefix)) {\n cursor.delete();\n }\n cursor.continue();\n };\n\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n}\n","/**\n * Auto-generated and bundled inline script sources for sandboxed iframe previews.\n * Inlining these scripts into about:srcdoc with CSP nonces eliminates network roundtrips\n * and prevents browser ad-blockers / Brave Shields from blocking bridge scripts with ERR_BLOCKED_BY_CLIENT.\n */\n\nexport const IFRAME_STORAGE_BRIDGE_SCRIPT: string =\n '/**\\n * iframe-storage-bridge.js\\n *\\n * Injected into sandboxed preview iframes (via nonce-gated CSP) to provide\\n * a transparent storage proxy when the iframe is running in an opaque origin\\n * (i.e. sandbox without allow-same-origin).\\n *\\n * When IndexedDB and localStorage are unavailable due to opaque origin\\n * restrictions, this bridge intercepts storage calls and proxies them to\\n * the parent frame via postMessage. The parent frame performs the actual\\n * storage operations on the iframe\\'s behalf using a namespaced key-value\\n * store.\\n *\\n * SECURITY:\\n * - All messages use a unique type prefix to avoid collision.\\n * - The parent validates message source against the iframe\\'s contentWindow.\\n * - Storage is namespaced per-page to prevent cross-page data leakage.\\n * - This file is served same-origin and loaded with a per-render nonce.\\n */\\n\\n(function () {\\n \"use strict\";\\n\\n // Intercept and prevent unhandled sandboxed serviceWorker SecurityErrors from breaking execution flow\\n try {\\n window.addEventListener(\\n \"error\",\\n function (e) {\\n if (\\n e.message &&\\n (e.message.indexOf(\"serviceWorker\") !== -1 ||\\n e.message.indexOf(\"Service worker\") !== -1)\\n ) {\\n e.preventDefault();\\n e.stopImmediatePropagation();\\n }\\n },\\n true,\\n );\\n window.addEventListener(\\n \"unhandledrejection\",\\n function (e) {\\n if (\\n e.reason &&\\n (String(e.reason).indexOf(\"serviceWorker\") !== -1 ||\\n String(e.reason).indexOf(\"Service worker\") !== -1)\\n ) {\\n e.preventDefault();\\n e.stopImmediatePropagation();\\n }\\n },\\n true,\\n );\\n } catch (e) {}\\n\\n // Safely trap serviceWorker access in sandboxed cross-origin iframes\\n try {\\n var swDesc = {\\n get: function () {\\n return undefined;\\n },\\n configurable: true,\\n enumerable: false,\\n };\\n if (typeof Navigator !== \"undefined\" && Navigator.prototype) {\\n try {\\n Object.defineProperty(Navigator.prototype, \"serviceWorker\", swDesc);\\n } catch (e1) {}\\n }\\n if (typeof navigator !== \"undefined\") {\\n try {\\n Object.defineProperty(navigator, \"serviceWorker\", swDesc);\\n } catch (e2) {}\\n }\\n } catch (e) {\\n // ignore\\n }\\n\\n // Safely trap caches (CacheStorage) access in sandboxed cross-origin iframes\\n try {\\n var cacheDesc = {\\n get: function () {\\n return undefined;\\n },\\n configurable: true,\\n enumerable: false,\\n };\\n if (typeof Window !== \"undefined\" && Window.prototype) {\\n try {\\n Object.defineProperty(Window.prototype, \"caches\", cacheDesc);\\n } catch (e1) {}\\n }\\n if (typeof window !== \"undefined\") {\\n try {\\n Object.defineProperty(window, \"caches\", cacheDesc);\\n } catch (e2) {}\\n }\\n } catch (e) {\\n // ignore\\n }\\n\\n // Polyfill showOpenFilePicker using standard <input type=\"file\"> in sandboxed iframes\\n try {\\n Object.defineProperty(window, \"showOpenFilePicker\", {\\n value: function (options) {\\n return new Promise(function (resolve, reject) {\\n var input = document.createElement(\"input\");\\n input.type = \"file\";\\n if (options && options.multiple) {\\n input.multiple = true;\\n }\\n if (options && options.types && options.types.length > 0) {\\n var accept = [];\\n options.types.forEach(function (t) {\\n if (t.accept) {\\n Object.keys(t.accept).forEach(function (mime) {\\n accept.push(mime);\\n var exts = t.accept[mime];\\n if (Array.isArray(exts)) {\\n exts.forEach(function (ext) {\\n accept.push(ext);\\n });\\n }\\n });\\n }\\n });\\n if (accept.length > 0) {\\n input.accept = accept.join(\",\");\\n }\\n }\\n\\n input.onchange = function () {\\n if (!input.files || input.files.length === 0) {\\n reject(\\n new DOMException(\"The user aborted a request.\", \"AbortError\"),\\n );\\n return;\\n }\\n var handles = Array.from(input.files).map(function (file) {\\n return {\\n kind: \"file\",\\n name: file.name,\\n getFile: function () {\\n return Promise.resolve(file);\\n },\\n };\\n });\\n resolve(handles);\\n };\\n\\n input.oncancel = function () {\\n reject(\\n new DOMException(\"The user aborted a request.\", \"AbortError\"),\\n );\\n };\\n\\n input.click();\\n });\\n },\\n configurable: true,\\n writable: true,\\n });\\n } catch (e) {\\n // ignore\\n }\\n\\n // Polyfill showSaveFilePicker using standard <a download> in sandboxed iframes\\n try {\\n Object.defineProperty(window, \"showSaveFilePicker\", {\\n value: function (options) {\\n var filename = (options && options.suggestedName) || \"download\";\\n var mimeType = \"application/octet-stream\";\\n if (\\n options &&\\n options.types &&\\n options.types.length > 0 &&\\n options.types[0].accept\\n ) {\\n var mimes = Object.keys(options.types[0].accept);\\n if (mimes.length > 0) {\\n mimeType = mimes[0];\\n }\\n }\\n\\n var chunks = [];\\n\\n var writable = {\\n write: function (data) {\\n if (\\n data &&\\n typeof data === \"object\" &&\\n data.type === \"write\" &&\\n data.data\\n ) {\\n chunks.push(data.data);\\n } else if (data !== undefined && data !== null) {\\n chunks.push(data);\\n }\\n return Promise.resolve();\\n },\\n seek: function () {\\n return Promise.resolve();\\n },\\n truncate: function () {\\n return Promise.resolve();\\n },\\n close: function () {\\n return new Promise(function (resolve) {\\n try {\\n var blob = new Blob(chunks, { type: mimeType });\\n var url = URL.createObjectURL(blob);\\n var a = document.createElement(\"a\");\\n a.href = url;\\n a.download = filename;\\n a.style.display = \"none\";\\n document.body.appendChild(a);\\n a.click();\\n setTimeout(function () {\\n if (a.parentNode) {\\n a.parentNode.removeChild(a);\\n }\\n URL.revokeObjectURL(url);\\n }, 1000);\\n } catch (e) {\\n // ignore\\n }\\n resolve();\\n });\\n },\\n };\\n\\n var handle = {\\n kind: \"file\",\\n name: filename,\\n createWritable: function () {\\n return Promise.resolve(writable);\\n },\\n getFile: function () {\\n var blob = new Blob(chunks, { type: mimeType });\\n var file = new File([blob], filename, { type: mimeType });\\n return Promise.resolve(file);\\n },\\n };\\n\\n return Promise.resolve(handle);\\n },\\n configurable: true,\\n writable: true,\\n });\\n } catch (e) {\\n // ignore\\n }\\n\\n // Always install proxy immediately for sandboxed preview iframes.\\n installProxy();\\n\\n // ----------------------------------------------------------------\\n // Pending request tracking\\n // ----------------------------------------------------------------\\n var pendingRequests = {};\\n var requestIdCounter = 0;\\n\\n function sendRequest(method, args) {\\n return new Promise(function (resolve, reject) {\\n var requestId = \"sc-storage-\" + ++requestIdCounter;\\n pendingRequests[requestId] = { resolve: resolve, reject: reject };\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-storage-proxy\",\\n requestId: requestId,\\n method: method,\\n args: args,\\n },\\n \"*\",\\n );\\n\\n // Timeout after 10 seconds to avoid hanging forever.\\n setTimeout(function () {\\n if (pendingRequests[requestId]) {\\n delete pendingRequests[requestId];\\n reject(new Error(\"Storage proxy request timed out: \" + method));\\n }\\n }, 10000);\\n });\\n }\\n\\n window.addEventListener(\"message\", function (event) {\\n if (!event.data || event.data.type !== \"shadow-claw-storage-proxy-result\") {\\n return;\\n }\\n var requestId = event.data.requestId;\\n var pending = pendingRequests[requestId];\\n if (!pending) {\\n return;\\n }\\n delete pendingRequests[requestId];\\n if (event.data.error) {\\n pending.reject(new Error(event.data.error));\\n } else {\\n pending.resolve(event.data.result);\\n }\\n });\\n\\n // ----------------------------------------------------------------\\n // localStorage shim\\n // ----------------------------------------------------------------\\n function installProxy() {\\n // localStorage shim — backed by parent-proxied key-value store.\\n var localStorageShim = {\\n _cache: {},\\n\\n getItem: function (key) {\\n // Return cached value synchronously (best-effort).\\n // Async warm-up happens in the background.\\n return this._cache[key] !== undefined ? this._cache[key] : null;\\n },\\n\\n setItem: function (key, value) {\\n var stringValue = String(value);\\n this._cache[key] = stringValue;\\n sendRequest(\"setItem\", { key: key, value: stringValue }).catch(\\n function () {\\n // Silently ignore write failures\\n },\\n );\\n },\\n\\n removeItem: function (key) {\\n delete this._cache[key];\\n sendRequest(\"removeItem\", { key: key }).catch(function () {});\\n },\\n\\n clear: function () {\\n this._cache = {};\\n sendRequest(\"clear\", {}).catch(function () {});\\n },\\n\\n key: function (index) {\\n var keys = Object.keys(this._cache);\\n return index >= 0 && index < keys.length ? keys[index] : null;\\n },\\n\\n get length() {\\n return Object.keys(this._cache).length;\\n },\\n };\\n\\n // Warm up the cache from the parent.\\n sendRequest(\"getAllItems\", {})\\n .then(function (items) {\\n if (items && typeof items === \"object\") {\\n for (var k in items) {\\n if (Object.prototype.hasOwnProperty.call(items, k)) {\\n localStorageShim._cache[k] = items[k];\\n }\\n }\\n }\\n })\\n .catch(function () {});\\n\\n try {\\n Object.defineProperty(window, \"localStorage\", {\\n get: function () {\\n return localStorageShim;\\n },\\n configurable: true,\\n });\\n } catch (e) {\\n // If we can\\'t override localStorage, leave the native (broken) one.\\n }\\n\\n // ----------------------------------------------------------------\\n // IndexedDB shim — minimal proxy supporting open / transaction / objectStore CRUD\\n // ----------------------------------------------------------------\\n var IDBShimDatabase = function (name) {\\n this.name = name;\\n this._closed = false;\\n };\\n\\n IDBShimDatabase.prototype.close = function () {\\n this._closed = true;\\n };\\n\\n IDBShimDatabase.prototype.transaction = function (storeNames) {\\n return new IDBShimTransaction(this.name, storeNames);\\n };\\n\\n // Expose objectStoreNames for compatibility (always returns the default store).\\n Object.defineProperty(IDBShimDatabase.prototype, \"objectStoreNames\", {\\n get: function () {\\n return {\\n length: 1,\\n item: function () {\\n return \"__default__\";\\n },\\n contains: function () {\\n return true;\\n },\\n };\\n },\\n });\\n\\n var IDBShimTransaction = function (dbName, storeNames) {\\n this._dbName = dbName;\\n this._storeNames = storeNames;\\n this.oncomplete = null;\\n this.onerror = null;\\n this.onabort = null;\\n\\n // Fire oncomplete asynchronously.\\n var self = this;\\n setTimeout(function () {\\n if (typeof self.oncomplete === \"function\") {\\n self.oncomplete({ target: self });\\n }\\n }, 0);\\n };\\n\\n IDBShimTransaction.prototype.objectStore = function (name) {\\n return new IDBShimObjectStore(this._dbName, name);\\n };\\n\\n var IDBShimObjectStore = function (dbName, storeName) {\\n this._dbName = dbName;\\n this._storeName = storeName;\\n };\\n\\n IDBShimObjectStore.prototype.get = function (key) {\\n return createIDBRequest(\\n sendRequest(\"idb-get\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.getAll = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.put = function (value, key) {\\n return createIDBRequest(\\n sendRequest(\"idb-put\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n value: value,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.delete = function (key) {\\n return createIDBRequest(\\n sendRequest(\"idb-delete\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.clear = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-clear\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.getAllKeys = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }).then(function (items) {\\n if (items && typeof items === \"object\") {\\n return Object.keys(items);\\n }\\n return [];\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.openKeyCursor = function () {\\n return this.openCursor();\\n };\\n\\n IDBShimObjectStore.prototype.openCursor = function () {\\n var request = {\\n result: null,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n readyState: \"pending\",\\n };\\n\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n })\\n .then(function (items) {\\n var keys =\\n items && typeof items === \"object\" ? Object.keys(items) : [];\\n var index = 0;\\n\\n function advanceCursor() {\\n if (index >= keys.length) {\\n request.result = null;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n return;\\n }\\n\\n var currentKey = keys[index];\\n var currentValue = items[currentKey];\\n\\n var cursor = {\\n key: currentKey,\\n primaryKey: currentKey,\\n value: currentValue,\\n continue: function () {\\n index++;\\n advanceCursor();\\n },\\n };\\n\\n request.result = cursor;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n }\\n\\n advanceCursor();\\n })\\n .catch(function (err) {\\n request.error = err;\\n request.readyState = \"done\";\\n if (typeof request.onerror === \"function\") {\\n request.onerror({ target: request });\\n }\\n });\\n\\n return request;\\n };\\n\\n function createIDBRequest(promise) {\\n var request = {\\n result: undefined,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n readyState: \"pending\",\\n };\\n\\n promise\\n .then(function (result) {\\n request.result = result;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n })\\n .catch(function (err) {\\n request.error = err;\\n request.readyState = \"done\";\\n if (typeof request.onerror === \"function\") {\\n request.onerror({ target: request });\\n }\\n });\\n\\n return request;\\n }\\n\\n // indexedDB.open() shim\\n var indexedDBShim = {\\n open: function (name) {\\n var request = {\\n result: null,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n onupgradeneeded: null,\\n readyState: \"pending\",\\n };\\n\\n // Simulate async open.\\n setTimeout(function () {\\n request.result = new IDBShimDatabase(name);\\n request.readyState = \"done\";\\n\\n // Fire onupgradeneeded first (for initial setup), then onsuccess.\\n if (typeof request.onupgradeneeded === \"function\") {\\n request.onupgradeneeded({\\n target: request,\\n oldVersion: 0,\\n newVersion: 1,\\n });\\n }\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n }, 0);\\n\\n return request;\\n },\\n\\n deleteDatabase: function (name) {\\n var request = createIDBRequest(\\n sendRequest(\"idb-deleteDatabase\", { dbName: name }),\\n );\\n return request;\\n },\\n };\\n\\n try {\\n Object.defineProperty(window, \"indexedDB\", {\\n get: function () {\\n return indexedDBShim;\\n },\\n configurable: true,\\n });\\n } catch (e) {\\n // If we can\\'t override, leave native.\\n }\\n }\\n})();\\n';\n\nexport const FILE_VIEWER_PREVIEW_BRIDGE_SCRIPT: string =\n '/**\\n * file-viewer-preview-bridge.js\\n *\\n * Injected into sandboxed preview iframes (file viewer + pages HTML preview)\\n * via a per-render nonce. Intercepts link clicks and posts them to the parent\\n * so the app can handle workspace-relative navigation.\\n *\\n * SECURITY: This file is served same-origin and loaded with a per-render nonce.\\n * The Trusted Types policy and nonce-gated CSP prevent any other scripts from\\n * running inside the sandboxed srcdoc iframe.\\n */\\n\\n(function () {\\n \"use strict\";\\n\\n // ---------------------------------------------------------------------------\\n // BroadcastChannel Opaque-Origin Proxy Bridge\\n // ---------------------------------------------------------------------------\\n // When allow-same-origin is omitted from sandboxed preview iframes, the iframe\\n // operates under a null (opaque) origin. Native BroadcastChannel instances are\\n // partitioned by origin, preventing direct communication between parent/worker\\n // tools and the iframe.\\n //\\n // This bridge wraps window.BroadcastChannel inside the iframe so that any\\n // message posted by iframe scripts (e.g., tool responses) is automatically\\n // relayed to the parent window via postMessage. It also listens for commands\\n // posted from the parent window and re-emits them to the iframe\\'s BroadcastChannel.\\n // ---------------------------------------------------------------------------\\n var isRelayingCommandFromParent = false;\\n\\n if (\\n typeof BroadcastChannel !== \"undefined\" &&\\n !window._shadowClawBcBridgeInstalled\\n ) {\\n window._shadowClawBcBridgeInstalled = true;\\n var NativeBroadcastChannel = window.BroadcastChannel;\\n var origPostMessage = NativeBroadcastChannel.prototype.postMessage;\\n\\n NativeBroadcastChannel.prototype.postMessage = function (message) {\\n origPostMessage.call(this, message);\\n if (isRelayingCommandFromParent) {\\n return;\\n }\\n try {\\n if (window.parent && window.parent !== window) {\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-broadcast-result\",\\n channel: this.name,\\n payload: message,\\n },\\n \"*\",\\n );\\n }\\n } catch (e) {\\n // Ignore postMessage transfer errors\\n }\\n };\\n }\\n\\n window.addEventListener(\"message\", function (event) {\\n if (!event.data || typeof event.data !== \"object\") {\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-broadcast-command\") {\\n var channelName = event.data.channel;\\n var payload = event.data.payload;\\n if (channelName && typeof NativeBroadcastChannel !== \"undefined\") {\\n try {\\n var bc = new NativeBroadcastChannel(channelName);\\n isRelayingCommandFromParent = true;\\n bc.postMessage(payload);\\n isRelayingCommandFromParent = false;\\n bc.close();\\n } catch (e) {\\n isRelayingCommandFromParent = false;\\n // Ignore command relay errors\\n }\\n }\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-theme-update\") {\\n if (event.data.customProperties) {\\n for (var key in event.data.customProperties) {\\n if (\\n Object.prototype.hasOwnProperty.call(\\n event.data.customProperties,\\n key,\\n )\\n ) {\\n document.documentElement.style.setProperty(\\n key,\\n event.data.customProperties[key],\\n );\\n }\\n }\\n }\\n\\n var isDark = event.data.theme === \"dark\";\\n if (isDark) {\\n document.documentElement.classList.add(\"dark-mode\");\\n document.documentElement.classList.remove(\"light-mode\");\\n if (document.body) {\\n document.body.classList.add(\"dark-mode\");\\n document.body.classList.remove(\"light-mode\");\\n }\\n } else {\\n document.documentElement.classList.add(\"light-mode\");\\n document.documentElement.classList.remove(\"dark-mode\");\\n if (document.body) {\\n document.body.classList.add(\"light-mode\");\\n document.body.classList.remove(\"dark-mode\");\\n }\\n }\\n try {\\n document.documentElement.style.colorScheme = isDark ? \"dark\" : \"light\";\\n } catch (e) {}\\n }\\n\\n if (event.data.type === \"shadow-claw-scroll-to-anchor\") {\\n var anchorId = event.data.anchor || \"\";\\n if (anchorId) {\\n var el =\\n document.getElementById(anchorId) ||\\n document.querySelector(\\'a[name=\"\\' + anchorId + \\'\"]\\');\\n if (el && typeof el.scrollIntoView === \"function\") {\\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\\n }\\n }\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-update-url-params\") {\\n var searchStr = event.data.search || \"\";\\n if (searchStr) {\\n try {\\n window.history.replaceState(\\n null,\\n \"\",\\n window.location.pathname + searchStr,\\n );\\n } catch (e) {}\\n\\n try {\\n window.dispatchEvent(new Event(\"popstate\"));\\n window.dispatchEvent(new Event(\"locationchange\"));\\n } catch (e) {}\\n\\n var customEls = document.querySelectorAll(\"*\");\\n var retriggered = false;\\n for (var i = 0; i < customEls.length; i++) {\\n var el = customEls[i];\\n if (el.tagName && el.tagName.indexOf(\"-\") !== -1 && el.parentNode) {\\n try {\\n var cb = el.connectedCallback;\\n var clone = el.cloneNode(true);\\n if (typeof cb === \"function\") {\\n clone.connectedCallback = cb;\\n }\\n el.parentNode.replaceChild(clone, el);\\n if (typeof clone.connectedCallback === \"function\") {\\n try {\\n clone.connectedCallback();\\n } catch (e3) {}\\n }\\n retriggered = true;\\n } catch (err) {\\n if (typeof el.connectedCallback === \"function\") {\\n try {\\n el.connectedCallback();\\n retriggered = true;\\n } catch (e2) {}\\n }\\n }\\n }\\n }\\n\\n if (!retriggered) {\\n window.location.reload();\\n }\\n }\\n return;\\n }\\n });\\n\\n function isNavSuppressed(event) {\\n if (!event) return false;\\n var navAttributes = [\\n \"data-no-nav\",\\n \"data-no-swipe\",\\n \"data-no-page-nav\",\\n \"data-prevent-nav\",\\n \"data-prevent-page-nav\",\\n \"data-isolate-input\",\\n \"data-isolate-navigation\",\\n \"data-game-controls\",\\n ];\\n\\n var path =\\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\\n\\n for (var i = 0; i < path.length; i++) {\\n var node = path[i];\\n if (node && node.nodeType === 1) {\\n var tag = (node.tagName || \"\").toLowerCase();\\n if (\\n tag === \"input\" ||\\n tag === \"textarea\" ||\\n tag === \"select\" ||\\n tag === \"option\" ||\\n node.isContentEditable ||\\n node.getAttribute(\"contenteditable\") === \"true\"\\n ) {\\n return true;\\n }\\n\\n for (var j = 0; j < navAttributes.length; j++) {\\n if (node.hasAttribute(navAttributes[j])) {\\n return true;\\n }\\n }\\n }\\n }\\n var target = event.target;\\n if (target && target.nodeType === 3) {\\n target = target.parentNode;\\n }\\n\\n if (target && target instanceof Element) {\\n var targetTag = (target.tagName || \"\").toLowerCase();\\n if (\\n targetTag === \"input\" ||\\n targetTag === \"textarea\" ||\\n targetTag === \"select\" ||\\n targetTag === \"option\" ||\\n target.isContentEditable ||\\n target.getAttribute(\"contenteditable\") === \"true\"\\n ) {\\n return true;\\n }\\n\\n for (var k = 0; k < navAttributes.length; k++) {\\n if (target.closest(\"[\" + navAttributes[k] + \"]\")) {\\n return true;\\n }\\n }\\n }\\n\\n return false;\\n }\\n\\n var touchStartX = 0;\\n var touchStartY = 0;\\n var touchStartTime = 0;\\n\\n document.addEventListener(\\n \"touchstart\",\\n function (event) {\\n if (isNavSuppressed(event)) {\\n touchStartX = 0;\\n touchStartY = 0;\\n touchStartTime = 0;\\n return;\\n }\\n if (event.touches && event.touches.length === 1) {\\n touchStartX = event.touches[0].clientX;\\n touchStartY = event.touches[0].clientY;\\n touchStartTime = Date.now();\\n }\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\\n \"touchend\",\\n function (event) {\\n if (!touchStartTime || isNavSuppressed(event)) {\\n touchStartTime = 0;\\n return;\\n }\\n if (event.changedTouches && event.changedTouches.length === 1) {\\n var touchEndX = event.changedTouches[0].clientX;\\n var touchEndY = event.changedTouches[0].clientY;\\n var deltaTime = Date.now() - touchStartTime;\\n\\n var deltaX = touchEndX - touchStartX;\\n var deltaY = touchEndY - touchStartY;\\n\\n if (\\n Math.abs(deltaX) >= 50 &&\\n Math.abs(deltaX) > Math.abs(deltaY) &&\\n deltaTime <= 600\\n ) {\\n var direction = deltaX < 0 ? \"left\" : \"right\";\\n window.parent.postMessage(\\n { type: \"shadow-claw-swipe\", direction: direction },\\n \"*\",\\n );\\n }\\n }\\n touchStartTime = 0;\\n },\\n { passive: true },\\n );\\n\\n var mouseStartX = 0;\\n var mouseStartY = 0;\\n var mouseStartTime = 0;\\n var isMouseDown = false;\\n\\n document.addEventListener(\\n \"mousedown\",\\n function (event) {\\n if (event.button !== 0 || isNavSuppressed(event)) {\\n isMouseDown = false;\\n return;\\n }\\n isMouseDown = true;\\n mouseStartX = event.clientX;\\n mouseStartY = event.clientY;\\n mouseStartTime = Date.now();\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\\n \"mouseup\",\\n function (event) {\\n if (!isMouseDown) {\\n return;\\n }\\n isMouseDown = false;\\n if (isNavSuppressed(event)) {\\n return;\\n }\\n\\n var selection = window.getSelection();\\n if (selection && selection.toString().length > 0) {\\n return;\\n }\\n\\n var mouseEndX = event.clientX;\\n var mouseEndY = event.clientY;\\n var deltaTime = Date.now() - mouseStartTime;\\n\\n var deltaX = mouseEndX - mouseStartX;\\n var deltaY = mouseEndY - mouseStartY;\\n\\n if (\\n Math.abs(deltaX) >= 50 &&\\n Math.abs(deltaX) > Math.abs(deltaY) &&\\n deltaTime <= 600\\n ) {\\n var direction = deltaX < 0 ? \"left\" : \"right\";\\n window.parent.postMessage(\\n { type: \"shadow-claw-swipe\", direction: direction },\\n \"*\",\\n );\\n }\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\"click\", function (event) {\\n // Only handle unmodified primary clicks.\\n if (event.defaultPrevented || event.button !== 0) {\\n return;\\n }\\n\\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\\n return;\\n }\\n\\n var target = event.target;\\n if (!target) {\\n return;\\n }\\n\\n if (target.nodeType === 3) {\\n {\\n // Node.TEXT_NODE;\\n }\\n\\n target = target.parentNode;\\n }\\n\\n if (!(target instanceof Element)) {\\n return;\\n }\\n\\n var link = target.closest(\"a\");\\n if (!(link instanceof HTMLAnchorElement)) {\\n return;\\n }\\n\\n var href = link.getAttribute(\"href\") || \"\";\\n if (!href) {\\n return;\\n }\\n\\n // Let fragment-only same-page anchors pass through normally.\\n if (\\n href.startsWith(\"#\") &&\\n !href.includes(\"?\") &&\\n !href.includes(\"groupId\")\\n ) {\\n return;\\n }\\n\\n // Intercept all links so sandboxed preview iframes never navigate away from srcdoc.\\n event.preventDefault();\\n\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-file-viewer-link\",\\n href: href,\\n target: link.getAttribute(\"target\") || \"\",\\n },\\n \"*\",\\n );\\n });\\n\\n var lastReportedHeight = -1;\\n\\n function reportHeight() {\\n var body = document.body;\\n var docEl = document.documentElement;\\n\\n if (!body && !docEl) {\\n return;\\n }\\n\\n // Temporarily collapse documentElement height so that scrollHeight reflects\\n // only the natural content size — not the height the parent previously\\n // injected into the iframe via style.height. Without this reset the\\n // browser keeps scrollHeight equal to the externally-set height, which\\n // creates a feedback loop that leaves a scrollbar on the parent at wide\\n // widths (the iframe reports its own height, the parent honours it, repeat).\\n var prevDocElHeight = docEl ? docEl.style.height : null;\\n if (docEl) {\\n docEl.style.height = \"0\";\\n }\\n\\n var height = Math.max(\\n body ? body.scrollHeight : 0,\\n body ? body.offsetHeight : 0,\\n );\\n\\n if (body && body.lastElementChild) {\\n try {\\n var lastEl = body.lastElementChild;\\n var rect = lastEl.getBoundingClientRect();\\n var bodyRect = body.getBoundingClientRect();\\n var lastElBottom = rect.bottom - bodyRect.top + (window.scrollY || 0);\\n if (lastElBottom > height) {\\n height = Math.ceil(lastElBottom);\\n }\\n } catch (e) {\\n // Fallback if bounding rect computation fails\\n }\\n }\\n\\n // Restore documentElement height.\\n if (docEl) {\\n docEl.style.height = prevDocElHeight || \"\";\\n }\\n\\n if (height > 0 && Math.abs(height - lastReportedHeight) > 1) {\\n lastReportedHeight = height;\\n window.parent.postMessage(\\n { type: \"shadow-claw-iframe-resize\", height: height },\\n \"*\",\\n );\\n }\\n }\\n\\n // Always schedule via rAF so layout is settled before measuring.\\n function scheduleReportHeight() {\\n if (typeof requestAnimationFrame === \"function\") {\\n requestAnimationFrame(reportHeight);\\n } else {\\n reportHeight();\\n }\\n }\\n\\n // First measurement: wait for DOM to be parsed.\\n // If the script runs during \"loading\" (sync <script> in <head>) we listen\\n // for DOMContentLoaded; otherwise the DOM is already ready so measure now.\\n if (document.readyState === \"loading\") {\\n document.addEventListener(\"DOMContentLoaded\", scheduleReportHeight);\\n } else {\\n scheduleReportHeight();\\n }\\n\\n // Re-measure after all sub-resources (images, fonts, etc.) have loaded,\\n // in case they affect the layout height.\\n window.addEventListener(\"load\", scheduleReportHeight);\\n\\n // Re-measure on viewport resize (e.g. window narrowed → text reflows taller).\\n window.addEventListener(\"resize\", scheduleReportHeight);\\n\\n // Ongoing: watch for dynamic content changes after initial load.\\n if (typeof ResizeObserver !== \"undefined\") {\\n var ro = new ResizeObserver(scheduleReportHeight);\\n if (document.documentElement) {\\n ro.observe(document.documentElement);\\n }\\n if (document.body) {\\n ro.observe(document.body);\\n }\\n }\\n})();\\n';\n\n/**\n * Escapes any closing script tags to ensure safe HTML interpolation.\n */\nexport function safeInlineScript(code: string): string {\n return code.replace(/<\\/script/gi, (m) => `<\\\\/${m.slice(2)}`);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"iframe-bridge-scripts-Dx825LLG.js","names":[],"sources":["../../src/ui/iframe-theme.ts","../../src/components/shadow-claw-pages/utils/iframe-broadcast-proxy.ts","../../src/components/shadow-claw-pages/utils/iframe-storage-proxy.ts","../../src/components/shadow-claw-file-viewer/utils/iframe-bridge-scripts.ts"],"sourcesContent":["import { applyBasePath } from \"../core/app-routes.js\";\nimport { getSiteConfig } from \"../utils/site-config.js\";\n\n/**\n * Prefixes whose contents are flattened into the distribution root.\n */\nconst FLATTENED_STYLESHEET_PREFIXES = [\n \"pages/resources/\",\n \"pages/deps/\",\n \"resources/\",\n \"deps/\",\n \"pages/assets/\",\n \"pages/main/assets/\",\n];\n\n/**\n * Resolves a configured theme.stylesheet path to its actual distribution path.\n */\nexport function resolveThemeStylesheetHref(stylesheet: string): string {\n for (const prefix of FLATTENED_STYLESHEET_PREFIXES) {\n if (stylesheet.startsWith(prefix)) {\n return stylesheet.slice(prefix.length).replace(/^\\/+/, \"\");\n }\n }\n return stylesheet.replace(/^\\/+/, \"\");\n}\n\n/**\n * Generates an optional `<style>` or `<link rel=\"stylesheet\">` tag for the preview iframe\n * when an inline theme or theme stylesheet is configured.\n * When neither is configured, returns an empty string to avoid 404 requests.\n */\nexport function getIframeThemeStylesheetLink(siteConfig?: unknown): string {\n let config = siteConfig;\n if (!config && typeof document !== \"undefined\") {\n config = getSiteConfig();\n }\n\n let inlineThemeStyleText: string | undefined;\n if (typeof document !== \"undefined\") {\n let styleElementId = \"shadow-claw-theme\";\n if (config && typeof config === \"object\") {\n const customId = (config as { theme?: { styleElement?: unknown } }).theme\n ?.styleElement;\n if (typeof customId === \"string\" && customId.trim()) {\n styleElementId = customId.trim();\n }\n }\n const inlineStyle =\n document.getElementById(styleElementId) ||\n document.querySelector(\"style[data-shadow-claw-theme]\");\n if (inlineStyle?.textContent) {\n inlineThemeStyleText = inlineStyle.textContent;\n }\n }\n\n let stylesheet: string | undefined;\n if (config && typeof config === \"object\") {\n const rawTheme = (config as { theme?: { stylesheet?: unknown } }).theme;\n if (\n typeof rawTheme?.stylesheet === \"string\" &&\n rawTheme.stylesheet.trim()\n ) {\n stylesheet = rawTheme.stylesheet.trim();\n }\n }\n\n let result = \"\";\n if (inlineThemeStyleText) {\n result += `<style data-theme-style=\"true\">${inlineThemeStyleText}</style>`;\n }\n\n if (!stylesheet) {\n return result;\n }\n\n const isExternal =\n stylesheet.startsWith(\"http://\") ||\n stylesheet.startsWith(\"https://\") ||\n stylesheet.startsWith(\"//\");\n\n if (isExternal) {\n return `${result}<link rel=\"stylesheet\" href=\"${stylesheet}\">`;\n }\n\n // Runtime links must be site-root absolute (with the deployment base path):\n // srcdoc preview iframes set `<base href=\"/<base>/files/<group>/...\">`, so a\n // relative href would resolve under the file route and 404.\n const resolvedHref = resolveThemeStylesheetHref(stylesheet).replace(\n /^\\/+/,\n \"\",\n );\n return `${result}<link rel=\"stylesheet\" href=\"${applyBasePath(`/${resolvedHref}`)}\">`;\n}\n\n/**\n * Generates the CSS style block and html root class for sandboxed preview iframes\n * (file viewer and pages HTML preview) to synchronize theme CSS variables,\n * fonts, link styling, and dark/light mode color-scheme without FOUC.\n */\nexport function getIframeThemeStyleHtml(): string {\n const isDark =\n typeof document !== \"undefined\" &&\n document.documentElement.classList.contains(\"dark-mode\");\n const customProperties: string[] = [];\n\n if (typeof document !== \"undefined\") {\n const styles = getComputedStyle(document.documentElement);\n for (let i = 0; i < styles.length; i++) {\n const prop = styles[i];\n if (prop.startsWith(\"--\")) {\n customProperties.push(`${prop}: ${styles.getPropertyValue(prop)};`);\n }\n }\n }\n\n return [\n \"<style>\",\n \" :root {\",\n ` color-scheme: ${isDark ? \"dark\" : \"light\"};`,\n ` overflow: hidden;`,\n ` line-height: 1.5;`,\n ` ${customProperties.join(\"\\n \")}`,\n \" }\",\n \" * {\",\n \" scrollbar-width: thin;\",\n \" scrollbar-color: var(--shadow-claw-border-color) transparent;\",\n \" }\",\n \" ::-webkit-scrollbar {\",\n \" height: 0.5rem;\",\n \" width: 0.5rem;\",\n \" }\",\n \" ::-webkit-scrollbar-track {\",\n \" background: transparent;\",\n \" }\",\n \" ::-webkit-scrollbar-thumb {\",\n \" background: var(--shadow-claw-border-color);\",\n \" border-radius: 0.25rem;\",\n \" }\",\n \" ::-webkit-scrollbar-thumb:hover {\",\n \" background: var(--shadow-claw-text-tertiary);\",\n \" }\",\n \" body {\",\n \" color: var(--shadow-claw-text-primary);\",\n \" background-color: var(--shadow-claw-bg-primary);\",\n \" font-family: var(--shadow-claw-font-sans);\",\n \" margin: 0;\",\n \" }\",\n \" pre, code, kbd, samp {\",\n \" font-family: var(--shadow-claw-font-mono);\",\n \" }\",\n \" a {\",\n \" color: var(--shadow-claw-link);\",\n \" text-decoration: underline;\",\n \" text-underline-offset: 0.125rem;\",\n \" }\",\n \" a:hover {\",\n \" color: var(--shadow-claw-link-hover);\",\n \" }\",\n \" img {\",\n \" max-width: 100%;\",\n \" height: auto;\",\n \" }\",\n \" ul {\",\n \" line-height: 1.5;\",\n \" }\",\n \" article {\",\n \" padding: 1rem 1.5rem 1rem 1rem;\",\n \" }\",\n \" article > h1, article > h2 {\",\n \" margin-top: 0;\",\n \" }\",\n \"</style>\",\n ].join(\"\\n\");\n}\n\nexport function getIframeHtmlClass(): string {\n const isDark =\n typeof document !== \"undefined\" &&\n document.documentElement.classList.contains(\"dark-mode\");\n\n return isDark ? \"dark-mode\" : \"light-mode\";\n}\n","/**\n * iframe-broadcast-proxy.ts\n *\n * Parent-side BroadcastChannel proxy for sandboxed iframes.\n * When allow-same-origin is omitted from preview iframes, the iframe operates\n * under an opaque (null) origin. Browser BroadcastChannel instances are partitioned\n * by origin, preventing direct communication between parent/worker tools and the iframe.\n *\n * This proxy is completely AGNOSTIC and generic. It dynamically tracks BroadcastChannels\n * instantiated on the parent origin and extracts channel names declaratively from tool\n * definitions registered via site-config/toolsStore.\n */\n\nexport class IframeBroadcastProxy {\n private commandChannels: Map<string, BroadcastChannel> = new Map();\n private originalBroadcastChannel: typeof BroadcastChannel | null = null;\n\n constructor(private getTargetWindow: () => WindowProxy | null) {\n if (typeof BroadcastChannel !== \"undefined\") {\n this.patchParentBroadcastChannel();\n }\n }\n\n /**\n * Automatically intercept BroadcastChannel creation on parent window to\n * dynamically track and forward any channel used by tools or parent scripts.\n */\n private patchParentBroadcastChannel(): void {\n if ((globalThis as any)._shadowClawParentBcPatched) {\n return;\n }\n (globalThis as any)._shadowClawParentBcPatched = true;\n\n const self = this;\n const NativeBc = globalThis.BroadcastChannel;\n this.originalBroadcastChannel = NativeBc;\n\n const WrappedBc = function (this: BroadcastChannel, channelName: string) {\n const instance = new NativeBc(channelName);\n self.registerChannel(channelName);\n return instance;\n } as any;\n\n WrappedBc.prototype = NativeBc.prototype;\n globalThis.BroadcastChannel = WrappedBc;\n }\n\n /**\n * Declaratively scan tool execution code definitions for BroadcastChannel names\n * and register them automatically.\n */\n public registerChannelsFromTools(\n tools: Array<{ execution?: { code?: string }; code?: string }>,\n ): void {\n if (!Array.isArray(tools)) return;\n\n const bcRegex = /new\\s+BroadcastChannel\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/g;\n for (const tool of tools) {\n const code = tool.execution?.code || tool.code || \"\";\n if (!code) continue;\n\n let match: RegExpExecArray | null;\n bcRegex.lastIndex = 0;\n while ((match = bcRegex.exec(code)) !== null) {\n if (match[1]) {\n this.registerChannel(match[1]);\n }\n }\n }\n }\n\n /**\n * Register a channel name to forward parent messages to the sandboxed iframe.\n */\n public registerChannel(channelName: string): void {\n if (\n typeof BroadcastChannel === \"undefined\" ||\n !channelName ||\n channelName.endsWith(\"-results\") ||\n this.commandChannels.has(channelName)\n ) {\n return;\n }\n this.listenOnCommandChannel(channelName);\n }\n\n private listenOnCommandChannel(channelName: string): void {\n try {\n const NativeBc =\n this.originalBroadcastChannel || globalThis.BroadcastChannel;\n const bc = new NativeBc(channelName);\n bc.onmessage = (evt) => {\n const target = this.getTargetWindow();\n if (target) {\n target.postMessage(\n {\n type: \"shadow-claw-broadcast-command\",\n channel: channelName,\n payload: evt.data,\n },\n \"*\",\n );\n }\n };\n this.commandChannels.set(channelName, bc);\n } catch (e) {\n console.warn(\n `[IframeBroadcastProxy] Failed to listen on channel ${channelName}:`,\n e,\n );\n }\n }\n\n /**\n * Handle incoming broadcast result/message from the sandboxed iframe and relay it\n * to the parent-origin BroadcastChannel.\n */\n public handleResultFromIframe(\n sourceWindow: WindowProxy,\n channelName: string,\n payload: unknown,\n ): boolean {\n const target = this.getTargetWindow();\n if (target && sourceWindow !== target) {\n return false;\n }\n\n if (channelName) {\n try {\n const NativeBc =\n this.originalBroadcastChannel || globalThis.BroadcastChannel;\n const resBc = new NativeBc(channelName);\n resBc.postMessage(payload);\n resBc.close();\n return true;\n } catch (e) {\n console.warn(\n `[IframeBroadcastProxy] Failed to relay result for channel ${channelName}:`,\n e,\n );\n }\n }\n return false;\n }\n\n public dispose(): void {\n for (const bc of this.commandChannels.values()) {\n try {\n bc.close();\n } catch (e) {}\n }\n this.commandChannels.clear();\n }\n}\n","/**\n * iframe-storage-proxy.ts\n *\n * Parent-side storage implementation for the iframe storage bridge.\n * Provides a namespaced IndexedDB key-value store that the parent frame\n * uses to proxy storage operations on behalf of sandboxed iframes that\n * lack direct storage access due to opaque-origin isolation.\n *\n * Each page gets its own namespace to prevent cross-page data leakage.\n */\n\nconst DB_NAME = \"shadow-claw-iframe-storage\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"kv\";\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDb(): Promise<IDBDatabase> {\n if (dbPromise) {\n return dbPromise;\n }\n\n dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => {\n dbPromise = null;\n reject(request.error);\n };\n });\n\n return dbPromise;\n}\n\n/**\n * Build a composite key from a namespace and item key.\n */\nfunction compositeKey(namespace: string, key: string): string {\n return `${namespace}\\0${key}`;\n}\n\n/**\n * Set a value in the namespaced store.\n */\nexport async function iframeStorageSet(\n namespace: string,\n key: string,\n value: unknown,\n): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).put(value, compositeKey(namespace, key));\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Get a single value from the namespaced store.\n */\nexport async function iframeStorageGet(\n namespace: string,\n key: string,\n): Promise<unknown> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const req = tx.objectStore(STORE_NAME).get(compositeKey(namespace, key));\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n}\n\n/**\n * Get all values for a namespace as a key-value object.\n */\nexport async function iframeStorageGetAll(\n namespace: string,\n): Promise<Record<string, unknown>> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const result: Record<string, unknown> = {};\n const prefix = `${namespace}\\0`;\n const cursorReq = store.openCursor();\n\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (!cursor) {\n resolve(result);\n return;\n }\n const cursorKey =\n typeof cursor.key === \"string\" ? cursor.key : String(cursor.key);\n if (cursorKey.startsWith(prefix)) {\n result[cursorKey.slice(prefix.length)] = cursor.value;\n }\n cursor.continue();\n };\n\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n}\n\n/**\n * Delete a single value from the namespaced store.\n */\nexport async function iframeStorageDelete(\n namespace: string,\n key: string,\n): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n tx.objectStore(STORE_NAME).delete(compositeKey(namespace, key));\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\n/**\n * Clear all values for a namespace.\n */\nexport async function iframeStorageClear(namespace: string): Promise<void> {\n const db = await openDb();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const prefix = `${namespace}\\0`;\n const cursorReq = store.openCursor();\n\n cursorReq.onsuccess = () => {\n const cursor = cursorReq.result;\n if (!cursor) {\n resolve();\n return;\n }\n const cursorKey =\n typeof cursor.key === \"string\" ? cursor.key : String(cursor.key);\n if (cursorKey.startsWith(prefix)) {\n cursor.delete();\n }\n cursor.continue();\n };\n\n cursorReq.onerror = () => reject(cursorReq.error);\n });\n}\n","/**\n * Auto-generated and bundled inline script sources for sandboxed iframe previews.\n * Inlining these scripts into about:srcdoc with CSP nonces eliminates network roundtrips\n * and prevents browser ad-blockers / Brave Shields from blocking bridge scripts with ERR_BLOCKED_BY_CLIENT.\n */\n\nexport const IFRAME_STORAGE_BRIDGE_SCRIPT: string =\n '/**\\n * iframe-storage-bridge.js\\n *\\n * Injected into sandboxed preview iframes (via nonce-gated CSP) to provide\\n * a transparent storage proxy when the iframe is running in an opaque origin\\n * (i.e. sandbox without allow-same-origin).\\n *\\n * When IndexedDB and localStorage are unavailable due to opaque origin\\n * restrictions, this bridge intercepts storage calls and proxies them to\\n * the parent frame via postMessage. The parent frame performs the actual\\n * storage operations on the iframe\\'s behalf using a namespaced key-value\\n * store.\\n *\\n * SECURITY:\\n * - All messages use a unique type prefix to avoid collision.\\n * - The parent validates message source against the iframe\\'s contentWindow.\\n * - Storage is namespaced per-page to prevent cross-page data leakage.\\n * - This file is served same-origin and loaded with a per-render nonce.\\n */\\n\\n(function () {\\n \"use strict\";\\n\\n // Intercept and prevent unhandled sandboxed serviceWorker SecurityErrors from breaking execution flow\\n try {\\n window.addEventListener(\\n \"error\",\\n function (e) {\\n if (\\n e.message &&\\n (e.message.indexOf(\"serviceWorker\") !== -1 ||\\n e.message.indexOf(\"Service worker\") !== -1)\\n ) {\\n e.preventDefault();\\n e.stopImmediatePropagation();\\n }\\n },\\n true,\\n );\\n window.addEventListener(\\n \"unhandledrejection\",\\n function (e) {\\n if (\\n e.reason &&\\n (String(e.reason).indexOf(\"serviceWorker\") !== -1 ||\\n String(e.reason).indexOf(\"Service worker\") !== -1)\\n ) {\\n e.preventDefault();\\n e.stopImmediatePropagation();\\n }\\n },\\n true,\\n );\\n } catch (e) {}\\n\\n // Safely trap serviceWorker access in sandboxed cross-origin iframes\\n try {\\n var swDesc = {\\n get: function () {\\n return undefined;\\n },\\n configurable: true,\\n enumerable: false,\\n };\\n if (typeof Navigator !== \"undefined\" && Navigator.prototype) {\\n try {\\n Object.defineProperty(Navigator.prototype, \"serviceWorker\", swDesc);\\n } catch (e1) {}\\n }\\n if (typeof navigator !== \"undefined\") {\\n try {\\n Object.defineProperty(navigator, \"serviceWorker\", swDesc);\\n } catch (e2) {}\\n }\\n } catch (e) {\\n // ignore\\n }\\n\\n // Safely trap caches (CacheStorage) access in sandboxed cross-origin iframes\\n try {\\n var cacheDesc = {\\n get: function () {\\n return undefined;\\n },\\n configurable: true,\\n enumerable: false,\\n };\\n if (typeof Window !== \"undefined\" && Window.prototype) {\\n try {\\n Object.defineProperty(Window.prototype, \"caches\", cacheDesc);\\n } catch (e1) {}\\n }\\n if (typeof window !== \"undefined\") {\\n try {\\n Object.defineProperty(window, \"caches\", cacheDesc);\\n } catch (e2) {}\\n }\\n } catch (e) {\\n // ignore\\n }\\n\\n // Polyfill showOpenFilePicker using standard <input type=\"file\"> in sandboxed iframes\\n try {\\n Object.defineProperty(window, \"showOpenFilePicker\", {\\n value: function (options) {\\n return new Promise(function (resolve, reject) {\\n var input = document.createElement(\"input\");\\n input.type = \"file\";\\n if (options && options.multiple) {\\n input.multiple = true;\\n }\\n if (options && options.types && options.types.length > 0) {\\n var accept = [];\\n options.types.forEach(function (t) {\\n if (t.accept) {\\n Object.keys(t.accept).forEach(function (mime) {\\n accept.push(mime);\\n var exts = t.accept[mime];\\n if (Array.isArray(exts)) {\\n exts.forEach(function (ext) {\\n accept.push(ext);\\n });\\n }\\n });\\n }\\n });\\n if (accept.length > 0) {\\n input.accept = accept.join(\",\");\\n }\\n }\\n\\n input.onchange = function () {\\n if (!input.files || input.files.length === 0) {\\n reject(\\n new DOMException(\"The user aborted a request.\", \"AbortError\"),\\n );\\n return;\\n }\\n var handles = Array.from(input.files).map(function (file) {\\n return {\\n kind: \"file\",\\n name: file.name,\\n getFile: function () {\\n return Promise.resolve(file);\\n },\\n };\\n });\\n resolve(handles);\\n };\\n\\n input.oncancel = function () {\\n reject(\\n new DOMException(\"The user aborted a request.\", \"AbortError\"),\\n );\\n };\\n\\n input.click();\\n });\\n },\\n configurable: true,\\n writable: true,\\n });\\n } catch (e) {\\n // ignore\\n }\\n\\n // Polyfill showSaveFilePicker using standard <a download> in sandboxed iframes\\n try {\\n Object.defineProperty(window, \"showSaveFilePicker\", {\\n value: function (options) {\\n var filename = (options && options.suggestedName) || \"download\";\\n var mimeType = \"application/octet-stream\";\\n if (\\n options &&\\n options.types &&\\n options.types.length > 0 &&\\n options.types[0].accept\\n ) {\\n var mimes = Object.keys(options.types[0].accept);\\n if (mimes.length > 0) {\\n mimeType = mimes[0];\\n }\\n }\\n\\n var chunks = [];\\n\\n var writable = {\\n write: function (data) {\\n if (\\n data &&\\n typeof data === \"object\" &&\\n data.type === \"write\" &&\\n data.data\\n ) {\\n chunks.push(data.data);\\n } else if (data !== undefined && data !== null) {\\n chunks.push(data);\\n }\\n return Promise.resolve();\\n },\\n seek: function () {\\n return Promise.resolve();\\n },\\n truncate: function () {\\n return Promise.resolve();\\n },\\n close: function () {\\n return new Promise(function (resolve) {\\n try {\\n var blob = new Blob(chunks, { type: mimeType });\\n var url = URL.createObjectURL(blob);\\n var a = document.createElement(\"a\");\\n a.href = url;\\n a.download = filename;\\n a.style.display = \"none\";\\n document.body.appendChild(a);\\n a.click();\\n setTimeout(function () {\\n if (a.parentNode) {\\n a.parentNode.removeChild(a);\\n }\\n URL.revokeObjectURL(url);\\n }, 1000);\\n } catch (e) {\\n // ignore\\n }\\n resolve();\\n });\\n },\\n };\\n\\n var handle = {\\n kind: \"file\",\\n name: filename,\\n createWritable: function () {\\n return Promise.resolve(writable);\\n },\\n getFile: function () {\\n var blob = new Blob(chunks, { type: mimeType });\\n var file = new File([blob], filename, { type: mimeType });\\n return Promise.resolve(file);\\n },\\n };\\n\\n return Promise.resolve(handle);\\n },\\n configurable: true,\\n writable: true,\\n });\\n } catch (e) {\\n // ignore\\n }\\n\\n // Always install proxy immediately for sandboxed preview iframes.\\n installProxy();\\n\\n // ----------------------------------------------------------------\\n // Pending request tracking\\n // ----------------------------------------------------------------\\n var pendingRequests = {};\\n var requestIdCounter = 0;\\n\\n function sendRequest(method, args) {\\n return new Promise(function (resolve, reject) {\\n var requestId = \"sc-storage-\" + ++requestIdCounter;\\n pendingRequests[requestId] = { resolve: resolve, reject: reject };\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-storage-proxy\",\\n requestId: requestId,\\n method: method,\\n args: args,\\n },\\n \"*\",\\n );\\n\\n // Timeout after 10 seconds to avoid hanging forever.\\n setTimeout(function () {\\n if (pendingRequests[requestId]) {\\n delete pendingRequests[requestId];\\n reject(new Error(\"Storage proxy request timed out: \" + method));\\n }\\n }, 10000);\\n });\\n }\\n\\n window.addEventListener(\"message\", function (event) {\\n if (!event.data || event.data.type !== \"shadow-claw-storage-proxy-result\") {\\n return;\\n }\\n var requestId = event.data.requestId;\\n var pending = pendingRequests[requestId];\\n if (!pending) {\\n return;\\n }\\n delete pendingRequests[requestId];\\n if (event.data.error) {\\n pending.reject(new Error(event.data.error));\\n } else {\\n pending.resolve(event.data.result);\\n }\\n });\\n\\n // ----------------------------------------------------------------\\n // localStorage shim\\n // ----------------------------------------------------------------\\n function installProxy() {\\n // localStorage shim — backed by parent-proxied key-value store.\\n var localStorageShim = {\\n _cache: {},\\n\\n getItem: function (key) {\\n // Return cached value synchronously (best-effort).\\n // Async warm-up happens in the background.\\n return this._cache[key] !== undefined ? this._cache[key] : null;\\n },\\n\\n setItem: function (key, value) {\\n var stringValue = String(value);\\n this._cache[key] = stringValue;\\n sendRequest(\"setItem\", { key: key, value: stringValue }).catch(\\n function () {\\n // Silently ignore write failures\\n },\\n );\\n },\\n\\n removeItem: function (key) {\\n delete this._cache[key];\\n sendRequest(\"removeItem\", { key: key }).catch(function () {});\\n },\\n\\n clear: function () {\\n this._cache = {};\\n sendRequest(\"clear\", {}).catch(function () {});\\n },\\n\\n key: function (index) {\\n var keys = Object.keys(this._cache);\\n return index >= 0 && index < keys.length ? keys[index] : null;\\n },\\n\\n get length() {\\n return Object.keys(this._cache).length;\\n },\\n };\\n\\n // Warm up the cache from the parent.\\n sendRequest(\"getAllItems\", {})\\n .then(function (items) {\\n if (items && typeof items === \"object\") {\\n for (var k in items) {\\n if (Object.prototype.hasOwnProperty.call(items, k)) {\\n localStorageShim._cache[k] = items[k];\\n }\\n }\\n }\\n })\\n .catch(function () {});\\n\\n try {\\n Object.defineProperty(window, \"localStorage\", {\\n get: function () {\\n return localStorageShim;\\n },\\n configurable: true,\\n });\\n } catch (e) {\\n // If we can\\'t override localStorage, leave the native (broken) one.\\n }\\n\\n // ----------------------------------------------------------------\\n // IndexedDB shim — minimal proxy supporting open / transaction / objectStore CRUD\\n // ----------------------------------------------------------------\\n var IDBShimDatabase = function (name) {\\n this.name = name;\\n this._closed = false;\\n };\\n\\n IDBShimDatabase.prototype.close = function () {\\n this._closed = true;\\n };\\n\\n IDBShimDatabase.prototype.transaction = function (storeNames) {\\n return new IDBShimTransaction(this.name, storeNames);\\n };\\n\\n // Expose objectStoreNames for compatibility (always returns the default store).\\n Object.defineProperty(IDBShimDatabase.prototype, \"objectStoreNames\", {\\n get: function () {\\n return {\\n length: 1,\\n item: function () {\\n return \"__default__\";\\n },\\n contains: function () {\\n return true;\\n },\\n };\\n },\\n });\\n\\n var IDBShimTransaction = function (dbName, storeNames) {\\n this._dbName = dbName;\\n this._storeNames = storeNames;\\n this.oncomplete = null;\\n this.onerror = null;\\n this.onabort = null;\\n\\n // Fire oncomplete asynchronously.\\n var self = this;\\n setTimeout(function () {\\n if (typeof self.oncomplete === \"function\") {\\n self.oncomplete({ target: self });\\n }\\n }, 0);\\n };\\n\\n IDBShimTransaction.prototype.objectStore = function (name) {\\n return new IDBShimObjectStore(this._dbName, name);\\n };\\n\\n var IDBShimObjectStore = function (dbName, storeName) {\\n this._dbName = dbName;\\n this._storeName = storeName;\\n };\\n\\n IDBShimObjectStore.prototype.get = function (key) {\\n return createIDBRequest(\\n sendRequest(\"idb-get\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.getAll = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.put = function (value, key) {\\n return createIDBRequest(\\n sendRequest(\"idb-put\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n value: value,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.delete = function (key) {\\n return createIDBRequest(\\n sendRequest(\"idb-delete\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n key: key,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.clear = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-clear\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.getAllKeys = function () {\\n return createIDBRequest(\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n }).then(function (items) {\\n if (items && typeof items === \"object\") {\\n return Object.keys(items);\\n }\\n return [];\\n }),\\n );\\n };\\n\\n IDBShimObjectStore.prototype.openKeyCursor = function () {\\n return this.openCursor();\\n };\\n\\n IDBShimObjectStore.prototype.openCursor = function () {\\n var request = {\\n result: null,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n readyState: \"pending\",\\n };\\n\\n sendRequest(\"idb-getAll\", {\\n dbName: this._dbName,\\n storeName: this._storeName,\\n })\\n .then(function (items) {\\n var keys =\\n items && typeof items === \"object\" ? Object.keys(items) : [];\\n var index = 0;\\n\\n function advanceCursor() {\\n if (index >= keys.length) {\\n request.result = null;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n return;\\n }\\n\\n var currentKey = keys[index];\\n var currentValue = items[currentKey];\\n\\n var cursor = {\\n key: currentKey,\\n primaryKey: currentKey,\\n value: currentValue,\\n continue: function () {\\n index++;\\n advanceCursor();\\n },\\n };\\n\\n request.result = cursor;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n }\\n\\n advanceCursor();\\n })\\n .catch(function (err) {\\n request.error = err;\\n request.readyState = \"done\";\\n if (typeof request.onerror === \"function\") {\\n request.onerror({ target: request });\\n }\\n });\\n\\n return request;\\n };\\n\\n function createIDBRequest(promise) {\\n var request = {\\n result: undefined,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n readyState: \"pending\",\\n };\\n\\n promise\\n .then(function (result) {\\n request.result = result;\\n request.readyState = \"done\";\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n })\\n .catch(function (err) {\\n request.error = err;\\n request.readyState = \"done\";\\n if (typeof request.onerror === \"function\") {\\n request.onerror({ target: request });\\n }\\n });\\n\\n return request;\\n }\\n\\n // indexedDB.open() shim\\n var indexedDBShim = {\\n open: function (name) {\\n var request = {\\n result: null,\\n error: null,\\n onsuccess: null,\\n onerror: null,\\n onupgradeneeded: null,\\n readyState: \"pending\",\\n };\\n\\n // Simulate async open.\\n setTimeout(function () {\\n request.result = new IDBShimDatabase(name);\\n request.readyState = \"done\";\\n\\n // Fire onupgradeneeded first (for initial setup), then onsuccess.\\n if (typeof request.onupgradeneeded === \"function\") {\\n request.onupgradeneeded({\\n target: request,\\n oldVersion: 0,\\n newVersion: 1,\\n });\\n }\\n if (typeof request.onsuccess === \"function\") {\\n request.onsuccess({ target: request });\\n }\\n }, 0);\\n\\n return request;\\n },\\n\\n deleteDatabase: function (name) {\\n var request = createIDBRequest(\\n sendRequest(\"idb-deleteDatabase\", { dbName: name }),\\n );\\n return request;\\n },\\n };\\n\\n try {\\n Object.defineProperty(window, \"indexedDB\", {\\n get: function () {\\n return indexedDBShim;\\n },\\n configurable: true,\\n });\\n } catch (e) {\\n // If we can\\'t override, leave native.\\n }\\n }\\n})();\\n';\n\nexport const FILE_VIEWER_PREVIEW_BRIDGE_SCRIPT: string =\n '/**\\n * file-viewer-preview-bridge.js\\n *\\n * Injected into sandboxed preview iframes (file viewer + pages HTML preview)\\n * via a per-render nonce. Intercepts link clicks and posts them to the parent\\n * so the app can handle workspace-relative navigation.\\n *\\n * SECURITY: This file is served same-origin and loaded with a per-render nonce.\\n * The Trusted Types policy and nonce-gated CSP prevent any other scripts from\\n * running inside the sandboxed srcdoc iframe.\\n */\\n\\n(function () {\\n \"use strict\";\\n\\n // ---------------------------------------------------------------------------\\n // BroadcastChannel Opaque-Origin Proxy Bridge\\n // ---------------------------------------------------------------------------\\n // When allow-same-origin is omitted from sandboxed preview iframes, the iframe\\n // operates under a null (opaque) origin. Native BroadcastChannel instances are\\n // partitioned by origin, preventing direct communication between parent/worker\\n // tools and the iframe.\\n //\\n // This bridge wraps window.BroadcastChannel inside the iframe so that any\\n // message posted by iframe scripts (e.g., tool responses) is automatically\\n // relayed to the parent window via postMessage. It also listens for commands\\n // posted from the parent window and re-emits them to the iframe\\'s BroadcastChannel.\\n // ---------------------------------------------------------------------------\\n var isRelayingCommandFromParent = false;\\n\\n if (\\n typeof BroadcastChannel !== \"undefined\" &&\\n !window._shadowClawBcBridgeInstalled\\n ) {\\n window._shadowClawBcBridgeInstalled = true;\\n var NativeBroadcastChannel = window.BroadcastChannel;\\n var origPostMessage = NativeBroadcastChannel.prototype.postMessage;\\n\\n NativeBroadcastChannel.prototype.postMessage = function (message) {\\n origPostMessage.call(this, message);\\n if (isRelayingCommandFromParent) {\\n return;\\n }\\n try {\\n if (window.parent && window.parent !== window) {\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-broadcast-result\",\\n channel: this.name,\\n payload: message,\\n },\\n \"*\",\\n );\\n }\\n } catch (e) {\\n // Ignore postMessage transfer errors\\n }\\n };\\n }\\n\\n window.addEventListener(\"message\", function (event) {\\n if (!event.data || typeof event.data !== \"object\") {\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-broadcast-command\") {\\n var channelName = event.data.channel;\\n var payload = event.data.payload;\\n if (channelName && typeof NativeBroadcastChannel !== \"undefined\") {\\n try {\\n var bc = new NativeBroadcastChannel(channelName);\\n isRelayingCommandFromParent = true;\\n bc.postMessage(payload);\\n isRelayingCommandFromParent = false;\\n bc.close();\\n } catch (e) {\\n isRelayingCommandFromParent = false;\\n // Ignore command relay errors\\n }\\n }\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-theme-update\") {\\n if (event.data.customProperties) {\\n for (var key in event.data.customProperties) {\\n if (\\n Object.prototype.hasOwnProperty.call(\\n event.data.customProperties,\\n key,\\n )\\n ) {\\n document.documentElement.style.setProperty(\\n key,\\n event.data.customProperties[key],\\n );\\n }\\n }\\n }\\n\\n var isDark = event.data.theme === \"dark\";\\n if (isDark) {\\n document.documentElement.classList.add(\"dark-mode\");\\n document.documentElement.classList.remove(\"light-mode\");\\n if (document.body) {\\n document.body.classList.add(\"dark-mode\");\\n document.body.classList.remove(\"light-mode\");\\n }\\n } else {\\n document.documentElement.classList.add(\"light-mode\");\\n document.documentElement.classList.remove(\"dark-mode\");\\n if (document.body) {\\n document.body.classList.add(\"light-mode\");\\n document.body.classList.remove(\"dark-mode\");\\n }\\n }\\n try {\\n document.documentElement.style.colorScheme = isDark ? \"dark\" : \"light\";\\n } catch (e) {}\\n }\\n\\n if (event.data.type === \"shadow-claw-scroll-to-anchor\") {\\n var anchorId = event.data.anchor || \"\";\\n if (anchorId) {\\n var el =\\n document.getElementById(anchorId) ||\\n document.querySelector(\\'a[name=\"\\' + anchorId + \\'\"]\\');\\n if (el && typeof el.scrollIntoView === \"function\") {\\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\\n }\\n }\\n return;\\n }\\n\\n if (event.data.type === \"shadow-claw-update-url-params\") {\\n var searchStr = event.data.search || \"\";\\n if (searchStr) {\\n try {\\n window.history.replaceState(\\n null,\\n \"\",\\n window.location.pathname + searchStr,\\n );\\n } catch (e) {}\\n\\n try {\\n window.dispatchEvent(new Event(\"popstate\"));\\n window.dispatchEvent(new Event(\"locationchange\"));\\n } catch (e) {}\\n\\n var customEls = document.querySelectorAll(\"*\");\\n var retriggered = false;\\n for (var i = 0; i < customEls.length; i++) {\\n var el = customEls[i];\\n if (el.tagName && el.tagName.indexOf(\"-\") !== -1 && el.parentNode) {\\n try {\\n var cb = el.connectedCallback;\\n var clone = el.cloneNode(true);\\n if (typeof cb === \"function\") {\\n clone.connectedCallback = cb;\\n }\\n el.parentNode.replaceChild(clone, el);\\n if (typeof clone.connectedCallback === \"function\") {\\n try {\\n clone.connectedCallback();\\n } catch (e3) {}\\n }\\n retriggered = true;\\n } catch (err) {\\n if (typeof el.connectedCallback === \"function\") {\\n try {\\n el.connectedCallback();\\n retriggered = true;\\n } catch (e2) {}\\n }\\n }\\n }\\n }\\n\\n if (!retriggered) {\\n window.location.reload();\\n }\\n }\\n return;\\n }\\n });\\n\\n function isNavSuppressed(event) {\\n if (!event) return false;\\n var navAttributes = [\\n \"data-no-nav\",\\n \"data-no-swipe\",\\n \"data-no-page-nav\",\\n \"data-prevent-nav\",\\n \"data-prevent-page-nav\",\\n \"data-isolate-input\",\\n \"data-isolate-navigation\",\\n \"data-game-controls\",\\n ];\\n\\n var path =\\n typeof event.composedPath === \"function\" ? event.composedPath() : [];\\n\\n for (var i = 0; i < path.length; i++) {\\n var node = path[i];\\n if (node && node.nodeType === 1) {\\n var tag = (node.tagName || \"\").toLowerCase();\\n if (\\n tag === \"input\" ||\\n tag === \"textarea\" ||\\n tag === \"select\" ||\\n tag === \"option\" ||\\n node.isContentEditable ||\\n node.getAttribute(\"contenteditable\") === \"true\"\\n ) {\\n return true;\\n }\\n\\n for (var j = 0; j < navAttributes.length; j++) {\\n if (node.hasAttribute(navAttributes[j])) {\\n return true;\\n }\\n }\\n }\\n }\\n var target = event.target;\\n if (target && target.nodeType === 3) {\\n target = target.parentNode;\\n }\\n\\n if (target && target instanceof Element) {\\n var targetTag = (target.tagName || \"\").toLowerCase();\\n if (\\n targetTag === \"input\" ||\\n targetTag === \"textarea\" ||\\n targetTag === \"select\" ||\\n targetTag === \"option\" ||\\n target.isContentEditable ||\\n target.getAttribute(\"contenteditable\") === \"true\"\\n ) {\\n return true;\\n }\\n\\n for (var k = 0; k < navAttributes.length; k++) {\\n if (target.closest(\"[\" + navAttributes[k] + \"]\")) {\\n return true;\\n }\\n }\\n }\\n\\n return false;\\n }\\n\\n var touchStartX = 0;\\n var touchStartY = 0;\\n var touchStartTime = 0;\\n\\n document.addEventListener(\\n \"touchstart\",\\n function (event) {\\n if (isNavSuppressed(event)) {\\n touchStartX = 0;\\n touchStartY = 0;\\n touchStartTime = 0;\\n return;\\n }\\n if (event.touches && event.touches.length === 1) {\\n touchStartX = event.touches[0].clientX;\\n touchStartY = event.touches[0].clientY;\\n touchStartTime = Date.now();\\n }\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\\n \"touchend\",\\n function (event) {\\n if (!touchStartTime || isNavSuppressed(event)) {\\n touchStartTime = 0;\\n return;\\n }\\n if (event.changedTouches && event.changedTouches.length === 1) {\\n var touchEndX = event.changedTouches[0].clientX;\\n var touchEndY = event.changedTouches[0].clientY;\\n var deltaTime = Date.now() - touchStartTime;\\n\\n var deltaX = touchEndX - touchStartX;\\n var deltaY = touchEndY - touchStartY;\\n\\n if (\\n Math.abs(deltaX) >= 50 &&\\n Math.abs(deltaX) > Math.abs(deltaY) &&\\n deltaTime <= 600\\n ) {\\n var direction = deltaX < 0 ? \"left\" : \"right\";\\n window.parent.postMessage(\\n { type: \"shadow-claw-swipe\", direction: direction },\\n \"*\",\\n );\\n }\\n }\\n touchStartTime = 0;\\n },\\n { passive: true },\\n );\\n\\n var mouseStartX = 0;\\n var mouseStartY = 0;\\n var mouseStartTime = 0;\\n var isMouseDown = false;\\n\\n document.addEventListener(\\n \"mousedown\",\\n function (event) {\\n if (event.button !== 0 || isNavSuppressed(event)) {\\n isMouseDown = false;\\n return;\\n }\\n isMouseDown = true;\\n mouseStartX = event.clientX;\\n mouseStartY = event.clientY;\\n mouseStartTime = Date.now();\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\\n \"mouseup\",\\n function (event) {\\n if (!isMouseDown) {\\n return;\\n }\\n isMouseDown = false;\\n if (isNavSuppressed(event)) {\\n return;\\n }\\n\\n var selection = window.getSelection();\\n if (selection && selection.toString().length > 0) {\\n return;\\n }\\n\\n var mouseEndX = event.clientX;\\n var mouseEndY = event.clientY;\\n var deltaTime = Date.now() - mouseStartTime;\\n\\n var deltaX = mouseEndX - mouseStartX;\\n var deltaY = mouseEndY - mouseStartY;\\n\\n if (\\n Math.abs(deltaX) >= 50 &&\\n Math.abs(deltaX) > Math.abs(deltaY) &&\\n deltaTime <= 600\\n ) {\\n var direction = deltaX < 0 ? \"left\" : \"right\";\\n window.parent.postMessage(\\n { type: \"shadow-claw-swipe\", direction: direction },\\n \"*\",\\n );\\n }\\n },\\n { passive: true },\\n );\\n\\n document.addEventListener(\"click\", function (event) {\\n // Only handle unmodified primary clicks.\\n if (event.defaultPrevented || event.button !== 0) {\\n return;\\n }\\n\\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\\n return;\\n }\\n\\n var target = event.target;\\n if (!target) {\\n return;\\n }\\n\\n if (target.nodeType === 3) {\\n {\\n // Node.TEXT_NODE;\\n }\\n\\n target = target.parentNode;\\n }\\n\\n if (!(target instanceof Element)) {\\n return;\\n }\\n\\n var link = target.closest(\"a\");\\n if (!(link instanceof HTMLAnchorElement)) {\\n return;\\n }\\n\\n var href = link.getAttribute(\"href\") || \"\";\\n if (!href) {\\n return;\\n }\\n\\n // Let fragment-only same-page anchors pass through normally.\\n if (\\n href.startsWith(\"#\") &&\\n !href.includes(\"?\") &&\\n !href.includes(\"groupId\")\\n ) {\\n return;\\n }\\n\\n // Intercept all links so sandboxed preview iframes never navigate away from srcdoc.\\n event.preventDefault();\\n\\n window.parent.postMessage(\\n {\\n type: \"shadow-claw-file-viewer-link\",\\n href: href,\\n target: link.getAttribute(\"target\") || \"\",\\n },\\n \"*\",\\n );\\n });\\n\\n var lastReportedHeight = -1;\\n\\n function reportHeight() {\\n var body = document.body;\\n var docEl = document.documentElement;\\n\\n if (!body && !docEl) {\\n return;\\n }\\n\\n // Temporarily collapse documentElement height so that scrollHeight reflects\\n // only the natural content size — not the height the parent previously\\n // injected into the iframe via style.height. Without this reset the\\n // browser keeps scrollHeight equal to the externally-set height, which\\n // creates a feedback loop that leaves a scrollbar on the parent at wide\\n // widths (the iframe reports its own height, the parent honours it, repeat).\\n var prevDocElHeight = docEl ? docEl.style.height : null;\\n if (docEl) {\\n docEl.style.height = \"0\";\\n }\\n\\n var height = Math.max(\\n body ? body.scrollHeight : 0,\\n body ? body.offsetHeight : 0,\\n );\\n\\n if (body && body.lastElementChild) {\\n try {\\n var lastEl = body.lastElementChild;\\n var rect = lastEl.getBoundingClientRect();\\n var bodyRect = body.getBoundingClientRect();\\n var lastElBottom = rect.bottom - bodyRect.top + (window.scrollY || 0);\\n if (lastElBottom > height) {\\n height = Math.ceil(lastElBottom);\\n }\\n } catch (e) {\\n // Fallback if bounding rect computation fails\\n }\\n }\\n\\n // Restore documentElement height.\\n if (docEl) {\\n docEl.style.height = prevDocElHeight || \"\";\\n }\\n\\n if (height > 0 && Math.abs(height - lastReportedHeight) > 1) {\\n lastReportedHeight = height;\\n window.parent.postMessage(\\n { type: \"shadow-claw-iframe-resize\", height: height },\\n \"*\",\\n );\\n }\\n }\\n\\n // Always schedule via rAF so layout is settled before measuring.\\n function scheduleReportHeight() {\\n if (typeof requestAnimationFrame === \"function\") {\\n requestAnimationFrame(reportHeight);\\n } else {\\n reportHeight();\\n }\\n }\\n\\n // First measurement: wait for DOM to be parsed.\\n // If the script runs during \"loading\" (sync <script> in <head>) we listen\\n // for DOMContentLoaded; otherwise the DOM is already ready so measure now.\\n if (document.readyState === \"loading\") {\\n document.addEventListener(\"DOMContentLoaded\", scheduleReportHeight);\\n } else {\\n scheduleReportHeight();\\n }\\n\\n // Re-measure after all sub-resources (images, fonts, etc.) have loaded,\\n // in case they affect the layout height.\\n window.addEventListener(\"load\", scheduleReportHeight);\\n\\n // Re-measure on viewport resize (e.g. window narrowed → text reflows taller).\\n window.addEventListener(\"resize\", scheduleReportHeight);\\n\\n // Ongoing: watch for dynamic content changes after initial load.\\n if (typeof ResizeObserver !== \"undefined\") {\\n var ro = new ResizeObserver(scheduleReportHeight);\\n if (document.documentElement) {\\n ro.observe(document.documentElement);\\n }\\n if (document.body) {\\n ro.observe(document.body);\\n }\\n }\\n})();\\n';\n\n/**\n * Escapes any closing script tags to ensure safe HTML interpolation.\n */\nexport function safeInlineScript(code: string): string {\n return code.replace(/<\\/script/gi, (m) => `<\\\\/${m.slice(2)}`);\n}\n"],"mappings":"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"}
|
package/dist/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
|
2
2
|
import { computeDelay, sleep, yieldToMain } from "./utils/delay.js";
|
|
3
3
|
import { ulid } from "./utils/ulid.js";
|
|
4
4
|
import { escapeHtml, escapeJsonForHtmlScript, stripHtml, unescapeHtml } from "./utils/html.js";
|
|
5
|
-
import { o as handleSpecialLinkNavigation, s as sanitizeHtml } from "./trusted-types-
|
|
5
|
+
import { o as handleSpecialLinkNavigation, s as sanitizeHtml } from "./trusted-types-HwsGS5Nj.js";
|
|
6
6
|
import { getNamespacedItem, getNamespacedStorageKey, removeNamespacedItem, setNamespacedItem } from "./utils/namespaced-storage.js";
|
|
7
7
|
import { normalizeStringList } from "./utils/normalize-string-list.js";
|
|
8
8
|
import { isPagePathAllowed } from "./utils/is-page-path-allowed.js";
|
|
@@ -12,50 +12,50 @@ import { applyJsonPatch } from "./utils/json-patch.js";
|
|
|
12
12
|
import { isTruthyConfigValue, parseBooleanConfig } from "./utils/parse-boolean-config.js";
|
|
13
13
|
import { parseStoredStringList } from "./utils/parse-stored-string-list.js";
|
|
14
14
|
import { bufferToHex, computeSha256, toArrayBuffer } from "./utils/crypto.js";
|
|
15
|
-
import { t as ShadowClaw } from "./shadow-claw-
|
|
16
|
-
import { t as ShadowClawChat } from "./shadow-claw-chat-
|
|
15
|
+
import { t as ShadowClaw } from "./shadow-claw-CGl8tXtG.js";
|
|
16
|
+
import { t as ShadowClawChat } from "./shadow-claw-chat-Wx3y9y6c.js";
|
|
17
17
|
import { IMAGE_MIME_TYPES, MIME_TYPES, getImageMimeType, getMimeType, guessMimeTypeFromFilename, inferAttachmentMimeType, isImagePath, isMimeType, mime } from "./utils/mime.js";
|
|
18
18
|
import { createFrontmatterDetailsElement, createFrontmatterElement, renderFrontmatterMarkup, splitFrontmatter } from "./utils/frontmatter.js";
|
|
19
19
|
import { basename, cleanFilename, sanitizeFilename } from "./utils/filename.js";
|
|
20
|
-
import { t as ShadowClawA2UI } from "./shadow-claw-a2ui-
|
|
20
|
+
import { t as ShadowClawA2UI } from "./shadow-claw-a2ui-lG0vQbW8.js";
|
|
21
21
|
import { formatDateForFilename, formatTimestamp } from "./utils/date.js";
|
|
22
22
|
import { t as ShadowClawPageHeaderActionButton } from "./shadow-claw-page-header-action-button-BXXm5b5N.js";
|
|
23
23
|
import { ShadowClawA2UIInterceptor } from "./components/shadow-claw-a2ui-interceptor.js";
|
|
24
24
|
import { ShadowClawDialog } from "./components/shadow-claw-dialog.js";
|
|
25
|
-
import { t as ShadowClawPageHeader } from "./shadow-claw-page-header-
|
|
26
|
-
import { t as ShadowClawFiles } from "./shadow-claw-files-
|
|
25
|
+
import { t as ShadowClawPageHeader } from "./shadow-claw-page-header-C_Qr3xZM.js";
|
|
26
|
+
import { t as ShadowClawFiles } from "./shadow-claw-files-BOUULrlX.js";
|
|
27
27
|
import { t as ShadowClawEmptyState } from "./shadow-claw-empty-state-D9bnqWMF.js";
|
|
28
|
-
import { t as ShadowClawFileViewer } from "./shadow-claw-file-viewer-
|
|
28
|
+
import { t as ShadowClawFileViewer } from "./shadow-claw-file-viewer-CG40kwWV.js";
|
|
29
29
|
import { t as ShadowClawPdfViewer } from "./shadow-claw-pdf-viewer-D-7W4CFV.js";
|
|
30
|
-
import { t as ShadowClawTasks } from "./shadow-claw-tasks-
|
|
31
|
-
import { n as ShadowClawTerminal } from "./shadow-claw-terminal-
|
|
30
|
+
import { t as ShadowClawTasks } from "./shadow-claw-tasks-B2EEqrcY.js";
|
|
31
|
+
import { n as ShadowClawTerminal } from "./shadow-claw-terminal-DSHfO2b9.js";
|
|
32
32
|
import { resolvePageScriptDependencies } from "./utils/resolve-page-script-dependencies.js";
|
|
33
33
|
import { extractMarkdownDescription, formatSeoTitle, patchHtmlHeadMetadata, resolveCanonicalUrl } from "./utils/seo.js";
|
|
34
|
-
import { t as ShadowClawPages } from "./shadow-claw-pages-
|
|
34
|
+
import { t as ShadowClawPages } from "./shadow-claw-pages-CfAjUKgd.js";
|
|
35
35
|
import { asNumber, asStringArray, asUidArray, coerce, coerceArray, coerceNumber, coerceStringArray, coerceUidArray } from "./utils/coerce.js";
|
|
36
36
|
import { base64, base64ToBytes, bytesToBase64 } from "./utils/base64.js";
|
|
37
|
-
import { t as ShadowClawSettings } from "./shadow-claw-settings-
|
|
38
|
-
import { t as ShadowClawPeerJs } from "./shadow-claw-peerjs-
|
|
39
|
-
import { t as ShadowClawChannelConfig } from "./shadow-claw-channel-config-
|
|
40
|
-
import { t as ShadowClawChannels } from "./shadow-claw-channels-
|
|
41
|
-
import { t as ShadowClawProviderModelPicker } from "./shadow-claw-provider-model-picker-
|
|
37
|
+
import { t as ShadowClawSettings } from "./shadow-claw-settings-Cg5V0e9g.js";
|
|
38
|
+
import { t as ShadowClawPeerJs } from "./shadow-claw-peerjs-t4YibS9s.js";
|
|
39
|
+
import { t as ShadowClawChannelConfig } from "./shadow-claw-channel-config-BNIWCdsL.js";
|
|
40
|
+
import { t as ShadowClawChannels } from "./shadow-claw-channels-C2QSn4Ew.js";
|
|
41
|
+
import { t as ShadowClawProviderModelPicker } from "./shadow-claw-provider-model-picker-B-Ct4yW-.js";
|
|
42
42
|
import { t as ShadowClawProviderModuleSettings } from "./shadow-claw-provider-module-settings-3sCTnCSp.js";
|
|
43
|
-
import { t as ShadowClawConversations } from "./shadow-claw-conversations-
|
|
43
|
+
import { t as ShadowClawConversations } from "./shadow-claw-conversations-BtDv7GRW.js";
|
|
44
44
|
import { t as ShadowClawToast } from "./shadow-claw-toast-DEqsSFJH.js";
|
|
45
|
-
import { t as ShadowClawTools } from "./shadow-claw-tools-
|
|
45
|
+
import { t as ShadowClawTools } from "./shadow-claw-tools-DwPBADua.js";
|
|
46
46
|
import { t as ShadowClawActions } from "./shadow-claw-actions-G99P9oxr.js";
|
|
47
47
|
import { t as ShadowClawCard } from "./shadow-claw-card-D9azfSMu.js";
|
|
48
|
-
import { t as ShadowClawAccounts } from "./shadow-claw-accounts-
|
|
49
|
-
import { t as ShadowClawControlPlane } from "./shadow-claw-control-plane-
|
|
50
|
-
import { t as ShadowClawGit } from "./shadow-claw-git-
|
|
51
|
-
import { t as ShadowClawIntegrations } from "./shadow-claw-integrations-
|
|
52
|
-
import { t as ShadowClawLlm } from "./shadow-claw-llm-
|
|
53
|
-
import { t as ShadowClawMcpRemote } from "./shadow-claw-mcp-remote-
|
|
54
|
-
import { t as ShadowClawNetworking } from "./shadow-claw-networking-
|
|
55
|
-
import { t as ShadowClawNotifications } from "./shadow-claw-notifications-
|
|
56
|
-
import { t as ShadowClawStorage } from "./shadow-claw-storage-
|
|
57
|
-
import { t as ShadowClawTaskServer } from "./shadow-claw-task-server-
|
|
58
|
-
import { t as ShadowClawWebvm } from "./shadow-claw-webvm-
|
|
48
|
+
import { t as ShadowClawAccounts } from "./shadow-claw-accounts-CkqyCxwp.js";
|
|
49
|
+
import { t as ShadowClawControlPlane } from "./shadow-claw-control-plane-D5E4cFGu.js";
|
|
50
|
+
import { t as ShadowClawGit } from "./shadow-claw-git-BeHV73_9.js";
|
|
51
|
+
import { t as ShadowClawIntegrations } from "./shadow-claw-integrations-RZZ-m-Id.js";
|
|
52
|
+
import { t as ShadowClawLlm } from "./shadow-claw-llm-KONyWKZM.js";
|
|
53
|
+
import { t as ShadowClawMcpRemote } from "./shadow-claw-mcp-remote-BKFROurv.js";
|
|
54
|
+
import { t as ShadowClawNetworking } from "./shadow-claw-networking-Diy3JJkc.js";
|
|
55
|
+
import { t as ShadowClawNotifications } from "./shadow-claw-notifications-C-upPa-4.js";
|
|
56
|
+
import { t as ShadowClawStorage } from "./shadow-claw-storage-C7tCnsSG.js";
|
|
57
|
+
import { t as ShadowClawTaskServer } from "./shadow-claw-task-server-BObsRdf8.js";
|
|
58
|
+
import { t as ShadowClawWebvm } from "./shadow-claw-webvm-CY4qGaMB.js";
|
|
59
59
|
import "./components/index.js";
|
|
60
60
|
import { hasPathTraversal, normalizeWorkspacePath, toPosixPath, trimSlashes } from "./utils/normalize-workspace-path.js";
|
|
61
61
|
import { HttpError } from "./utils/http-error.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getConfig } from "./get-config-BWhs5HFF.js";
|
|
2
|
-
import { r as CONFIG_KEYS } from "./config-
|
|
2
|
+
import { r as CONFIG_KEYS } from "./config-BrHR97zt.js";
|
|
3
3
|
import { t as setConfig } from "./set-config-CUadvYZ1.js";
|
|
4
4
|
|
|
5
5
|
//#region src/components/shadow-claw/utils/clamp-chat-split-height.ts
|
|
@@ -129,4 +129,4 @@ async function initChatSplitResize(shadow, shadowClaw, handle, db) {
|
|
|
129
129
|
|
|
130
130
|
//#endregion
|
|
131
131
|
export { initChatSplitResize };
|
|
132
|
-
//# sourceMappingURL=init-chat-split-resize-
|
|
132
|
+
//# sourceMappingURL=init-chat-split-resize-Cc0bd2z9.js.map
|
package/dist/lib/{init-chat-split-resize-B0ODULx9.js.map → init-chat-split-resize-Cc0bd2z9.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-chat-split-resize-B0ODULx9.js","names":[],"sources":["../../src/components/shadow-claw/utils/clamp-chat-split-height.ts","../../src/components/shadow-claw/utils/persist-chat-split-height.ts","../../src/components/shadow-claw/utils/set-chat-split-height.ts","../../src/components/shadow-claw/utils/init-chat-split-resize.ts"],"sourcesContent":["import { MIN_CHAT_SPLIT_HEIGHT_PX } from \"../constants.js\";\n\nexport function clampChatSplitHeight(\n shadow: ShadowRoot | null,\n px: number,\n): number {\n const mainContent = shadow?.querySelector(\".main-content\");\n\n if (!(mainContent instanceof HTMLElement)) {\n return Math.max(MIN_CHAT_SPLIT_HEIGHT_PX, px);\n }\n\n const containerHeight =\n mainContent.getBoundingClientRect().height || window.innerHeight || 600;\n const maxByContainer = Math.max(\n MIN_CHAT_SPLIT_HEIGHT_PX,\n containerHeight - 100,\n );\n\n return Math.max(MIN_CHAT_SPLIT_HEIGHT_PX, Math.min(maxByContainer, px));\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { setConfig } from \"../../../db/set-config.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nexport async function persistChatSplitHeight(\n db: ShadowClawDatabase,\n px: number,\n): Promise<void> {\n if (!db) {\n return;\n }\n\n try {\n await setConfig(db, CONFIG_KEYS.CHAT_SPLIT_VIEW_HEIGHT, px);\n } catch {\n // Ignore persistence failures so resize remains usable in degraded test/runtime states.\n }\n}\n","import { clampChatSplitHeight } from \"./clamp-chat-split-height.js\";\n\nexport function setChatSplitHeight(\n shadow: ShadowRoot | null,\n px: number,\n): void {\n const mainContent = shadow?.querySelector(\".main-content\");\n\n if (!(mainContent instanceof HTMLElement)) {\n return;\n }\n\n const clamped = clampChatSplitHeight(shadow, px);\n mainContent.style.setProperty(\"--chat-split-height\", `${clamped}px`);\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { getConfig } from \"../../../db/get-config.js\";\n\nimport {\n DEFAULT_CHAT_SPLIT_HEIGHT_PX,\n MIN_CHAT_SPLIT_HEIGHT_PX,\n} from \"../constants.js\";\n\nimport { clampChatSplitHeight } from \"./clamp-chat-split-height.js\";\nimport { persistChatSplitHeight } from \"./persist-chat-split-height.js\";\nimport { setChatSplitHeight } from \"./set-chat-split-height.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\ninterface ChatSplitResizeHost {\n addCleanup: (fn: () => void) => void;\n}\n\nexport async function initChatSplitResize(\n shadow: ShadowRoot | null,\n shadowClaw: ChatSplitResizeHost,\n handle: HTMLElement,\n db: ShadowClawDatabase | undefined,\n): Promise<void> {\n if (!shadow || !handle) {\n return;\n }\n\n handle.setAttribute(\"tabindex\", \"0\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"horizontal\");\n handle.setAttribute(\"aria-label\", \"Resize chat panel height\");\n\n const getCurrentHeight = () => {\n const mainContent = shadow.querySelector(\".main-content\");\n if (!(mainContent instanceof HTMLElement)) {\n return DEFAULT_CHAT_SPLIT_HEIGHT_PX;\n }\n\n const stored = parseFloat(\n mainContent.style.getPropertyValue(\"--chat-split-height\"),\n );\n if (Number.isFinite(stored) && stored > 0) {\n return stored;\n }\n\n const chatPage = shadow.querySelector(\".chat-page\");\n return (\n (chatPage instanceof HTMLElement &&\n chatPage.getBoundingClientRect().height) ||\n DEFAULT_CHAT_SPLIT_HEIGHT_PX\n );\n };\n\n const updateAria = () => {\n const current = Math.round(\n clampChatSplitHeight(shadow, getCurrentHeight()),\n );\n const max = Math.round(\n clampChatSplitHeight(shadow, Number.MAX_SAFE_INTEGER),\n );\n handle.setAttribute(\"aria-valuemin\", String(MIN_CHAT_SPLIT_HEIGHT_PX));\n handle.setAttribute(\"aria-valuemax\", String(max));\n handle.setAttribute(\"aria-valuenow\", String(current));\n };\n\n try {\n const saved = db\n ? await getConfig(db, CONFIG_KEYS.CHAT_SPLIT_VIEW_HEIGHT)\n : undefined;\n\n if (typeof saved === \"number\" && Number.isFinite(saved) && saved > 0) {\n setChatSplitHeight(shadow, saved);\n } else if (typeof saved === \"string\" && !isNaN(parseFloat(saved))) {\n setChatSplitHeight(shadow, parseFloat(saved));\n } else {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n } catch {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n\n let activePointerId: number | null = null;\n let startY = 0;\n let startHeight = 0;\n\n const onPointerMove = (event: PointerEvent) => {\n if (event.pointerId !== activePointerId) {\n return;\n }\n\n // Dragging handle UP (delta > 0) increases height of bottom chat panel\n const delta = startY - event.clientY;\n const nextHeight = startHeight + delta;\n setChatSplitHeight(shadow, nextHeight);\n updateAria();\n };\n\n const stopResize = () => {\n if (activePointerId === null) {\n return;\n }\n\n activePointerId = null;\n handle.classList.remove(\"active\");\n document.removeEventListener(\"pointermove\", onPointerMove);\n\n const mainContent = shadow.querySelector(\".main-content\");\n if (mainContent instanceof HTMLElement) {\n const value = parseFloat(\n mainContent.style.getPropertyValue(\"--chat-split-height\"),\n );\n if (Number.isFinite(value) && value > 0 && db) {\n void persistChatSplitHeight(db, value);\n }\n }\n };\n\n const onPointerUp = (event: PointerEvent) => {\n if (event.pointerId !== activePointerId) {\n return;\n }\n\n stopResize();\n };\n\n handle.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n if (\n event.pointerType === \"mouse\" &&\n event.button !== 0 &&\n event.button !== -1\n ) {\n return;\n }\n\n if (window.innerWidth < 896) {\n return;\n }\n\n event.preventDefault();\n activePointerId = event.pointerId;\n startY = event.clientY;\n const chatPage = shadow.querySelector(\".chat-page\");\n startHeight =\n chatPage instanceof HTMLElement &&\n chatPage.getBoundingClientRect().height > 0\n ? chatPage.getBoundingClientRect().height\n : getCurrentHeight();\n handle.classList.add(\"active\");\n\n handle.setPointerCapture(event.pointerId);\n document.addEventListener(\"pointermove\", onPointerMove);\n });\n\n handle.addEventListener(\"pointerup\", onPointerUp);\n handle.addEventListener(\"pointercancel\", stopResize);\n handle.addEventListener(\"dblclick\", () => {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n if (db) {\n void persistChatSplitHeight(db, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n\n updateAria();\n });\n\n handle.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n if (window.innerWidth < 896) {\n return;\n }\n\n const step = event.shiftKey ? 32 : 12;\n const current = getCurrentHeight();\n let next: number | null = null;\n\n if (event.key === \"ArrowUp\") {\n next = current + step;\n } else if (event.key === \"ArrowDown\") {\n next = current - step;\n } else if (event.key === \"Home\") {\n next = MIN_CHAT_SPLIT_HEIGHT_PX;\n } else if (event.key === \"End\") {\n next = clampChatSplitHeight(shadow, Number.MAX_SAFE_INTEGER);\n }\n\n if (next === null) {\n return;\n }\n\n event.preventDefault();\n setChatSplitHeight(shadow, next);\n updateAria();\n if (db) {\n void persistChatSplitHeight(\n db,\n clampChatSplitHeight(shadow, getCurrentHeight()),\n );\n }\n });\n\n updateAria();\n\n shadowClaw.addCleanup(() => {\n stopResize();\n handle.removeEventListener(\"pointerup\", onPointerUp);\n handle.removeEventListener(\"pointercancel\", stopResize);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init-chat-split-resize-Cc0bd2z9.js","names":[],"sources":["../../src/components/shadow-claw/utils/clamp-chat-split-height.ts","../../src/components/shadow-claw/utils/persist-chat-split-height.ts","../../src/components/shadow-claw/utils/set-chat-split-height.ts","../../src/components/shadow-claw/utils/init-chat-split-resize.ts"],"sourcesContent":["import { MIN_CHAT_SPLIT_HEIGHT_PX } from \"../constants.js\";\n\nexport function clampChatSplitHeight(\n shadow: ShadowRoot | null,\n px: number,\n): number {\n const mainContent = shadow?.querySelector(\".main-content\");\n\n if (!(mainContent instanceof HTMLElement)) {\n return Math.max(MIN_CHAT_SPLIT_HEIGHT_PX, px);\n }\n\n const containerHeight =\n mainContent.getBoundingClientRect().height || window.innerHeight || 600;\n const maxByContainer = Math.max(\n MIN_CHAT_SPLIT_HEIGHT_PX,\n containerHeight - 100,\n );\n\n return Math.max(MIN_CHAT_SPLIT_HEIGHT_PX, Math.min(maxByContainer, px));\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { setConfig } from \"../../../db/set-config.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nexport async function persistChatSplitHeight(\n db: ShadowClawDatabase,\n px: number,\n): Promise<void> {\n if (!db) {\n return;\n }\n\n try {\n await setConfig(db, CONFIG_KEYS.CHAT_SPLIT_VIEW_HEIGHT, px);\n } catch {\n // Ignore persistence failures so resize remains usable in degraded test/runtime states.\n }\n}\n","import { clampChatSplitHeight } from \"./clamp-chat-split-height.js\";\n\nexport function setChatSplitHeight(\n shadow: ShadowRoot | null,\n px: number,\n): void {\n const mainContent = shadow?.querySelector(\".main-content\");\n\n if (!(mainContent instanceof HTMLElement)) {\n return;\n }\n\n const clamped = clampChatSplitHeight(shadow, px);\n mainContent.style.setProperty(\"--chat-split-height\", `${clamped}px`);\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { getConfig } from \"../../../db/get-config.js\";\n\nimport {\n DEFAULT_CHAT_SPLIT_HEIGHT_PX,\n MIN_CHAT_SPLIT_HEIGHT_PX,\n} from \"../constants.js\";\n\nimport { clampChatSplitHeight } from \"./clamp-chat-split-height.js\";\nimport { persistChatSplitHeight } from \"./persist-chat-split-height.js\";\nimport { setChatSplitHeight } from \"./set-chat-split-height.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\ninterface ChatSplitResizeHost {\n addCleanup: (fn: () => void) => void;\n}\n\nexport async function initChatSplitResize(\n shadow: ShadowRoot | null,\n shadowClaw: ChatSplitResizeHost,\n handle: HTMLElement,\n db: ShadowClawDatabase | undefined,\n): Promise<void> {\n if (!shadow || !handle) {\n return;\n }\n\n handle.setAttribute(\"tabindex\", \"0\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"horizontal\");\n handle.setAttribute(\"aria-label\", \"Resize chat panel height\");\n\n const getCurrentHeight = () => {\n const mainContent = shadow.querySelector(\".main-content\");\n if (!(mainContent instanceof HTMLElement)) {\n return DEFAULT_CHAT_SPLIT_HEIGHT_PX;\n }\n\n const stored = parseFloat(\n mainContent.style.getPropertyValue(\"--chat-split-height\"),\n );\n if (Number.isFinite(stored) && stored > 0) {\n return stored;\n }\n\n const chatPage = shadow.querySelector(\".chat-page\");\n return (\n (chatPage instanceof HTMLElement &&\n chatPage.getBoundingClientRect().height) ||\n DEFAULT_CHAT_SPLIT_HEIGHT_PX\n );\n };\n\n const updateAria = () => {\n const current = Math.round(\n clampChatSplitHeight(shadow, getCurrentHeight()),\n );\n const max = Math.round(\n clampChatSplitHeight(shadow, Number.MAX_SAFE_INTEGER),\n );\n handle.setAttribute(\"aria-valuemin\", String(MIN_CHAT_SPLIT_HEIGHT_PX));\n handle.setAttribute(\"aria-valuemax\", String(max));\n handle.setAttribute(\"aria-valuenow\", String(current));\n };\n\n try {\n const saved = db\n ? await getConfig(db, CONFIG_KEYS.CHAT_SPLIT_VIEW_HEIGHT)\n : undefined;\n\n if (typeof saved === \"number\" && Number.isFinite(saved) && saved > 0) {\n setChatSplitHeight(shadow, saved);\n } else if (typeof saved === \"string\" && !isNaN(parseFloat(saved))) {\n setChatSplitHeight(shadow, parseFloat(saved));\n } else {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n } catch {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n\n let activePointerId: number | null = null;\n let startY = 0;\n let startHeight = 0;\n\n const onPointerMove = (event: PointerEvent) => {\n if (event.pointerId !== activePointerId) {\n return;\n }\n\n // Dragging handle UP (delta > 0) increases height of bottom chat panel\n const delta = startY - event.clientY;\n const nextHeight = startHeight + delta;\n setChatSplitHeight(shadow, nextHeight);\n updateAria();\n };\n\n const stopResize = () => {\n if (activePointerId === null) {\n return;\n }\n\n activePointerId = null;\n handle.classList.remove(\"active\");\n document.removeEventListener(\"pointermove\", onPointerMove);\n\n const mainContent = shadow.querySelector(\".main-content\");\n if (mainContent instanceof HTMLElement) {\n const value = parseFloat(\n mainContent.style.getPropertyValue(\"--chat-split-height\"),\n );\n if (Number.isFinite(value) && value > 0 && db) {\n void persistChatSplitHeight(db, value);\n }\n }\n };\n\n const onPointerUp = (event: PointerEvent) => {\n if (event.pointerId !== activePointerId) {\n return;\n }\n\n stopResize();\n };\n\n handle.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n if (\n event.pointerType === \"mouse\" &&\n event.button !== 0 &&\n event.button !== -1\n ) {\n return;\n }\n\n if (window.innerWidth < 896) {\n return;\n }\n\n event.preventDefault();\n activePointerId = event.pointerId;\n startY = event.clientY;\n const chatPage = shadow.querySelector(\".chat-page\");\n startHeight =\n chatPage instanceof HTMLElement &&\n chatPage.getBoundingClientRect().height > 0\n ? chatPage.getBoundingClientRect().height\n : getCurrentHeight();\n handle.classList.add(\"active\");\n\n handle.setPointerCapture(event.pointerId);\n document.addEventListener(\"pointermove\", onPointerMove);\n });\n\n handle.addEventListener(\"pointerup\", onPointerUp);\n handle.addEventListener(\"pointercancel\", stopResize);\n handle.addEventListener(\"dblclick\", () => {\n setChatSplitHeight(shadow, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n if (db) {\n void persistChatSplitHeight(db, DEFAULT_CHAT_SPLIT_HEIGHT_PX);\n }\n\n updateAria();\n });\n\n handle.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n if (window.innerWidth < 896) {\n return;\n }\n\n const step = event.shiftKey ? 32 : 12;\n const current = getCurrentHeight();\n let next: number | null = null;\n\n if (event.key === \"ArrowUp\") {\n next = current + step;\n } else if (event.key === \"ArrowDown\") {\n next = current - step;\n } else if (event.key === \"Home\") {\n next = MIN_CHAT_SPLIT_HEIGHT_PX;\n } else if (event.key === \"End\") {\n next = clampChatSplitHeight(shadow, Number.MAX_SAFE_INTEGER);\n }\n\n if (next === null) {\n return;\n }\n\n event.preventDefault();\n setChatSplitHeight(shadow, next);\n updateAria();\n if (db) {\n void persistChatSplitHeight(\n db,\n clampChatSplitHeight(shadow, getCurrentHeight()),\n );\n }\n });\n\n updateAria();\n\n shadowClaw.addCleanup(() => {\n stopResize();\n handle.removeEventListener(\"pointerup\", onPointerUp);\n handle.removeEventListener(\"pointercancel\", stopResize);\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { i as __toESM } from "./rolldown-runtime-DwyhSnWe.js";
|
|
2
2
|
import { o as getDb } from "./get-config-BWhs5HFF.js";
|
|
3
3
|
import { t as require_browser } from "./browser-sqa-Vhnx.js";
|
|
4
|
-
import { r as CONFIG_KEYS } from "./config-
|
|
5
|
-
import {
|
|
6
|
-
import { t as toolsStore, u as getAllTasks } from "./tools-
|
|
4
|
+
import { r as CONFIG_KEYS } from "./config-BrHR97zt.js";
|
|
5
|
+
import { a as getDeploymentNamespace } from "./app-routes-BXiRvlNl.js";
|
|
6
|
+
import { t as toolsStore, u as getAllTasks } from "./tools-B8OJ4sMF.js";
|
|
7
7
|
import { ulid } from "./utils/ulid.js";
|
|
8
8
|
|
|
9
9
|
//#region src/core/control-plane-client.ts
|
|
@@ -432,7 +432,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
432
432
|
switch (action) {
|
|
433
433
|
case "send-message": {
|
|
434
434
|
if (!args.text) throw new Error("Missing text parameter");
|
|
435
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
435
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
436
436
|
const orch = options.orchestrator || orchestratorStore.orchestrator;
|
|
437
437
|
const targetGroupId = args.groupId || orchestratorStore.activeGroupId || "br:main";
|
|
438
438
|
if (orch?.browserChat?.submit) {
|
|
@@ -468,7 +468,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
468
468
|
return { tasks };
|
|
469
469
|
}
|
|
470
470
|
case "read-state": {
|
|
471
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
471
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
472
472
|
const orch = options.orchestrator || orchestratorStore.orchestrator;
|
|
473
473
|
return {
|
|
474
474
|
clientId,
|
|
@@ -481,7 +481,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
481
481
|
}
|
|
482
482
|
case "list-tools": {
|
|
483
483
|
try {
|
|
484
|
-
const { getWebMcpTools } = await import("./webmcp-
|
|
484
|
+
const { getWebMcpTools } = await import("./webmcp-BoMTvgmX.js").then((n) => n.c);
|
|
485
485
|
const webMcpTools = await getWebMcpTools();
|
|
486
486
|
if (webMcpTools && webMcpTools.length > 0) return { tools: webMcpTools.map((t) => ({
|
|
487
487
|
name: t.name,
|
|
@@ -491,13 +491,13 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
491
491
|
})) };
|
|
492
492
|
} catch (_) {}
|
|
493
493
|
try {
|
|
494
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
494
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
495
495
|
const orch = options.orchestrator || orchestratorStore.orchestrator || (typeof document !== "undefined" ? document.querySelector("shadow-claw")?.orchestrator : null);
|
|
496
496
|
const activeGroupId = args.groupId || orch?.activeGroupId || orchestratorStore.activeGroupId || "br:main";
|
|
497
497
|
const group = orchestratorStore.groups.find((g) => g.groupId === activeGroupId);
|
|
498
498
|
if (group?.toolTags && group.toolTags.length > 0) {
|
|
499
499
|
const { TOOL_DEFINITIONS } = await import("./tools-tRG7Gu0x.js").then((n) => n.n);
|
|
500
|
-
const { parseWebMcpInputSchema } = await import("./webmcp-
|
|
500
|
+
const { parseWebMcpInputSchema } = await import("./webmcp-BoMTvgmX.js").then((n) => n.c);
|
|
501
501
|
return { tools: TOOL_DEFINITIONS.filter((t) => group.toolTags.includes(t.name)).map((t) => ({
|
|
502
502
|
name: t.name,
|
|
503
503
|
description: t.description,
|
|
@@ -506,7 +506,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
506
506
|
}
|
|
507
507
|
} catch (_) {}
|
|
508
508
|
const { TOOL_DEFINITIONS } = await import("./tools-tRG7Gu0x.js").then((n) => n.n);
|
|
509
|
-
const { parseWebMcpInputSchema } = await import("./webmcp-
|
|
509
|
+
const { parseWebMcpInputSchema } = await import("./webmcp-BoMTvgmX.js").then((n) => n.c);
|
|
510
510
|
return { tools: TOOL_DEFINITIONS.map((t) => ({
|
|
511
511
|
name: t.name,
|
|
512
512
|
description: t.description,
|
|
@@ -516,7 +516,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
516
516
|
case "invoke-tool": {
|
|
517
517
|
if (!args.toolName) throw new Error("Missing toolName parameter");
|
|
518
518
|
try {
|
|
519
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
519
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
520
520
|
const orch = options.orchestrator || orchestratorStore.orchestrator || (typeof document !== "undefined" ? document.querySelector("shadow-claw")?.orchestrator : null);
|
|
521
521
|
const activeGroupId = args.groupId || orch?.activeGroupId || orchestratorStore.activeGroupId || "br:main";
|
|
522
522
|
const group = orchestratorStore.groups.find((g) => g.groupId === activeGroupId);
|
|
@@ -543,7 +543,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
543
543
|
} catch (err) {
|
|
544
544
|
if (err.message && err.message.includes("is not enabled")) throw err;
|
|
545
545
|
}
|
|
546
|
-
const { executeWebMcpTool } = await import("./webmcp-
|
|
546
|
+
const { executeWebMcpTool } = await import("./webmcp-BoMTvgmX.js").then((n) => n.c);
|
|
547
547
|
if (typeof ctx.executeTool === "function") {
|
|
548
548
|
if (matchedTool) try {
|
|
549
549
|
return { result: await executeWebMcpTool(ctx, matchedTool, args.input) };
|
|
@@ -569,7 +569,7 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
569
569
|
return { result: await ctx.invoke(args.toolName, typeof args.input === "string" ? JSON.parse(args.input) : args.input || {}) };
|
|
570
570
|
} catch (_) {}
|
|
571
571
|
}
|
|
572
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
572
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
573
573
|
const orch = options.orchestrator || orchestratorStore.orchestrator || (typeof document !== "undefined" ? document.querySelector("shadow-claw")?.orchestrator : null);
|
|
574
574
|
const worker = orch?.agentWorker;
|
|
575
575
|
if (worker && typeof worker.postMessage === "function") {
|
|
@@ -605,10 +605,10 @@ async function executeClientControlCommand(action, args = {}, options = {}) {
|
|
|
605
605
|
throw new Error(`Tool ${args.toolName} could not be executed (no context or worker available)`);
|
|
606
606
|
}
|
|
607
607
|
case "trigger-backup": {
|
|
608
|
-
const { orchestratorStore } = await import("./orchestrator-
|
|
608
|
+
const { orchestratorStore } = await import("./orchestrator-cRBe3lhq.js").then((n) => n.n);
|
|
609
609
|
const targetGroupId = args.groupId || options.orchestrator?.activeGroupId || orchestratorStore.activeGroupId || "br:main";
|
|
610
610
|
const db = await getDb();
|
|
611
|
-
const { getGroupDir } = await import("./parse-path-
|
|
611
|
+
const { getGroupDir } = await import("./parse-path-BOHQP_IQ.js").then((n) => n.r);
|
|
612
612
|
const groupDir = await getGroupDir(db, targetGroupId);
|
|
613
613
|
async function collectFiles(dir, prefix = "") {
|
|
614
614
|
const result = [];
|
|
@@ -726,4 +726,4 @@ async function ensureControlPlaneConnected(options = {}) {
|
|
|
726
726
|
|
|
727
727
|
//#endregion
|
|
728
728
|
export { detectDeviceLabel, ensureControlPlaneConnected, executeClientControlCommand, getOrCreateControlPlaneClientId, isControlPlaneEnabled, shouldConnectControlPlane, stopControlPlaneClient };
|
|
729
|
-
//# sourceMappingURL=init-control-plane-
|
|
729
|
+
//# sourceMappingURL=init-control-plane-CEGdzgWX.js.map
|