termdock 1.4.350 → 1.4.352
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/dist/client/assets/AndroidMirrorView-DkOZxYLg.js +3 -0
- package/dist/client/assets/AndroidMirrorView-DkOZxYLg.js.br +0 -0
- package/dist/client/assets/AndroidMirrorView-DkOZxYLg.js.gz +0 -0
- package/dist/client/assets/App-DqRkfVSm.js +178 -0
- package/dist/client/assets/App-DqRkfVSm.js.br +0 -0
- package/dist/client/assets/App-DqRkfVSm.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js +9 -0
- package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-m9GKl3cl.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js +2 -0
- package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-HZ0zvFvi.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js +1 -0
- package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-B4OMk92m.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-Cbg3iH6E.js +2 -0
- package/dist/client/assets/ComputerControlView-CSs54lf0.js +6 -0
- package/dist/client/assets/ComputerControlView-CSs54lf0.js.br +0 -0
- package/dist/client/assets/ComputerControlView-CSs54lf0.js.gz +0 -0
- package/dist/client/assets/DagPlayground-yoS2llnB.js +1 -0
- package/dist/client/assets/DagPlayground-yoS2llnB.js.br +0 -0
- package/dist/client/assets/DagPlayground-yoS2llnB.js.gz +0 -0
- package/dist/client/assets/{DiffLab-DEw4y4Hk.js → DiffLab-Dj1MT9pY.js} +2 -2
- package/dist/client/assets/DiffLab-Dj1MT9pY.js.br +0 -0
- package/dist/client/assets/DiffLab-Dj1MT9pY.js.gz +0 -0
- package/dist/client/assets/DiffReview-BX2S9hNp.js +1 -0
- package/dist/client/assets/DiffReview-BX2S9hNp.js.br +0 -0
- package/dist/client/assets/DiffReview-BX2S9hNp.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-CDXsy0jE.js → DiffReviewLab-DqI14GEk.js} +2 -2
- package/dist/client/assets/DiffReviewLab-DqI14GEk.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-DqI14GEk.js.gz +0 -0
- package/dist/client/assets/DiffViewer-AZvdDGfH.js +34 -0
- package/dist/client/assets/DiffViewer-AZvdDGfH.js.br +0 -0
- package/dist/client/assets/DiffViewer-AZvdDGfH.js.gz +0 -0
- package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js +1 -0
- package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js.br +0 -0
- package/dist/client/assets/GitLoadingSkeleton-CBPykkZP.js.gz +0 -0
- package/dist/client/assets/MarkdownPreview-DpvTnKkj.js +19 -0
- package/dist/client/assets/MarkdownPreview-DpvTnKkj.js.br +0 -0
- package/dist/client/assets/MarkdownPreview-DpvTnKkj.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-BEiOgE0G.js → ModelPreview-Du_AyPr9.js} +166 -166
- package/dist/client/assets/ModelPreview-Du_AyPr9.js.br +0 -0
- package/dist/client/assets/ModelPreview-Du_AyPr9.js.gz +0 -0
- package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js +1 -0
- package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js.br +0 -0
- package/dist/client/assets/RecordingSaveDialog-CtXaGgIo.js.gz +0 -0
- package/dist/client/assets/RightSidebar-DU3gwdzg.js +1662 -0
- package/dist/client/assets/RightSidebar-DU3gwdzg.js.br +0 -0
- package/dist/client/assets/RightSidebar-DU3gwdzg.js.gz +0 -0
- package/dist/client/assets/SessionChatView-CxfwJMuK.js +13 -0
- package/dist/client/assets/SessionChatView-CxfwJMuK.js.br +0 -0
- package/dist/client/assets/SessionChatView-CxfwJMuK.js.gz +0 -0
- package/dist/client/assets/SessionChatView-D8GoESjb.css +1 -0
- package/dist/client/assets/SessionChatView-D8GoESjb.css.br +0 -0
- package/dist/client/assets/SessionChatView-D8GoESjb.css.gz +0 -0
- package/dist/client/assets/SessionResourceSidebar-B31PU57J.js +2 -0
- package/dist/client/assets/SessionResourceSidebar-B31PU57J.js.br +0 -0
- package/dist/client/assets/SessionResourceSidebar-B31PU57J.js.gz +0 -0
- package/dist/client/assets/TodoWorkspace-j9BLgk94.js +1 -0
- package/dist/client/assets/TodoWorkspace-j9BLgk94.js.br +0 -0
- package/dist/client/assets/TodoWorkspace-j9BLgk94.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-ByzlUu_B.js → abnfDiagram-VCTEODGH-LfmMIpPX.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-LfmMIpPX.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-LfmMIpPX.js.gz +0 -0
- package/dist/client/assets/app-BMJesFDU.js +36 -0
- package/dist/client/assets/app-BMJesFDU.js.br +0 -0
- package/dist/client/assets/app-BMJesFDU.js.gz +0 -0
- package/dist/client/assets/{arc-BA6JM6vl.js → arc-DMzcmH2U.js} +1 -1
- package/dist/client/assets/arc-DMzcmH2U.js.br +0 -0
- package/dist/client/assets/arc-DMzcmH2U.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-hCHxOfKw.js → architectureDiagram-5GKGNRK7-CphS_S5Q.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CphS_S5Q.js.br +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-hCHxOfKw.js.gz → architectureDiagram-5GKGNRK7-CphS_S5Q.js.gz} +0 -0
- package/dist/client/assets/arrow-down-D-WZS308.js +1 -0
- package/dist/client/assets/arrow-up-CelbB9FE.js +1 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-OmEN9hUB.js → blockDiagram-I7D4REHJ-Dx_4qkcL.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-Dx_4qkcL.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-Dx_4qkcL.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-DfLTv8zh.js → c4Diagram-7LVT6UL2-DiGdnPo4.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-DiGdnPo4.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DiGdnPo4.js.gz +0 -0
- package/dist/client/assets/channel-BxAJ9Qmh.js +1 -0
- package/dist/client/assets/chevron-left-5sk7gL3u.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-C3O76PNZ.js → chunk-2Q5K7J3B-M50KNmR8.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-CsWZd30k.js → chunk-5VM5RSS4-wXVM-Max.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-yxCv2Uqk.js → chunk-F27PBJKO-BfQILS9u.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-BfQILS9u.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-BfQILS9u.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-CdPjlb9f.js → chunk-IMKFNOWR-D111Jpl3.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-D111Jpl3.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-D111Jpl3.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-BiiOLq2R.js → chunk-JWPE2WC7-BBDyly5c.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-BOu_1Brt.js → chunk-POPQ4Y6H-BaI-_yc7.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-D1tOJung.js → chunk-SVP7TREG-BvQafCMJ.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-BvQafCMJ.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-BvQafCMJ.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-DZjDfYNw.js → chunk-TICWLB2K-CQXPwGBz.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-CQXPwGBz.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-CQXPwGBz.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-CtGPyXWh.js → chunk-XXDRQBXY-CmwZc4xV.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-D0oXVFxd.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-D0oXVFxd.js +1 -0
- package/dist/client/assets/clipboard-uSv3AiJM.js +1 -0
- package/dist/client/assets/clipboardText-5puxqqm_.js +1 -0
- package/dist/client/assets/clipboardText-5puxqqm_.js.br +0 -0
- package/dist/client/assets/clipboardText-5puxqqm_.js.gz +0 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-C4Wb5lqD.js → cose-bilkent-JH36ORCC-CqWarkUj.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-CqWarkUj.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-CqWarkUj.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX-BvWKB1Xk.js → cynefin-OW5HDTMX-CFW2ifig.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-CFW2ifig.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CFW2ifig.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-7tAkHD2P.js → cynefinDiagram-5FMLGOSQ-yggxM55S.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-yggxM55S.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-yggxM55S.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-Bs6IPwks.js → dagre-GXQ25YYZ-inq7o--x.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-inq7o--x.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-inq7o--x.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-CmYXaTya.js → diagram-S7CK7UJ4-BUXMnyQN.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-BUXMnyQN.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BUXMnyQN.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-CqxoefB7.js → diagram-UQ7AKVKN-BJbw-Imf.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-BJbw-Imf.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-BJbw-Imf.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-Dxp1MKPT.js → diagram-VSXAHHWV-CSfl8yS7.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-CSfl8yS7.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CSfl8yS7.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-BKbWvvEr.js → diagram-VX7I27RA-zV-Vrv89.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-zV-Vrv89.js.br +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-BKbWvvEr.js.gz → diagram-VX7I27RA-zV-Vrv89.js.gz} +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-BZnNaP7F.js → diagram-Z3DM3KII-CRnE-snw.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-CRnE-snw.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-CRnE-snw.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-BXVlN_P7.js → ebnfDiagram-PWID7BFC-CE30oImc.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CE30oImc.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CE30oImc.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-CEdYDZU7.js → erDiagram-RLTQ6QDP-D-5bIySI.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-D-5bIySI.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-D-5bIySI.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-Bbw8GPCZ.js → flowDiagram-HODETNUW-E_jPKtQR.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-E_jPKtQR.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-E_jPKtQR.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-CcFbtP2y.js → ganttDiagram-EL5Y4UJY-BWvLOUzC.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-BWvLOUzC.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-BWvLOUzC.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-DszagC-d.js +1 -0
- package/dist/client/assets/gestureArbiter-DszagC-d.js.br +0 -0
- package/dist/client/assets/gestureArbiter-DszagC-d.js.gz +0 -0
- package/dist/client/assets/git-compare-BlcHEuBI.js +1 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-Eiust154.js → gitGraphDiagram-WWUBYQGX-nOlVCBmL.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-nOlVCBmL.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-nOlVCBmL.js.gz +0 -0
- package/dist/client/assets/index-CA1fR_jI.css +1 -0
- package/dist/client/assets/index-CA1fR_jI.css.br +0 -0
- package/dist/client/assets/index-CA1fR_jI.css.gz +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-DUmaNZJW.js → infoDiagram-27XIBGKW-CjVm9Lzz.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-qTwgXfx_.js → ishikawaDiagram-5VMMS53U-DmVMaGVp.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-qTwgXfx_.js.br → ishikawaDiagram-5VMMS53U-DmVMaGVp.js.br} +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-DmVMaGVp.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-DKy1msWo.js → journeyDiagram-3NMN7TZE-DLwkoAy9.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DLwkoAy9.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DLwkoAy9.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-BxibybDd.js → kanban-definition-UXKFOSKX-GWkp_QiO.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-GWkp_QiO.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-GWkp_QiO.js.gz +0 -0
- package/dist/client/assets/{layout-Bh6fKHRM.js → layout-DFg5a61y.js} +1 -1
- package/dist/client/assets/layout-DFg5a61y.js.br +0 -0
- package/dist/client/assets/layout-DFg5a61y.js.gz +0 -0
- package/dist/client/assets/{linear-SRlL3VWX.js → linear-B0OdJLe1.js} +1 -1
- package/dist/client/assets/{linear-SRlL3VWX.js.br → linear-B0OdJLe1.js.br} +0 -0
- package/dist/client/assets/linear-B0OdJLe1.js.gz +0 -0
- package/dist/client/assets/link-BnxdKJ7b.js +8 -0
- package/dist/client/assets/link-BnxdKJ7b.js.br +0 -0
- package/dist/client/assets/link-BnxdKJ7b.js.gz +0 -0
- package/dist/client/assets/list-tree-Bou8VSzi.js +1 -0
- package/dist/client/assets/loader-circle-q7h8uwFI.js +1 -0
- package/dist/client/assets/maximize-2-BGTBw-Ku.js +1 -0
- package/dist/client/assets/{mermaid.core-D0bcNdw3.js → mermaid.core-DQA3ykXv.js} +5 -5
- package/dist/client/assets/mermaid.core-DQA3ykXv.js.br +0 -0
- package/dist/client/assets/mermaid.core-DQA3ykXv.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-CImZ_aI0.js → mindmap-definition-YA3MSWOX-DsZAVAGP.js} +2 -2
- package/dist/client/assets/mindmap-definition-YA3MSWOX-DsZAVAGP.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-DsZAVAGP.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-CEZSL94g.js +2 -0
- package/dist/client/assets/passwordBootstrap-CEZSL94g.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-CEZSL94g.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-BT4pTf8O.js → pegDiagram-XKGWAZYB-C3ar01Lf.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-C3ar01Lf.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-C3ar01Lf.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-C5K58ien.js → pieDiagram-E7YTZNPT-C8LIa9gE.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-C8LIa9gE.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-C8LIa9gE.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-DzSugYXz.js → quadrantDiagram-AXDQQJYC-BuRJ1f9F.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BuRJ1f9F.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BuRJ1f9F.js.gz +0 -0
- package/dist/client/assets/quote-qXNI_NTi.js +1 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BY07SouQ.js → railroadDiagram-O6MQD6OU-D7iZy3dO.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-D7iZy3dO.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-D7iZy3dO.js.gz +0 -0
- package/dist/client/assets/rdpSession-DUBlG26K.js +1 -0
- package/dist/client/assets/rdpSession-DUBlG26K.js.br +0 -0
- package/dist/client/assets/rdpSession-DUBlG26K.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-C7WieVuE.js → requirementDiagram-BXWQKSXE-DhY8g8qK.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DhY8g8qK.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DhY8g8qK.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-BJsDWNs4.js → sankeyDiagram-P5KCCOFB-DDA_LQcg.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DDA_LQcg.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DDA_LQcg.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BeJ_7853.js → sequenceDiagram-WJ2MYXX4-bWgfdfwY.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BeJ_7853.js.br → sequenceDiagram-WJ2MYXX4-bWgfdfwY.js.br} +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-bWgfdfwY.js.gz +0 -0
- package/dist/client/assets/settings-2-B-sr3wQM.js +1 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-DOsjXKPV.js → sizeCapture-INFHLROL-BYxi7e0R.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-BYxi7e0R.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-BYxi7e0R.js.gz +0 -0
- package/dist/client/assets/{sparkles-e9SkpP7a.js → sparkles-CCLflSFy.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-6s709_RT.js → stateDiagram-D77RDMKH-6vqC2h36.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-6vqC2h36.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-6vqC2h36.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Bb23lB9W.js +1 -0
- package/dist/client/assets/sun-B9_TfxlA.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-5R5dw9_R.js → swimlanes-42K2YHIH-B4qrXam7.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-B4qrXam7.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-B4qrXam7.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-CQ1XJUVU.js +8 -0
- package/dist/client/assets/swiper-DJjq1TYT.js +1 -0
- package/dist/client/assets/swiper-DJjq1TYT.js.br +0 -0
- package/dist/client/assets/swiper-DJjq1TYT.js.gz +0 -0
- package/dist/client/assets/syntaxHighlight-bcOB6oww.js +4 -0
- package/dist/client/assets/syntaxHighlight-bcOB6oww.js.br +0 -0
- package/dist/client/assets/syntaxHighlight-bcOB6oww.js.gz +0 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-B4YN0lsx.js → timeline-definition-24CTP7MA-D0_004MF.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-D0_004MF.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-D0_004MF.js.gz +0 -0
- package/dist/client/assets/triangle-alert-D3w7mA17.js +1 -0
- package/dist/client/assets/unplug-BSblgecr.js +1 -0
- package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js +1 -0
- package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.br +0 -0
- package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.gz +0 -0
- package/dist/client/assets/v4-EwEgHOG0.js +1 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-Wd83SmWI.js → vennDiagram-4TSXK5OY-Bqrx-47p.js} +1 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-Bqrx-47p.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-Bqrx-47p.js.gz +0 -0
- package/dist/client/assets/videoCompression-df1Ej3AR.js +3 -0
- package/dist/client/assets/videoCompression-df1Ej3AR.js.br +0 -0
- package/dist/client/assets/videoCompression-df1Ej3AR.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-CGsYvqWN.js → wardleyDiagram-VM6X3IG4-C4LCUdfd.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-C4LCUdfd.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-C4LCUdfd.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-ednJq1_u.js → xychartDiagram-S5SC5T6Z-E5AQcZVI.js} +1 -1
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-ednJq1_u.js.br → xychartDiagram-S5SC5T6Z-E5AQcZVI.js.br} +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-E5AQcZVI.js.gz +0 -0
- package/dist/client/index.html +2 -2
- package/dist/client/index.html.br +0 -0
- package/dist/client/index.html.gz +0 -0
- package/dist/client/sw-encrypted-background.js +1 -1
- package/dist/client/sw-encrypted-background.js.br +0 -0
- package/dist/client/sw-encrypted-background.js.gz +0 -0
- package/dist/client/sw.js +1 -1
- package/dist/client/sw.js.br +0 -0
- package/dist/client/sw.js.gz +0 -0
- package/dist/server/agent/collaborationDeliveryWorker.js +11 -0
- package/dist/server/agent/collaborationPrompt.js +4 -2
- package/dist/server/agent/collaborationRoutes.js +2 -0
- package/dist/server/agent/collaborationStore.js +7 -1
- package/dist/server/agent/sessionAttachmentRoutes.js +39 -0
- package/dist/server/agent/sessionChatRoutes.js +64 -0
- package/dist/server/agent/sessionViewModeRoutes.js +72 -0
- package/dist/server/android/recording.js +19 -17
- package/dist/server/cli.js +34 -0
- package/dist/server/entry.js +26 -17
- package/dist/server/federation/accessPolicy.js +8 -3
- package/dist/server/federation/authorization.js +26 -3
- package/dist/server/federation/invitations.js +27 -6
- package/dist/server/federation/relay.js +21 -3
- package/dist/server/federation/requestContext.js +5 -1
- package/dist/server/federation/resourceAccess.js +63 -0
- package/dist/server/federation/runtime.js +67 -18
- package/dist/server/federation/sessionSharing.js +39 -0
- package/dist/server/federation/socketDuplex.js +3 -3
- package/dist/server/routes/android.js +36 -7
- package/dist/server/routes/computer.js +14 -4
- package/dist/server/routes/filesystem.js +6 -3
- package/dist/server/routes/rdp.js +4 -3
- package/dist/server/routes/sharedFiles.js +51 -0
- package/dist/server/routes/terminal.js +83 -14
- package/dist/server/routes/vncReadOnly.js +134 -0
- package/dist/server/shared/shareResources.js +37 -0
- package/dist/server/todos/cli.js +91 -0
- package/dist/server/todos/routes.js +73 -0
- package/dist/server/todos/store.js +240 -0
- package/dist/server/todos/types.js +1 -0
- package/dist/server/utils/autoUpdate.js +7 -2
- package/dist/server/utils/clientSnapshotMaintenance.js +200 -0
- package/dist/server/utils/runtimeClient.js +79 -0
- package/dist/server/utils/serverCleanup.js +24 -0
- package/dist/server/utils/storageMaintenance.js +60 -0
- package/dist/server/utils/version.js +2 -0
- package/dist/server/utils/workspaceCacheMaintenance.js +158 -0
- package/docs/integrations.md +23 -0
- package/package.json +1 -1
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/App-TPJoJbGD.js +0 -187
- package/dist/client/assets/App-TPJoJbGD.js.br +0 -0
- package/dist/client/assets/App-TPJoJbGD.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-DzVy71gM.js +0 -9
- package/dist/client/assets/ArchitecturePanel-DzVy71gM.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-DzVy71gM.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js +0 -2
- package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-DN7BCzqC.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js +0 -1
- package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-B1PZuCC6.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-CG7g1LMH.js +0 -2
- package/dist/client/assets/ComputerControlView-BlI9Ai_k.js +0 -6
- package/dist/client/assets/ComputerControlView-BlI9Ai_k.js.br +0 -0
- package/dist/client/assets/ComputerControlView-BlI9Ai_k.js.gz +0 -0
- package/dist/client/assets/DagPlayground-V0hTKB-S.js +0 -1
- package/dist/client/assets/DagPlayground-V0hTKB-S.js.br +0 -0
- package/dist/client/assets/DagPlayground-V0hTKB-S.js.gz +0 -0
- package/dist/client/assets/DiffLab-DEw4y4Hk.js.br +0 -0
- package/dist/client/assets/DiffLab-DEw4y4Hk.js.gz +0 -0
- package/dist/client/assets/DiffReview-Cnnt3TMK.js +0 -1
- package/dist/client/assets/DiffReview-Cnnt3TMK.js.br +0 -0
- package/dist/client/assets/DiffReview-Cnnt3TMK.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-CDXsy0jE.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-CDXsy0jE.js.gz +0 -0
- package/dist/client/assets/DiffViewer-Dh40XiCM.js +0 -37
- package/dist/client/assets/DiffViewer-Dh40XiCM.js.br +0 -0
- package/dist/client/assets/DiffViewer-Dh40XiCM.js.gz +0 -0
- package/dist/client/assets/ModelPreview-BEiOgE0G.js.br +0 -0
- package/dist/client/assets/ModelPreview-BEiOgE0G.js.gz +0 -0
- package/dist/client/assets/RightSidebar-DiECnX5D.js +0 -1679
- package/dist/client/assets/RightSidebar-DiECnX5D.js.br +0 -0
- package/dist/client/assets/RightSidebar-DiECnX5D.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-ByzlUu_B.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-ByzlUu_B.js.gz +0 -0
- package/dist/client/assets/app-CKAFlgMD.js +0 -35
- package/dist/client/assets/app-CKAFlgMD.js.br +0 -0
- package/dist/client/assets/app-CKAFlgMD.js.gz +0 -0
- package/dist/client/assets/arc-BA6JM6vl.js.br +0 -0
- package/dist/client/assets/arc-BA6JM6vl.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-hCHxOfKw.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-OmEN9hUB.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-OmEN9hUB.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DfLTv8zh.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DfLTv8zh.js.gz +0 -0
- package/dist/client/assets/channel-gcmN0N0m.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-yxCv2Uqk.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-yxCv2Uqk.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-CdPjlb9f.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-CdPjlb9f.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-D1tOJung.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-D1tOJung.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DZjDfYNw.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DZjDfYNw.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-k4BRymfG.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-k4BRymfG.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-C4Wb5lqD.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-C4Wb5lqD.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-BvWKB1Xk.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-BvWKB1Xk.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-7tAkHD2P.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-7tAkHD2P.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-Bs6IPwks.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-Bs6IPwks.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CmYXaTya.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CmYXaTya.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CqxoefB7.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CqxoefB7.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-Dxp1MKPT.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-Dxp1MKPT.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-BKbWvvEr.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-BZnNaP7F.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-BZnNaP7F.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BXVlN_P7.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BXVlN_P7.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-CEdYDZU7.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-CEdYDZU7.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-Bbw8GPCZ.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-Bbw8GPCZ.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-CcFbtP2y.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-CcFbtP2y.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-sdzs-66-.js +0 -1
- package/dist/client/assets/gestureArbiter-sdzs-66-.js.br +0 -0
- package/dist/client/assets/gestureArbiter-sdzs-66-.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Eiust154.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Eiust154.js.gz +0 -0
- package/dist/client/assets/index-DtPsPZ7W.css +0 -1
- package/dist/client/assets/index-DtPsPZ7W.css.br +0 -0
- package/dist/client/assets/index-DtPsPZ7W.css.gz +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-qTwgXfx_.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DKy1msWo.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DKy1msWo.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-BxibybDd.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-BxibybDd.js.gz +0 -0
- package/dist/client/assets/layout-Bh6fKHRM.js.br +0 -0
- package/dist/client/assets/layout-Bh6fKHRM.js.gz +0 -0
- package/dist/client/assets/linear-SRlL3VWX.js.gz +0 -0
- package/dist/client/assets/mermaid.core-D0bcNdw3.js.br +0 -0
- package/dist/client/assets/mermaid.core-D0bcNdw3.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CImZ_aI0.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CImZ_aI0.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-f7-mFb1b.js +0 -2
- package/dist/client/assets/passwordBootstrap-f7-mFb1b.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-f7-mFb1b.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-BT4pTf8O.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-BT4pTf8O.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-C5K58ien.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-C5K58ien.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DzSugYXz.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DzSugYXz.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BY07SouQ.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BY07SouQ.js.gz +0 -0
- package/dist/client/assets/rdpSession-RNjO6yLw.js +0 -1
- package/dist/client/assets/rdpSession-RNjO6yLw.js.br +0 -0
- package/dist/client/assets/rdpSession-RNjO6yLw.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-B9K9yPKR.js +0 -1
- package/dist/client/assets/referenceLongPress-B9K9yPKR.js.br +0 -0
- package/dist/client/assets/referenceLongPress-B9K9yPKR.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-C7WieVuE.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-C7WieVuE.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BJsDWNs4.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BJsDWNs4.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BeJ_7853.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-DOsjXKPV.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-DOsjXKPV.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-6s709_RT.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-6s709_RT.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-B43A9Hsz.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-5R5dw9_R.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-5R5dw9_R.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoFbqN_4.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-B4YN0lsx.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-B4YN0lsx.js.gz +0 -0
- package/dist/client/assets/triangle-alert-BzBDJvJX.js +0 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-Wd83SmWI.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-Wd83SmWI.js.gz +0 -0
- package/dist/client/assets/videoCompression-Bsw--tMn.js +0 -3
- package/dist/client/assets/videoCompression-Bsw--tMn.js.br +0 -0
- package/dist/client/assets/videoCompression-Bsw--tMn.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CGsYvqWN.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CGsYvqWN.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-ednJq1_u.js.gz +0 -0
- /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css → swiper-C2J0D0kV.css} +0 -0
- /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css.br → swiper-C2J0D0kV.css.br} +0 -0
- /package/dist/client/assets/{gestureArbiter-C2J0D0kV.css.gz → swiper-C2J0D0kV.css.gz} +0 -0
|
Binary file
|
|
Binary file
|
package/dist/client/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let
|
|
1
|
+
if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let r={};const c=e=>n(e,o),d={module:{uri:o},exports:r,require:c};s[o]=Promise.all(i.map(e=>d[e]||c(e))).then(e=>(a(...e),r))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"d9f1254be198520fd331492bd81d83ec"},{url:"assets/app-BMJesFDU.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-Dea8wJF3.js",revision:null},{url:"assets/index-CA1fR_jI.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
|
package/dist/client/sw.js.br
CHANGED
|
Binary file
|
package/dist/client/sw.js.gz
CHANGED
|
Binary file
|
|
@@ -120,6 +120,17 @@ export class CollaborationDeliveryWorker {
|
|
|
120
120
|
const pending = store.inbox(id, { pendingOnly: true, limit: 1 });
|
|
121
121
|
if (!pending.length)
|
|
122
122
|
return;
|
|
123
|
+
// Removal is an observed inventory fact, so this recipient cannot recover
|
|
124
|
+
// through a network retry. Preserve the message as a failed delivery.
|
|
125
|
+
if (route.state === 'offline' && (route.reason === 'SESSION_REMOVED' || route.reason === 'SESSION_REMOVED_DURING_RECOVERY')) {
|
|
126
|
+
const message = pending[0];
|
|
127
|
+
store.recordTransport(message.id, { ...store.diagnostic(message.id), relay_online: null, peer_reachable: false,
|
|
128
|
+
attempt_count: store.diagnostic(message.id)?.attempt_count ?? 0, next_retry_at: null,
|
|
129
|
+
last_error: route.reason, checked_at: Date.now(), route_state: route.state, route_diagnostics: route.diagnostics });
|
|
130
|
+
store.fail(message.id, route.reason);
|
|
131
|
+
this.failures.delete(id);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
123
134
|
if (route.state !== 'ready' || !route.write) {
|
|
124
135
|
this.retry(id, pending, route.reason ?? route.state, false, route);
|
|
125
136
|
return;
|
|
@@ -89,7 +89,7 @@ export function formatCollaborationDelivery(input) {
|
|
|
89
89
|
const sourceSession = message.fromSessionId ? sessionsById.get(message.fromSessionId) : null;
|
|
90
90
|
const source = message.fromSessionId
|
|
91
91
|
? sanitizeCollaborationName(sourceSession?.name ?? message.fromSessionId)
|
|
92
|
-
: message.integrationOrigin ? `后台接入 ${sanitizeCollaborationName(message.integrationOrigin.integrationId, 80)}` : '用户';
|
|
92
|
+
: message.integrationOrigin ? message.integrationOrigin.source === 'session-chat' ? '网页对话用户' : `后台接入 ${sanitizeCollaborationName(message.integrationOrigin.integrationId, 80)}` : '用户';
|
|
93
93
|
const token = tokens.get(message.id) ?? message.id;
|
|
94
94
|
const bytes = Buffer.byteLength(message.content);
|
|
95
95
|
// A remote recipient's CLI cannot detect its identity (the session is not
|
|
@@ -103,7 +103,9 @@ export function formatCollaborationDelivery(input) {
|
|
|
103
103
|
const fannedNames = (message.fanOutIds ?? [])
|
|
104
104
|
.map((sessionId) => sanitizeCollaborationName(sessionsById.get(sessionId)?.name ?? sessionId));
|
|
105
105
|
blocks.push(formatCollaborationMessage({ ...message, content: body }, source, fannedNames, fence, token));
|
|
106
|
-
if (message.integrationOrigin)
|
|
106
|
+
if (message.integrationOrigin?.source === 'session-chat')
|
|
107
|
+
blocks.push(`此消息来自用户的普通对话界面。请自然地与用户交流,并用 td collab --session ${input.targetSessionId} reply ${token} \"答复正文\" --response-kind result --idempotency-key <稳定唯一key> --text 将面向用户的答复写回对话。终端中的普通输出不会成为聊天回复。需要补充问题时也使用 reply;不要仅在终端打印答案。`);
|
|
108
|
+
else if (message.integrationOrigin)
|
|
107
109
|
blocks.push(`此消息来自后台程序,使用原消息 id 回复:td collab --session ${input.targetSessionId} reply ${token} "答复正文" --response-kind result --idempotency-key <稳定唯一key> --text\n需要时用 --response-kind ack|progress 明确回复收到或进展;result 提交结果。回复持久保存为 stored 并主动推送给后台,不创建看板任务,不代表用户验收。`);
|
|
108
110
|
}
|
|
109
111
|
// The shell header names the group only when every block belongs to one;
|
|
@@ -162,6 +162,8 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, di
|
|
|
162
162
|
};
|
|
163
163
|
router.get('/capabilities', run((_req, res) => {
|
|
164
164
|
res.json({ protocol_version: 2, server_version: getTermdockVersion(), limits: COLLAB_LIMITS,
|
|
165
|
+
relay_authorization_errors: true, relay_authorization_errors_min_version: '1.4.351',
|
|
166
|
+
relay_self_target_guard: true, relay_self_target_guard_min_version: '1.4.351',
|
|
165
167
|
route_diagnostics: !!diagnoseRoute, route_identity_recovery: !!diagnoseRoute, route_identity_recovery_min_version: '1.4.321',
|
|
166
168
|
agent_launch_generation_consistency: true, agent_launch_generation_consistency_min_version: '1.4.322',
|
|
167
169
|
terminal_input_check_diagnostics: true,
|
|
@@ -727,10 +727,16 @@ export class CollaborationStore {
|
|
|
727
727
|
this.applyContext(incoming, this.context(group.id));
|
|
728
728
|
if (existing && stableJson(existing) === stableJson(incoming))
|
|
729
729
|
return;
|
|
730
|
+
// Remote directory snapshots contain output/observation timestamps that
|
|
731
|
+
// change on every poll. Keep them current for readers without rewriting
|
|
732
|
+
// the complete message journal or notifying durable-change subscribers.
|
|
733
|
+
const metadataChanged = !existing
|
|
734
|
+
|| stableJson({ ...existing, remoteSessions: undefined }) !== stableJson({ ...incoming, remoteSessions: undefined });
|
|
730
735
|
this.document.groups = [...this.document.groups.filter((item) => item.id !== group.id), incoming];
|
|
731
736
|
if (group.deleted)
|
|
732
737
|
this.document.messages = this.document.messages.filter((item) => item.groupId !== group.id);
|
|
733
|
-
|
|
738
|
+
if (metadataChanged)
|
|
739
|
+
this.persist();
|
|
734
740
|
}
|
|
735
741
|
/** Promote the source group and its complete history in one atomic file replacement. */
|
|
736
742
|
promoteGroup(id, group, expectedUpdatedAt) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { Router } from 'express';
|
|
5
|
+
import { encryptedRequestSubject } from '../federation/requestContext.js';
|
|
6
|
+
import { handleFileUpload } from '../routes/filesystem.js';
|
|
7
|
+
/** A Session input capability may add new attachments, never choose a server path. */
|
|
8
|
+
export function sessionAttachmentRoutes(directory, resolve) {
|
|
9
|
+
const router = Router();
|
|
10
|
+
router.post('/:sessionId/chat/attachments', async (req, res) => {
|
|
11
|
+
const subject = encryptedRequestSubject(req), session = subject && resolve(req.params.sessionId);
|
|
12
|
+
if (!session) {
|
|
13
|
+
res.status(404).json({ error: '会话不可用' });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (Object.keys(req.query).some(key => key !== 'fileCount')) {
|
|
17
|
+
res.status(400).json({ error: '附件不能指定服务端保存目录' });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let destination;
|
|
21
|
+
try {
|
|
22
|
+
const root = path.resolve(directory, createHash('sha256').update(session).digest('hex'));
|
|
23
|
+
await fs.mkdir(root, { recursive: true, mode: 0o700 });
|
|
24
|
+
if (await fs.realpath(root) !== root)
|
|
25
|
+
throw new Error('附件目录不可用');
|
|
26
|
+
destination = await fs.mkdtemp(path.join(root, 'upload-'));
|
|
27
|
+
await handleFileUpload(req, res, destination);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
if (!res.headersSent && !res.destroyed)
|
|
31
|
+
res.status(500).json({ error: '附件上传失败,请重试' });
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
if (destination)
|
|
35
|
+
await fs.rmdir(destination).catch(() => { });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return router;
|
|
39
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { Router } from 'express';
|
|
3
|
+
import { encryptedRequestSubject } from '../federation/requestContext.js';
|
|
4
|
+
/** Clients authorized to view this Session share its durable chat history.
|
|
5
|
+
* Per-device delivery addresses remain stable for retries and explicit replies. */
|
|
6
|
+
export function sessionChatRoutes(options) {
|
|
7
|
+
const router = Router();
|
|
8
|
+
const context = (req) => {
|
|
9
|
+
const session = options.resolve(String(req.params.sessionId));
|
|
10
|
+
const subject = encryptedRequestSubject(req);
|
|
11
|
+
if (!session || !subject)
|
|
12
|
+
return null;
|
|
13
|
+
const principal = `webchat-${createHash('sha256').update(subject).digest('hex').slice(0, 48)}`;
|
|
14
|
+
const groupName = `Session 对话 ${session.sessionId}`;
|
|
15
|
+
return { session, principal, groupName };
|
|
16
|
+
};
|
|
17
|
+
router.get('/:sessionId/chat', (req, res) => {
|
|
18
|
+
const ctx = context(req);
|
|
19
|
+
if (!ctx) {
|
|
20
|
+
res.status(404).json({ error: '会话不可用,请刷新连接' });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const group = options.store.list().find(g => g.name === ctx.groupName && !g.federated && g.sessionIds.length === 1 && g.sessionIds[0] === ctx.session.sessionId);
|
|
24
|
+
const canSeeRequest = (message) => message?.integrationOrigin?.source === 'session-chat';
|
|
25
|
+
const messages = group ? options.store.listMessages(group.id, 500).filter(message => {
|
|
26
|
+
if (canSeeRequest(message))
|
|
27
|
+
return true;
|
|
28
|
+
const original = message.toPrincipalId && message.replyTo ? options.store.getMessage(message.replyTo) : null;
|
|
29
|
+
return original?.groupId === group.id && message.toPrincipalId === original.integrationOrigin?.integrationId && canSeeRequest(original);
|
|
30
|
+
}).map(m => ({ id: m.id, role: m.toPrincipalId ? 'assistant' : 'user', content: m.content, createdAt: m.createdAt, status: m.status === 'read' ? 'delivered' : m.status, replyTo: m.replyTo, requestId: m.idempotencyKey, responseKind: m.responseKind })) : [];
|
|
31
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
32
|
+
res.json({ messages, agentAvailable: !!ctx.session.agent, agent: ctx.session.agent ? { slug: ctx.session.agent.slug, displayName: ctx.session.agent.displayName || ctx.session.agent.slug } : null });
|
|
33
|
+
});
|
|
34
|
+
router.post('/:sessionId/chat', (req, res) => {
|
|
35
|
+
const ctx = context(req);
|
|
36
|
+
if (!ctx) {
|
|
37
|
+
res.status(404).json({ error: '会话不可用,请刷新连接' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!ctx.session.agent) {
|
|
41
|
+
res.status(409).json({ error: '当前会话未识别到 Agent,请切换终端确认 Agent 已启动' });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const body = req.body;
|
|
45
|
+
if (!body || Object.keys(body).some(k => !['content', 'requestId'].includes(k)) || typeof body.content !== 'string' || !body.content.trim() || Buffer.byteLength(body.content) > 32000 || typeof body.requestId !== 'string' || !/^[a-zA-Z0-9_-]{16,100}$/.test(body.requestId)) {
|
|
46
|
+
res.status(400).json({ error: '消息为空、过长或请求无效' });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
let group = options.store.list().find(g => g.name === ctx.groupName && !g.federated && g.sessionIds.length === 1 && g.sessionIds[0] === ctx.session.sessionId);
|
|
51
|
+
if (!group) {
|
|
52
|
+
group = options.store.save({ name: ctx.groupName, sessionIds: [ctx.session.sessionId] });
|
|
53
|
+
options.store.setLocalGroupArchived(group.id, true, group.updatedAt, `chat-${group.id}`);
|
|
54
|
+
}
|
|
55
|
+
const [message] = options.store.send({ groupId: group.id, fromSessionId: null, toSessionIds: [ctx.session.sessionId], kind: 'ask', content: body.content.trim(), integrationOrigin: { integrationId: ctx.principal, source: 'session-chat' }, idempotencyKey: body.requestId, threadId: ctx.principal });
|
|
56
|
+
options.deliver(ctx.session.sessionId);
|
|
57
|
+
res.json({ id: message.id, status: message.status, createdAt: message.createdAt });
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
res.status(409).json({ error: error instanceof Error ? error.message : '发送失败,草稿已保留' });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return router;
|
|
64
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { readFileSync, mkdirSync, writeFileSync, renameSync, unlinkSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { encryptedRequestSubject } from '../federation/requestContext.js';
|
|
6
|
+
export class SessionViewModeStore {
|
|
7
|
+
filePath;
|
|
8
|
+
constructor(filePath) {
|
|
9
|
+
this.filePath = filePath;
|
|
10
|
+
}
|
|
11
|
+
read() {
|
|
12
|
+
try {
|
|
13
|
+
const data = JSON.parse(readFileSync(this.filePath, 'utf8'));
|
|
14
|
+
if (data.version !== 1 || !data.sessions || typeof data.sessions !== 'object' || Array.isArray(data.sessions))
|
|
15
|
+
throw new Error('Invalid session view preferences');
|
|
16
|
+
for (const value of Object.values(data.sessions))
|
|
17
|
+
if (!value || !['terminal', 'chat'].includes(value.mode) || !Number.isSafeInteger(value.updatedAt))
|
|
18
|
+
throw new Error('Invalid session view preference');
|
|
19
|
+
return data.sessions;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error.code === 'ENOENT')
|
|
23
|
+
return {};
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
get(id) { const records = this.read(); return Object.prototype.hasOwnProperty.call(records, id) ? records[id] : null; }
|
|
28
|
+
set(id, mode) {
|
|
29
|
+
const records = this.read(), previous = Object.prototype.hasOwnProperty.call(records, id) ? records[id] : null;
|
|
30
|
+
const next = { mode, updatedAt: Math.max(Date.now(), (previous?.updatedAt || 0) + 1) };
|
|
31
|
+
mkdirSync(dirname(this.filePath), { recursive: true, mode: 0o700 });
|
|
32
|
+
const temporary = `${this.filePath}.${randomUUID()}.tmp`;
|
|
33
|
+
try {
|
|
34
|
+
writeFileSync(temporary, JSON.stringify({ version: 1, sessions: { ...records, [id]: next } }), { mode: 0o600, flag: 'wx' });
|
|
35
|
+
renameSync(temporary, this.filePath);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
try {
|
|
39
|
+
unlinkSync(temporary);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
if (error.code !== 'ENOENT')
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return next;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function sessionViewModeRoutes(store, resolve) {
|
|
50
|
+
const router = Router();
|
|
51
|
+
router.route('/:sessionId/view-mode').get((req, res) => {
|
|
52
|
+
const id = encryptedRequestSubject(req) && resolve(req.params.sessionId);
|
|
53
|
+
if (!id) {
|
|
54
|
+
res.status(404).json({ error: '会话不可用' });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
58
|
+
res.json(store.get(id) || { mode: null, updatedAt: 0 });
|
|
59
|
+
}).put((req, res) => {
|
|
60
|
+
const id = encryptedRequestSubject(req) && resolve(req.params.sessionId);
|
|
61
|
+
if (!id) {
|
|
62
|
+
res.status(404).json({ error: '会话不可用' });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!req.body || Object.keys(req.body).some(key => key !== 'mode') || !['chat', 'terminal'].includes(req.body.mode)) {
|
|
66
|
+
res.status(400).json({ error: '显示模式无效' });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
res.json(store.set(id, req.body.mode));
|
|
70
|
+
});
|
|
71
|
+
return router;
|
|
72
|
+
}
|
|
@@ -43,28 +43,29 @@ export class AndroidRecordings {
|
|
|
43
43
|
}
|
|
44
44
|
})();
|
|
45
45
|
}
|
|
46
|
-
async list(serial) {
|
|
46
|
+
async list(serial, ownerId) {
|
|
47
47
|
await this.load();
|
|
48
|
-
return [...this.jobs.values()].filter(job => job.info.serial === serial && !job.info.savedPath).map(job => ({ ...job.info }));
|
|
48
|
+
return [...this.jobs.values()].filter(job => job.info.serial === serial && !job.info.savedPath && job.info.ownerId === ownerId).map(job => ({ ...job.info }));
|
|
49
49
|
}
|
|
50
|
-
start(serial) {
|
|
51
|
-
const
|
|
50
|
+
start(serial, ownerId) {
|
|
51
|
+
const key = JSON.stringify([serial, ownerId]);
|
|
52
|
+
const pending = this.starts.get(key);
|
|
52
53
|
if (pending)
|
|
53
54
|
return pending;
|
|
54
|
-
const promise = this.startNew(serial).finally(() => this.starts.delete(
|
|
55
|
-
this.starts.set(
|
|
55
|
+
const promise = this.startNew(serial, ownerId).finally(() => this.starts.delete(key));
|
|
56
|
+
this.starts.set(key, promise);
|
|
56
57
|
return promise;
|
|
57
58
|
}
|
|
58
|
-
async startNew(serial) {
|
|
59
|
+
async startNew(serial, ownerId) {
|
|
59
60
|
await this.load();
|
|
60
|
-
const active = [...this.jobs.values()].find(job => job.info.serial === serial && job.child);
|
|
61
|
+
const active = [...this.jobs.values()].find(job => job.info.serial === serial && job.info.ownerId === ownerId && job.child);
|
|
61
62
|
if (active)
|
|
62
63
|
return { ...active.info };
|
|
63
64
|
const { bin, serverJar } = await resolveScrcpyBinaries();
|
|
64
65
|
if ([...this.jobs.values()].filter(job => ['starting', 'recording', 'stopping'].includes(job.info.status)).length >= 3)
|
|
65
66
|
throw new Error('同时最多录制三个设备');
|
|
66
67
|
const id = randomUUID();
|
|
67
|
-
const job = { info: { id, serial, name: `termdock-recording-${id}.mp4`, size: 0, startedAt: Date.now(), status: 'starting' } };
|
|
68
|
+
const job = { info: { id, serial, name: `termdock-recording-${id}.mp4`, size: 0, startedAt: Date.now(), status: 'starting', ...(ownerId ? { ownerId } : {}) } };
|
|
68
69
|
this.jobs.set(id, job);
|
|
69
70
|
await this.persist(job);
|
|
70
71
|
const child = spawn(bin, [
|
|
@@ -120,15 +121,16 @@ export class AndroidRecordings {
|
|
|
120
121
|
await this.persist(job);
|
|
121
122
|
return { ...job.info };
|
|
122
123
|
}
|
|
123
|
-
async get(id) {
|
|
124
|
+
async get(id, ownerId) {
|
|
124
125
|
await this.load();
|
|
125
126
|
const job = this.jobs.get(id);
|
|
126
|
-
if (!job)
|
|
127
|
+
if (!job || ownerId && job.info.ownerId !== ownerId)
|
|
127
128
|
throw new Error('录像不存在');
|
|
128
129
|
return job;
|
|
129
130
|
}
|
|
130
|
-
async
|
|
131
|
-
|
|
131
|
+
async info(id, ownerId) { return { ...(await this.get(id, ownerId)).info }; }
|
|
132
|
+
async stop(id, ownerId) {
|
|
133
|
+
const job = await this.get(id, ownerId);
|
|
132
134
|
if (job.child && job.info.status !== 'stopping') {
|
|
133
135
|
job.info.status = 'stopping';
|
|
134
136
|
job.child.kill('SIGINT');
|
|
@@ -139,8 +141,8 @@ export class AndroidRecordings {
|
|
|
139
141
|
await job.done;
|
|
140
142
|
return { ...job.info };
|
|
141
143
|
}
|
|
142
|
-
async save(id, directory) {
|
|
143
|
-
const job = await this.get(id);
|
|
144
|
+
async save(id, directory, ownerId) {
|
|
145
|
+
const job = await this.get(id, ownerId);
|
|
144
146
|
if (job.info.savedPath) {
|
|
145
147
|
if (directory && join(directory, job.info.name) !== job.info.savedPath)
|
|
146
148
|
throw new Error(`录像已保存到 ${job.info.savedPath}`);
|
|
@@ -158,11 +160,11 @@ export class AndroidRecordings {
|
|
|
158
160
|
await fs.rm(source, { force: true }).catch(() => { });
|
|
159
161
|
return destination;
|
|
160
162
|
}
|
|
161
|
-
async discard(id) {
|
|
163
|
+
async discard(id, ownerId) {
|
|
162
164
|
await this.load();
|
|
163
165
|
if (!this.jobs.has(id))
|
|
164
166
|
return;
|
|
165
|
-
const job = await this.get(id);
|
|
167
|
+
const job = await this.get(id, ownerId);
|
|
166
168
|
if (job.info.savedPath) {
|
|
167
169
|
await fs.rm(join(this.directory, `${id}.json`), { force: true });
|
|
168
170
|
this.jobs.delete(id);
|
package/dist/server/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { parseTodoCommand, executeTodoCommand, TODO_HELP } from './todos/cli.js';
|
|
2
3
|
// libuv 线程池默认只有 4 个线程,慢/挂起的异步 IO(fs.promises、crypto 等)
|
|
3
4
|
// 会把池耗尽,表现为整个服务的 IO 全部卡死。必须在任何异步 fs 调用之前
|
|
4
5
|
// 设置(同步 fs 不占线程池,所以放在文件体顶部仍然足够早)。
|
|
@@ -213,6 +214,7 @@ Short commands:
|
|
|
213
214
|
pi Same as agent-plugin
|
|
214
215
|
n [message] Progress reminder; run td n for help and Agent instructions
|
|
215
216
|
notify [message] Same as n (see td n --prompt)
|
|
217
|
+
todo Manage todos (see td todo --help)
|
|
216
218
|
automation Manage scheduled tasks (see td automation --help)
|
|
217
219
|
integration Manage local scoped integrations (see integration help)
|
|
218
220
|
collab status Show this Session's collaboration groups and peers
|
|
@@ -669,6 +671,7 @@ function parseArgs(argv) {
|
|
|
669
671
|
let integration;
|
|
670
672
|
let collab;
|
|
671
673
|
let automation;
|
|
674
|
+
let todo;
|
|
672
675
|
let notify;
|
|
673
676
|
// Short command aliases for the common path. Keep these positional-only so
|
|
674
677
|
// long-form flags remain the single source of truth for option semantics.
|
|
@@ -796,6 +799,16 @@ function parseArgs(argv) {
|
|
|
796
799
|
}
|
|
797
800
|
argv = [];
|
|
798
801
|
}
|
|
802
|
+
else if (command === 'todo') {
|
|
803
|
+
try {
|
|
804
|
+
todo = parseTodoCommand(argv.slice(1));
|
|
805
|
+
}
|
|
806
|
+
catch (error) {
|
|
807
|
+
console.error(JSON.stringify({ ok: false, error: getMessage(error) }));
|
|
808
|
+
process.exit(1);
|
|
809
|
+
}
|
|
810
|
+
argv = [];
|
|
811
|
+
}
|
|
799
812
|
else if (command === 'automation') {
|
|
800
813
|
try {
|
|
801
814
|
automation = parseAutomationCommand(argv.slice(1));
|
|
@@ -1199,6 +1212,7 @@ function parseArgs(argv) {
|
|
|
1199
1212
|
integration,
|
|
1200
1213
|
collab,
|
|
1201
1214
|
automation,
|
|
1215
|
+
todo,
|
|
1202
1216
|
notify,
|
|
1203
1217
|
};
|
|
1204
1218
|
}
|
|
@@ -3489,6 +3503,26 @@ async function main() {
|
|
|
3489
3503
|
await runNotify(options.notify);
|
|
3490
3504
|
return;
|
|
3491
3505
|
}
|
|
3506
|
+
if (options.todo) {
|
|
3507
|
+
if (options.todo.action === 'help') {
|
|
3508
|
+
console.log(TODO_HELP);
|
|
3509
|
+
return;
|
|
3510
|
+
}
|
|
3511
|
+
const state = getRunningState();
|
|
3512
|
+
if (!state?.localApiToken) {
|
|
3513
|
+
console.error(JSON.stringify({ ok: false, error: 'Termdock is not running' }));
|
|
3514
|
+
process.exitCode = 1;
|
|
3515
|
+
return;
|
|
3516
|
+
}
|
|
3517
|
+
const baseUrl = state.localUrl ?? `${state.scheme ?? 'http'}://${state.host === '0.0.0.0' ? 'localhost' : state.host}:${state.port}`;
|
|
3518
|
+
process.exitCode = await executeTodoCommand(options.todo, {
|
|
3519
|
+
request: (method, endpoint, body) => method === 'POST'
|
|
3520
|
+
? postLocalJson(baseUrl, state.localApiToken, endpoint, body)
|
|
3521
|
+
: getLocalJson(baseUrl, state.localApiToken, endpoint),
|
|
3522
|
+
stdin: readStdinText, write: line => console.log(line),
|
|
3523
|
+
});
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3492
3526
|
if (options.automation) {
|
|
3493
3527
|
await runAutomation(options.automation);
|
|
3494
3528
|
return;
|
package/dist/server/entry.js
CHANGED
|
@@ -52,10 +52,12 @@ import { isAllowedHost, isUpgradeOriginAllowed, validateHostMiddleware, validate
|
|
|
52
52
|
import { getCookieSecurityOptions, setSecureCookieMode } from './utils/cookieSecurity.js';
|
|
53
53
|
import { requestDeadlineMiddleware } from './utils/requestDeadline.js';
|
|
54
54
|
import { RuntimeMonitor } from './utils/runtimeMonitor.js';
|
|
55
|
+
import { serverCleanup } from './utils/serverCleanup.js';
|
|
55
56
|
import { startOnboardingServer, stopOnboardingServer, getOnboardingServerUrl } from './onboardingServer.js';
|
|
56
57
|
import { CertificateWatcher } from './certificateWatcher.js';
|
|
57
58
|
import { startTermdockLogMaintenance, writeDiffTraceLog, writeErrorLog, writeJsonLog, writeTextLog, } from './utils/serverLogger.js';
|
|
58
|
-
import { indexRetainedClientModules, pinBundledRuntimeClientDist } from './utils/runtimeClient.js';
|
|
59
|
+
import { indexRetainedClientModules, pinBundledRuntimeClientDist, resolveRetainedClientModule } from './utils/runtimeClient.js';
|
|
60
|
+
import { startGeneratedStorageMaintenance } from './utils/storageMaintenance.js';
|
|
59
61
|
import { installCrashForensics } from './utils/crashForensics.js';
|
|
60
62
|
import { getTermdockVersion, TERMDOCK_CAPABILITIES, TERMDOCK_PROTOCOL_VERSION, } from './utils/version.js';
|
|
61
63
|
import { PORT, DEFAULT_HOST } from './config.js';
|
|
@@ -363,6 +365,7 @@ export function createApp(options = {}) {
|
|
|
363
365
|
app.use('/api/computer', computerRoutes);
|
|
364
366
|
if (fs.existsSync(bundledClientIndexPath)) {
|
|
365
367
|
const clientPath = pinBundledRuntimeClientDist(bundledClientDistPath);
|
|
368
|
+
app.locals.runtimeClientPath = clientPath;
|
|
366
369
|
const compression = createStaticCompressionMiddleware(clientPath);
|
|
367
370
|
const staticFiles = express.static(clientPath, {
|
|
368
371
|
setHeaders: (res, filePath, stat) => {
|
|
@@ -395,7 +398,7 @@ export function createApp(options = {}) {
|
|
|
395
398
|
});
|
|
396
399
|
const retainedModules = indexRetainedClientModules();
|
|
397
400
|
app.get(/^\/assets\//, (req, res, next) => {
|
|
398
|
-
const retainedPath = retainedModules
|
|
401
|
+
const retainedPath = resolveRetainedClientModule(retainedModules, req.path);
|
|
399
402
|
if (!retainedPath) {
|
|
400
403
|
// Never cache a missing module or return the SPA HTML as JavaScript.
|
|
401
404
|
res.setHeader('Cache-Control', 'no-store');
|
|
@@ -403,7 +406,7 @@ export function createApp(options = {}) {
|
|
|
403
406
|
return;
|
|
404
407
|
}
|
|
405
408
|
setStaticCacheHeaders(req, res);
|
|
406
|
-
res.sendFile(retainedPath, error => {
|
|
409
|
+
res.sendFile(path.basename(retainedPath), { root: path.dirname(retainedPath) }, error => {
|
|
407
410
|
if (!error)
|
|
408
411
|
return;
|
|
409
412
|
if (res.headersSent)
|
|
@@ -414,7 +417,7 @@ export function createApp(options = {}) {
|
|
|
414
417
|
});
|
|
415
418
|
app.get(/^(?!\/api(?:\/|$)|\/health$|\/onboarding(?:\/|$)|\/ca(?:\/|$)).*/, (req, res) => {
|
|
416
419
|
setStaticCacheHeaders(req, res);
|
|
417
|
-
res.sendFile(
|
|
420
|
+
res.sendFile('index.html', { root: clientPath });
|
|
418
421
|
});
|
|
419
422
|
}
|
|
420
423
|
// Never expose parser errors, submitted passwords, or stack traces to callers.
|
|
@@ -471,9 +474,14 @@ export function startServer(options = {}) {
|
|
|
471
474
|
runtimeMonitor,
|
|
472
475
|
});
|
|
473
476
|
const { server, scheme } = createServerForApp(app, options);
|
|
477
|
+
const onServerClose = serverCleanup(server);
|
|
478
|
+
if (typeof app.locals.runtimeClientPath === 'string')
|
|
479
|
+
onServerClose(startGeneratedStorageMaintenance({
|
|
480
|
+
stateDirectory: path.join(homedir(), '.termdock'), clientDirectory: app.locals.runtimeClientPath,
|
|
481
|
+
}));
|
|
474
482
|
let webTransport;
|
|
475
483
|
const webTransportDescriptor = () => webTransport?.descriptor();
|
|
476
|
-
|
|
484
|
+
onServerClose(() => webTransport?.close());
|
|
477
485
|
const collaborationChannels = new Map();
|
|
478
486
|
const reverseCollaboration = (id) => [...(collaborationChannels.get(id) ?? [])].find(rpc => !rpc.closed);
|
|
479
487
|
let collaborationService;
|
|
@@ -485,6 +493,7 @@ export function startServer(options = {}) {
|
|
|
485
493
|
const desktopTargets = () => desktopDirectTargets(path.join(homedir(), '.termdock', 'desktop.json'), federationServiceId);
|
|
486
494
|
const routeAccess = new RouteAccess(path.join(homedir(), '.termdock', 'federation', 'routes.json'), Date.now, (subjectId, targetServiceId) => routeInvitations?.allows(subjectId, targetServiceId) === true || collaborationTransport?.canRoute(subjectId, targetServiceId) === true, desktopTargets, () => activeRouteIds());
|
|
487
495
|
const relayRouter = new RelayRouter({
|
|
496
|
+
isLocalTarget: id => id === federationServiceId,
|
|
488
497
|
authenticate: context => context,
|
|
489
498
|
allowRegister: (principal, serviceId) => routeAccess.allowRegister(principal, serviceId),
|
|
490
499
|
allowRoute: (principal, serviceId) => routeAccess.allowRoute(principal, serviceId),
|
|
@@ -511,11 +520,11 @@ export function startServer(options = {}) {
|
|
|
511
520
|
refreshDirectTargets();
|
|
512
521
|
const desktopRoutesTimer = setInterval(refreshDirectTargets, 2000);
|
|
513
522
|
desktopRoutesTimer.unref();
|
|
514
|
-
|
|
523
|
+
onServerClose(() => { clearInterval(desktopRoutesTimer); for (const target of dynamicDirectTargets.values())
|
|
515
524
|
target.close(); });
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
525
|
+
onServerClose(() => relayRouter.close());
|
|
526
|
+
onServerClose(() => { void stopAllScrcpySessions(); void androidRecordings.stopAll(); });
|
|
527
|
+
onServerClose(stopComputerBridges);
|
|
519
528
|
const federation = createFederationRuntime(app, path.join(homedir(), '.termdock', 'federation'), {
|
|
520
529
|
terminal: handleTerminalWebSocket, control: handleControlWebSocket, android: handleAndroidWebSocket, computer: handleComputerWebSocket,
|
|
521
530
|
}, {
|
|
@@ -654,7 +663,7 @@ export function startServer(options = {}) {
|
|
|
654
663
|
messages: collaborationStore, taskStore: collaborationTaskStore, tasks: collaborationTasks, peers: collaborationService, sessions: integrationSessionAdapter });
|
|
655
664
|
await integration.listen();
|
|
656
665
|
app.locals.integrationRuntime = integration;
|
|
657
|
-
|
|
666
|
+
onServerClose(() => { void integration?.close(); });
|
|
658
667
|
}
|
|
659
668
|
catch {
|
|
660
669
|
await integration?.close();
|
|
@@ -662,11 +671,11 @@ export function startServer(options = {}) {
|
|
|
662
671
|
}
|
|
663
672
|
}
|
|
664
673
|
collaborationTasks.start();
|
|
665
|
-
|
|
674
|
+
onServerClose(() => collaborationTasks.close());
|
|
666
675
|
collaborationService.start();
|
|
667
|
-
|
|
676
|
+
onServerClose(() => collaborationService?.close());
|
|
668
677
|
collaborationTransport.start();
|
|
669
|
-
|
|
678
|
+
onServerClose(() => collaborationTransport?.close());
|
|
670
679
|
entrySubjectAllowed = subjectId => runtime.store.authorize({ subjectId, serviceId: runtime.serviceId, action: 'authorization.manage' }).allowed;
|
|
671
680
|
routeInvitations = new RouteInvitationStore({
|
|
672
681
|
filePath: path.join(homedir(), '.termdock', 'federation', 'route-invitations.json'), serviceId: runtime.serviceId,
|
|
@@ -687,10 +696,10 @@ export function startServer(options = {}) {
|
|
|
687
696
|
localOrigin: `${scheme}://${localAuthority}:${port}`, ...(localCa ? { localCa } : {}),
|
|
688
697
|
});
|
|
689
698
|
selfRelay.start();
|
|
690
|
-
|
|
699
|
+
onServerClose(() => selfRelay.close());
|
|
691
700
|
}).catch(() => console.error('Route invitations unavailable; uninitialized route grants remain denied.'));
|
|
692
701
|
void federation.catch(() => console.error('Encrypted access initialization failed; business access remains closed.'));
|
|
693
|
-
|
|
702
|
+
onServerClose(() => { void federation.then(runtime => runtime.close()).catch(() => { }); });
|
|
694
703
|
server.headersTimeout = 10_000;
|
|
695
704
|
server.requestTimeout = 120_000;
|
|
696
705
|
server.keepAliveTimeout = 5_000;
|
|
@@ -698,7 +707,7 @@ export function startServer(options = {}) {
|
|
|
698
707
|
server.maxRequestsPerSocket = 1000;
|
|
699
708
|
server.maxConnections = 1024;
|
|
700
709
|
server.on('connection', (socket) => runtimeMonitor.trackSocket(socket));
|
|
701
|
-
|
|
710
|
+
onServerClose(() => runtimeMonitor.stop());
|
|
702
711
|
setSecureCookieMode(scheme === 'https');
|
|
703
712
|
const certWatcher = new CertificateWatcher({
|
|
704
713
|
enabled: scheme === 'https' && Boolean(options.httpsCertPath && options.httpsKeyPath),
|
|
@@ -864,7 +873,7 @@ export function startServer(options = {}) {
|
|
|
864
873
|
console.error('Server error:', error);
|
|
865
874
|
process.exit(1);
|
|
866
875
|
});
|
|
867
|
-
|
|
876
|
+
onServerClose(() => {
|
|
868
877
|
stopLogMaintenance();
|
|
869
878
|
crashForensics.dispose();
|
|
870
879
|
certWatcher.stop();
|
|
@@ -90,13 +90,18 @@ export function resolveAccessRequest(method, path) {
|
|
|
90
90
|
return { action: 'file.read' };
|
|
91
91
|
if (method === 'POST' && route === 'create')
|
|
92
92
|
return { action: 'service.create-session' };
|
|
93
|
-
const
|
|
93
|
+
const attachment = /^([^/]+)\/chat\/attachments$/.exec(route);
|
|
94
|
+
if (method === 'POST' && attachment && !reservedSessionIds.has(attachment[1].toLowerCase()))
|
|
95
|
+
return { action: 'session.input', sessionId: attachment[1] };
|
|
96
|
+
const session = /^([^/]+)(?:\/(health|attach|stream|input|resize|tmux|restart|agent-resume|chat|view-mode))?$/.exec(route);
|
|
94
97
|
if (session && !reservedSessionIds.has(session[1].toLowerCase())) {
|
|
95
98
|
const sessionId = session[1];
|
|
96
99
|
const op = session[2];
|
|
97
|
-
if (read && ['health', 'attach', 'stream', 'agent-resume'].includes(op))
|
|
100
|
+
if (read && ['health', 'attach', 'stream', 'agent-resume', 'chat', 'view-mode'].includes(op))
|
|
98
101
|
return { action: 'session.view', sessionId };
|
|
99
|
-
if (method === '
|
|
102
|
+
if (method === 'PUT' && op === 'view-mode')
|
|
103
|
+
return { action: 'session.view', sessionId };
|
|
104
|
+
if (method === 'POST' && (op === 'input' || op === 'chat'))
|
|
100
105
|
return { action: 'session.input', sessionId };
|
|
101
106
|
if (method === 'POST' && op === 'resize')
|
|
102
107
|
return { action: 'session.resize', sessionId };
|