shadow-claw 1.59.6 → 1.59.7
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 +12 -4
- package/.well-known/mcp.json +12 -4
- package/dist/cli/build/build.js +1 -1
- package/dist/cli/{chunk-DM4xsTry.js → chunk-3vNYrs_L.js} +1 -1
- package/dist/cli/{chunk-Ctg5L55n.js → chunk-66BvqAV0.js} +1 -1
- package/dist/cli/{chunk-Bq38OubR.js → chunk-B0qusANw.js} +1 -1
- package/dist/cli/{chunk-yiVdvGCJ.js → chunk-B3TrWbca.js} +7 -7
- package/dist/cli/{chunk-C8DBACtx.js → chunk-B88Z8T_9.js} +1 -1
- package/dist/cli/chunk-BCjL0JXf.js +1 -0
- package/dist/cli/chunk-BNcu1oiT.js +1 -0
- package/dist/cli/{chunk-gvNsvav0.js → chunk-C5ypckWC.js} +7 -7
- package/dist/cli/{chunk-Dw8GndPD.js → chunk-CAAeGOdy.js} +1 -1
- package/dist/cli/chunk-CFxww5Yz.js +1 -0
- package/dist/cli/chunk-CGIgtL6R.js +1 -0
- package/dist/cli/{chunk-DJqHK-qS.js → chunk-CQaCgswD.js} +7 -7
- package/dist/cli/chunk-CZdCRqNe.js +7 -0
- package/dist/cli/chunk-CafdvLx-.js +1 -0
- package/dist/cli/{chunk-Bc_weULz.js → chunk-CncW6_WL.js} +1 -1
- package/dist/cli/chunk-DDvuLVfW.js +1 -0
- package/dist/cli/{chunk-Cq_kQohv.js → chunk-DMs7kREC.js} +1 -1
- package/dist/cli/{chunk-CX2itile.js → chunk-D_te8ufL.js} +1 -1
- package/dist/cli/{chunk-3wTukVof.js → chunk-DhOU6GYX.js} +1 -1
- package/dist/cli/chunk-Dhap1VwA.js +1 -0
- package/dist/cli/chunk-DwvavohW.js +1 -0
- package/dist/cli/{chunk-DLde6nuO.js → chunk-SRBRVorc.js} +1 -1
- package/dist/cli/{chunk-D3y7h9Xe.js → chunk-SxK79JmB.js} +1 -1
- package/dist/cli/chunk-_a0CkUNS.js +139 -0
- package/dist/cli/{chunk-C9o6lXP3.js → chunk-hVf839t7.js} +1 -1
- package/dist/cli/chunk-iB8OoMmW.js +7 -0
- package/dist/cli/cli.js +1 -1
- package/dist/headless-agent.js +1 -1
- 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-mmdGzPkT.js} +3 -3
- package/dist/lib/{channel-Dlru5ofR.js.map → channel-mmdGzPkT.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-CY9BBlUQ.js} +19 -19
- package/dist/lib/{compact-context-BtR55YPU.js.map → compact-context-CY9BBlUQ.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-ccNvax2N.js} +3 -3
- package/dist/lib/{configure-peer-js-ChDhOZU4.js.map → configure-peer-js-ccNvax2N.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/{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-OwlQ2sXA.js} +13 -13
- package/dist/lib/{discover-skills-CD0sKvAI.js.map → discover-skills-OwlQ2sXA.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-D2J_j9X9.js} +5 -5
- package/dist/lib/{git-B3Q1euc5.js.map → git-D2J_j9X9.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-B7blDVIE.js} +15 -15
- package/dist/lib/{init-control-plane-C1FRRmjC.js.map → init-control-plane-B7blDVIE.js.map} +1 -1
- package/dist/lib/{invoke-agent-CzN7sVh-.js → invoke-agent-SxvudiDT.js} +11 -11
- package/dist/lib/{invoke-agent-CzN7sVh-.js.map → invoke-agent-SxvudiDT.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-DDpjxa10.js} +5 -5
- package/dist/lib/{move-group-entry-NMTJ59M9.js.map → move-group-entry-DDpjxa10.js.map} +1 -1
- package/dist/lib/{orchestrator-B8FV1V7x.js → orchestrator-C7fkh7T7.js} +24 -24
- package/dist/lib/{orchestrator-B8FV1V7x.js.map → orchestrator-C7fkh7T7.js.map} +1 -1
- package/dist/lib/{orchestrator-i_QJ-o22.js → orchestrator-CCARkxQC.js} +11 -11
- package/dist/lib/orchestrator-CCARkxQC.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-Bfw_FWLB.js} +8 -8
- package/dist/lib/{peerjs-z5zeioPV.js.map → peerjs-Bfw_FWLB.js.map} +1 -1
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js → process-peer-query-param-BxYiZNdf.js} +5 -5
- package/dist/lib/{process-peer-query-param-CJp7w7AU.js.map → process-peer-query-param-BxYiZNdf.js.map} +1 -1
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js → process-pending-shared-payloads-DPIbwRb3.js} +4 -4
- package/dist/lib/{process-pending-shared-payloads-B6_TlBFA.js.map → process-pending-shared-payloads-DPIbwRb3.js.map} +1 -1
- package/dist/lib/{process-room-query-param-C3FFGGn6.js → process-room-query-param-B2_d50nE.js} +4 -4
- package/dist/lib/{process-room-query-param-C3FFGGn6.js.map → process-room-query-param-B2_d50nE.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-rrjTdc-U.js} +5 -5
- package/dist/lib/{push-client-Cx5rMs6J.js.map → push-client-rrjTdc-U.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-bwGoYb1q.js} +2 -2
- package/dist/lib/{rooms-CwlkYLDU.js.map → rooms-bwGoYb1q.js.map} +1 -1
- package/dist/lib/{shadow-claw-DoQ7fgl5.js → shadow-claw-CypGVlVO.js} +17 -20
- package/dist/lib/shadow-claw-CypGVlVO.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-DJpDovkF.js} +4 -4
- package/dist/lib/{shadow-claw-channel-config-IKiL34tI.js.map → shadow-claw-channel-config-DJpDovkF.js.map} +1 -1
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js → shadow-claw-channels-DJLwRovH.js} +3 -3
- package/dist/lib/{shadow-claw-channels-JgEzuHWK.js.map → shadow-claw-channels-DJLwRovH.js.map} +1 -1
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js → shadow-claw-chat-B92cPaft.js} +15 -15
- package/dist/lib/{shadow-claw-chat-SGUDT31r.js.map → shadow-claw-chat-B92cPaft.js.map} +1 -1
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js → shadow-claw-control-plane-fvn-qyHj.js} +7 -7
- package/dist/lib/{shadow-claw-control-plane-CRWFZ3vD.js.map → shadow-claw-control-plane-fvn-qyHj.js.map} +1 -1
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js → shadow-claw-conversations-CsVyDOny.js} +7 -7
- package/dist/lib/{shadow-claw-conversations-D23GJ7qo.js.map → shadow-claw-conversations-CsVyDOny.js.map} +1 -1
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js → shadow-claw-file-viewer-DFfyP7s5.js} +10 -10
- package/dist/lib/{shadow-claw-file-viewer-C1V8WTiU.js.map → shadow-claw-file-viewer-DFfyP7s5.js.map} +1 -1
- package/dist/lib/{shadow-claw-files-DN7irmE1.js → shadow-claw-files-cT6HL7ye.js} +11 -11
- package/dist/lib/{shadow-claw-files-DN7irmE1.js.map → shadow-claw-files-cT6HL7ye.js.map} +1 -1
- package/dist/lib/{shadow-claw-git-D-1oIh65.js → shadow-claw-git-Cv9mQgTx.js} +6 -6
- package/dist/lib/{shadow-claw-git-D-1oIh65.js.map → shadow-claw-git-Cv9mQgTx.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-CKOYzPDp.js} +9 -9
- package/dist/lib/{shadow-claw-llm-4Gefh5FN.js.map → shadow-claw-llm-CKOYzPDp.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-DYfiUQaH.js} +2 -2
- package/dist/lib/{shadow-claw-networking-BN5BB4hb.js.map → shadow-claw-networking-DYfiUQaH.js.map} +1 -1
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js → shadow-claw-notifications-JJlzriuX.js} +3 -3
- package/dist/lib/{shadow-claw-notifications-71KARtkY.js.map → shadow-claw-notifications-JJlzriuX.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-BCo3ihZI.js} +11 -11
- package/dist/lib/{shadow-claw-pages-BiRM6qiA.js.map → shadow-claw-pages-BCo3ihZI.js.map} +1 -1
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js → shadow-claw-peerjs-CFNjfrY5.js} +6 -6
- package/dist/lib/{shadow-claw-peerjs-BZu7jNSe.js.map → shadow-claw-peerjs-CFNjfrY5.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-BMwne0bh.js} +7 -7
- package/dist/lib/{shadow-claw-settings-CcT5EK08.js.map → shadow-claw-settings-BMwne0bh.js.map} +1 -1
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js → shadow-claw-storage-DUY8B9m-.js} +5 -5
- package/dist/lib/{shadow-claw-storage-eTOpbvpi.js.map → shadow-claw-storage-DUY8B9m-.js.map} +1 -1
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js → shadow-claw-task-server-yWeoA3eL.js} +2 -2
- package/dist/lib/{shadow-claw-task-server-DFImTUbw.js.map → shadow-claw-task-server-yWeoA3eL.js.map} +1 -1
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js → shadow-claw-tasks-Bg0uM15I.js} +9 -9
- package/dist/lib/{shadow-claw-tasks-BjaxsmUx.js.map → shadow-claw-tasks-Bg0uM15I.js.map} +1 -1
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js → shadow-claw-terminal-fyJPppY_.js} +2 -2
- package/dist/lib/{shadow-claw-terminal-C-4wreFe.js.map → shadow-claw-terminal-fyJPppY_.js.map} +1 -1
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js → shadow-claw-tools-D0T8m3go.js} +7 -7
- package/dist/lib/{shadow-claw-tools-COdrGZJk.js.map → shadow-claw-tools-D0T8m3go.js.map} +1 -1
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js → shadow-claw-webvm-CQvzJwKI.js} +3 -3
- package/dist/lib/{shadow-claw-webvm-sxqVjO0L.js.map → shadow-claw-webvm-CQvzJwKI.js.map} +1 -1
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js → sync-web-mcp-registration-BFtG_4kx.js} +6 -6
- package/dist/lib/{sync-web-mcp-registration-D4hdUwtv.js.map → sync-web-mcp-registration-BFtG_4kx.js.map} +1 -1
- package/dist/lib/{system-prompt-DT_KeYaL.js → system-prompt-bhGRLoL2.js} +7 -7
- package/dist/lib/{system-prompt-DT_KeYaL.js.map → system-prompt-bhGRLoL2.js.map} +1 -1
- 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 +12 -4
- package/dist/public/.well-known/mcp.json +12 -4
- package/dist/public/agent.worker.js +1 -1
- package/dist/public/attachment-capabilities-AdwXt3--.js +1 -0
- package/dist/public/{channel-BylT3rJC.js → channel-Dk7wl-Av.js} +1 -1
- package/dist/public/{chat-template-DPHJy7tr.js → chat-template-BwAnTFKf.js} +1 -1
- package/dist/public/{compact-context-BINQh64w.js → compact-context-fOTqwKF6.js} +2 -2
- package/dist/public/config-C16fFWtP.js +1 -0
- package/dist/public/{configure-peer-js-DChhcOfe.js → configure-peer-js-BOV0tR6G.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-DSAFjOwc.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-D1sNTy2r.js} +6 -6
- package/dist/public/docs/example/article/index.html +28 -29
- package/dist/public/docs/example/article.html +28 -29
- package/dist/public/docs/publishing/index.html +28 -29
- package/dist/public/docs/publishing.html +28 -29
- package/dist/public/docs/skill-creator/index.html +28 -29
- package/dist/public/docs/skill-creator.html +28 -29
- package/dist/public/{download-group-file-BapoRgfU.js → download-group-file-BkMH-JKi.js} +1 -1
- package/dist/public/{e2e-bridge-C0g8vZKr.js → e2e-bridge-Cz95DLlb.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-BmMlwIMP.js} +2 -2
- package/dist/public/{iframe-bridge-scripts-BnqtKhE4.js → iframe-bridge-scripts-Cibg0m6A.js} +1 -1
- package/dist/public/index.html +28 -29
- 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-Cb31yLTY.js +1 -0
- package/dist/public/{invoke-agent-B3Osw6K7.js → invoke-agent-CN7mSV0Z.js} +1 -1
- package/dist/public/main/index.html +28 -29
- package/dist/public/main/memory/index.html +28 -29
- package/dist/public/main/memory.html +28 -29
- package/dist/public/main.html +28 -29
- 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-CXneuNVa.js} +1 -1
- package/dist/public/orchestrator-DBO4NZqd.js +63 -0
- package/dist/public/{orchestrator-BrDjQbGf.js → orchestrator-Dyylc8IU.js} +2 -2
- package/dist/public/{peerjs-CgF4Iz5W.js → peerjs-l0jiBoh6.js} +1 -1
- package/dist/public/{process-peer-query-param-BL2k0Hu-.js → process-peer-query-param-s-aSP1Rq.js} +1 -1
- package/dist/public/{process-pending-shared-payloads-C1AgGvn8.js → process-pending-shared-payloads-BN3GigPT.js} +1 -1
- package/dist/public/{process-room-query-param-DM0QCq3_.js → process-room-query-param-B2Qe0F0M.js} +1 -1
- package/dist/public/provider-YPZmsuHR.js +1 -0
- package/dist/public/{push-client-DJEOz7bi.js → push-client-B2LC8Qp9.js} +1 -1
- package/dist/public/{rooms-C6LXIJl4.js → rooms-ChCEOvkw.js} +1 -1
- package/dist/public/service-worker.js +1 -1
- package/dist/public/shadow-claw-Br8mWDUx.js +1176 -0
- package/dist/public/{shadow-claw-accounts--4hd_oCz.js → shadow-claw-accounts-Dm6G7KMP.js} +1 -1
- package/dist/public/{shadow-claw-card-IbNlZAdK.js → shadow-claw-card-CggS8uSa.js} +1 -1
- package/dist/public/{shadow-claw-channels-Vq_pPGa2.js → shadow-claw-channels-088vhuWO.js} +1 -1
- package/dist/public/{shadow-claw-chat-D7_GS25e.js → shadow-claw-chat-BRwRlq-n.js} +3 -3
- package/dist/public/{shadow-claw-control-plane-WTMEV8_p.js → shadow-claw-control-plane-rhKACK85.js} +2 -2
- package/dist/public/{shadow-claw-conversations-CLQgU1IT.js → shadow-claw-conversations-CF_yUfKl.js} +1 -1
- package/dist/public/{shadow-claw-empty-state-D4CrFGsN.js → shadow-claw-empty-state-CkpOSXCS.js} +1 -1
- package/dist/public/{shadow-claw-file-viewer-BhqiqLWQ.js → shadow-claw-file-viewer-DWCejuY3.js} +4 -4
- package/dist/public/{shadow-claw-files-senDiG9l.js → shadow-claw-files-L6_ioyzh.js} +2 -2
- package/dist/public/{shadow-claw-git-DOOCqY23.js → shadow-claw-git-DsdkwLqQ.js} +2 -2
- package/dist/public/{shadow-claw-integrations-Bsvc3Agq.js → shadow-claw-integrations-CSbRTOm3.js} +1 -1
- package/dist/public/{shadow-claw-llm-actYICAk.js → shadow-claw-llm-BitaeAVc.js} +2 -2
- package/dist/public/{shadow-claw-mcp-remote-BYUgrK3v.js → shadow-claw-mcp-remote-gSbV5riy.js} +1 -1
- package/dist/public/{shadow-claw-networking-Dk3p5Ny_.js → shadow-claw-networking-Dn_y6Cl9.js} +1 -1
- package/dist/public/{shadow-claw-notifications-CzPAlay8.js → shadow-claw-notifications-Cj4Lqx8U.js} +1 -1
- package/dist/public/{shadow-claw-page-header-CjJpVkyL.js → shadow-claw-page-header-DR4OZFt2.js} +1 -1
- package/dist/public/{shadow-claw-page-header-action-button-2DH5O1TD.js → shadow-claw-page-header-action-button-BnCV_2Kb.js} +1 -1
- package/dist/public/{shadow-claw-pages-3r5I-wI8.js → shadow-claw-pages-mpDOtNYj.js} +6 -6
- package/dist/public/{shadow-claw-pdf-viewer-BiCEwsoY.js → shadow-claw-pdf-viewer-DZ_84qJH.js} +1 -1
- package/dist/public/{shadow-claw-settings-DgB9RSZN.js → shadow-claw-settings-CfFTYTEy.js} +2 -2
- package/dist/public/{shadow-claw-storage-JB_43nd8.js → shadow-claw-storage-DLmiT4bG.js} +1 -1
- package/dist/public/{shadow-claw-task-server-oi5UIxdA.js → shadow-claw-task-server-BoMBCsiS.js} +1 -1
- package/dist/public/{shadow-claw-tasks-CnyiOt81.js → shadow-claw-tasks-ChEp1j7x.js} +3 -3
- package/dist/public/{shadow-claw-terminal-BC3RynHt.js → shadow-claw-terminal-BaoVbOda.js} +1 -1
- package/dist/public/{shadow-claw-toast-YjG--2Za.js → shadow-claw-toast-e8oz7z6Z.js} +1 -1
- package/dist/public/{shadow-claw-tools-Bbwk4vlT.js → shadow-claw-tools-BYjUBiJz.js} +1 -1
- package/dist/public/{shadow-claw-webvm-HZqzl2H5.js → shadow-claw-webvm-xGb13TME.js} +1 -1
- package/dist/public/{sync-web-mcp-registration-BaH2nAP0.js → sync-web-mcp-registration-CQluj-Kz.js} +1 -1
- package/dist/public/{system-prompt-Dck3N8T0.js → system-prompt-CTJn0tK-.js} +1 -1
- 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/{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-DN7FB-Q0.js} +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-BFziiMKt.js +0 -7
- package/dist/cli/chunk-BM3llsxb.js +0 -1
- 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-DsQhAF31.js +0 -1
- package/dist/cli/chunk-VM-dECyG.js +0 -1
- 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/public/app-routes-V_-URXc5.js +0 -1
- package/dist/public/attachment-capabilities-B6ibLwQB.js +0 -1
- 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
package/dist/lib/{shadow-claw-storage-eTOpbvpi.js.map → shadow-claw-storage-DUY8B9m-.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-storage-eTOpbvpi.js","names":["shadowClawStorageStyles","shadowClawStorageTemplate"],"sources":["../../src/storage/get-storage-estimate.ts","../../src/storage/is-persistent.ts","../../src/storage/request-persistent-storage.ts","../../src/storage/select-storage-directory.ts","../../src/components/settings/shadow-claw-storage/shadow-claw-storage.ts"],"sourcesContent":["/**\n * Get storage usage estimate.\n */\nexport async function getStorageEstimate(): Promise<{\n usage: number;\n quota: number;\n}> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.estimate\n ) {\n const estimate = await navigator.storage.estimate();\n\n return {\n usage: estimate.usage || 0,\n quota: estimate.quota || 0,\n };\n }\n } catch (err) {\n console.warn(\"Failed to get storage estimate:\", err);\n }\n\n return { usage: 0, quota: 0 };\n}\n","/**\n * Check if the current storage is persistent.\n */\nexport async function isPersistent(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persisted\n ) {\n return await navigator.storage.persisted();\n }\n } catch (err) {\n console.warn(\"Failed to check persistent storage:\", err);\n }\n\n return false;\n}\n","/**\n * Request persistent storage so the browser doesn't evict our data.\n */\nexport async function requestPersistentStorage(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persist\n ) {\n return await navigator.storage.persist();\n }\n } catch (err) {\n console.warn(\"Failed to request persistent storage:\", err);\n }\n\n return false;\n}\n","import { CONFIG_KEYS } from \"../config/config.js\";\nimport { setConfig } from \"../db/set-config.js\";\nimport { ensureMainGroupMemory } from \"./ensure-main-group-memory.js\";\nimport { ensureMainGroupIndex } from \"./ensure-main-group-index.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\n\n/**\n * Select a local directory for storage using the File System Access API.\n */\nexport async function selectStorageDirectory(\n db: ShadowClawDatabase,\n): Promise<boolean> {\n const pickerMaybe = Reflect.get(globalThis, \"showDirectoryPicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Local folder picker is unavailable in this browser/context.\",\n );\n }\n\n try {\n const handle = await picker({\n mode: \"readwrite\",\n id: \"shadowclaw-storage\",\n });\n\n // Verify it's not the same as OPFS or something restricted\n // (Most browsers handle this, but good to have a handle)\n await setConfig(db, CONFIG_KEYS.STORAGE_HANDLE, handle);\n await ensureMainGroupMemory(db);\n await ensureMainGroupIndex(db);\n\n return true;\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return false;\n }\n\n throw err;\n }\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { effect } from \"../../../core/effect.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/get-config.js\";\n\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { getStorageEstimate } from \"../../../storage/get-storage-estimate.js\";\nimport { isPersistent } from \"../../../storage/is-persistent.js\";\nimport { requestPersistentStorage } from \"../../../storage/request-persistent-storage.js\";\nimport { selectStorageDirectory } from \"../../../storage/select-storage-directory.js\";\nimport { resetStorageDirectory } from \"../../../storage/storage.js\";\n\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../../utils/parse-boolean-config.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawStorageStyles from \"./shadow-claw-storage.css\" with { type: \"css\" };\nimport shadowClawStorageTemplate from \"./shadow-claw-storage.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-storage\";\n\n/**\n * Settings sub-component for Storage configuration:\n * usage display, persistent storage, directory selection.\n */\nexport class ShadowClawStorage extends ShadowClawElement {\n static styles = shadowClawStorageStyles;\n static template = shadowClawStorageTemplate;\n\n public db: ShadowClawDatabase | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n\n this.bindEventListeners();\n this.setupEffects();\n\n await this.updateStorageInfo();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"request-persistent\"]')\n ?.addEventListener(\"click\", () => this.handleRequestPersistent());\n\n root\n .querySelector('[data-action=\"change-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleChangeStorageDir());\n\n root\n .querySelector('[data-action=\"reset-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleResetStorageDir());\n\n root\n .querySelector('[data-action=\"reset-site-config\"]')\n ?.addEventListener(\"click\", () => this.handleResetSiteConfig());\n\n root\n .querySelector('[data-action=\"grant-storage-permission\"]')\n ?.addEventListener(\"click\", () => {\n if (this.db) {\n orchestratorStore.grantStorageAccess(this.db);\n }\n });\n\n root\n .querySelector('[data-setting=\"files-upload-append-ulid-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onUploadAppendUlidToggle(target.checked);\n }\n });\n }\n\n /**\n * Format bytes to human readable string.\n */\n formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const k = 1024;\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + units[i];\n }\n\n /**\n * Setup reactive effects for storage status from orchestratorStore.\n */\n setupEffects() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.addCleanup(\n effect(() => {\n const status = orchestratorStore.storageStatus;\n if (!status) {\n return;\n }\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const statusBadge = root.querySelector(\n '[data-info=\"storage-status-badge\"]',\n ) as HTMLElement | null;\n const grantBtn = root.querySelector(\n '[data-action=\"grant-storage-permission\"]',\n ) as HTMLElement | null;\n\n if (typeEl) {\n typeEl.textContent =\n status.type === \"local\"\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n if (statusBadge) {\n statusBadge.style.display =\n status.type === \"local\" ? \"inline-block\" : \"none\";\n if (status.type === \"local\") {\n statusBadge.textContent =\n status.permission === \"granted\"\n ? \"CONNECTED\"\n : \"NEEDS PERMISSION\";\n statusBadge.style.backgroundColor =\n status.permission === \"granted\"\n ? \"var(--shadow-claw-success-color)\"\n : \"var(--shadow-claw-error-color)\";\n statusBadge.style.color = \"white\";\n }\n }\n\n if (grantBtn) {\n grantBtn.style.display =\n status.type === \"local\" && status.permission !== \"granted\"\n ? \"inline-block\"\n : \"none\";\n }\n }),\n );\n }\n\n /**\n * Handle changing storage directory.\n */\n async handleChangeStorageDir() {\n if (!this.db) {\n return;\n }\n\n try {\n const success = await selectStorageDirectory(this.db);\n if (success) {\n showSuccess(\n \"Storage location changed. Existing OPFS files were not moved.\",\n 4500,\n );\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to change storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle persistent storage request.\n */\n async handleRequestPersistent() {\n if (!this.db) {\n return;\n }\n\n try {\n const granted = await requestPersistentStorage();\n if (granted) {\n showSuccess(\"Persistent storage granted\", 3500);\n } else {\n showWarning(\n \"Persistent storage was not granted. Browsers may deny this based on site usage.\",\n 5500,\n );\n }\n\n await this.updateStorageInfo();\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Storage request failed: ${errorMsg}`, 6000);\n }\n }\n\n async handleResetSiteConfig() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Site Config\",\n message:\n \"Allow embedded site-config.json defaults to apply again after the next reload?\",\n confirmLabel: \"Reset\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.resetSiteConfigSeed(this.db);\n showSuccess(\n \"Site config reset. Reload to apply its defaults again.\",\n 5000,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset site config: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle resetting storage directory.\n */\n async handleResetStorageDir() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Storage Location\",\n message: \"Revert storage to browser-internal (OPFS)?\",\n confirmLabel: \"Revert\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await resetStorageDirectory(this.db);\n\n showSuccess(\"Reverted to browser-internal storage\", 3500);\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle toggling unique ID prefix for uploaded files.\n */\n async onUploadAppendUlidToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../../db/set-config.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Unique ID prefix on file upload enabled\"\n : \"Unique ID prefix on file upload disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving unique ID file upload setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showWarning(options.message, 4500);\n\n return false;\n }\n\n /**\n * Update storage information in UI.\n */\n async updateStorageInfo() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n const estimate = await getStorageEstimate();\n const usageStr = this.formatBytes(estimate.usage);\n const quotaStr = this.formatBytes(estimate.quota);\n const percent =\n estimate.quota > 0 ? (estimate.usage / estimate.quota) * 100 : 0;\n\n const usageEl = root.querySelector('[data-info=\"storage-usage\"]');\n const quotaEl = root.querySelector('[data-info=\"storage-quota\"]');\n const progressEl = root.querySelector(\n '[data-info=\"storage-progress\"]',\n ) as HTMLElement | null;\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const persistentBadge = root.querySelector(\n '[data-info=\"storage-persistent-badge\"]',\n ) as HTMLElement | null;\n\n if (usageEl) {\n usageEl.textContent = `${usageStr} used`;\n }\n\n if (quotaEl) {\n quotaEl.textContent = `of ${quotaStr}`;\n }\n\n if (progressEl) {\n progressEl.style.width = `${percent}%`;\n }\n\n // Check storage type\n const handle = await getConfig(this.db, CONFIG_KEYS.STORAGE_HANDLE);\n if (typeEl) {\n typeEl.textContent = handle\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n // Check persistence\n const persistent = await isPersistent();\n if (persistentBadge) {\n persistentBadge.style.display = persistent ? \"inline-block\" : \"none\";\n }\n\n // Update help text\n const helpGeneralEl = root.querySelector(\n '[data-info=\"storage-help-general\"]',\n );\n\n const helpLocalEl = root.querySelector(\n '[data-info=\"storage-help-local\"]',\n );\n\n if (helpGeneralEl) {\n setSanitizedHtml(\n helpGeneralEl,\n handle\n ? `Persistent storage protects your <b>chat history, tasks, and settings</b> in the browser database.\n Without it, the browser might clear this data if your disk is almost full.`\n : `Persistent storage protects your <b>files, chat history, and settings</b> in the browser.\n Without it, the browser might clear your data if your disk is almost full.`,\n );\n }\n\n if (helpLocalEl) {\n setSanitizedHtml(\n helpLocalEl,\n handle\n ? `ShadowClaw is currently <b>connected to a local folder</b>. Your files are safe on your disk,\n but browser persistence is still recommended for your chat history.`\n : `You can use a local folder on your computer for storage. This makes files directly accessible\n on your disk and independent of browser storage limits.`,\n );\n }\n\n // Disable persistent button if already persistent\n const requestPersistentBtn = root.querySelector(\n '[data-action=\"request-persistent\"]',\n ) as HTMLButtonElement | null;\n if (requestPersistentBtn) {\n requestPersistentBtn.disabled = persistent;\n }\n\n // Sync upload append ULID toggle\n const uploadAppendUlidVal = await getConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n );\n const uploadAppendUlidToggle = root.querySelector(\n '[data-setting=\"files-upload-append-ulid-toggle\"]',\n ) as HTMLInputElement | null;\n if (uploadAppendUlidToggle) {\n uploadAppendUlidToggle.checked = isTruthyConfigValue(\n uploadAppendUlidVal,\n false,\n );\n }\n } catch (err) {\n console.warn(\"Failed to update storage info:\", err);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawStorage);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-storage-DUY8B9m-.js","names":["shadowClawStorageStyles","shadowClawStorageTemplate"],"sources":["../../src/storage/get-storage-estimate.ts","../../src/storage/is-persistent.ts","../../src/storage/request-persistent-storage.ts","../../src/storage/select-storage-directory.ts","../../src/components/settings/shadow-claw-storage/shadow-claw-storage.ts"],"sourcesContent":["/**\n * Get storage usage estimate.\n */\nexport async function getStorageEstimate(): Promise<{\n usage: number;\n quota: number;\n}> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.estimate\n ) {\n const estimate = await navigator.storage.estimate();\n\n return {\n usage: estimate.usage || 0,\n quota: estimate.quota || 0,\n };\n }\n } catch (err) {\n console.warn(\"Failed to get storage estimate:\", err);\n }\n\n return { usage: 0, quota: 0 };\n}\n","/**\n * Check if the current storage is persistent.\n */\nexport async function isPersistent(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persisted\n ) {\n return await navigator.storage.persisted();\n }\n } catch (err) {\n console.warn(\"Failed to check persistent storage:\", err);\n }\n\n return false;\n}\n","/**\n * Request persistent storage so the browser doesn't evict our data.\n */\nexport async function requestPersistentStorage(): Promise<boolean> {\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.storage &&\n navigator.storage.persist\n ) {\n return await navigator.storage.persist();\n }\n } catch (err) {\n console.warn(\"Failed to request persistent storage:\", err);\n }\n\n return false;\n}\n","import { CONFIG_KEYS } from \"../config/config.js\";\nimport { setConfig } from \"../db/set-config.js\";\nimport { ensureMainGroupMemory } from \"./ensure-main-group-memory.js\";\nimport { ensureMainGroupIndex } from \"./ensure-main-group-index.js\";\nimport type { ShadowClawDatabase } from \"../db/types.js\";\n\n/**\n * Select a local directory for storage using the File System Access API.\n */\nexport async function selectStorageDirectory(\n db: ShadowClawDatabase,\n): Promise<boolean> {\n const pickerMaybe = Reflect.get(globalThis, \"showDirectoryPicker\");\n const picker =\n typeof pickerMaybe === \"function\" ? pickerMaybe.bind(globalThis) : null;\n\n if (!picker) {\n throw new Error(\n \"Local folder picker is unavailable in this browser/context.\",\n );\n }\n\n try {\n const handle = await picker({\n mode: \"readwrite\",\n id: \"shadowclaw-storage\",\n });\n\n // Verify it's not the same as OPFS or something restricted\n // (Most browsers handle this, but good to have a handle)\n await setConfig(db, CONFIG_KEYS.STORAGE_HANDLE, handle);\n await ensureMainGroupMemory(db);\n await ensureMainGroupIndex(db);\n\n return true;\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return false;\n }\n\n throw err;\n }\n}\n","import { CONFIG_KEYS } from \"../../../config/config.js\";\nimport { effect } from \"../../../core/effect.js\";\n\nimport { getDb } from \"../../../db/db.js\";\nimport { getConfig } from \"../../../db/get-config.js\";\n\nimport { setSanitizedHtml } from \"../../../security/trusted-types.js\";\nimport { getStorageEstimate } from \"../../../storage/get-storage-estimate.js\";\nimport { isPersistent } from \"../../../storage/is-persistent.js\";\nimport { requestPersistentStorage } from \"../../../storage/request-persistent-storage.js\";\nimport { selectStorageDirectory } from \"../../../storage/select-storage-directory.js\";\nimport { resetStorageDirectory } from \"../../../storage/storage.js\";\n\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess, showWarning } from \"../../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../../utils/parse-boolean-config.js\";\n\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawStorageStyles from \"./shadow-claw-storage.css\" with { type: \"css\" };\nimport shadowClawStorageTemplate from \"./shadow-claw-storage.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-storage\";\n\n/**\n * Settings sub-component for Storage configuration:\n * usage display, persistent storage, directory selection.\n */\nexport class ShadowClawStorage extends ShadowClawElement {\n static styles = shadowClawStorageStyles;\n static template = shadowClawStorageTemplate;\n\n public db: ShadowClawDatabase | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n\n this.bindEventListeners();\n this.setupEffects();\n\n await this.updateStorageInfo();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n }\n\n /**\n * Bind all event listeners.\n */\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"request-persistent\"]')\n ?.addEventListener(\"click\", () => this.handleRequestPersistent());\n\n root\n .querySelector('[data-action=\"change-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleChangeStorageDir());\n\n root\n .querySelector('[data-action=\"reset-storage-dir\"]')\n ?.addEventListener(\"click\", () => this.handleResetStorageDir());\n\n root\n .querySelector('[data-action=\"reset-site-config\"]')\n ?.addEventListener(\"click\", () => this.handleResetSiteConfig());\n\n root\n .querySelector('[data-action=\"grant-storage-permission\"]')\n ?.addEventListener(\"click\", () => {\n if (this.db) {\n orchestratorStore.grantStorageAccess(this.db);\n }\n });\n\n root\n .querySelector('[data-setting=\"files-upload-append-ulid-toggle\"]')\n ?.addEventListener(\"change\", (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target) {\n void this.onUploadAppendUlidToggle(target.checked);\n }\n });\n }\n\n /**\n * Format bytes to human readable string.\n */\n formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const k = 1024;\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + units[i];\n }\n\n /**\n * Setup reactive effects for storage status from orchestratorStore.\n */\n setupEffects() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n this.addCleanup(\n effect(() => {\n const status = orchestratorStore.storageStatus;\n if (!status) {\n return;\n }\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const statusBadge = root.querySelector(\n '[data-info=\"storage-status-badge\"]',\n ) as HTMLElement | null;\n const grantBtn = root.querySelector(\n '[data-action=\"grant-storage-permission\"]',\n ) as HTMLElement | null;\n\n if (typeEl) {\n typeEl.textContent =\n status.type === \"local\"\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n if (statusBadge) {\n statusBadge.style.display =\n status.type === \"local\" ? \"inline-block\" : \"none\";\n if (status.type === \"local\") {\n statusBadge.textContent =\n status.permission === \"granted\"\n ? \"CONNECTED\"\n : \"NEEDS PERMISSION\";\n statusBadge.style.backgroundColor =\n status.permission === \"granted\"\n ? \"var(--shadow-claw-success-color)\"\n : \"var(--shadow-claw-error-color)\";\n statusBadge.style.color = \"white\";\n }\n }\n\n if (grantBtn) {\n grantBtn.style.display =\n status.type === \"local\" && status.permission !== \"granted\"\n ? \"inline-block\"\n : \"none\";\n }\n }),\n );\n }\n\n /**\n * Handle changing storage directory.\n */\n async handleChangeStorageDir() {\n if (!this.db) {\n return;\n }\n\n try {\n const success = await selectStorageDirectory(this.db);\n if (success) {\n showSuccess(\n \"Storage location changed. Existing OPFS files were not moved.\",\n 4500,\n );\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to change storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle persistent storage request.\n */\n async handleRequestPersistent() {\n if (!this.db) {\n return;\n }\n\n try {\n const granted = await requestPersistentStorage();\n if (granted) {\n showSuccess(\"Persistent storage granted\", 3500);\n } else {\n showWarning(\n \"Persistent storage was not granted. Browsers may deny this based on site usage.\",\n 5500,\n );\n }\n\n await this.updateStorageInfo();\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Storage request failed: ${errorMsg}`, 6000);\n }\n }\n\n async handleResetSiteConfig() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Site Config\",\n message:\n \"Allow embedded site-config.json defaults to apply again after the next reload?\",\n confirmLabel: \"Reset\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.resetSiteConfigSeed(this.db);\n showSuccess(\n \"Site config reset. Reload to apply its defaults again.\",\n 5000,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset site config: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle resetting storage directory.\n */\n async handleResetStorageDir() {\n if (!this.db) {\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Reset Storage Location\",\n message: \"Revert storage to browser-internal (OPFS)?\",\n confirmLabel: \"Revert\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await resetStorageDirectory(this.db);\n\n showSuccess(\"Reverted to browser-internal storage\", 3500);\n\n await this.updateStorageInfo();\n await orchestratorStore.loadFiles(this.db);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(`Failed to reset storage location: ${errorMsg}`, 6000);\n }\n }\n\n /**\n * Handle toggling unique ID prefix for uploaded files.\n */\n async onUploadAppendUlidToggle(enabled: boolean) {\n if (!this.db) {\n return;\n }\n\n try {\n const { setConfig } = await import(\"../../../db/set-config.js\");\n await setConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n enabled ? \"true\" : \"false\",\n );\n\n showSuccess(\n enabled\n ? \"Unique ID prefix on file upload enabled\"\n : \"Unique ID prefix on file upload disabled\",\n 2500,\n );\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\n \"Error saving unique ID file upload setting: \" + errorMsg,\n 6000,\n );\n }\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showWarning(options.message, 4500);\n\n return false;\n }\n\n /**\n * Update storage information in UI.\n */\n async updateStorageInfo() {\n if (!this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n try {\n const estimate = await getStorageEstimate();\n const usageStr = this.formatBytes(estimate.usage);\n const quotaStr = this.formatBytes(estimate.quota);\n const percent =\n estimate.quota > 0 ? (estimate.usage / estimate.quota) * 100 : 0;\n\n const usageEl = root.querySelector('[data-info=\"storage-usage\"]');\n const quotaEl = root.querySelector('[data-info=\"storage-quota\"]');\n const progressEl = root.querySelector(\n '[data-info=\"storage-progress\"]',\n ) as HTMLElement | null;\n\n const typeEl = root.querySelector('[data-info=\"storage-type\"]');\n const persistentBadge = root.querySelector(\n '[data-info=\"storage-persistent-badge\"]',\n ) as HTMLElement | null;\n\n if (usageEl) {\n usageEl.textContent = `${usageStr} used`;\n }\n\n if (quotaEl) {\n quotaEl.textContent = `of ${quotaStr}`;\n }\n\n if (progressEl) {\n progressEl.style.width = `${percent}%`;\n }\n\n // Check storage type\n const handle = await getConfig(this.db, CONFIG_KEYS.STORAGE_HANDLE);\n if (typeEl) {\n typeEl.textContent = handle\n ? \"Local Directory\"\n : \"Browser Internal (OPFS)\";\n }\n\n // Check persistence\n const persistent = await isPersistent();\n if (persistentBadge) {\n persistentBadge.style.display = persistent ? \"inline-block\" : \"none\";\n }\n\n // Update help text\n const helpGeneralEl = root.querySelector(\n '[data-info=\"storage-help-general\"]',\n );\n\n const helpLocalEl = root.querySelector(\n '[data-info=\"storage-help-local\"]',\n );\n\n if (helpGeneralEl) {\n setSanitizedHtml(\n helpGeneralEl,\n handle\n ? `Persistent storage protects your <b>chat history, tasks, and settings</b> in the browser database.\n Without it, the browser might clear this data if your disk is almost full.`\n : `Persistent storage protects your <b>files, chat history, and settings</b> in the browser.\n Without it, the browser might clear your data if your disk is almost full.`,\n );\n }\n\n if (helpLocalEl) {\n setSanitizedHtml(\n helpLocalEl,\n handle\n ? `ShadowClaw is currently <b>connected to a local folder</b>. Your files are safe on your disk,\n but browser persistence is still recommended for your chat history.`\n : `You can use a local folder on your computer for storage. This makes files directly accessible\n on your disk and independent of browser storage limits.`,\n );\n }\n\n // Disable persistent button if already persistent\n const requestPersistentBtn = root.querySelector(\n '[data-action=\"request-persistent\"]',\n ) as HTMLButtonElement | null;\n if (requestPersistentBtn) {\n requestPersistentBtn.disabled = persistent;\n }\n\n // Sync upload append ULID toggle\n const uploadAppendUlidVal = await getConfig(\n this.db,\n CONFIG_KEYS.FILES_UPLOAD_APPEND_ULID,\n );\n const uploadAppendUlidToggle = root.querySelector(\n '[data-setting=\"files-upload-append-ulid-toggle\"]',\n ) as HTMLInputElement | null;\n if (uploadAppendUlidToggle) {\n uploadAppendUlidToggle.checked = isTruthyConfigValue(\n uploadAppendUlidVal,\n false,\n );\n }\n } catch (err) {\n console.warn(\"Failed to update storage info:\", err);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawStorage);\n}\n"],"mappings":"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"}
|
package/dist/lib/{shadow-claw-task-server-DFImTUbw.js → shadow-claw-task-server-yWeoA3eL.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
2
|
import { o as getDb } from "./get-config-BWhs5HFF.js";
|
|
3
|
-
import { M as setTaskServerUrl, j as setTaskServerEnabled, t as orchestratorStore } from "./orchestrator-
|
|
3
|
+
import { M as setTaskServerUrl, j as setTaskServerEnabled, t as orchestratorStore } from "./orchestrator-CCARkxQC.js";
|
|
4
4
|
import { a as showSuccess, r as showError } from "./toast-Ck7OIKDf.js";
|
|
5
5
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
6
6
|
|
|
@@ -268,4 +268,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
268
268
|
|
|
269
269
|
//#endregion
|
|
270
270
|
export { ShadowClawTaskServer as t };
|
|
271
|
-
//# sourceMappingURL=shadow-claw-task-server-
|
|
271
|
+
//# sourceMappingURL=shadow-claw-task-server-yWeoA3eL.js.map
|
package/dist/lib/{shadow-claw-task-server-DFImTUbw.js.map → shadow-claw-task-server-yWeoA3eL.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-task-server-
|
|
1
|
+
{"version":3,"file":"shadow-claw-task-server-yWeoA3eL.js","names":["shadowClawTaskServerStyles","shadowClawTaskServerTemplate"],"sources":["../../src/components/settings/shadow-claw-task-server/shadow-claw-task-server.ts"],"sourcesContent":["import { effect } from \"../../../core/effect.js\";\nimport {\n setTaskServerEnabled,\n setTaskServerUrl,\n} from \"../../../core/orchestrator/utils/settings.js\";\nimport { getDb } from \"../../../db/db.js\";\nimport { orchestratorStore } from \"../../../stores/orchestrator.js\";\nimport { showError, showSuccess } from \"../../../ui/toast.js\";\n\nimport type { Orchestrator } from \"../../../core/orchestrator/orchestrator.js\";\nimport type { ShadowClawDatabase } from \"../../../db/types.js\";\n\nimport ShadowClawElement from \"../../shadow-claw-element.js\";\nimport shadowClawTaskServerStyles from \"./shadow-claw-task-server.css\" with { type: \"css\" };\nimport shadowClawTaskServerTemplate from \"./shadow-claw-task-server.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-task-server\";\n\n/**\n * Settings sub-component for Task Server URL and server-side task scheduling configuration.\n */\nexport class ShadowClawTaskServer extends ShadowClawElement {\n static styles = shadowClawTaskServerStyles;\n static template = shadowClawTaskServerTemplate;\n\n db: ShadowClawDatabase | null;\n orchestrator: Orchestrator | null;\n\n constructor() {\n super();\n\n this.db = null;\n this.orchestrator = null;\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n this.db = await getDb();\n this.orchestrator = orchestratorStore.orchestrator;\n\n this.bindEventListeners();\n this.setupEffects();\n await this.render();\n }\n\n bindEventListeners() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n root\n .querySelector('[data-action=\"save-task-server-url\"]')\n ?.addEventListener(\"click\", () => {\n void this.saveTaskServerUrl();\n });\n\n root\n .querySelector('[data-setting=\"task-server-enabled-toggle\"]')\n ?.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLInputElement;\n void this.saveTaskServerEnabled(target.checked);\n });\n }\n\n setupEffects() {\n effect(() => {\n if (orchestratorStore.ready) {\n this.orchestrator = orchestratorStore.orchestrator;\n this.render();\n }\n });\n }\n\n async render() {\n if (!this.orchestrator) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (input) {\n input.value = this.orchestrator.taskServerUrl;\n }\n\n const enabledToggle = root.querySelector(\n '[data-setting=\"task-server-enabled-toggle\"]',\n ) as HTMLInputElement | null;\n if (enabledToggle) {\n enabledToggle.checked = this.orchestrator.taskServerEnabled;\n }\n }\n\n async saveTaskServerEnabled(enabled: boolean) {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n try {\n await setTaskServerEnabled(this.orchestrator, this.db, enabled);\n if (\n enabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server setting: \" + errorMsg, 6000);\n }\n }\n\n async saveTaskServerUrl() {\n if (!this.orchestrator || !this.db) {\n return;\n }\n\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const input = root.querySelector(\n '[data-setting=\"task-server-url-input\"]',\n ) as HTMLInputElement | null;\n if (!input) {\n return;\n }\n\n const url = input.value.trim();\n\n try {\n await setTaskServerUrl(this.orchestrator, this.db, url || \"/schedule\");\n if (\n this.orchestrator.taskServerEnabled &&\n typeof this.orchestrator.ensureAllConnections === \"function\"\n ) {\n void this.orchestrator.ensureAllConnections();\n }\n showSuccess(\"Task Server URL saved\", 3000);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n showError(\"Error saving Task Server URL: \" + errorMsg, 6000);\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTaskServer);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAM,cAAc;;;;AAKpB,IAAa,uBAAb,cAA0C,kBAAkB;CAC1D,OAAO,SAASA;CAChB,OAAO,WAAWC;CAElB;CACA;CAEA,cAAc;EACZ,MAAM;EAEN,KAAK,KAAK;EACV,KAAK,eAAe;CACtB;CAEA,MAAM,oBAAoB;EAExB,IAAI,CADS,KAAK,YAEhB,MAAM,IAAI,MAAM,sBAAsB;EAGxC,KAAK,KAAK,MAAM,MAAM;EACtB,KAAK,eAAe,kBAAkB;EAEtC,KAAK,mBAAmB;EACxB,KAAK,aAAa;EAClB,MAAM,KAAK,OAAO;CACpB;CAEA,qBAAqB;EACnB,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,KACG,cAAc,wCAAsC,CAAC,EACpD,iBAAiB,eAAe;GAChC,AAAK,KAAK,kBAAkB;EAC9B,CAAC;EAEH,KACG,cAAc,+CAA6C,CAAC,EAC3D,iBAAiB,WAAW,MAAM;GAClC,MAAM,SAAS,EAAE;GACjB,AAAK,KAAK,sBAAsB,OAAO,OAAO;EAChD,CAAC;CACL;CAEA,eAAe;EACb,aAAa;GACX,IAAI,kBAAkB,OAAO;IAC3B,KAAK,eAAe,kBAAkB;IACtC,KAAK,OAAO;GACd;EACF,CAAC;CACH;CAEA,MAAM,SAAS;EACb,IAAI,CAAC,KAAK,cACR;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,OACF,MAAM,QAAQ,KAAK,aAAa;EAGlC,MAAM,gBAAgB,KAAK,cACzB,+CACF;EACA,IAAI,eACF,cAAc,UAAU,KAAK,aAAa;CAE9C;CAEA,MAAM,sBAAsB,SAAkB;EAC5C,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,IAAI;GACF,MAAM,qBAAqB,KAAK,cAAc,KAAK,IAAI,OAAO;GAC9D,IACE,WACA,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;EAEhD,SAAS,KAAK;GACZ,MAAM,WAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAChE,UAAU,uCAAuC,UAAU,GAAI;EACjE;CACF;CAEA,MAAM,oBAAoB;EACxB,IAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,IAC9B;EAGF,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MACH;EAGF,MAAM,QAAQ,KAAK,cACjB,0CACF;EACA,IAAI,CAAC,OACH;EAGF,MAAM,MAAM,MAAM,MAAM,KAAK;EAE7B,IAAI;GACF,MAAM,iBAAiB,KAAK,cAAc,KAAK,IAAI,OAAO,WAAW;GACrE,IACE,KAAK,aAAa,qBAClB,OAAO,KAAK,aAAa,yBAAyB,YAElD,AAAK,KAAK,aAAa,qBAAqB;GAE9C,YAAY,yBAAyB,GAAI;EAC3C,SAAS,KAAK;GACZ,MAAM,WAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAChE,UAAU,mCAAmC,UAAU,GAAI;EAC7D;CACF;AACF;AAEA,IAAI,CAAC,eAAe,IAAI,WAAW,GACjC,eAAe,OAAO,aAAa,oBAAoB"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
2
|
import { o as getDb, t as getConfig } from "./get-config-BWhs5HFF.js";
|
|
3
|
-
import { r as CONFIG_KEYS } from "./config-
|
|
4
|
-
import {
|
|
5
|
-
import { t as fileViewerStore } from "./file-viewer-
|
|
6
|
-
import { t as orchestratorStore } from "./orchestrator-
|
|
3
|
+
import { r as CONFIG_KEYS } from "./config-BrHR97zt.js";
|
|
4
|
+
import { r as decodePathSegment } from "./app-routes-BXiRvlNl.js";
|
|
5
|
+
import { t as fileViewerStore } from "./file-viewer-DOfvX6yy.js";
|
|
6
|
+
import { t as orchestratorStore } from "./orchestrator-CCARkxQC.js";
|
|
7
7
|
import { escapeHtml } from "./utils/html.js";
|
|
8
|
-
import { n as setSanitizedHtml } from "./trusted-types-
|
|
8
|
+
import { n as setSanitizedHtml } from "./trusted-types-HwsGS5Nj.js";
|
|
9
9
|
import { a as showSuccess, i as showInfo, r as showError } from "./toast-Ck7OIKDf.js";
|
|
10
10
|
import { isTruthyConfigValue } from "./utils/parse-boolean-config.js";
|
|
11
11
|
import { t as effect } from "./effect-DL6j9HJp.js";
|
|
12
|
-
import { n as renderMarkdown } from "./markdown
|
|
12
|
+
import { n as renderMarkdown } from "./markdown--6vTAPEH.js";
|
|
13
13
|
import "./shadow-claw-page-header-action-button-BXXm5b5N.js";
|
|
14
14
|
import "./components/shadow-claw-dialog.js";
|
|
15
|
-
import "./shadow-claw-page-header-
|
|
15
|
+
import "./shadow-claw-page-header-C_Qr3xZM.js";
|
|
16
16
|
import "./shadow-claw-empty-state-D9bnqWMF.js";
|
|
17
|
-
import { t as getCurrentSubscription } from "./push-client-
|
|
17
|
+
import { t as getCurrentSubscription } from "./push-client-rrjTdc-U.js";
|
|
18
18
|
|
|
19
19
|
//#region src/components/shadow-claw-tasks/shadow-claw-tasks.css
|
|
20
20
|
const sheet = new CSSStyleSheet();
|
|
@@ -1908,4 +1908,4 @@ if (!customElements.get(elementName)) customElements.define(elementName, ShadowC
|
|
|
1908
1908
|
|
|
1909
1909
|
//#endregion
|
|
1910
1910
|
export { ShadowClawTasks as t };
|
|
1911
|
-
//# sourceMappingURL=shadow-claw-tasks-
|
|
1911
|
+
//# sourceMappingURL=shadow-claw-tasks-Bg0uM15I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadow-claw-tasks-BjaxsmUx.js","names":["shadowClawTasksStyles","shadowClawTasksTemplate"],"sources":["../../src/components/shadow-claw-tasks/shadow-claw-tasks.ts"],"sourcesContent":["import { renderMarkdown } from \"../../content/markdown.js\";\nimport { CONFIG_KEYS } from \"../../config/config.js\";\nimport { effect } from \"../../core/effect.js\";\nimport { decodePathSegment } from \"../../core/app-routes.js\";\n\nimport { getDb, ShadowClawDatabase } from \"../../db/db.js\";\nimport { getConfig } from \"../../db/get-config.js\";\nimport { Task } from \"../../db/types.js\";\n\nimport { setSanitizedHtml } from \"../../security/trusted-types.js\";\nimport { fileViewerStore } from \"../../stores/file-viewer.js\";\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { getCurrentSubscription } from \"../../subsystems/notifications/push-client.js\";\n\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../utils/parse-boolean-config.js\";\nimport { escapeHtml } from \"../../utils/html.js\";\n\nimport \"../common/shadow-claw-empty-state/shadow-claw-empty-state.js\";\nimport \"../common/shadow-claw-page-header-action-button/shadow-claw-page-header-action-button.js\";\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawTasksStyles from \"./shadow-claw-tasks.css\" with { type: \"css\" };\nimport shadowClawTasksTemplate from \"./shadow-claw-tasks.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-tasks\";\n\nasync function resolveFrontmatterToggle(\n db: ShadowClawDatabase | null,\n key: string,\n): Promise<boolean> {\n if (!db || typeof (db as any).transaction !== \"function\") {\n return true;\n }\n\n try {\n return isTruthyConfigValue(await getConfig(db, key), true);\n } catch {\n return true;\n }\n}\n\nexport class ShadowClawTasks extends ShadowClawElement {\n static styles = shadowClawTasksStyles;\n static template = shadowClawTasksTemplate;\n\n editingTask: any | null = null;\n editingTools: any[] = [];\n renderFrontmatter = true;\n tasks: any[] = [];\n private _autoScrollActive = false;\n private _autoScrollSpeed = 0;\n\n private _draggedTaskId: string | null = null;\n private _keyboardGrabbedId: string | null = null;\n private _touchDraggedTaskId: string | null = null;\n private _touchId: number | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n root.addEventListener(\"click\", (event: Event) => {\n if (event instanceof MouseEvent) {\n getDb()\n .then((db) => this.handlePreviewLinkClick(event, db))\n .catch(console.error);\n }\n });\n\n // Backup button\n const backupBtn = root.querySelector(\".tasks__backup-btn\");\n backupBtn?.addEventListener(\"click\", () => this.handleBackup());\n\n // Restore button\n const restoreBtn = root.querySelector(\".tasks__restore-btn\");\n const restoreInput = root.querySelector(\".tasks__hidden-restore\");\n restoreBtn?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.click();\n }\n });\n\n restoreInput?.addEventListener(\"change\", (e) => {\n if (e.target instanceof HTMLInputElement) {\n const target = e.target;\n getDb()\n .then((db) => this.handleRestore(db, target))\n .catch(console.error);\n }\n });\n\n // Clear all button\n const clearBtn = root.querySelector(\".tasks__clear-btn\");\n clearBtn?.addEventListener(\"click\", () => {\n getDb()\n .then((db) => this.handleClearAll(db))\n .catch(console.error);\n });\n\n // Add task button\n const addBtn = root.querySelector(\".tasks__add-btn\");\n addBtn?.addEventListener(\"click\", () => this.handleAdd());\n\n // Dialog controls\n const dialog = root.querySelector(\"dialog\");\n const closeBtn = root.querySelector(\".tasks__dialog-close\");\n const cancelBtn = root.querySelector(\".tasks__btn-cancel\");\n const form = root.querySelector(\n \".tasks__dialog-form\",\n ) as HTMLFormElement | null;\n\n closeBtn?.addEventListener(\"click\", () => {\n dialog?.close();\n });\n\n cancelBtn?.addEventListener(\"click\", () => {\n dialog?.close();\n });\n\n form?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (form) {\n getDb()\n .then((db) => this.handleEditSubmit(db, form))\n .catch(console.error);\n }\n });\n\n // Close dialog when clicking outside (on backdrop)\n dialog?.addEventListener(\"click\", (e) => {\n if (e.target === dialog) {\n dialog.close();\n }\n });\n\n // Preview update logic\n const promptTextarea = root.querySelector(\"textarea[name='prompt']\");\n const previewDiv = root.querySelector(\".tasks__preview\");\n const typeRadios = root.querySelectorAll(\"input[name='taskType']\");\n const promptGroup = root.querySelector(\".tasks__prompt-group\");\n const toolsGroup = root.querySelector(\".tasks__tools-group\");\n const addToolBtn = root.querySelector(\".tasks__add-tool-btn\");\n\n const updatePreview = async () => {\n if (previewDiv instanceof HTMLElement) {\n const type =\n Array.from(typeRadios)\n .find((r: any) => r.checked)\n ?.getAttribute(\"value\") || \"prompt\";\n if (type === \"tools\") {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n } else if (promptTextarea instanceof HTMLTextAreaElement) {\n setSanitizedHtml(\n previewDiv,\n await this.renderPreview(promptTextarea.value),\n );\n }\n }\n };\n\n promptTextarea?.addEventListener(\"input\", updatePreview);\n\n const scheduleInput = root.querySelector(\"input[name='schedule']\");\n scheduleInput?.addEventListener(\"input\", () => {\n this.updatePushNotificationsCheckboxState();\n });\n\n typeRadios.forEach((radio) => {\n radio.addEventListener(\"change\", (e) => {\n const val = (e.target as HTMLInputElement).value;\n if (val === \"tools\") {\n promptGroup?.setAttribute(\"style\", \"display: none;\");\n toolsGroup?.removeAttribute(\"style\");\n promptTextarea?.removeAttribute(\"required\");\n } else {\n toolsGroup?.setAttribute(\"style\", \"display: none;\");\n promptGroup?.removeAttribute(\"style\");\n }\n\n updatePreview();\n });\n });\n\n addToolBtn?.addEventListener(\"click\", () => {\n this.editingTools.push({ name: \"\", input: {} });\n this.renderToolsEditor();\n updatePreview();\n });\n\n const db = await getDb();\n this.renderFrontmatter = await resolveFrontmatterToggle(\n db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS,\n );\n\n // apply highlight.js atom-one-dark.min.css to shadow dom\n try {\n const cssText = await (\n await fetch(\n \"https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/atom-one-dark.min.css\",\n )\n ).text();\n\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n\n if (this.shadowRoot?.adoptedStyleSheets) {\n this.shadowRoot.adoptedStyleSheets.push(sheet);\n }\n } catch (err) {\n console.warn(\"Failed to load highlight.js styles:\", err);\n }\n\n // Global dragover auto-scroll listener on shadowRoot\n root.addEventListener(\"dragover\", (e: any) => {\n if (this._draggedTaskId !== null) {\n this._updateAutoScrollSpeed(e.clientY);\n }\n });\n\n // Ensure we stop scrolling if the drag ends or leaves\n root.addEventListener(\"dragend\", () => {\n this._stopAutoScroll();\n });\n root.addEventListener(\"drop\", () => {\n this._stopAutoScroll();\n });\n\n this.render();\n this.dispatchTerminalSlotReady();\n\n // Re-render when tasks change\n this.cleanup = effect(() => {\n orchestratorStore.tasks;\n this.updateTaskList(db);\n });\n }\n\n disconnectedCallback() {\n this.cleanup();\n }\n\n cleanup: () => void = () => {};\n\n dispatchTerminalSlotReady() {\n this.dispatchEvent(\n new CustomEvent(\"shadow-claw-terminal-slot-ready\", {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Escape HTML special characters\n */\n escapeHtml(text: string) {\n const div = document.createElement(\"div\");\n div.textContent = text;\n\n return div.innerHTML;\n }\n\n /**\n * Open dialog to add a new task\n */\n handleAdd() {\n this.editingTask = null;\n this.editingTools = [];\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const dialog = root.querySelector(\"dialog\");\n const form = root.querySelector(\".tasks__dialog-form\");\n const title = root.querySelector(\".tasks__dialog-title\");\n const submitBtn = root.querySelector(\".tasks__dialog-submit\");\n\n if (!form || !(form instanceof HTMLFormElement)) {\n return;\n }\n\n // Update dialog for add mode\n if (title) {\n title.textContent = \"Add Task\";\n }\n\n if (submitBtn) {\n submitBtn.textContent = \"Add Task\";\n }\n\n // Clear form\n form.reset();\n\n const nameInput = form.querySelector(\"input[name='name']\");\n if (nameInput instanceof HTMLInputElement) {\n nameInput.value = \"\";\n }\n\n // Reset type toggle\n const promptRadio = form.querySelector(\n \"input[name='taskType'][value='prompt']\",\n ) as HTMLInputElement;\n if (promptRadio) {\n promptRadio.checked = true;\n promptRadio.dispatchEvent(new Event(\"change\"));\n }\n\n this.renderToolsEditor();\n\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (pushInput) {\n pushInput.checked = false;\n }\n this.updatePushNotificationsCheckboxState(false);\n\n // Reset preview\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv instanceof HTMLElement) {\n this.renderPreview(\"\", false).then((html) => {\n setSanitizedHtml(previewDiv, html);\n });\n }\n\n // Show dialog\n dialog?.showModal();\n }\n\n /**\n * Open edit dialog for a task\n */\n handleEdit(task: Task) {\n this.editingTask = task;\n this.editingTools = JSON.parse(JSON.stringify(task.tools || []));\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const dialog = root.querySelector(\"dialog\");\n const form = root.querySelector(\".tasks__dialog-form\");\n const title = root.querySelector(\".tasks__dialog-title\");\n const submitBtn = root.querySelector(\".tasks__dialog-submit\");\n\n if (!form || !(form instanceof HTMLFormElement)) {\n return;\n }\n\n // Update dialog for edit mode\n if (title) {\n title.textContent = \"Edit Task\";\n }\n\n if (submitBtn) {\n submitBtn.textContent = \"Save Changes\";\n }\n\n // Set form values\n const nameInput = form.querySelector(\"input[name='name']\");\n if (nameInput instanceof HTMLInputElement) {\n nameInput.value = task.name || \"\";\n }\n\n const scheduleInput = form.querySelector(\"input[name='schedule']\");\n const promptInput = form.querySelector(\"textarea[name='prompt']\");\n if (scheduleInput instanceof HTMLInputElement) {\n scheduleInput.value = task.schedule || \"\";\n }\n\n if (promptInput instanceof HTMLTextAreaElement) {\n promptInput.value = task.prompt || \"\";\n }\n\n const freshContextInput = form.querySelector(\"input[name='freshContext']\");\n if (freshContextInput instanceof HTMLInputElement) {\n freshContextInput.checked = !!task.freshContext;\n }\n\n const subagentInput = form.querySelector(\"input[name='subagent']\");\n if (subagentInput instanceof HTMLInputElement) {\n subagentInput.checked = !!task.subagent;\n }\n\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (pushInput) {\n pushInput.checked = !!task.pushNotifications;\n }\n this.updatePushNotificationsCheckboxState(!!task.pushNotifications);\n\n const typeRadio = form.querySelector(\n `input[name='taskType'][value='${task.type || \"prompt\"}']`,\n ) as HTMLInputElement;\n if (typeRadio) {\n typeRadio.checked = true;\n typeRadio.dispatchEvent(new Event(\"change\"));\n }\n\n this.renderToolsEditor();\n\n // Set initial preview\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv instanceof HTMLElement) {\n if (task.type === \"tools\") {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n } else {\n this.renderPreview(task.prompt).then((html) => {\n setSanitizedHtml(previewDiv, html);\n });\n }\n }\n\n // Show dialog\n dialog?.showModal();\n }\n\n /**\n * Run a task\n */\n handleRun(task: Task) {\n orchestratorStore.runTask(task, true);\n }\n\n renderToolsEditor() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tasks__tools-list\");\n if (!list) {\n return;\n }\n\n list.innerHTML = \"\";\n\n this.editingTools.forEach((tool, index) => {\n const item = document.createElement(\"div\");\n item.className = \"tasks__tool-item\";\n\n const header = document.createElement(\"div\");\n header.className = \"tasks__tool-header\";\n\n const title = document.createElement(\"div\");\n title.className = \"tasks__tool-title\";\n title.textContent = `Tool ${index + 1}`;\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.type = \"button\";\n removeBtn.className = \"tasks__tool-remove-btn\";\n removeBtn.textContent = \"Remove\";\n removeBtn.addEventListener(\"click\", () => {\n this.editingTools.splice(index, 1);\n this.renderToolsEditor();\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n header.appendChild(title);\n header.appendChild(removeBtn);\n\n const nameInput = document.createElement(\"input\");\n nameInput.type = \"text\";\n nameInput.className = \"tasks__form-input\";\n nameInput.placeholder = \"Tool Name (e.g. show_toast)\";\n nameInput.value = tool.name || \"\";\n nameInput.addEventListener(\"input\", (e) => {\n tool.name = (e.target as HTMLInputElement).value;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n const paramsInput = document.createElement(\"textarea\");\n paramsInput.className = \"tasks__form-textarea\";\n paramsInput.placeholder = '{\\n \"key\": \"value\"\\n}';\n try {\n paramsInput.value =\n tool.input && Object.keys(tool.input).length\n ? JSON.stringify(tool.input, null, 2)\n : \"\";\n } catch (e) {\n paramsInput.value = \"\";\n }\n\n paramsInput.addEventListener(\"change\", (e) => {\n const val = (e.target as HTMLTextAreaElement).value;\n if (!val.trim()) {\n tool.input = {};\n } else {\n try {\n tool.input = JSON.parse(val);\n (e.target as HTMLTextAreaElement).style.borderColor = \"\";\n } catch (err) {\n (e.target as HTMLTextAreaElement).style.borderColor =\n \"var(--shadow-claw-error-color)\";\n }\n }\n\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n const suppressLabel = document.createElement(\"label\");\n suppressLabel.className = \"tasks__tool-suppress\";\n\n const suppressInput = document.createElement(\"input\");\n suppressInput.type = \"checkbox\";\n suppressInput.checked = !!tool.suppressOutput;\n suppressInput.addEventListener(\"change\", (e) => {\n tool.suppressOutput = (e.target as HTMLInputElement).checked;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n suppressLabel.appendChild(suppressInput);\n suppressLabel.appendChild(document.createTextNode(\" Suppress Output\"));\n\n const suppressToastLabel = document.createElement(\"label\");\n suppressToastLabel.className = \"tasks__tool-suppress\";\n\n const suppressToastInput = document.createElement(\"input\");\n suppressToastInput.type = \"checkbox\";\n suppressToastInput.checked = !!tool.suppressToast;\n suppressToastInput.addEventListener(\"change\", (e) => {\n tool.suppressToast = (e.target as HTMLInputElement).checked;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n suppressToastLabel.appendChild(suppressToastInput);\n suppressToastLabel.appendChild(\n document.createTextNode(\" Suppress Toast\"),\n );\n\n item.appendChild(header);\n item.appendChild(nameInput);\n item.appendChild(paramsInput);\n item.appendChild(suppressLabel);\n item.appendChild(suppressToastLabel);\n list.appendChild(item);\n });\n }\n\n renderToolsPreview(tools: any[], allowCollapse = false) {\n if (!tools || tools.length === 0) {\n return '<span class=\"tasks__preview-empty\">No tools configured</span>';\n }\n\n const html = tools\n .map((t, i) => {\n let params = \"{}\";\n try {\n params = JSON.stringify(t.input, null, 2);\n } catch (e) {\n params = \"Invalid JSON\";\n }\n\n return `<div><strong>${i + 1}. ${escapeHtml(t.name || \"Unnamed Tool\")}</strong><pre><code>${escapeHtml(params)}</code></pre></div>`;\n })\n .join(\"\");\n\n if (allowCollapse && tools.length > 2) {\n return `\n <details class=\"tasks__content-details\">\n <summary class=\"tasks__content-summary\">\n <span class=\"tasks__summary-text\">${tools.length} Tools configured</span>\n <span class=\"tasks__summary-label\">(View more)</span>\n </summary>\n <div class=\"tasks__prompt\">${html}</div>\n </details>\n `;\n }\n\n return `<div class=\"tasks__prompt\">${html}</div>`;\n }\n\n resolveWorkspaceLinkPath(href: string): string | null {\n const trimmed = href.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n return null;\n }\n\n let candidate = trimmed;\n const hasScheme = /^[a-zA-Z][a-zA-Z\\d+.-]*:/.test(trimmed);\n\n if (hasScheme || trimmed.startsWith(\"//\")) {\n let parsed: URL;\n try {\n parsed = new URL(trimmed, window.location.href);\n } catch {\n return null;\n }\n\n const isHttp =\n parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n if (!isHttp || parsed.host !== window.location.host) {\n return null;\n }\n\n candidate = `${parsed.pathname}${parsed.search}${parsed.hash}`;\n }\n\n let normalized = candidate.split(/[?#]/, 1)[0].replace(/\\\\/g, \"/\");\n normalized = normalized.replace(/^\\/+/, \"\");\n normalized = normalized.replace(/^\\.\\//, \"\");\n\n if (!normalized) {\n return null;\n }\n\n const parts = normalized\n .split(\"/\")\n .filter(Boolean)\n .map((part) => decodePathSegment(part));\n if (parts.some((part) => part === \"..\")) {\n return null;\n }\n\n return parts.join(\"/\");\n }\n\n /**\n * Handle backup (download all tasks as JSON)\n */\n async handleBackup() {\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__backup-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n const tasks = orchestratorStore.getTasksForBackup();\n const json = JSON.stringify(tasks, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `shadowclaw-tasks-backup-${Date.now()}.json`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to create backup: ${message}`);\n console.error(\"Backup error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__backup-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"💾 Backup\";\n }\n }\n }\n\n /**\n * Handle clear all (delete all tasks)\n */\n async handleClearAll(db: ShadowClawDatabase) {\n const confirmed = await this.requestConfirmation({\n title: \"Clear All Tasks\",\n message: \"Delete ALL tasks? This cannot be undone!\",\n confirmLabel: \"Delete All\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__clear-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n await orchestratorStore.clearAllTasks(db);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to clear tasks: ${message}`);\n console.error(\"Clear error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__clear-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"🗑️ Clear All\";\n }\n }\n }\n\n /**\n * Copy a task's ID to the clipboard\n */\n async handleCopyId(id: string) {\n try {\n await navigator.clipboard.writeText(id);\n showSuccess(\"Task ID copied to clipboard!\");\n } catch (err) {\n showError(\"Failed to copy task ID.\");\n }\n }\n\n /**\n * Delete a task\n */\n async handleDelete(db: ShadowClawDatabase, id: string) {\n const confirmed = await this.requestConfirmation({\n title: \"Delete Scheduled Task\",\n message: \"Are you sure you want to delete this scheduled task?\",\n confirmLabel: \"Delete\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.deleteTask(db, id);\n } catch (err) {\n console.error(\"Failed to delete task:\", err);\n }\n }\n\n async handleEditSubmit(db: ShadowClawDatabase, form: HTMLFormElement) {\n const formData = new FormData(form);\n const name = formData.get(\"name\");\n const schedule = formData.get(\"schedule\");\n const prompt = formData.get(\"prompt\");\n const type = (formData.get(\"taskType\") as \"prompt\" | \"tools\") || \"prompt\";\n\n const nameStr = name ? String(name).trim() : \"\";\n const scheduleStr = schedule ? String(schedule).trim() : \"\";\n\n if (type === \"prompt\" && !prompt) {\n showInfo(\"Please provide a task prompt.\");\n\n return;\n }\n\n const freshContext = !!formData.get(\"freshContext\");\n const subagent = !!formData.get(\"subagent\");\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n const pushNotifications =\n pushInput instanceof HTMLInputElement\n ? !pushInput.disabled && pushInput.checked\n : false;\n\n try {\n let taskToSave;\n\n if (this.editingTask) {\n // Update existing task\n taskToSave = {\n ...this.editingTask,\n name: nameStr || undefined,\n schedule: scheduleStr,\n type,\n prompt: String(prompt || \"\"),\n tools: JSON.parse(JSON.stringify(this.editingTools)),\n freshContext,\n subagent,\n pushNotifications,\n };\n } else {\n // Create new task\n const currentGroupId = orchestratorStore.activeGroupId;\n taskToSave = {\n id: crypto.randomUUID\n ? crypto.randomUUID()\n : `task-${Date.now()}-${Math.random()}`,\n groupId: currentGroupId,\n name: nameStr || undefined,\n schedule: scheduleStr,\n type,\n prompt: String(prompt || \"\"),\n tools: JSON.parse(JSON.stringify(this.editingTools)),\n enabled: true,\n lastRun: null,\n createdAt: Date.now(),\n freshContext,\n subagent,\n pushNotifications,\n };\n }\n\n await orchestratorStore.upsertTask(db, taskToSave);\n\n const root = this.shadowRoot;\n const dialog = root?.querySelector(\"dialog\");\n dialog?.close();\n\n this.editingTask = null;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to save task: ${message}`);\n console.error(\"Save error:\", err);\n }\n }\n\n async handlePreviewLinkClick(event: MouseEvent, db: ShadowClawDatabase) {\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 const target = event.target;\n if (!(target instanceof Element)) {\n return;\n }\n\n const link = target.closest(\"a\");\n if (!(link instanceof HTMLAnchorElement)) {\n return;\n }\n\n const href = link.getAttribute(\"href\") || \"\";\n const resolved = this.resolveWorkspaceLinkPath(href);\n if (!resolved) {\n return;\n }\n\n event.preventDefault();\n\n const attempts = [resolved];\n const lastSegment = resolved.split(\"/\").filter(Boolean).pop() || \"\";\n const hasExtension = /\\.[^./]+$/u.test(lastSegment);\n\n if (!hasExtension) {\n attempts.push(`${resolved}.md`, `${resolved}/index.md`);\n }\n\n for (const candidate of attempts) {\n try {\n await fileViewerStore.openFile(\n db,\n candidate,\n orchestratorStore.activeGroupId,\n );\n\n return;\n } catch {\n // Try next candidate path.\n }\n }\n\n showError(`Failed to open linked file: ${resolved}`, 5000);\n }\n\n async handleReorder(\n draggedId: string,\n targetId: string,\n precomputedIds?: string[],\n ) {\n const db = await getDb();\n if (!db) {\n return;\n }\n\n if (precomputedIds) {\n await orchestratorStore.reorderTasks(\n db,\n orchestratorStore.activeGroupId,\n precomputedIds,\n );\n return;\n }\n\n const tasks = orchestratorStore.tasks || [];\n const ids = tasks.map((t) => t.id);\n const fromIdx = ids.indexOf(draggedId);\n const toIdx = ids.indexOf(targetId);\n\n if (fromIdx < 0 || toIdx < 0) {\n return;\n }\n\n ids.splice(fromIdx, 1);\n ids.splice(toIdx, 0, draggedId);\n\n await orchestratorStore.reorderTasks(\n db,\n orchestratorStore.activeGroupId,\n ids,\n );\n }\n\n /**\n * Handle restore (upload and import JSON)\n */\n async handleRestore(db: ShadowClawDatabase, input: HTMLInputElement) {\n const files = input.files;\n if (!files || files.length === 0) {\n return;\n }\n\n const jsonFile = files[0];\n if (!jsonFile.name.endsWith(\".json\")) {\n showInfo(\"Please select a .json file\");\n\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Restore Tasks\",\n message: \"Restore from backup will replace all current tasks. Continue?\",\n confirmLabel: \"Restore\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n input.value = \"\";\n\n return;\n }\n\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__restore-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n const text = await jsonFile.text();\n const tasks = JSON.parse(text);\n\n if (!Array.isArray(tasks)) {\n throw new Error(\"Invalid backup file format\");\n }\n\n await orchestratorStore.restoreTasksFromBackup(db, tasks);\n input.value = \"\";\n showSuccess(\"Tasks restored successfully!\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to restore from backup: ${message}`);\n console.error(\"Restore error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__restore-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"♻️ Restore\";\n }\n }\n }\n\n async renderPreview(prompt: string, allowCollapse = false) {\n if (!prompt.trim()) {\n return '<span class=\"tasks__preview-empty\">No content</span>';\n }\n\n const lines = prompt.split(\"\\n\");\n const isLong = prompt.length > 120 || lines.length > 1;\n\n const rendered = await renderMarkdown(prompt, {\n breaks: true,\n renderFrontmatter: this.renderFrontmatter,\n });\n\n if (allowCollapse && isLong) {\n const summaryText = prompt.trim();\n\n return `\n <details class=\"tasks__content-details\">\n <summary class=\"tasks__content-summary\">\n <span class=\"tasks__summary-text\">${escapeHtml(summaryText)}</span>\n <span class=\"tasks__summary-label\">(View more)</span>\n </summary>\n <div class=\"tasks__prompt\">${rendered}</div>\n </details>\n `;\n }\n\n return `<div class=\"tasks__prompt\">${rendered}</div>`;\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showInfo(options.message, 4000);\n\n return false;\n }\n\n /**\n * Update the disabled/checked state of the push notifications checkbox\n */\n async updatePushNotificationsCheckboxState(\n preserveCheckedIfEnabled?: boolean,\n ): Promise<void> {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const pushInput = root.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (!pushInput) {\n return;\n }\n\n const scheduleInput = root.querySelector(\n \"input[name='schedule']\",\n ) as HTMLInputElement | null;\n const scheduleVal = scheduleInput?.value.trim() ?? \"\";\n\n let hasSubscription = false;\n try {\n const sub = await getCurrentSubscription();\n hasSubscription = !!sub;\n } catch {\n hasSubscription = false;\n }\n\n const canEnablePush =\n scheduleVal.length > 0 &&\n orchestratorStore.taskServerEnabled &&\n hasSubscription;\n\n pushInput.disabled = !canEnablePush;\n if (!canEnablePush) {\n pushInput.checked = false;\n } else if (preserveCheckedIfEnabled !== undefined) {\n pushInput.checked = preserveCheckedIfEnabled;\n }\n }\n\n async updateTaskList(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tasks__list\");\n if (!list) {\n return;\n }\n\n const tasks = orchestratorStore.tasks;\n\n if (tasks.length === 0) {\n setSanitizedHtml(\n list,\n `<shadow-claw-empty-state\n class=\"tasks__empty\"\n message=\"No scheduled tasks for this group.\"\n hint=\"Ask the agent to create one using 'create_task'.\"\n ></shadow-claw-empty-state>`,\n );\n\n return;\n }\n\n // Capture render content first to avoid partially cleared list while awaiting\n const fragment = document.createDocumentFragment();\n\n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i];\n const item = document.createElement(\"div\");\n item.className = \"tasks__item\";\n item.setAttribute(\"role\", \"listitem\");\n item.setAttribute(\"tabindex\", \"0\");\n item.setAttribute(\"aria-describedby\", \"reorder-instructions\");\n item.setAttribute(\n \"aria-label\",\n `${task.name || \"Task\"}, position ${i + 1} of ${tasks.length}`,\n );\n item.setAttribute(\"data-task-id\", task.id);\n\n if (this._keyboardGrabbedId === task.id) {\n item.classList.add(\"keyboard-grabbed\");\n item.setAttribute(\"aria-grabbed\", \"true\");\n }\n\n const lastRunStr = task.lastRun\n ? new Date(task.lastRun).toLocaleString()\n : \"Never\";\n\n const isTools = task.type === \"tools\";\n const previewHtml = isTools\n ? this.renderToolsPreview(task.tools || [], true)\n : await this.renderPreview(task.prompt, true);\n\n const scheduleDisplay = task.schedule\n ? `⏰ ${escapeHtml(task.schedule)}`\n : \"⏸ Unscheduled\";\n const toggleHtml = task.schedule\n ? `\n <label class=\"tasks__toggle\">\n <input type=\"checkbox\" ${task.enabled ? \"checked\" : \"\"} data-id=\"${escapeHtml(task.id)}\" class=\"tasks__toggle-input\" aria-label=\"${task.enabled ? \"Disable\" : \"Enable\"} task scheduled ${escapeHtml(task.schedule)}\">\n ${task.enabled ? \"Enabled\" : \"Disabled\"}\n </label>`\n : \"\";\n\n const badges = [isTools ? \"Tools\" : \"Prompt\"];\n if (task.freshContext) {\n badges.push(\"Fresh Context\");\n }\n if (task.subagent) {\n badges.push(\"Subagent\");\n }\n if (task.pushNotifications) {\n badges.push(\"Push\");\n }\n const badgesDisplay = badges.join(\" · \");\n\n const nameHtml = task.name\n ? `<div class=\"tasks__name\" style=\"font-weight: 600; font-size: var(--shadow-claw-font-size-md); margin-bottom: 0.25rem;\">${escapeHtml(task.name)}</div>`\n : \"\";\n\n const dragHandleHtml = `<span class=\"tasks__drag-handle\" draggable=\"true\" aria-hidden=\"true\" title=\"Drag to reorder\">⠿</span>`;\n\n setSanitizedHtml(\n item,\n `<div class=\"tasks__item-header\">\n <div style=\"display: flex; align-items: flex-start; flex: 1; min-width: 0;\">\n ${dragHandleHtml}\n <div class=\"tasks__item-info\">\n ${nameHtml}\n <div class=\"tasks__schedule-row\">\n <div class=\"tasks__schedule\">${scheduleDisplay} <span class=\"tasks__type-badge\">(${escapeHtml(badgesDisplay)})</span></div>\n </div>\n <div class=\"tasks__prompt-container\">\n ${previewHtml}\n </div>\n <div class=\"tasks__last-run\">Last run: ${escapeHtml(lastRunStr)}</div>\n </div>\n </div>\n <div class=\"tasks__actions\">\n ${toggleHtml}\n <button type=\"button\" class=\"tasks__copy-id-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Copy task ID\" title=\"Copy task ID\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" width=\"1em\" viewBox=\"0 -960 960 960\" fill=\"currentColor\" aria-hidden=\"true\" style=\"vertical-align: middle; margin-right: 0.125rem; margin-top: -0.125rem;\"><path d=\"M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z\"/></svg> Copy ID\n </button>\n <button type=\"button\" class=\"tasks__run-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Run task\">Run</button>\n <button type=\"button\" class=\"tasks__edit-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Edit task\">✎ Edit</button>\n <button type=\"button\" class=\"tasks__delete-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Delete task\">Delete</button>\n </div>\n </div>`,\n );\n\n // Bind events\n const toggle = item.querySelector(\n \".tasks__toggle-input\",\n ) as HTMLInputElement | null;\n\n toggle?.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLInputElement;\n orchestratorStore.toggleTask(db, task, target.checked);\n });\n\n const copyIdBtn = item.querySelector(\".tasks__copy-id-btn\");\n copyIdBtn?.addEventListener(\"click\", () => this.handleCopyId(task.id));\n\n const runBtn = item.querySelector(\".tasks__run-btn\");\n runBtn?.addEventListener(\"click\", () => this.handleRun(task));\n\n const editBtn = item.querySelector(\".tasks__edit-btn\");\n editBtn?.addEventListener(\"click\", () => this.handleEdit(task));\n\n const deleteBtn = item.querySelector(\".tasks__delete-btn\");\n deleteBtn?.addEventListener(\"click\", () =>\n this.handleDelete(db, task.id),\n );\n\n const handleEl = item.querySelector(\n \".tasks__drag-handle\",\n ) as HTMLElement | null;\n\n handleEl?.addEventListener(\"dragstart\", (e) => {\n this._draggedTaskId = task.id;\n item.classList.add(\"dragging\");\n e.dataTransfer?.setData(\"text/plain\", task.id);\n });\n\n handleEl?.addEventListener(\"dragend\", () => {\n item.classList.remove(\"dragging\");\n this._draggedTaskId = null;\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n });\n\n handleEl?.addEventListener(\n \"touchstart\",\n (e) => {\n const touch = e.touches[0];\n if (!touch) {\n return;\n }\n this._touchId = touch.identifier;\n this._touchDraggedTaskId = task.id;\n item.classList.add(\"dragging\");\n e.preventDefault();\n },\n { passive: false },\n );\n\n item.addEventListener(\"dragover\", (e) => {\n e.preventDefault();\n if (this._draggedTaskId && this._draggedTaskId !== task.id) {\n item.classList.add(\"drag-over\");\n }\n });\n\n item.addEventListener(\"dragleave\", () => {\n item.classList.remove(\"drag-over\");\n });\n\n item.addEventListener(\"drop\", (e) => {\n e.preventDefault();\n item.classList.remove(\"drag-over\");\n if (this._draggedTaskId && this._draggedTaskId !== task.id) {\n this.handleReorder(this._draggedTaskId, task.id);\n }\n });\n\n item.addEventListener(\"keydown\", (e) => {\n this._handleKeyboard(e, task.id, task.name || \"Task\");\n });\n\n fragment.appendChild(item);\n }\n\n list.replaceChildren();\n list.appendChild(fragment);\n\n this._bindTouchListEvents(list);\n }\n\n _announce(message: string) {\n const region = this.shadowRoot?.querySelector(\"#live-region\");\n if (region) {\n region.textContent = \"\";\n requestAnimationFrame(() => {\n region.textContent = message;\n });\n }\n }\n\n _bindTouchListEvents(list: Element) {\n if ((list as any)._touchBound) {\n return;\n }\n (list as any)._touchBound = true;\n\n list.addEventListener(\n \"touchmove\",\n (e) => {\n if (this._touchDraggedTaskId === null) {\n return;\n }\n\n const touch = this._findTouch(e as TouchEvent);\n if (!touch) {\n return;\n }\n\n e.preventDefault();\n\n const target = this._itemAtPoint(touch.clientX, touch.clientY);\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n\n if (\n target &&\n target.getAttribute(\"data-task-id\") !== this._touchDraggedTaskId\n ) {\n target.classList.add(\"drag-over\");\n }\n\n this._updateAutoScrollSpeed(touch.clientY);\n },\n { passive: false },\n );\n\n list.addEventListener(\"touchend\", (e) => {\n if (this._touchDraggedTaskId === null) {\n return;\n }\n\n const touch = this._findChangedTouch(e as TouchEvent);\n if (!touch) {\n return;\n }\n\n const target = this._itemAtPoint(touch.clientX, touch.clientY);\n const targetId = target?.getAttribute(\"data-task-id\");\n\n list\n .querySelectorAll(\".dragging\")\n .forEach((el) => el.classList.remove(\"dragging\"));\n\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n\n if (targetId && targetId !== this._touchDraggedTaskId) {\n this.handleReorder(this._touchDraggedTaskId, targetId);\n }\n\n this._stopAutoScroll();\n this._touchDraggedTaskId = null;\n this._touchId = null;\n });\n\n list.addEventListener(\"touchcancel\", () => {\n list\n .querySelectorAll(\".dragging\")\n .forEach((el) => el.classList.remove(\"dragging\"));\n\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n this._stopAutoScroll();\n this._touchDraggedTaskId = null;\n this._touchId = null;\n });\n }\n\n _findChangedTouch(e: TouchEvent): Touch | undefined {\n for (let i = 0; i < e.changedTouches.length; i++) {\n const t = e.changedTouches[i];\n if (t.identifier === this._touchId) {\n return t;\n }\n }\n }\n\n _findTouch(e: TouchEvent): Touch | undefined {\n for (let i = 0; i < e.touches.length; i++) {\n const t = e.touches[i];\n if (t.identifier === this._touchId) {\n return t;\n }\n }\n }\n\n _focusNext(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const focusables = Array.from(\n root.querySelectorAll(\n '.tasks__item[tabindex=\"0\"], button:not([disabled]), input:not([type=\"hidden\"]):not([disabled])',\n ),\n ) as HTMLElement[];\n const idx = focusables.indexOf(current);\n if (idx !== -1 && idx < focusables.length - 1) {\n focusables[idx + 1].focus();\n }\n }\n\n _focusNextItem(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const items = Array.from(\n root.querySelectorAll(\".tasks__item\"),\n ) as HTMLElement[];\n const currentItem = current.closest(\".tasks__item\") as HTMLElement;\n const idx = items.indexOf(currentItem);\n if (idx !== -1 && idx < items.length - 1) {\n items[idx + 1].focus();\n }\n }\n\n _focusPrev(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const focusables = Array.from(\n root.querySelectorAll(\n '.tasks__item[tabindex=\"0\"], button:not([disabled]), input:not([type=\"hidden\"]):not([disabled])',\n ),\n ) as HTMLElement[];\n const idx = focusables.indexOf(current);\n if (idx > 0) {\n focusables[idx - 1].focus();\n }\n }\n\n _focusPrevItem(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const items = Array.from(\n root.querySelectorAll(\".tasks__item\"),\n ) as HTMLElement[];\n const currentItem = current.closest(\".tasks__item\") as HTMLElement;\n const idx = items.indexOf(currentItem);\n if (idx > 0) {\n items[idx - 1].focus();\n }\n }\n\n _handleKeyboard(e: KeyboardEvent, taskId: string, name: string) {\n const tasks = orchestratorStore.tasks || [];\n const ids = tasks.map((t) => t.id);\n const total = ids.length;\n\n if (this._keyboardGrabbedId === null) {\n // Navigation & Selection\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n this._focusNextItem(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n this._focusPrevItem(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n this._focusNext(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n this._focusPrev(e.target as HTMLElement);\n return;\n }\n\n // Grab for reorder\n if (e.key === \"m\" || e.key === \"M\") {\n e.preventDefault();\n this._keyboardGrabbedId = taskId;\n const pos = ids.indexOf(taskId) + 1;\n this._announce(\n `${name} grabbed. Current position ${pos} of ${total}. Use Arrow Up and Down to move, Space or Enter to drop.`,\n );\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n }\n\n return;\n }\n\n // Currently grabbed\n if (e.key === \"Escape\") {\n e.preventDefault();\n this._announce(\n `Reorder cancelled. ${name} returned to original position.`,\n );\n this._keyboardGrabbedId = null;\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n return;\n }\n\n if (e.key === \" \" || e.key === \"Spacebar\" || e.key === \"Enter\") {\n // Drop\n e.preventDefault();\n const pos = ids.indexOf(this._keyboardGrabbedId) + 1;\n const droppedName =\n tasks.find((t) => t.id === this._keyboardGrabbedId)?.name || \"Task\";\n this._announce(\n `${droppedName} dropped at position ${pos} of ${total}. Reordering complete.`,\n );\n this._keyboardGrabbedId = null;\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n return;\n }\n\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n const currentIdx = ids.indexOf(this._keyboardGrabbedId);\n const newIdx = e.key === \"ArrowUp\" ? currentIdx - 1 : currentIdx + 1;\n if (newIdx < 0 || newIdx >= total) {\n return;\n }\n\n // Swap\n ids.splice(currentIdx, 1);\n ids.splice(newIdx, 0, this._keyboardGrabbedId);\n this._announce(`Moved to position ${newIdx + 1} of ${total}.`);\n this.handleReorder(this._keyboardGrabbedId, ids[currentIdx], ids);\n }\n }\n\n _itemAtPoint(x: number, y: number): Element | null {\n const root = this.shadowRoot;\n if (!root) {\n return null;\n }\n\n const el = root.elementFromPoint(x, y);\n return el?.closest?.(\".tasks__item\") || null;\n }\n\n _startAutoScroll() {\n if (this._autoScrollActive) {\n return;\n }\n this._autoScrollActive = true;\n\n const scrollLoop = () => {\n if (!this._autoScrollActive) {\n return;\n }\n\n const root = this.shadowRoot;\n const content = root?.querySelector(\n \".tasks__content\",\n ) as HTMLElement | null;\n if (content && this._autoScrollSpeed !== 0) {\n content.scrollTop += this._autoScrollSpeed;\n }\n\n requestAnimationFrame(scrollLoop);\n };\n\n requestAnimationFrame(scrollLoop);\n }\n\n _stopAutoScroll() {\n this._autoScrollActive = false;\n this._autoScrollSpeed = 0;\n }\n\n _updateAutoScrollSpeed(clientY: number) {\n const root = this.shadowRoot;\n const content = root?.querySelector(\n \".tasks__content\",\n ) as HTMLElement | null;\n if (!content) {\n this._autoScrollSpeed = 0;\n return;\n }\n\n const rect = content.getBoundingClientRect();\n const threshold = 50; // pixels from top/bottom to start scrolling\n\n const distTop = clientY - rect.top;\n const distBottom = rect.bottom - clientY;\n\n if (distTop >= 0 && distTop < threshold) {\n // Near the top: scroll up. Speed is faster the closer to the edge.\n this._autoScrollSpeed = -((threshold - distTop) / threshold) * 8;\n this._startAutoScroll();\n } else if (distBottom >= 0 && distBottom < threshold) {\n // Near the bottom: scroll down.\n this._autoScrollSpeed = ((threshold - distBottom) / threshold) * 8;\n this._startAutoScroll();\n } else {\n this._autoScrollSpeed = 0;\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTasks);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadow-claw-tasks-Bg0uM15I.js","names":["shadowClawTasksStyles","shadowClawTasksTemplate"],"sources":["../../src/components/shadow-claw-tasks/shadow-claw-tasks.ts"],"sourcesContent":["import { renderMarkdown } from \"../../content/markdown.js\";\nimport { CONFIG_KEYS } from \"../../config/config.js\";\nimport { effect } from \"../../core/effect.js\";\nimport { decodePathSegment } from \"../../core/app-routes.js\";\n\nimport { getDb, ShadowClawDatabase } from \"../../db/db.js\";\nimport { getConfig } from \"../../db/get-config.js\";\nimport { Task } from \"../../db/types.js\";\n\nimport { setSanitizedHtml } from \"../../security/trusted-types.js\";\nimport { fileViewerStore } from \"../../stores/file-viewer.js\";\nimport { orchestratorStore } from \"../../stores/orchestrator.js\";\nimport { getCurrentSubscription } from \"../../subsystems/notifications/push-client.js\";\n\nimport { showError, showInfo, showSuccess } from \"../../ui/toast.js\";\nimport { isTruthyConfigValue } from \"../../utils/parse-boolean-config.js\";\nimport { escapeHtml } from \"../../utils/html.js\";\n\nimport \"../common/shadow-claw-empty-state/shadow-claw-empty-state.js\";\nimport \"../common/shadow-claw-page-header-action-button/shadow-claw-page-header-action-button.js\";\nimport \"../shadow-claw-dialog/shadow-claw-dialog.js\";\nimport \"../shadow-claw-page-header/shadow-claw-page-header.js\";\n\nimport ShadowClawElement from \"../shadow-claw-element.js\";\nimport shadowClawTasksStyles from \"./shadow-claw-tasks.css\" with { type: \"css\" };\nimport shadowClawTasksTemplate from \"./shadow-claw-tasks.html\" with { type: \"html\" };\n\nconst elementName = \"shadow-claw-tasks\";\n\nasync function resolveFrontmatterToggle(\n db: ShadowClawDatabase | null,\n key: string,\n): Promise<boolean> {\n if (!db || typeof (db as any).transaction !== \"function\") {\n return true;\n }\n\n try {\n return isTruthyConfigValue(await getConfig(db, key), true);\n } catch {\n return true;\n }\n}\n\nexport class ShadowClawTasks extends ShadowClawElement {\n static styles = shadowClawTasksStyles;\n static template = shadowClawTasksTemplate;\n\n editingTask: any | null = null;\n editingTools: any[] = [];\n renderFrontmatter = true;\n tasks: any[] = [];\n private _autoScrollActive = false;\n private _autoScrollSpeed = 0;\n\n private _draggedTaskId: string | null = null;\n private _keyboardGrabbedId: string | null = null;\n private _touchDraggedTaskId: string | null = null;\n private _touchId: number | null = null;\n\n constructor() {\n super();\n }\n\n async connectedCallback() {\n const root = this.shadowRoot;\n if (!root) {\n throw new Error(\"shadowRoot not found\");\n }\n\n root.addEventListener(\"click\", (event: Event) => {\n if (event instanceof MouseEvent) {\n getDb()\n .then((db) => this.handlePreviewLinkClick(event, db))\n .catch(console.error);\n }\n });\n\n // Backup button\n const backupBtn = root.querySelector(\".tasks__backup-btn\");\n backupBtn?.addEventListener(\"click\", () => this.handleBackup());\n\n // Restore button\n const restoreBtn = root.querySelector(\".tasks__restore-btn\");\n const restoreInput = root.querySelector(\".tasks__hidden-restore\");\n restoreBtn?.addEventListener(\"click\", () => {\n if (restoreInput instanceof HTMLInputElement) {\n restoreInput.click();\n }\n });\n\n restoreInput?.addEventListener(\"change\", (e) => {\n if (e.target instanceof HTMLInputElement) {\n const target = e.target;\n getDb()\n .then((db) => this.handleRestore(db, target))\n .catch(console.error);\n }\n });\n\n // Clear all button\n const clearBtn = root.querySelector(\".tasks__clear-btn\");\n clearBtn?.addEventListener(\"click\", () => {\n getDb()\n .then((db) => this.handleClearAll(db))\n .catch(console.error);\n });\n\n // Add task button\n const addBtn = root.querySelector(\".tasks__add-btn\");\n addBtn?.addEventListener(\"click\", () => this.handleAdd());\n\n // Dialog controls\n const dialog = root.querySelector(\"dialog\");\n const closeBtn = root.querySelector(\".tasks__dialog-close\");\n const cancelBtn = root.querySelector(\".tasks__btn-cancel\");\n const form = root.querySelector(\n \".tasks__dialog-form\",\n ) as HTMLFormElement | null;\n\n closeBtn?.addEventListener(\"click\", () => {\n dialog?.close();\n });\n\n cancelBtn?.addEventListener(\"click\", () => {\n dialog?.close();\n });\n\n form?.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n if (form) {\n getDb()\n .then((db) => this.handleEditSubmit(db, form))\n .catch(console.error);\n }\n });\n\n // Close dialog when clicking outside (on backdrop)\n dialog?.addEventListener(\"click\", (e) => {\n if (e.target === dialog) {\n dialog.close();\n }\n });\n\n // Preview update logic\n const promptTextarea = root.querySelector(\"textarea[name='prompt']\");\n const previewDiv = root.querySelector(\".tasks__preview\");\n const typeRadios = root.querySelectorAll(\"input[name='taskType']\");\n const promptGroup = root.querySelector(\".tasks__prompt-group\");\n const toolsGroup = root.querySelector(\".tasks__tools-group\");\n const addToolBtn = root.querySelector(\".tasks__add-tool-btn\");\n\n const updatePreview = async () => {\n if (previewDiv instanceof HTMLElement) {\n const type =\n Array.from(typeRadios)\n .find((r: any) => r.checked)\n ?.getAttribute(\"value\") || \"prompt\";\n if (type === \"tools\") {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n } else if (promptTextarea instanceof HTMLTextAreaElement) {\n setSanitizedHtml(\n previewDiv,\n await this.renderPreview(promptTextarea.value),\n );\n }\n }\n };\n\n promptTextarea?.addEventListener(\"input\", updatePreview);\n\n const scheduleInput = root.querySelector(\"input[name='schedule']\");\n scheduleInput?.addEventListener(\"input\", () => {\n this.updatePushNotificationsCheckboxState();\n });\n\n typeRadios.forEach((radio) => {\n radio.addEventListener(\"change\", (e) => {\n const val = (e.target as HTMLInputElement).value;\n if (val === \"tools\") {\n promptGroup?.setAttribute(\"style\", \"display: none;\");\n toolsGroup?.removeAttribute(\"style\");\n promptTextarea?.removeAttribute(\"required\");\n } else {\n toolsGroup?.setAttribute(\"style\", \"display: none;\");\n promptGroup?.removeAttribute(\"style\");\n }\n\n updatePreview();\n });\n });\n\n addToolBtn?.addEventListener(\"click\", () => {\n this.editingTools.push({ name: \"\", input: {} });\n this.renderToolsEditor();\n updatePreview();\n });\n\n const db = await getDb();\n this.renderFrontmatter = await resolveFrontmatterToggle(\n db,\n CONFIG_KEYS.MARKDOWN_FRONTMATTER_TASKS,\n );\n\n // apply highlight.js atom-one-dark.min.css to shadow dom\n try {\n const cssText = await (\n await fetch(\n \"https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/atom-one-dark.min.css\",\n )\n ).text();\n\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n\n if (this.shadowRoot?.adoptedStyleSheets) {\n this.shadowRoot.adoptedStyleSheets.push(sheet);\n }\n } catch (err) {\n console.warn(\"Failed to load highlight.js styles:\", err);\n }\n\n // Global dragover auto-scroll listener on shadowRoot\n root.addEventListener(\"dragover\", (e: any) => {\n if (this._draggedTaskId !== null) {\n this._updateAutoScrollSpeed(e.clientY);\n }\n });\n\n // Ensure we stop scrolling if the drag ends or leaves\n root.addEventListener(\"dragend\", () => {\n this._stopAutoScroll();\n });\n root.addEventListener(\"drop\", () => {\n this._stopAutoScroll();\n });\n\n this.render();\n this.dispatchTerminalSlotReady();\n\n // Re-render when tasks change\n this.cleanup = effect(() => {\n orchestratorStore.tasks;\n this.updateTaskList(db);\n });\n }\n\n disconnectedCallback() {\n this.cleanup();\n }\n\n cleanup: () => void = () => {};\n\n dispatchTerminalSlotReady() {\n this.dispatchEvent(\n new CustomEvent(\"shadow-claw-terminal-slot-ready\", {\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n /**\n * Escape HTML special characters\n */\n escapeHtml(text: string) {\n const div = document.createElement(\"div\");\n div.textContent = text;\n\n return div.innerHTML;\n }\n\n /**\n * Open dialog to add a new task\n */\n handleAdd() {\n this.editingTask = null;\n this.editingTools = [];\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const dialog = root.querySelector(\"dialog\");\n const form = root.querySelector(\".tasks__dialog-form\");\n const title = root.querySelector(\".tasks__dialog-title\");\n const submitBtn = root.querySelector(\".tasks__dialog-submit\");\n\n if (!form || !(form instanceof HTMLFormElement)) {\n return;\n }\n\n // Update dialog for add mode\n if (title) {\n title.textContent = \"Add Task\";\n }\n\n if (submitBtn) {\n submitBtn.textContent = \"Add Task\";\n }\n\n // Clear form\n form.reset();\n\n const nameInput = form.querySelector(\"input[name='name']\");\n if (nameInput instanceof HTMLInputElement) {\n nameInput.value = \"\";\n }\n\n // Reset type toggle\n const promptRadio = form.querySelector(\n \"input[name='taskType'][value='prompt']\",\n ) as HTMLInputElement;\n if (promptRadio) {\n promptRadio.checked = true;\n promptRadio.dispatchEvent(new Event(\"change\"));\n }\n\n this.renderToolsEditor();\n\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (pushInput) {\n pushInput.checked = false;\n }\n this.updatePushNotificationsCheckboxState(false);\n\n // Reset preview\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv instanceof HTMLElement) {\n this.renderPreview(\"\", false).then((html) => {\n setSanitizedHtml(previewDiv, html);\n });\n }\n\n // Show dialog\n dialog?.showModal();\n }\n\n /**\n * Open edit dialog for a task\n */\n handleEdit(task: Task) {\n this.editingTask = task;\n this.editingTools = JSON.parse(JSON.stringify(task.tools || []));\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const dialog = root.querySelector(\"dialog\");\n const form = root.querySelector(\".tasks__dialog-form\");\n const title = root.querySelector(\".tasks__dialog-title\");\n const submitBtn = root.querySelector(\".tasks__dialog-submit\");\n\n if (!form || !(form instanceof HTMLFormElement)) {\n return;\n }\n\n // Update dialog for edit mode\n if (title) {\n title.textContent = \"Edit Task\";\n }\n\n if (submitBtn) {\n submitBtn.textContent = \"Save Changes\";\n }\n\n // Set form values\n const nameInput = form.querySelector(\"input[name='name']\");\n if (nameInput instanceof HTMLInputElement) {\n nameInput.value = task.name || \"\";\n }\n\n const scheduleInput = form.querySelector(\"input[name='schedule']\");\n const promptInput = form.querySelector(\"textarea[name='prompt']\");\n if (scheduleInput instanceof HTMLInputElement) {\n scheduleInput.value = task.schedule || \"\";\n }\n\n if (promptInput instanceof HTMLTextAreaElement) {\n promptInput.value = task.prompt || \"\";\n }\n\n const freshContextInput = form.querySelector(\"input[name='freshContext']\");\n if (freshContextInput instanceof HTMLInputElement) {\n freshContextInput.checked = !!task.freshContext;\n }\n\n const subagentInput = form.querySelector(\"input[name='subagent']\");\n if (subagentInput instanceof HTMLInputElement) {\n subagentInput.checked = !!task.subagent;\n }\n\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (pushInput) {\n pushInput.checked = !!task.pushNotifications;\n }\n this.updatePushNotificationsCheckboxState(!!task.pushNotifications);\n\n const typeRadio = form.querySelector(\n `input[name='taskType'][value='${task.type || \"prompt\"}']`,\n ) as HTMLInputElement;\n if (typeRadio) {\n typeRadio.checked = true;\n typeRadio.dispatchEvent(new Event(\"change\"));\n }\n\n this.renderToolsEditor();\n\n // Set initial preview\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv instanceof HTMLElement) {\n if (task.type === \"tools\") {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n } else {\n this.renderPreview(task.prompt).then((html) => {\n setSanitizedHtml(previewDiv, html);\n });\n }\n }\n\n // Show dialog\n dialog?.showModal();\n }\n\n /**\n * Run a task\n */\n handleRun(task: Task) {\n orchestratorStore.runTask(task, true);\n }\n\n renderToolsEditor() {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tasks__tools-list\");\n if (!list) {\n return;\n }\n\n list.innerHTML = \"\";\n\n this.editingTools.forEach((tool, index) => {\n const item = document.createElement(\"div\");\n item.className = \"tasks__tool-item\";\n\n const header = document.createElement(\"div\");\n header.className = \"tasks__tool-header\";\n\n const title = document.createElement(\"div\");\n title.className = \"tasks__tool-title\";\n title.textContent = `Tool ${index + 1}`;\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.type = \"button\";\n removeBtn.className = \"tasks__tool-remove-btn\";\n removeBtn.textContent = \"Remove\";\n removeBtn.addEventListener(\"click\", () => {\n this.editingTools.splice(index, 1);\n this.renderToolsEditor();\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n header.appendChild(title);\n header.appendChild(removeBtn);\n\n const nameInput = document.createElement(\"input\");\n nameInput.type = \"text\";\n nameInput.className = \"tasks__form-input\";\n nameInput.placeholder = \"Tool Name (e.g. show_toast)\";\n nameInput.value = tool.name || \"\";\n nameInput.addEventListener(\"input\", (e) => {\n tool.name = (e.target as HTMLInputElement).value;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n const paramsInput = document.createElement(\"textarea\");\n paramsInput.className = \"tasks__form-textarea\";\n paramsInput.placeholder = '{\\n \"key\": \"value\"\\n}';\n try {\n paramsInput.value =\n tool.input && Object.keys(tool.input).length\n ? JSON.stringify(tool.input, null, 2)\n : \"\";\n } catch (e) {\n paramsInput.value = \"\";\n }\n\n paramsInput.addEventListener(\"change\", (e) => {\n const val = (e.target as HTMLTextAreaElement).value;\n if (!val.trim()) {\n tool.input = {};\n } else {\n try {\n tool.input = JSON.parse(val);\n (e.target as HTMLTextAreaElement).style.borderColor = \"\";\n } catch (err) {\n (e.target as HTMLTextAreaElement).style.borderColor =\n \"var(--shadow-claw-error-color)\";\n }\n }\n\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n const suppressLabel = document.createElement(\"label\");\n suppressLabel.className = \"tasks__tool-suppress\";\n\n const suppressInput = document.createElement(\"input\");\n suppressInput.type = \"checkbox\";\n suppressInput.checked = !!tool.suppressOutput;\n suppressInput.addEventListener(\"change\", (e) => {\n tool.suppressOutput = (e.target as HTMLInputElement).checked;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n suppressLabel.appendChild(suppressInput);\n suppressLabel.appendChild(document.createTextNode(\" Suppress Output\"));\n\n const suppressToastLabel = document.createElement(\"label\");\n suppressToastLabel.className = \"tasks__tool-suppress\";\n\n const suppressToastInput = document.createElement(\"input\");\n suppressToastInput.type = \"checkbox\";\n suppressToastInput.checked = !!tool.suppressToast;\n suppressToastInput.addEventListener(\"change\", (e) => {\n tool.suppressToast = (e.target as HTMLInputElement).checked;\n const previewDiv = root.querySelector(\".tasks__preview\");\n if (previewDiv) {\n setSanitizedHtml(\n previewDiv,\n this.renderToolsPreview(this.editingTools),\n );\n }\n });\n\n suppressToastLabel.appendChild(suppressToastInput);\n suppressToastLabel.appendChild(\n document.createTextNode(\" Suppress Toast\"),\n );\n\n item.appendChild(header);\n item.appendChild(nameInput);\n item.appendChild(paramsInput);\n item.appendChild(suppressLabel);\n item.appendChild(suppressToastLabel);\n list.appendChild(item);\n });\n }\n\n renderToolsPreview(tools: any[], allowCollapse = false) {\n if (!tools || tools.length === 0) {\n return '<span class=\"tasks__preview-empty\">No tools configured</span>';\n }\n\n const html = tools\n .map((t, i) => {\n let params = \"{}\";\n try {\n params = JSON.stringify(t.input, null, 2);\n } catch (e) {\n params = \"Invalid JSON\";\n }\n\n return `<div><strong>${i + 1}. ${escapeHtml(t.name || \"Unnamed Tool\")}</strong><pre><code>${escapeHtml(params)}</code></pre></div>`;\n })\n .join(\"\");\n\n if (allowCollapse && tools.length > 2) {\n return `\n <details class=\"tasks__content-details\">\n <summary class=\"tasks__content-summary\">\n <span class=\"tasks__summary-text\">${tools.length} Tools configured</span>\n <span class=\"tasks__summary-label\">(View more)</span>\n </summary>\n <div class=\"tasks__prompt\">${html}</div>\n </details>\n `;\n }\n\n return `<div class=\"tasks__prompt\">${html}</div>`;\n }\n\n resolveWorkspaceLinkPath(href: string): string | null {\n const trimmed = href.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n return null;\n }\n\n let candidate = trimmed;\n const hasScheme = /^[a-zA-Z][a-zA-Z\\d+.-]*:/.test(trimmed);\n\n if (hasScheme || trimmed.startsWith(\"//\")) {\n let parsed: URL;\n try {\n parsed = new URL(trimmed, window.location.href);\n } catch {\n return null;\n }\n\n const isHttp =\n parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n if (!isHttp || parsed.host !== window.location.host) {\n return null;\n }\n\n candidate = `${parsed.pathname}${parsed.search}${parsed.hash}`;\n }\n\n let normalized = candidate.split(/[?#]/, 1)[0].replace(/\\\\/g, \"/\");\n normalized = normalized.replace(/^\\/+/, \"\");\n normalized = normalized.replace(/^\\.\\//, \"\");\n\n if (!normalized) {\n return null;\n }\n\n const parts = normalized\n .split(\"/\")\n .filter(Boolean)\n .map((part) => decodePathSegment(part));\n if (parts.some((part) => part === \"..\")) {\n return null;\n }\n\n return parts.join(\"/\");\n }\n\n /**\n * Handle backup (download all tasks as JSON)\n */\n async handleBackup() {\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__backup-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n const tasks = orchestratorStore.getTasksForBackup();\n const json = JSON.stringify(tasks, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `shadowclaw-tasks-backup-${Date.now()}.json`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to create backup: ${message}`);\n console.error(\"Backup error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__backup-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"💾 Backup\";\n }\n }\n }\n\n /**\n * Handle clear all (delete all tasks)\n */\n async handleClearAll(db: ShadowClawDatabase) {\n const confirmed = await this.requestConfirmation({\n title: \"Clear All Tasks\",\n message: \"Delete ALL tasks? This cannot be undone!\",\n confirmLabel: \"Delete All\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__clear-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n await orchestratorStore.clearAllTasks(db);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to clear tasks: ${message}`);\n console.error(\"Clear error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__clear-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"🗑️ Clear All\";\n }\n }\n }\n\n /**\n * Copy a task's ID to the clipboard\n */\n async handleCopyId(id: string) {\n try {\n await navigator.clipboard.writeText(id);\n showSuccess(\"Task ID copied to clipboard!\");\n } catch (err) {\n showError(\"Failed to copy task ID.\");\n }\n }\n\n /**\n * Delete a task\n */\n async handleDelete(db: ShadowClawDatabase, id: string) {\n const confirmed = await this.requestConfirmation({\n title: \"Delete Scheduled Task\",\n message: \"Are you sure you want to delete this scheduled task?\",\n confirmLabel: \"Delete\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n return;\n }\n\n try {\n await orchestratorStore.deleteTask(db, id);\n } catch (err) {\n console.error(\"Failed to delete task:\", err);\n }\n }\n\n async handleEditSubmit(db: ShadowClawDatabase, form: HTMLFormElement) {\n const formData = new FormData(form);\n const name = formData.get(\"name\");\n const schedule = formData.get(\"schedule\");\n const prompt = formData.get(\"prompt\");\n const type = (formData.get(\"taskType\") as \"prompt\" | \"tools\") || \"prompt\";\n\n const nameStr = name ? String(name).trim() : \"\";\n const scheduleStr = schedule ? String(schedule).trim() : \"\";\n\n if (type === \"prompt\" && !prompt) {\n showInfo(\"Please provide a task prompt.\");\n\n return;\n }\n\n const freshContext = !!formData.get(\"freshContext\");\n const subagent = !!formData.get(\"subagent\");\n const pushInput = form.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n const pushNotifications =\n pushInput instanceof HTMLInputElement\n ? !pushInput.disabled && pushInput.checked\n : false;\n\n try {\n let taskToSave;\n\n if (this.editingTask) {\n // Update existing task\n taskToSave = {\n ...this.editingTask,\n name: nameStr || undefined,\n schedule: scheduleStr,\n type,\n prompt: String(prompt || \"\"),\n tools: JSON.parse(JSON.stringify(this.editingTools)),\n freshContext,\n subagent,\n pushNotifications,\n };\n } else {\n // Create new task\n const currentGroupId = orchestratorStore.activeGroupId;\n taskToSave = {\n id: crypto.randomUUID\n ? crypto.randomUUID()\n : `task-${Date.now()}-${Math.random()}`,\n groupId: currentGroupId,\n name: nameStr || undefined,\n schedule: scheduleStr,\n type,\n prompt: String(prompt || \"\"),\n tools: JSON.parse(JSON.stringify(this.editingTools)),\n enabled: true,\n lastRun: null,\n createdAt: Date.now(),\n freshContext,\n subagent,\n pushNotifications,\n };\n }\n\n await orchestratorStore.upsertTask(db, taskToSave);\n\n const root = this.shadowRoot;\n const dialog = root?.querySelector(\"dialog\");\n dialog?.close();\n\n this.editingTask = null;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to save task: ${message}`);\n console.error(\"Save error:\", err);\n }\n }\n\n async handlePreviewLinkClick(event: MouseEvent, db: ShadowClawDatabase) {\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 const target = event.target;\n if (!(target instanceof Element)) {\n return;\n }\n\n const link = target.closest(\"a\");\n if (!(link instanceof HTMLAnchorElement)) {\n return;\n }\n\n const href = link.getAttribute(\"href\") || \"\";\n const resolved = this.resolveWorkspaceLinkPath(href);\n if (!resolved) {\n return;\n }\n\n event.preventDefault();\n\n const attempts = [resolved];\n const lastSegment = resolved.split(\"/\").filter(Boolean).pop() || \"\";\n const hasExtension = /\\.[^./]+$/u.test(lastSegment);\n\n if (!hasExtension) {\n attempts.push(`${resolved}.md`, `${resolved}/index.md`);\n }\n\n for (const candidate of attempts) {\n try {\n await fileViewerStore.openFile(\n db,\n candidate,\n orchestratorStore.activeGroupId,\n );\n\n return;\n } catch {\n // Try next candidate path.\n }\n }\n\n showError(`Failed to open linked file: ${resolved}`, 5000);\n }\n\n async handleReorder(\n draggedId: string,\n targetId: string,\n precomputedIds?: string[],\n ) {\n const db = await getDb();\n if (!db) {\n return;\n }\n\n if (precomputedIds) {\n await orchestratorStore.reorderTasks(\n db,\n orchestratorStore.activeGroupId,\n precomputedIds,\n );\n return;\n }\n\n const tasks = orchestratorStore.tasks || [];\n const ids = tasks.map((t) => t.id);\n const fromIdx = ids.indexOf(draggedId);\n const toIdx = ids.indexOf(targetId);\n\n if (fromIdx < 0 || toIdx < 0) {\n return;\n }\n\n ids.splice(fromIdx, 1);\n ids.splice(toIdx, 0, draggedId);\n\n await orchestratorStore.reorderTasks(\n db,\n orchestratorStore.activeGroupId,\n ids,\n );\n }\n\n /**\n * Handle restore (upload and import JSON)\n */\n async handleRestore(db: ShadowClawDatabase, input: HTMLInputElement) {\n const files = input.files;\n if (!files || files.length === 0) {\n return;\n }\n\n const jsonFile = files[0];\n if (!jsonFile.name.endsWith(\".json\")) {\n showInfo(\"Please select a .json file\");\n\n return;\n }\n\n const confirmed = await this.requestConfirmation({\n title: \"Restore Tasks\",\n message: \"Restore from backup will replace all current tasks. Continue?\",\n confirmLabel: \"Restore\",\n cancelLabel: \"Cancel\",\n });\n\n if (!confirmed) {\n input.value = \"\";\n\n return;\n }\n\n try {\n const btn = this.shadowRoot?.querySelector(\".tasks__restore-btn\");\n btn?.toggleAttribute(\"disabled\", true);\n\n if (btn) {\n btn.textContent = \"⏳\";\n }\n\n const text = await jsonFile.text();\n const tasks = JSON.parse(text);\n\n if (!Array.isArray(tasks)) {\n throw new Error(\"Invalid backup file format\");\n }\n\n await orchestratorStore.restoreTasksFromBackup(db, tasks);\n input.value = \"\";\n showSuccess(\"Tasks restored successfully!\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n showError(`Failed to restore from backup: ${message}`);\n console.error(\"Restore error:\", err);\n } finally {\n const btn = this.shadowRoot?.querySelector(\".tasks__restore-btn\");\n btn?.toggleAttribute(\"disabled\", false);\n\n if (btn) {\n btn.textContent = \"♻️ Restore\";\n }\n }\n }\n\n async renderPreview(prompt: string, allowCollapse = false) {\n if (!prompt.trim()) {\n return '<span class=\"tasks__preview-empty\">No content</span>';\n }\n\n const lines = prompt.split(\"\\n\");\n const isLong = prompt.length > 120 || lines.length > 1;\n\n const rendered = await renderMarkdown(prompt, {\n breaks: true,\n renderFrontmatter: this.renderFrontmatter,\n });\n\n if (allowCollapse && isLong) {\n const summaryText = prompt.trim();\n\n return `\n <details class=\"tasks__content-details\">\n <summary class=\"tasks__content-summary\">\n <span class=\"tasks__summary-text\">${escapeHtml(summaryText)}</span>\n <span class=\"tasks__summary-label\">(View more)</span>\n </summary>\n <div class=\"tasks__prompt\">${rendered}</div>\n </details>\n `;\n }\n\n return `<div class=\"tasks__prompt\">${rendered}</div>`;\n }\n\n async requestConfirmation(options: {\n title: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n }): Promise<boolean> {\n const appShell = document.querySelector(\"shadow-claw\") as any;\n if (appShell && typeof appShell.requestDialog === \"function\") {\n return await appShell.requestDialog({ mode: \"confirm\", ...options });\n }\n\n showInfo(options.message, 4000);\n\n return false;\n }\n\n /**\n * Update the disabled/checked state of the push notifications checkbox\n */\n async updatePushNotificationsCheckboxState(\n preserveCheckedIfEnabled?: boolean,\n ): Promise<void> {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const pushInput = root.querySelector(\n \"#tasksPushNotificationsInput\",\n ) as HTMLInputElement | null;\n if (!pushInput) {\n return;\n }\n\n const scheduleInput = root.querySelector(\n \"input[name='schedule']\",\n ) as HTMLInputElement | null;\n const scheduleVal = scheduleInput?.value.trim() ?? \"\";\n\n let hasSubscription = false;\n try {\n const sub = await getCurrentSubscription();\n hasSubscription = !!sub;\n } catch {\n hasSubscription = false;\n }\n\n const canEnablePush =\n scheduleVal.length > 0 &&\n orchestratorStore.taskServerEnabled &&\n hasSubscription;\n\n pushInput.disabled = !canEnablePush;\n if (!canEnablePush) {\n pushInput.checked = false;\n } else if (preserveCheckedIfEnabled !== undefined) {\n pushInput.checked = preserveCheckedIfEnabled;\n }\n }\n\n async updateTaskList(db: ShadowClawDatabase) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const list = root.querySelector(\".tasks__list\");\n if (!list) {\n return;\n }\n\n const tasks = orchestratorStore.tasks;\n\n if (tasks.length === 0) {\n setSanitizedHtml(\n list,\n `<shadow-claw-empty-state\n class=\"tasks__empty\"\n message=\"No scheduled tasks for this group.\"\n hint=\"Ask the agent to create one using 'create_task'.\"\n ></shadow-claw-empty-state>`,\n );\n\n return;\n }\n\n // Capture render content first to avoid partially cleared list while awaiting\n const fragment = document.createDocumentFragment();\n\n for (let i = 0; i < tasks.length; i++) {\n const task = tasks[i];\n const item = document.createElement(\"div\");\n item.className = \"tasks__item\";\n item.setAttribute(\"role\", \"listitem\");\n item.setAttribute(\"tabindex\", \"0\");\n item.setAttribute(\"aria-describedby\", \"reorder-instructions\");\n item.setAttribute(\n \"aria-label\",\n `${task.name || \"Task\"}, position ${i + 1} of ${tasks.length}`,\n );\n item.setAttribute(\"data-task-id\", task.id);\n\n if (this._keyboardGrabbedId === task.id) {\n item.classList.add(\"keyboard-grabbed\");\n item.setAttribute(\"aria-grabbed\", \"true\");\n }\n\n const lastRunStr = task.lastRun\n ? new Date(task.lastRun).toLocaleString()\n : \"Never\";\n\n const isTools = task.type === \"tools\";\n const previewHtml = isTools\n ? this.renderToolsPreview(task.tools || [], true)\n : await this.renderPreview(task.prompt, true);\n\n const scheduleDisplay = task.schedule\n ? `⏰ ${escapeHtml(task.schedule)}`\n : \"⏸ Unscheduled\";\n const toggleHtml = task.schedule\n ? `\n <label class=\"tasks__toggle\">\n <input type=\"checkbox\" ${task.enabled ? \"checked\" : \"\"} data-id=\"${escapeHtml(task.id)}\" class=\"tasks__toggle-input\" aria-label=\"${task.enabled ? \"Disable\" : \"Enable\"} task scheduled ${escapeHtml(task.schedule)}\">\n ${task.enabled ? \"Enabled\" : \"Disabled\"}\n </label>`\n : \"\";\n\n const badges = [isTools ? \"Tools\" : \"Prompt\"];\n if (task.freshContext) {\n badges.push(\"Fresh Context\");\n }\n if (task.subagent) {\n badges.push(\"Subagent\");\n }\n if (task.pushNotifications) {\n badges.push(\"Push\");\n }\n const badgesDisplay = badges.join(\" · \");\n\n const nameHtml = task.name\n ? `<div class=\"tasks__name\" style=\"font-weight: 600; font-size: var(--shadow-claw-font-size-md); margin-bottom: 0.25rem;\">${escapeHtml(task.name)}</div>`\n : \"\";\n\n const dragHandleHtml = `<span class=\"tasks__drag-handle\" draggable=\"true\" aria-hidden=\"true\" title=\"Drag to reorder\">⠿</span>`;\n\n setSanitizedHtml(\n item,\n `<div class=\"tasks__item-header\">\n <div style=\"display: flex; align-items: flex-start; flex: 1; min-width: 0;\">\n ${dragHandleHtml}\n <div class=\"tasks__item-info\">\n ${nameHtml}\n <div class=\"tasks__schedule-row\">\n <div class=\"tasks__schedule\">${scheduleDisplay} <span class=\"tasks__type-badge\">(${escapeHtml(badgesDisplay)})</span></div>\n </div>\n <div class=\"tasks__prompt-container\">\n ${previewHtml}\n </div>\n <div class=\"tasks__last-run\">Last run: ${escapeHtml(lastRunStr)}</div>\n </div>\n </div>\n <div class=\"tasks__actions\">\n ${toggleHtml}\n <button type=\"button\" class=\"tasks__copy-id-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Copy task ID\" title=\"Copy task ID\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" width=\"1em\" viewBox=\"0 -960 960 960\" fill=\"currentColor\" aria-hidden=\"true\" style=\"vertical-align: middle; margin-right: 0.125rem; margin-top: -0.125rem;\"><path d=\"M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z\"/></svg> Copy ID\n </button>\n <button type=\"button\" class=\"tasks__run-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Run task\">Run</button>\n <button type=\"button\" class=\"tasks__edit-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Edit task\">✎ Edit</button>\n <button type=\"button\" class=\"tasks__delete-btn\" data-id=\"${escapeHtml(task.id)}\" aria-label=\"Delete task\">Delete</button>\n </div>\n </div>`,\n );\n\n // Bind events\n const toggle = item.querySelector(\n \".tasks__toggle-input\",\n ) as HTMLInputElement | null;\n\n toggle?.addEventListener(\"change\", (e) => {\n const target = e.target as HTMLInputElement;\n orchestratorStore.toggleTask(db, task, target.checked);\n });\n\n const copyIdBtn = item.querySelector(\".tasks__copy-id-btn\");\n copyIdBtn?.addEventListener(\"click\", () => this.handleCopyId(task.id));\n\n const runBtn = item.querySelector(\".tasks__run-btn\");\n runBtn?.addEventListener(\"click\", () => this.handleRun(task));\n\n const editBtn = item.querySelector(\".tasks__edit-btn\");\n editBtn?.addEventListener(\"click\", () => this.handleEdit(task));\n\n const deleteBtn = item.querySelector(\".tasks__delete-btn\");\n deleteBtn?.addEventListener(\"click\", () =>\n this.handleDelete(db, task.id),\n );\n\n const handleEl = item.querySelector(\n \".tasks__drag-handle\",\n ) as HTMLElement | null;\n\n handleEl?.addEventListener(\"dragstart\", (e) => {\n this._draggedTaskId = task.id;\n item.classList.add(\"dragging\");\n e.dataTransfer?.setData(\"text/plain\", task.id);\n });\n\n handleEl?.addEventListener(\"dragend\", () => {\n item.classList.remove(\"dragging\");\n this._draggedTaskId = null;\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n });\n\n handleEl?.addEventListener(\n \"touchstart\",\n (e) => {\n const touch = e.touches[0];\n if (!touch) {\n return;\n }\n this._touchId = touch.identifier;\n this._touchDraggedTaskId = task.id;\n item.classList.add(\"dragging\");\n e.preventDefault();\n },\n { passive: false },\n );\n\n item.addEventListener(\"dragover\", (e) => {\n e.preventDefault();\n if (this._draggedTaskId && this._draggedTaskId !== task.id) {\n item.classList.add(\"drag-over\");\n }\n });\n\n item.addEventListener(\"dragleave\", () => {\n item.classList.remove(\"drag-over\");\n });\n\n item.addEventListener(\"drop\", (e) => {\n e.preventDefault();\n item.classList.remove(\"drag-over\");\n if (this._draggedTaskId && this._draggedTaskId !== task.id) {\n this.handleReorder(this._draggedTaskId, task.id);\n }\n });\n\n item.addEventListener(\"keydown\", (e) => {\n this._handleKeyboard(e, task.id, task.name || \"Task\");\n });\n\n fragment.appendChild(item);\n }\n\n list.replaceChildren();\n list.appendChild(fragment);\n\n this._bindTouchListEvents(list);\n }\n\n _announce(message: string) {\n const region = this.shadowRoot?.querySelector(\"#live-region\");\n if (region) {\n region.textContent = \"\";\n requestAnimationFrame(() => {\n region.textContent = message;\n });\n }\n }\n\n _bindTouchListEvents(list: Element) {\n if ((list as any)._touchBound) {\n return;\n }\n (list as any)._touchBound = true;\n\n list.addEventListener(\n \"touchmove\",\n (e) => {\n if (this._touchDraggedTaskId === null) {\n return;\n }\n\n const touch = this._findTouch(e as TouchEvent);\n if (!touch) {\n return;\n }\n\n e.preventDefault();\n\n const target = this._itemAtPoint(touch.clientX, touch.clientY);\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n\n if (\n target &&\n target.getAttribute(\"data-task-id\") !== this._touchDraggedTaskId\n ) {\n target.classList.add(\"drag-over\");\n }\n\n this._updateAutoScrollSpeed(touch.clientY);\n },\n { passive: false },\n );\n\n list.addEventListener(\"touchend\", (e) => {\n if (this._touchDraggedTaskId === null) {\n return;\n }\n\n const touch = this._findChangedTouch(e as TouchEvent);\n if (!touch) {\n return;\n }\n\n const target = this._itemAtPoint(touch.clientX, touch.clientY);\n const targetId = target?.getAttribute(\"data-task-id\");\n\n list\n .querySelectorAll(\".dragging\")\n .forEach((el) => el.classList.remove(\"dragging\"));\n\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n\n if (targetId && targetId !== this._touchDraggedTaskId) {\n this.handleReorder(this._touchDraggedTaskId, targetId);\n }\n\n this._stopAutoScroll();\n this._touchDraggedTaskId = null;\n this._touchId = null;\n });\n\n list.addEventListener(\"touchcancel\", () => {\n list\n .querySelectorAll(\".dragging\")\n .forEach((el) => el.classList.remove(\"dragging\"));\n\n list\n .querySelectorAll(\".drag-over\")\n .forEach((el) => el.classList.remove(\"drag-over\"));\n this._stopAutoScroll();\n this._touchDraggedTaskId = null;\n this._touchId = null;\n });\n }\n\n _findChangedTouch(e: TouchEvent): Touch | undefined {\n for (let i = 0; i < e.changedTouches.length; i++) {\n const t = e.changedTouches[i];\n if (t.identifier === this._touchId) {\n return t;\n }\n }\n }\n\n _findTouch(e: TouchEvent): Touch | undefined {\n for (let i = 0; i < e.touches.length; i++) {\n const t = e.touches[i];\n if (t.identifier === this._touchId) {\n return t;\n }\n }\n }\n\n _focusNext(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const focusables = Array.from(\n root.querySelectorAll(\n '.tasks__item[tabindex=\"0\"], button:not([disabled]), input:not([type=\"hidden\"]):not([disabled])',\n ),\n ) as HTMLElement[];\n const idx = focusables.indexOf(current);\n if (idx !== -1 && idx < focusables.length - 1) {\n focusables[idx + 1].focus();\n }\n }\n\n _focusNextItem(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const items = Array.from(\n root.querySelectorAll(\".tasks__item\"),\n ) as HTMLElement[];\n const currentItem = current.closest(\".tasks__item\") as HTMLElement;\n const idx = items.indexOf(currentItem);\n if (idx !== -1 && idx < items.length - 1) {\n items[idx + 1].focus();\n }\n }\n\n _focusPrev(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const focusables = Array.from(\n root.querySelectorAll(\n '.tasks__item[tabindex=\"0\"], button:not([disabled]), input:not([type=\"hidden\"]):not([disabled])',\n ),\n ) as HTMLElement[];\n const idx = focusables.indexOf(current);\n if (idx > 0) {\n focusables[idx - 1].focus();\n }\n }\n\n _focusPrevItem(current: HTMLElement) {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const items = Array.from(\n root.querySelectorAll(\".tasks__item\"),\n ) as HTMLElement[];\n const currentItem = current.closest(\".tasks__item\") as HTMLElement;\n const idx = items.indexOf(currentItem);\n if (idx > 0) {\n items[idx - 1].focus();\n }\n }\n\n _handleKeyboard(e: KeyboardEvent, taskId: string, name: string) {\n const tasks = orchestratorStore.tasks || [];\n const ids = tasks.map((t) => t.id);\n const total = ids.length;\n\n if (this._keyboardGrabbedId === null) {\n // Navigation & Selection\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n this._focusNextItem(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n this._focusPrevItem(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowRight\") {\n e.preventDefault();\n this._focusNext(e.target as HTMLElement);\n return;\n }\n\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n this._focusPrev(e.target as HTMLElement);\n return;\n }\n\n // Grab for reorder\n if (e.key === \"m\" || e.key === \"M\") {\n e.preventDefault();\n this._keyboardGrabbedId = taskId;\n const pos = ids.indexOf(taskId) + 1;\n this._announce(\n `${name} grabbed. Current position ${pos} of ${total}. Use Arrow Up and Down to move, Space or Enter to drop.`,\n );\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n }\n\n return;\n }\n\n // Currently grabbed\n if (e.key === \"Escape\") {\n e.preventDefault();\n this._announce(\n `Reorder cancelled. ${name} returned to original position.`,\n );\n this._keyboardGrabbedId = null;\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n return;\n }\n\n if (e.key === \" \" || e.key === \"Spacebar\" || e.key === \"Enter\") {\n // Drop\n e.preventDefault();\n const pos = ids.indexOf(this._keyboardGrabbedId) + 1;\n const droppedName =\n tasks.find((t) => t.id === this._keyboardGrabbedId)?.name || \"Task\";\n this._announce(\n `${droppedName} dropped at position ${pos} of ${total}. Reordering complete.`,\n );\n this._keyboardGrabbedId = null;\n getDb()\n .then((db) => this.updateTaskList(db))\n .catch(console.error);\n return;\n }\n\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n const currentIdx = ids.indexOf(this._keyboardGrabbedId);\n const newIdx = e.key === \"ArrowUp\" ? currentIdx - 1 : currentIdx + 1;\n if (newIdx < 0 || newIdx >= total) {\n return;\n }\n\n // Swap\n ids.splice(currentIdx, 1);\n ids.splice(newIdx, 0, this._keyboardGrabbedId);\n this._announce(`Moved to position ${newIdx + 1} of ${total}.`);\n this.handleReorder(this._keyboardGrabbedId, ids[currentIdx], ids);\n }\n }\n\n _itemAtPoint(x: number, y: number): Element | null {\n const root = this.shadowRoot;\n if (!root) {\n return null;\n }\n\n const el = root.elementFromPoint(x, y);\n return el?.closest?.(\".tasks__item\") || null;\n }\n\n _startAutoScroll() {\n if (this._autoScrollActive) {\n return;\n }\n this._autoScrollActive = true;\n\n const scrollLoop = () => {\n if (!this._autoScrollActive) {\n return;\n }\n\n const root = this.shadowRoot;\n const content = root?.querySelector(\n \".tasks__content\",\n ) as HTMLElement | null;\n if (content && this._autoScrollSpeed !== 0) {\n content.scrollTop += this._autoScrollSpeed;\n }\n\n requestAnimationFrame(scrollLoop);\n };\n\n requestAnimationFrame(scrollLoop);\n }\n\n _stopAutoScroll() {\n this._autoScrollActive = false;\n this._autoScrollSpeed = 0;\n }\n\n _updateAutoScrollSpeed(clientY: number) {\n const root = this.shadowRoot;\n const content = root?.querySelector(\n \".tasks__content\",\n ) as HTMLElement | null;\n if (!content) {\n this._autoScrollSpeed = 0;\n return;\n }\n\n const rect = content.getBoundingClientRect();\n const threshold = 50; // pixels from top/bottom to start scrolling\n\n const distTop = clientY - rect.top;\n const distBottom = rect.bottom - clientY;\n\n if (distTop >= 0 && distTop < threshold) {\n // Near the top: scroll up. Speed is faster the closer to the edge.\n this._autoScrollSpeed = -((threshold - distTop) / threshold) * 8;\n this._startAutoScroll();\n } else if (distBottom >= 0 && distBottom < threshold) {\n // Near the bottom: scroll down.\n this._autoScrollSpeed = ((threshold - distBottom) / threshold) * 8;\n this._startAutoScroll();\n } else {\n this._autoScrollSpeed = 0;\n }\n }\n}\n\nif (!customElements.get(elementName)) {\n customElements.define(elementName, ShadowClawTasks);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ShadowClawElement from "./components/shadow-claw-element.js";
|
|
2
|
-
import { L as closeTerminalSession, R as openTerminalSession, t as orchestratorStore, z as sendTerminalInput } from "./orchestrator-
|
|
2
|
+
import { L as closeTerminalSession, R as openTerminalSession, t as orchestratorStore, z as sendTerminalInput } from "./orchestrator-CCARkxQC.js";
|
|
3
3
|
|
|
4
4
|
//#region src/components/shadow-claw-terminal/utils/extract-last-prompt-line.ts
|
|
5
5
|
function extractLastPromptLine(text) {
|
|
@@ -703,4 +703,4 @@ customElements.define("shadow-claw-terminal", ShadowClawTerminal);
|
|
|
703
703
|
|
|
704
704
|
//#endregion
|
|
705
705
|
export { ShadowClawTerminal as n, AUTO_SCROLL_BOTTOM_THRESHOLD_PX as t };
|
|
706
|
-
//# sourceMappingURL=shadow-claw-terminal-
|
|
706
|
+
//# sourceMappingURL=shadow-claw-terminal-fyJPppY_.js.map
|