termdock 1.4.355 → 1.4.357
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/README.md +22 -4
- package/dist/client/assets/AndroidMirrorView-BGagwKtL.js +3 -0
- package/dist/client/assets/AndroidMirrorView-BGagwKtL.js.br +0 -0
- package/dist/client/assets/AndroidMirrorView-BGagwKtL.js.gz +0 -0
- package/dist/client/assets/App-DpMhxwYW.js +178 -0
- package/dist/client/assets/App-DpMhxwYW.js.br +0 -0
- package/dist/client/assets/App-DpMhxwYW.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-Bd_l74EC.js +9 -0
- package/dist/client/assets/ArchitecturePanel-Bd_l74EC.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-Bd_l74EC.js.gz +0 -0
- package/dist/client/assets/{ChangeWalkthroughPanel-mAiaX5i8.js → ChangeWalkthroughPanel-6DN-2BdR.js} +2 -2
- package/dist/client/assets/ChangeWalkthroughPanel-6DN-2BdR.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-6DN-2BdR.js.gz +0 -0
- package/dist/client/assets/{ChatRichContent-D2NtgMuL.js → ChatRichContent-DjwpmW7d.js} +55 -55
- package/dist/client/assets/ChatRichContent-DjwpmW7d.js.br +0 -0
- package/dist/client/assets/ChatRichContent-DjwpmW7d.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-DPTJ9pCt.js +1 -0
- package/dist/client/assets/CollaborationMainWorkspace-DPTJ9pCt.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-DPTJ9pCt.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-Cbu1Bjl0.js +1 -0
- package/dist/client/assets/ComputerControlView-CwB-wQqB.js +6 -0
- package/dist/client/assets/ComputerControlView-CwB-wQqB.js.br +0 -0
- package/dist/client/assets/ComputerControlView-CwB-wQqB.js.gz +0 -0
- package/dist/client/assets/{DagPlayground-CbEuQA68.js → DagPlayground-DMn9Gyrw.js} +1 -1
- package/dist/client/assets/DagPlayground-DMn9Gyrw.js.br +0 -0
- package/dist/client/assets/DagPlayground-DMn9Gyrw.js.gz +0 -0
- package/dist/client/assets/{DiffLab-PysBkJrJ.js → DiffLab-YBWlCU2T.js} +1 -1
- package/dist/client/assets/DiffLab-YBWlCU2T.js.br +0 -0
- package/dist/client/assets/DiffLab-YBWlCU2T.js.gz +0 -0
- package/dist/client/assets/DiffReview-YOPDWqhv.js +1 -0
- package/dist/client/assets/DiffReview-YOPDWqhv.js.br +0 -0
- package/dist/client/assets/DiffReview-YOPDWqhv.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-D6PxvtBY.js → DiffReviewLab-SYomq14c.js} +1 -1
- package/dist/client/assets/DiffReviewLab-SYomq14c.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-SYomq14c.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-Bp-BLT2f.js → DiffViewer-mh9cBl5v.js} +1 -1
- package/dist/client/assets/DiffViewer-mh9cBl5v.js.br +0 -0
- package/dist/client/assets/DiffViewer-mh9cBl5v.js.gz +0 -0
- package/dist/client/assets/{GitLoadingSkeleton-Fa4AXG-N.js → GitLoadingSkeleton-DKRTc5sz.js} +1 -1
- package/dist/client/assets/GitLoadingSkeleton-DKRTc5sz.js.br +0 -0
- package/dist/client/assets/GitLoadingSkeleton-DKRTc5sz.js.gz +0 -0
- package/dist/client/assets/Markdown-C8OP1j-g.js +23 -0
- package/dist/client/assets/Markdown-C8OP1j-g.js.br +0 -0
- package/dist/client/assets/Markdown-C8OP1j-g.js.gz +0 -0
- package/dist/client/assets/Markdown-DKQhs57e.css +1 -0
- package/dist/client/assets/Markdown-DKQhs57e.css.br +0 -0
- package/dist/client/assets/Markdown-DKQhs57e.css.gz +0 -0
- package/dist/client/assets/{ModelPreview-Cl0X7I-U.js → ModelPreview-CsZry3Wd.js} +3 -3
- package/dist/client/assets/ModelPreview-CsZry3Wd.js.br +0 -0
- package/dist/client/assets/ModelPreview-CsZry3Wd.js.gz +0 -0
- package/dist/client/assets/RecordingSaveDialog-CoRGi97z.js +1 -0
- package/dist/client/assets/RecordingSaveDialog-CoRGi97z.js.br +0 -0
- package/dist/client/assets/RecordingSaveDialog-CoRGi97z.js.gz +0 -0
- package/dist/client/assets/RightSidebar-DNY2kC6B.js +1662 -0
- package/dist/client/assets/RightSidebar-DNY2kC6B.js.br +0 -0
- package/dist/client/assets/RightSidebar-DNY2kC6B.js.gz +0 -0
- package/dist/client/assets/SessionChatView-DXNpYUrk.js +13 -0
- package/dist/client/assets/SessionChatView-DXNpYUrk.js.br +0 -0
- package/dist/client/assets/SessionChatView-DXNpYUrk.js.gz +0 -0
- package/dist/client/assets/SessionResourceSidebar-B_379HBJ.js +2 -0
- package/dist/client/assets/SessionResourceSidebar-B_379HBJ.js.br +0 -0
- package/dist/client/assets/SessionResourceSidebar-B_379HBJ.js.gz +0 -0
- package/dist/client/assets/TodoWorkspace-DfwGOAHB.js +1 -0
- package/dist/client/assets/TodoWorkspace-DfwGOAHB.js.br +0 -0
- package/dist/client/assets/TodoWorkspace-DfwGOAHB.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-BajyXVpH.js → abnfDiagram-VCTEODGH-C9M0gnl-.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-C9M0gnl-.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-C9M0gnl-.js.gz +0 -0
- package/dist/client/assets/app-CovJYQoW.js +37 -0
- package/dist/client/assets/app-CovJYQoW.js.br +0 -0
- package/dist/client/assets/app-CovJYQoW.js.gz +0 -0
- package/dist/client/assets/{arc-CbhM5I2d.js → arc-q4wfkQcT.js} +1 -1
- package/dist/client/assets/arc-q4wfkQcT.js.br +0 -0
- package/dist/client/assets/arc-q4wfkQcT.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-CDKLcS6D.js → architectureDiagram-5GKGNRK7-CCuna3ab.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CCuna3ab.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CCuna3ab.js.gz +0 -0
- package/dist/client/assets/{arrow-down-Dp27yS0N.js → arrow-down-WyzmLXwQ.js} +1 -1
- package/dist/client/assets/{blockDiagram-I7D4REHJ-CXiIO6_W.js → blockDiagram-I7D4REHJ-BXK68Qyt.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-BXK68Qyt.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BXK68Qyt.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-uZ-i2eKH.js → c4Diagram-7LVT6UL2-BqwmmVmS.js} +1 -1
- package/dist/client/assets/{c4Diagram-7LVT6UL2-uZ-i2eKH.js.br → c4Diagram-7LVT6UL2-BqwmmVmS.js.br} +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-BqwmmVmS.js.gz +0 -0
- package/dist/client/assets/channel-Dd6WQGB7.js +1 -0
- package/dist/client/assets/{chevron-left-D8ntyw2S.js → chevron-left-CxeWIsDK.js} +1 -1
- package/dist/client/assets/{chunk-2Q5K7J3B-DVe3dVJR.js → chunk-2Q5K7J3B-esKGR38U.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-BDBNKGuU.js → chunk-5VM5RSS4-B3InxqDA.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-BP7hTwtm.js → chunk-F27PBJKO-CjUVyF-E.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-CjUVyF-E.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-CjUVyF-E.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-LIGuOtnb.js → chunk-IMKFNOWR-BR8mmBs7.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-BR8mmBs7.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BR8mmBs7.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-C1_iFEvk.js → chunk-JWPE2WC7-CplXNOA7.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-CYZsO-QL.js → chunk-POPQ4Y6H-D0JWCGnb.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-FnWYLNCS.js → chunk-SVP7TREG-BdJtJSmy.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-BdJtJSmy.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-BdJtJSmy.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-dcOCcmQq.js → chunk-TICWLB2K-CoevFj8I.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-CoevFj8I.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-CoevFj8I.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-B2H2Yt9G.js → chunk-XXDRQBXY-D7qYRhMH.js} +1 -1
- package/dist/client/assets/{circle-Pldg1yI9.js → circle-xgKDXpwG.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-BdIUq_D7.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-BdIUq_D7.js +1 -0
- package/dist/client/assets/{clipboard-tTkMEO1S.js → clipboard-DeK6pJD3.js} +1 -1
- package/dist/client/assets/clipboardText-BWOwer6N.js +1 -0
- package/dist/client/assets/clipboardText-BWOwer6N.js.br +0 -0
- package/dist/client/assets/clipboardText-BWOwer6N.js.gz +0 -0
- package/dist/client/assets/clipboardText-vX90C7eX.css +1 -0
- package/dist/client/assets/clipboardText-vX90C7eX.css.br +0 -0
- package/dist/client/assets/clipboardText-vX90C7eX.css.gz +0 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-Bz38mqD8.js → cose-bilkent-JH36ORCC-CvnsiaWP.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-CvnsiaWP.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-CvnsiaWP.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX-CZAa1A6y.js → cynefin-OW5HDTMX-BSGz8Olu.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-BSGz8Olu.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-BSGz8Olu.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-BaQnW4VG.js → cynefinDiagram-5FMLGOSQ-DYYT0AHs.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DYYT0AHs.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-DYYT0AHs.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-BdnT61bc.js → dagre-GXQ25YYZ-BM883MN7.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-BM883MN7.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-BM883MN7.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-BWiF8QNc.js → diagram-S7CK7UJ4-CYnxXy7R.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-CYnxXy7R.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CYnxXy7R.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-DLURjCFp.js → diagram-UQ7AKVKN-UOIBVxRf.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-UOIBVxRf.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-UOIBVxRf.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-DYIcLklz.js → diagram-VSXAHHWV-CqTJzfmm.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-CqTJzfmm.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CqTJzfmm.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-C9vqviXX.js → diagram-VX7I27RA-T9Y88CFB.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-T9Y88CFB.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-T9Y88CFB.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-BJuQxTkw.js → diagram-Z3DM3KII-kIQDy7E0.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-kIQDy7E0.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-kIQDy7E0.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-BcbISm-z.js → ebnfDiagram-PWID7BFC-z_VqR_JE.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-z_VqR_JE.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-z_VqR_JE.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-fhNpRzUG.js → erDiagram-RLTQ6QDP-0q52Z-pm.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-0q52Z-pm.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-0q52Z-pm.js.gz +0 -0
- package/dist/client/assets/{external-link-DE8Gj-da.js → external-link-CsydVmO1.js} +1 -1
- package/dist/client/assets/{flowDiagram-HODETNUW-CVDJ_1Zu.js → flowDiagram-HODETNUW-BrGqcUWn.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-BrGqcUWn.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-BrGqcUWn.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-Dzn-mrfe.js → ganttDiagram-EL5Y4UJY-CHAN6vQv.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-CHAN6vQv.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-CHAN6vQv.js.gz +0 -0
- package/dist/client/assets/{git-compare-Ct2eJNs4.js → git-compare-BmKAtQTt.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-Ci-wfvCz.js → gitGraphDiagram-WWUBYQGX-C0ZV4FeB.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-C0ZV4FeB.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-C0ZV4FeB.js.gz +0 -0
- package/dist/client/assets/index-DEAMSl55.css +1 -0
- package/dist/client/assets/index-DEAMSl55.css.br +0 -0
- package/dist/client/assets/index-DEAMSl55.css.gz +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-npBmeTt7.js → infoDiagram-27XIBGKW-CrLj9y1o.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-CCn5Ha25.js → ishikawaDiagram-5VMMS53U-BxGvUfLX.js} +1 -1
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BxGvUfLX.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BxGvUfLX.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-CPl5oPfe.js → journeyDiagram-3NMN7TZE-rW9xlQ8G.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-rW9xlQ8G.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-rW9xlQ8G.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-Dmia2kLZ.js → kanban-definition-UXKFOSKX-CFI5iv9R.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-CFI5iv9R.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-CFI5iv9R.js.gz +0 -0
- package/dist/client/assets/{layout-B2Kz5M73.js → layout-Ct_an5XT.js} +1 -1
- package/dist/client/assets/layout-Ct_an5XT.js.br +0 -0
- package/dist/client/assets/layout-Ct_an5XT.js.gz +0 -0
- package/dist/client/assets/{linear-D2CT7wE3.js → linear-DpEFOA9l.js} +1 -1
- package/dist/client/assets/linear-DpEFOA9l.js.br +0 -0
- package/dist/client/assets/linear-DpEFOA9l.js.gz +0 -0
- package/dist/client/assets/{link-x33s12VI.js → link-34ChBc4F.js} +3 -3
- package/dist/client/assets/link-34ChBc4F.js.br +0 -0
- package/dist/client/assets/link-34ChBc4F.js.gz +0 -0
- package/dist/client/assets/{list-tree-XBmm9il2.js → list-tree-48dzbuUh.js} +1 -1
- package/dist/client/assets/{maximize-2-t-zzENew.js → maximize-2-CbvSsu7O.js} +1 -1
- package/dist/client/assets/{mermaid.core-G9XIcppl.js → mermaid.core-DnVKnMmy.js} +5 -5
- package/dist/client/assets/mermaid.core-DnVKnMmy.js.br +0 -0
- package/dist/client/assets/mermaid.core-DnVKnMmy.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-D2OX9OkO.js → mindmap-definition-YA3MSWOX-C6shupTY.js} +1 -1
- package/dist/client/assets/mindmap-definition-YA3MSWOX-C6shupTY.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-C6shupTY.js.gz +0 -0
- package/dist/client/assets/{passwordBootstrap-DkTynZfV.js → passwordBootstrap-Doe50DSa.js} +1 -1
- package/dist/client/assets/passwordBootstrap-Doe50DSa.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-Doe50DSa.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-qNjd6dbd.js → pegDiagram-XKGWAZYB-CDcnrvKX.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-CDcnrvKX.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-CDcnrvKX.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-DcCmKDFh.js → pieDiagram-E7YTZNPT-CrGc03Tg.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrGc03Tg.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrGc03Tg.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BpDzkl9h.js → quadrantDiagram-AXDQQJYC-3-aldwKj.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-3-aldwKj.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-3-aldwKj.js.gz +0 -0
- package/dist/client/assets/{quote-DeByS04O.js → quote-B5GeKEq1.js} +1 -1
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-DkwV8w7x.js → railroadDiagram-O6MQD6OU-51uKwR2_.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-51uKwR2_.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-51uKwR2_.js.gz +0 -0
- package/dist/client/assets/rdpSession-ocpkj4XY.js +1 -0
- package/dist/client/assets/rdpSession-ocpkj4XY.js.br +0 -0
- package/dist/client/assets/rdpSession-ocpkj4XY.js.gz +0 -0
- package/dist/client/assets/referenceSelection-fvfRDbgp.js +4 -0
- package/dist/client/assets/referenceSelection-fvfRDbgp.js.br +0 -0
- package/dist/client/assets/referenceSelection-fvfRDbgp.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-BRwt5MXl.js → requirementDiagram-BXWQKSXE-CY6kp0_Y.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CY6kp0_Y.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CY6kp0_Y.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-DZ8y_gv3.js → sankeyDiagram-P5KCCOFB-BsA0NkHG.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BsA0NkHG.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BsA0NkHG.js.gz +0 -0
- package/dist/client/assets/{search-CDJ4fv-q.js → search-CbpNLSpd.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CJ9lZEsN.js → sequenceDiagram-WJ2MYXX4-BDzn7N2D.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BDzn7N2D.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BDzn7N2D.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-Dt9ZzegQ.js → sizeCapture-INFHLROL-gxtam7nc.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-gxtam7nc.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-gxtam7nc.js.gz +0 -0
- package/dist/client/assets/{stateDiagram-D77RDMKH-DgeQtV3s.js → stateDiagram-D77RDMKH-C4XjYLZR.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-C4XjYLZR.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-C4XjYLZR.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BfHWFf-I.js +1 -0
- package/dist/client/assets/{sun-CvzpsfHU.js → sun-CMXn_ntS.js} +1 -1
- package/dist/client/assets/{swimlanes-42K2YHIH-DHB6MQ8v.js → swimlanes-42K2YHIH--a1wkQO8.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH--a1wkQO8.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH--a1wkQO8.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DsiDF1XD.js +8 -0
- package/dist/client/assets/swiper-CTPycjLq.js +1 -0
- package/dist/client/assets/swiper-CTPycjLq.js.br +0 -0
- package/dist/client/assets/swiper-CTPycjLq.js.gz +0 -0
- package/dist/client/assets/{terminal-Dea8wJF3.js → terminal-DaiFCKy_.js} +7 -7
- package/dist/client/assets/terminal-DaiFCKy_.js.br +0 -0
- package/dist/client/assets/terminal-DaiFCKy_.js.gz +0 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-EqVVyv-E.js → timeline-definition-24CTP7MA-DFmXXUuU.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-DFmXXUuU.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-DFmXXUuU.js.gz +0 -0
- package/dist/client/assets/triangle-alert-DgGU_xB4.js +1 -0
- package/dist/client/assets/{unplug-BNUx6Lmk.js → unplug-CnZtWzVW.js} +1 -1
- package/dist/client/assets/use-gesture-react.esm-DHU0wi7Q.js +1 -0
- package/dist/client/assets/use-gesture-react.esm-DHU0wi7Q.js.br +0 -0
- package/dist/client/assets/use-gesture-react.esm-DHU0wi7Q.js.gz +0 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-BBE17-sL.js → vennDiagram-4TSXK5OY-DgR4zroQ.js} +1 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-DgR4zroQ.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DgR4zroQ.js.gz +0 -0
- package/dist/client/assets/{videoCompression-B09OiyP5.js → videoCompression-CcffRZdP.js} +1 -1
- package/dist/client/assets/videoCompression-CcffRZdP.js.br +0 -0
- package/dist/client/assets/videoCompression-CcffRZdP.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-B4gZGXiA.js → wardleyDiagram-VM6X3IG4-CY4SVUkf.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CY4SVUkf.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CY4SVUkf.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-BDO5xF5D.js → xychartDiagram-S5SC5T6Z-PblQhR-b.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-PblQhR-b.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-PblQhR-b.js.gz +0 -0
- package/dist/client/index.html +3 -3
- 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/chatUIPrompt.js +1 -0
- package/dist/server/agent/collaborationPeerTransport.js +14 -69
- package/dist/server/agent/collaborationStore.js +5 -0
- package/dist/server/agent/installers.js +89 -33
- package/dist/server/agent/integrationServer.js +31 -2
- package/dist/server/agent/pluginPackages.js +51 -22
- package/dist/server/agent/sessionChatRoutes.js +45 -7
- package/dist/server/agentHook.js +56 -12
- package/dist/server/android/adb.js +24 -31
- package/dist/server/cli.js +52 -110
- package/dist/server/entry.js +17 -23
- package/dist/server/federation/cli.js +13 -47
- package/dist/server/federation/connectionErrors.js +37 -0
- package/dist/server/federation/connectionModel.js +83 -0
- package/dist/server/federation/desktopTargets.js +35 -13
- package/dist/server/federation/directRoutes.js +28 -36
- package/dist/server/federation/directTargetRegistry.js +106 -0
- package/dist/server/federation/httpUploadLimit.js +8 -0
- package/dist/server/federation/invitations.js +5 -1
- package/dist/server/federation/relay.js +13 -6
- package/dist/server/federation/relayTransport.js +147 -0
- package/dist/server/federation/routeAccess.js +5 -3
- package/dist/server/federation/routeInvitations.js +5 -1
- package/dist/server/federation/runtime.js +4 -2
- package/dist/server/federation/selfRelay.js +10 -59
- package/dist/server/federation/serviceTransport.js +123 -0
- package/dist/server/federation/streamLimits.js +3 -0
- package/dist/server/federation/trustedCa.js +61 -0
- package/dist/server/routes/android.js +5 -7
- package/dist/server/routes/terminal.js +149 -111
- package/dist/server/shared/androidDevices.js +64 -0
- package/dist/server/shared/programStatus.js +174 -0
- package/dist/server/shared/shareResources.js +3 -2
- package/dist/server/todos/routes.js +36 -0
- package/dist/server/todos/store.js +31 -1
- package/dist/server/utils/bootCheck.js +41 -271
- package/dist/server/utils/localHttpsSetup.js +257 -0
- package/dist/server/utils/oscBuffer.js +9 -0
- package/dist/server/utils/sessionDisplayName.js +11 -9
- package/dist/server/utils/settings.js +6 -3
- package/dist/server/utils/tmuxDisplayGeometry.js +54 -0
- package/dist/server/utils/tmuxObserverSize.js +26 -0
- package/docs/integrations.md +2 -1
- package/package.json +5 -1
- package/runtime-manifest.json +3 -3
- package/scripts/ensure-node-pty.cjs +22 -7
- package/scripts/install-utils.cjs +81 -0
- package/scripts/postinstall.mjs +24 -110
- package/dist/client/assets/AndroidMirrorView-BC_6L3mG.js +0 -3
- package/dist/client/assets/AndroidMirrorView-BC_6L3mG.js.br +0 -0
- package/dist/client/assets/AndroidMirrorView-BC_6L3mG.js.gz +0 -0
- package/dist/client/assets/App-BGECv_n_.js +0 -178
- package/dist/client/assets/App-BGECv_n_.js.br +0 -0
- package/dist/client/assets/App-BGECv_n_.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-CYdolNzT.js +0 -9
- package/dist/client/assets/ArchitecturePanel-CYdolNzT.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-CYdolNzT.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-mAiaX5i8.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-mAiaX5i8.js.gz +0 -0
- package/dist/client/assets/ChatRichContent-D2NtgMuL.js.br +0 -0
- package/dist/client/assets/ChatRichContent-D2NtgMuL.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-CcHsVfXD.js +0 -1
- package/dist/client/assets/CollaborationMainWorkspace-CcHsVfXD.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-CcHsVfXD.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-FcrGGSr_.js +0 -2
- package/dist/client/assets/ComputerControlView-DU9krDsg.js +0 -6
- package/dist/client/assets/ComputerControlView-DU9krDsg.js.br +0 -0
- package/dist/client/assets/ComputerControlView-DU9krDsg.js.gz +0 -0
- package/dist/client/assets/DagPlayground-CbEuQA68.js.br +0 -0
- package/dist/client/assets/DagPlayground-CbEuQA68.js.gz +0 -0
- package/dist/client/assets/DiffLab-PysBkJrJ.js.br +0 -0
- package/dist/client/assets/DiffLab-PysBkJrJ.js.gz +0 -0
- package/dist/client/assets/DiffReview-Ce3wKMBk.js +0 -1
- package/dist/client/assets/DiffReview-Ce3wKMBk.js.br +0 -0
- package/dist/client/assets/DiffReview-Ce3wKMBk.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-D6PxvtBY.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-D6PxvtBY.js.gz +0 -0
- package/dist/client/assets/DiffViewer-Bp-BLT2f.js.br +0 -0
- package/dist/client/assets/DiffViewer-Bp-BLT2f.js.gz +0 -0
- package/dist/client/assets/GitLoadingSkeleton-Fa4AXG-N.js.br +0 -0
- package/dist/client/assets/GitLoadingSkeleton-Fa4AXG-N.js.gz +0 -0
- package/dist/client/assets/MarkdownPreview-_Z5UzhLt.js +0 -19
- package/dist/client/assets/MarkdownPreview-_Z5UzhLt.js.br +0 -0
- package/dist/client/assets/MarkdownPreview-_Z5UzhLt.js.gz +0 -0
- package/dist/client/assets/ModelPreview-Cl0X7I-U.js.br +0 -0
- package/dist/client/assets/ModelPreview-Cl0X7I-U.js.gz +0 -0
- package/dist/client/assets/RecordingSaveDialog-Ca2iJsOW.js +0 -1
- package/dist/client/assets/RecordingSaveDialog-Ca2iJsOW.js.br +0 -0
- package/dist/client/assets/RecordingSaveDialog-Ca2iJsOW.js.gz +0 -0
- package/dist/client/assets/RightSidebar-CwXIBpEw.js +0 -1662
- package/dist/client/assets/RightSidebar-CwXIBpEw.js.br +0 -0
- package/dist/client/assets/RightSidebar-CwXIBpEw.js.gz +0 -0
- package/dist/client/assets/SessionChatView-D3sLcYAc.js +0 -13
- package/dist/client/assets/SessionChatView-D3sLcYAc.js.br +0 -0
- package/dist/client/assets/SessionChatView-D3sLcYAc.js.gz +0 -0
- package/dist/client/assets/SessionChatView-D8GoESjb.css +0 -1
- 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-BObKJeA9.js +0 -2
- package/dist/client/assets/SessionResourceSidebar-BObKJeA9.js.br +0 -0
- package/dist/client/assets/SessionResourceSidebar-BObKJeA9.js.gz +0 -0
- package/dist/client/assets/TodoWorkspace-BdesAuz4.js +0 -1
- package/dist/client/assets/TodoWorkspace-BdesAuz4.js.br +0 -0
- package/dist/client/assets/TodoWorkspace-BdesAuz4.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BajyXVpH.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BajyXVpH.js.gz +0 -0
- package/dist/client/assets/app-C3WX_u_Z.js +0 -37
- package/dist/client/assets/app-C3WX_u_Z.js.br +0 -0
- package/dist/client/assets/app-C3WX_u_Z.js.gz +0 -0
- package/dist/client/assets/arc-CbhM5I2d.js.br +0 -0
- package/dist/client/assets/arc-CbhM5I2d.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CDKLcS6D.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CDKLcS6D.js.gz +0 -0
- package/dist/client/assets/arrow-up-BEUQcf-s.js +0 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-CXiIO6_W.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-CXiIO6_W.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-uZ-i2eKH.js.gz +0 -0
- package/dist/client/assets/channel-Dg7JKsqi.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-BP7hTwtm.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-BP7hTwtm.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-LIGuOtnb.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-LIGuOtnb.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-FnWYLNCS.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-FnWYLNCS.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-dcOCcmQq.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-dcOCcmQq.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-D6QBd_IP.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-D6QBd_IP.js +0 -1
- package/dist/client/assets/clipboardText-BapOM7QN.js +0 -1
- package/dist/client/assets/clipboardText-BapOM7QN.js.br +0 -0
- package/dist/client/assets/clipboardText-BapOM7QN.js.gz +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-Bz38mqD8.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-Bz38mqD8.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CZAa1A6y.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CZAa1A6y.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BaQnW4VG.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BaQnW4VG.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-BdnT61bc.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-BdnT61bc.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BWiF8QNc.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BWiF8QNc.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-DLURjCFp.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-DLURjCFp.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-DYIcLklz.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-DYIcLklz.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C9vqviXX.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C9vqviXX.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-BJuQxTkw.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-BJuQxTkw.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BcbISm-z.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BcbISm-z.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-fhNpRzUG.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-fhNpRzUG.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CVDJ_1Zu.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CVDJ_1Zu.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-Dzn-mrfe.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-Dzn-mrfe.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Ci-wfvCz.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-Ci-wfvCz.js.gz +0 -0
- package/dist/client/assets/index-DOq3vkFG.css +0 -1
- package/dist/client/assets/index-DOq3vkFG.css.br +0 -0
- package/dist/client/assets/index-DOq3vkFG.css.gz +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-CCn5Ha25.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-CCn5Ha25.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-CPl5oPfe.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-CPl5oPfe.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Dmia2kLZ.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Dmia2kLZ.js.gz +0 -0
- package/dist/client/assets/layout-B2Kz5M73.js.br +0 -0
- package/dist/client/assets/layout-B2Kz5M73.js.gz +0 -0
- package/dist/client/assets/linear-D2CT7wE3.js.br +0 -0
- package/dist/client/assets/linear-D2CT7wE3.js.gz +0 -0
- package/dist/client/assets/link-x33s12VI.js.br +0 -0
- package/dist/client/assets/link-x33s12VI.js.gz +0 -0
- package/dist/client/assets/loader-circle-D_nJKmMD.js +0 -1
- package/dist/client/assets/mermaid.core-G9XIcppl.js.br +0 -0
- package/dist/client/assets/mermaid.core-G9XIcppl.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-D2OX9OkO.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-D2OX9OkO.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-DkTynZfV.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-DkTynZfV.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-qNjd6dbd.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-qNjd6dbd.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DcCmKDFh.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DcCmKDFh.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BpDzkl9h.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BpDzkl9h.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DkwV8w7x.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DkwV8w7x.js.gz +0 -0
- package/dist/client/assets/rdpSession-D5NrFTav.js +0 -1
- package/dist/client/assets/rdpSession-D5NrFTav.js.br +0 -0
- package/dist/client/assets/rdpSession-D5NrFTav.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BRwt5MXl.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BRwt5MXl.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DZ8y_gv3.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-DZ8y_gv3.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CJ9lZEsN.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CJ9lZEsN.js.gz +0 -0
- package/dist/client/assets/settings-2-DtFz7lgk.js +0 -1
- package/dist/client/assets/sizeCapture-INFHLROL-Dt9ZzegQ.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-Dt9ZzegQ.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DgeQtV3s.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DgeQtV3s.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CKS6y2rR.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-DHB6MQ8v.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-DHB6MQ8v.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DvUzDKPI.js +0 -8
- package/dist/client/assets/swiper-DJjq1TYT.js +0 -1
- 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-DF6Q5phI.js +0 -4
- package/dist/client/assets/syntaxHighlight-DF6Q5phI.js.br +0 -0
- package/dist/client/assets/syntaxHighlight-DF6Q5phI.js.gz +0 -0
- package/dist/client/assets/terminal-Dea8wJF3.js.br +0 -0
- package/dist/client/assets/terminal-Dea8wJF3.js.gz +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-EqVVyv-E.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-EqVVyv-E.js.gz +0 -0
- package/dist/client/assets/triangle-alert--5QOrsVl.js +0 -1
- package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js +0 -1
- 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/vennDiagram-4TSXK5OY-BBE17-sL.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-BBE17-sL.js.gz +0 -0
- package/dist/client/assets/videoCompression-B09OiyP5.js.br +0 -0
- package/dist/client/assets/videoCompression-B09OiyP5.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-B4gZGXiA.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-B4gZGXiA.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-BDO5xF5D.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-BDO5xF5D.js.gz +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { incompleteOscSuffix } from '../utils/oscBuffer.js';
|
|
2
|
+
export const PROGRAM_STATUS_REPLY = '\x1b]7501;?:states=idle,working,done,blocked,error:kinds=permission,question,auth\x1b\\';
|
|
3
|
+
const STATES = new Set(['idle', 'working', 'blocked', 'done', 'error', 'clear']);
|
|
4
|
+
const RANK = { idle: 0, done: 1, working: 2, error: 3, blocked: 4, clear: 0 };
|
|
5
|
+
function text(value, encodedLimit, decodedLimit) {
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return undefined;
|
|
8
|
+
if (value.length > encodedLimit || !/^[A-Za-z0-9+/]*={0,2}$/.test(value) || value.length % 4 === 1
|
|
9
|
+
|| value.includes('=') && value.length % 4 !== 0)
|
|
10
|
+
throw new Error('invalid text');
|
|
11
|
+
const decoded = Buffer.from(value, 'base64');
|
|
12
|
+
if (decoded.length > decodedLimit || decoded.toString('base64').replace(/=+$/, '') !== value.replace(/=+$/, ''))
|
|
13
|
+
throw new Error('invalid text');
|
|
14
|
+
const result = new TextDecoder('utf-8', { fatal: true }).decode(decoded);
|
|
15
|
+
if (/[\u0000-\u001f\u007f-\u009f]/.test(result))
|
|
16
|
+
throw new Error('invalid text');
|
|
17
|
+
return result.replace(/\p{Cf}/gu, '');
|
|
18
|
+
}
|
|
19
|
+
/** Independent implementation of the public OSC 7501 protocol, revision 0.4:
|
|
20
|
+
* https://www.superlogical.com/rex/docs/build/program-status */
|
|
21
|
+
export function parseProgramStatus(body) {
|
|
22
|
+
if (Buffer.byteLength(body) + 9 > 4096)
|
|
23
|
+
return null;
|
|
24
|
+
const pairs = Object.create(null);
|
|
25
|
+
for (const pair of body.split(':')) {
|
|
26
|
+
const index = pair.indexOf('=');
|
|
27
|
+
if (index < 1)
|
|
28
|
+
continue;
|
|
29
|
+
const key = pair.slice(0, index).trim(), value = pair.slice(index + 1).trim();
|
|
30
|
+
if (key.length > 16)
|
|
31
|
+
return null;
|
|
32
|
+
if (/^[a-z]+$/.test(key) && /^[A-Za-z0-9_.,+/=-]*$/.test(value))
|
|
33
|
+
pairs[key] = value;
|
|
34
|
+
}
|
|
35
|
+
if (!STATES.has(pairs.state))
|
|
36
|
+
return null;
|
|
37
|
+
const id = pairs.id ?? '';
|
|
38
|
+
if (id.length > 128 || (id && (id.split('/').length > 8 || !id.split('/').every(segment => /^[A-Za-z0-9_.+-]{1,32}$/.test(segment)))))
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
const state = pairs.state;
|
|
42
|
+
const progress = /^(?:100|[0-9]{1,2})$/.test(pairs.progress ?? '') ? Number(pairs.progress) : undefined;
|
|
43
|
+
return { id, state, app: /^[A-Za-z0-9_.+-]{1,32}$/.test(pairs.app ?? '') ? pairs.app : undefined,
|
|
44
|
+
msg: text(pairs.msg, 2732, 2048), title: text(pairs.title, 256, 192),
|
|
45
|
+
progress: state === 'working' || state === 'blocked' ? progress : undefined,
|
|
46
|
+
kind: state === 'blocked' && ['permission', 'question', 'auth'].includes(pairs.kind) ? pairs.kind : undefined };
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function parseLegacyProgress(body) {
|
|
53
|
+
const match = /^4;([0-4])(?:;([0-9]+))?$/.exec(body);
|
|
54
|
+
if (!match)
|
|
55
|
+
return null;
|
|
56
|
+
const states = ['remove', 'set', 'error', 'indeterminate', 'pause'];
|
|
57
|
+
const state = states[Number(match[1])];
|
|
58
|
+
const progress = match[2] !== undefined && ['set', 'error', 'pause'].includes(state)
|
|
59
|
+
? Math.min(100, Number(match[2])) : null;
|
|
60
|
+
return { state, progress };
|
|
61
|
+
}
|
|
62
|
+
/** State belongs to a PTY, not a browser. Native progress never mutates an
|
|
63
|
+
* Agent lifecycle, activity counter, permission decision, or notification. */
|
|
64
|
+
export class ProgramStatusTracker {
|
|
65
|
+
remaining = '';
|
|
66
|
+
native = false;
|
|
67
|
+
records = new Map();
|
|
68
|
+
legacy = null;
|
|
69
|
+
current = null;
|
|
70
|
+
feed(data) {
|
|
71
|
+
const previouslyActive = this.activeApps();
|
|
72
|
+
const explicitEnd = new Set();
|
|
73
|
+
const buffer = this.remaining + data;
|
|
74
|
+
const pattern = /\x1bc|\x1b\](7501|133|9);([^\x07\x1b]*)(?:\x07|\x1b\\)/g;
|
|
75
|
+
let match, consumed = 0, query = false;
|
|
76
|
+
while ((match = pattern.exec(buffer))) {
|
|
77
|
+
consumed = pattern.lastIndex;
|
|
78
|
+
if (match[0] === '\x1bc') {
|
|
79
|
+
this.records.clear();
|
|
80
|
+
this.native = false;
|
|
81
|
+
this.legacy = null;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (match[1] === '7501') {
|
|
85
|
+
if (match[2] === '?') {
|
|
86
|
+
query = true;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const record = parseProgramStatus(match[2]);
|
|
90
|
+
if (!record)
|
|
91
|
+
continue;
|
|
92
|
+
this.native = true;
|
|
93
|
+
if (record.app && ['idle', 'done', 'error', 'clear'].includes(record.state))
|
|
94
|
+
explicitEnd.add(record.app);
|
|
95
|
+
if (record.state === 'clear') {
|
|
96
|
+
for (const id of this.records.keys())
|
|
97
|
+
if (!record.id || id === record.id || id.startsWith(`${record.id}/`))
|
|
98
|
+
this.records.delete(id);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.records.delete(record.id);
|
|
102
|
+
this.records.set(record.id, record);
|
|
103
|
+
if (this.records.size > 256)
|
|
104
|
+
this.records.delete(this.records.keys().next().value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (match[1] === '133' && /^(?:A|P)(?:;|$)/.test(match[2])) {
|
|
108
|
+
this.legacy = null;
|
|
109
|
+
this.dropActive();
|
|
110
|
+
}
|
|
111
|
+
else if (match[1] === '9' && !this.native) {
|
|
112
|
+
const progress = parseLegacyProgress(match[2]);
|
|
113
|
+
if (progress)
|
|
114
|
+
this.legacy = progress.state === 'remove' ? null : progress;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
this.remaining = incompleteOscSuffix(buffer, consumed, 4096);
|
|
118
|
+
const active = this.activeApps();
|
|
119
|
+
return { ...this.update(), query, endedApps: [...new Set([...previouslyActive, ...explicitEnd])].filter(app => !active.includes(app)) };
|
|
120
|
+
}
|
|
121
|
+
activeApps() {
|
|
122
|
+
const apps = new Set();
|
|
123
|
+
for (const record of this.records.values()) {
|
|
124
|
+
if (!['working', 'blocked'].includes(record.state))
|
|
125
|
+
continue;
|
|
126
|
+
const app = this.appFor(record);
|
|
127
|
+
if (app)
|
|
128
|
+
apps.add(app);
|
|
129
|
+
}
|
|
130
|
+
return [...apps];
|
|
131
|
+
}
|
|
132
|
+
appFor(record) {
|
|
133
|
+
let app = record.app, parent = record.id;
|
|
134
|
+
while (!app && parent) {
|
|
135
|
+
parent = parent.includes('/') ? parent.slice(0, parent.lastIndexOf('/')) : '';
|
|
136
|
+
app = this.records.get(parent)?.app;
|
|
137
|
+
}
|
|
138
|
+
return app;
|
|
139
|
+
}
|
|
140
|
+
exit() {
|
|
141
|
+
this.dropActive();
|
|
142
|
+
this.legacy = null;
|
|
143
|
+
return this.update();
|
|
144
|
+
}
|
|
145
|
+
dropActive() {
|
|
146
|
+
for (const [id, record] of this.records)
|
|
147
|
+
if (['working', 'blocked', 'idle'].includes(record.state))
|
|
148
|
+
this.records.delete(id);
|
|
149
|
+
}
|
|
150
|
+
update() {
|
|
151
|
+
let selected;
|
|
152
|
+
for (const record of this.records.values())
|
|
153
|
+
if (RANK[record.state] > 0 && (!selected || RANK[record.state] >= RANK[selected.state]))
|
|
154
|
+
selected = record;
|
|
155
|
+
let progress = this.native ? null : this.legacy;
|
|
156
|
+
if (selected) {
|
|
157
|
+
const app = this.appFor(selected);
|
|
158
|
+
progress = { source: 'osc7501', state: selected.state === 'working' ? selected.progress === undefined ? 'indeterminate' : 'set' : selected.state,
|
|
159
|
+
progress: selected.progress ?? null, app, message: selected.msg ?? selected.title, kind: selected.kind };
|
|
160
|
+
}
|
|
161
|
+
const changed = JSON.stringify(progress) !== JSON.stringify(this.current);
|
|
162
|
+
this.current = progress;
|
|
163
|
+
return { changed, progress };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const trackers = new WeakMap();
|
|
167
|
+
export function terminalProgramStatus(terminal) {
|
|
168
|
+
let tracker = trackers.get(terminal);
|
|
169
|
+
if (!tracker) {
|
|
170
|
+
tracker = new ProgramStatusTracker();
|
|
171
|
+
trackers.set(terminal, tracker);
|
|
172
|
+
}
|
|
173
|
+
return tracker;
|
|
174
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isValidAndroidSerial, androidRouteAccess } from './androidDevices.js';
|
|
1
2
|
const record = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
|
|
2
3
|
const text = (v, max) => typeof v === 'string' && v.length > 0 && v.length <= max && !/[\x00-\x1f\x7f]/.test(v);
|
|
3
4
|
export function validShareResources(value) {
|
|
@@ -7,14 +8,14 @@ export function validShareResources(value) {
|
|
|
7
8
|
if (!record(item))
|
|
8
9
|
return false;
|
|
9
10
|
if (key === 'android')
|
|
10
|
-
return Object.keys(item).every(k => ['serial', 'access'].includes(k)) && text(item.serial, 128) &&
|
|
11
|
+
return Object.keys(item).every(k => ['serial', 'access'].includes(k)) && text(item.serial, 128) && isValidAndroidSerial(item.serial) && ['view', 'control'].includes(String(item.access));
|
|
11
12
|
if (key === 'computers')
|
|
12
13
|
return Object.keys(item).every(k => ['host', 'protocol', 'port', 'access'].includes(k)) && text(item.host, 253) && /^[a-zA-Z0-9:.\-]+$/.test(item.host) && ['vnc', 'rdp'].includes(String(item.protocol)) && Number.isInteger(item.port) && Number(item.port) > 0 && Number(item.port) <= 65535 && (item.protocol !== 'vnc' || item.port === 5900) && ['view', 'control'].includes(String(item.access));
|
|
13
14
|
return Object.keys(item).every(k => ['path', 'access'].includes(k)) && text(item.path, 4096) && (item.path.startsWith('/') || /^[A-Za-z]:[\\/]/.test(item.path)) && ['read', 'write'].includes(String(item.access));
|
|
14
15
|
}));
|
|
15
16
|
}
|
|
16
17
|
export function resourceSubset(child, parent) {
|
|
17
|
-
return (!child?.android?.length || child.android.every(c => parent?.android
|
|
18
|
+
return (!child?.android?.length || child.android.every(c => androidRouteAccess(parent?.android, c.serial) === 'control' || c.access === 'view' && androidRouteAccess(parent?.android, c.serial) === 'view'))
|
|
18
19
|
&& (!child?.computers?.length || child.computers.every(c => parent?.computers?.some(p => p.host === c.host && p.protocol === c.protocol && p.port === c.port && (p.access === 'control' || c.access === 'view'))))
|
|
19
20
|
&& (!child?.directories?.length || child.directories.every(c => parent?.directories?.some(p => p.path === c.path && (p.access === 'write' || c.access === 'read'))));
|
|
20
21
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import { launchConfig, TodoError } from './store.js';
|
|
3
|
+
export function handoffPrompt(store, run) {
|
|
4
|
+
return [run.handoff.todoIds.length === 1 ? '请处理这条待办:' : '请一起处理这些待办:',
|
|
5
|
+
...run.handoff.todoIds.map((id, index) => { const todo = store.get(id); return `${index + 1}. ${todo.title}\n${todo.description}\n来源:${todo.source}${todo.sourceUrl ? `\n参考来源:${todo.sourceUrl}` : ''}`; }),
|
|
6
|
+
run.handoff.note ? `我的补充要求:\n${run.handoff.note}` : '',
|
|
7
|
+
].filter(Boolean).join('\n\n');
|
|
8
|
+
}
|
|
3
9
|
function shellQuote(value) { return "'" + value.replace(/'/g, "'\"'\"'") + "'"; }
|
|
4
10
|
export function todoPrompt(store, run) {
|
|
5
11
|
const report = `完成或受阻时,请将结果写入一个 UTF-8 文件,并调用 td todo report ${run.id} --status complete --file <文件路径>;受阻时将 complete 换为 blocked,失败时换为 failed。报告只记录本次结果,由用户决定待办是否完成。`;
|
|
@@ -26,6 +32,35 @@ export class TodoRunner {
|
|
|
26
32
|
.catch(error => { this.store.mark(run.id, { status: 'failed', error: error instanceof Error ? error.message : String(error) }); });
|
|
27
33
|
return run;
|
|
28
34
|
}
|
|
35
|
+
async handoff(body, req) {
|
|
36
|
+
if (!body || !Array.isArray(body.todoIds) || !body.todoIds.length || body.todoIds.length > 50 || body.todoIds.some(id => typeof id !== 'string')
|
|
37
|
+
|| typeof body.note !== 'string' || body.note.length > 4000 || body.note.includes('\0') || typeof body.idempotencyKey !== 'string'
|
|
38
|
+
|| (body.sessionId !== undefined && (typeof body.sessionId !== 'string' || !body.sessionId || body.sessionId.length > 200))
|
|
39
|
+
|| (body.sessionId && body.config))
|
|
40
|
+
throw new TodoError('请选择待办和目标会话,补充要求最多 4000 字');
|
|
41
|
+
const input = { todoIds: [...new Set(body.todoIds)], note: body.note.trim(), idempotencyKey: body.idempotencyKey,
|
|
42
|
+
...(body.sessionId ? { sessionId: body.sessionId } : { config: launchConfig(body.config ?? {}, this.store.snapshot().defaults) }) };
|
|
43
|
+
const previous = this.store.previousHandoff(input);
|
|
44
|
+
if (previous)
|
|
45
|
+
return previous;
|
|
46
|
+
if (input.todoIds.some(id => this.store.get(id).status !== 'open'))
|
|
47
|
+
throw new TodoError('请先重新打开这条待办', 409);
|
|
48
|
+
const target = input.sessionId ? await this.runtime.target?.(input.sessionId, req) : undefined;
|
|
49
|
+
if (input.sessionId && (!target || !this.runtime.deliver))
|
|
50
|
+
throw new TodoError('目标会话不可用,请重新选择', 409);
|
|
51
|
+
const config = target?.config ?? await this.runtime.validate(input.config, req);
|
|
52
|
+
// Target validation can await; recheck the durable request before reserving any side effect.
|
|
53
|
+
const concurrent = this.store.previousHandoff(input);
|
|
54
|
+
if (concurrent)
|
|
55
|
+
return concurrent;
|
|
56
|
+
const run = this.store.beginHandoff(input, config, target?.name ?? `待办 · ${this.store.get(input.todoIds[0]).title}`.slice(0, 120));
|
|
57
|
+
const prompt = handoffPrompt(this.store, run);
|
|
58
|
+
void (input.sessionId ? this.runtime.deliver(run, prompt, req)
|
|
59
|
+
: this.runtime.launch(run, prompt, sessionId => this.store.mark(run.id, { sessionId }), req))
|
|
60
|
+
.then(() => this.store.mark(run.id, { status: 'delivered' }))
|
|
61
|
+
.catch(error => this.store.mark(run.id, { status: 'failed', error: error instanceof Error ? error.message : String(error) }));
|
|
62
|
+
return this.store.run(run.id);
|
|
63
|
+
}
|
|
29
64
|
async tick() {
|
|
30
65
|
for (const collector of this.store.due()) {
|
|
31
66
|
try {
|
|
@@ -59,6 +94,7 @@ export function todoRoutes(store, runner, runtime) {
|
|
|
59
94
|
router.get('/', route((_req, res) => res.json(store.snapshot())));
|
|
60
95
|
router.post('/', route((req, res) => res.json({ todo: store.create(req.body ?? {}) })));
|
|
61
96
|
router.post('/defaults', route(async (req, res) => res.json({ defaults: store.defaults(await runtime.validate(launchConfig(req.body ?? {}), req)) })));
|
|
97
|
+
router.post('/handoff', route(async (req, res) => res.json({ run: await runner.handoff(req.body, req) })));
|
|
62
98
|
router.post('/collectors', route(async (req, res) => {
|
|
63
99
|
const input = req.body ?? {};
|
|
64
100
|
const config = await runtime.validate(launchConfig(input.config ?? {}), req);
|
|
@@ -183,7 +183,7 @@ export class TodoStore {
|
|
|
183
183
|
const item = kind === 'execute' ? this.get(id) : this.collector(id);
|
|
184
184
|
if (kind === 'execute' && item.status !== 'open')
|
|
185
185
|
throw new TodoError('请先重新打开这条待办', 409);
|
|
186
|
-
if (this.doc.runs.some(r => r.status === 'launching' && (kind === 'execute' ? r.todoId === id : r.collectorId === id)))
|
|
186
|
+
if (this.doc.runs.some(r => r.status === 'launching' && (kind === 'execute' ? r.todoId === id || r.handoff?.todoIds.includes(id) : r.collectorId === id)))
|
|
187
187
|
throw new TodoError('此项正在启动,请稍候', 409);
|
|
188
188
|
return this.transaction(doc => {
|
|
189
189
|
const now = Date.now();
|
|
@@ -200,6 +200,36 @@ export class TodoStore {
|
|
|
200
200
|
return { run, fresh: true };
|
|
201
201
|
});
|
|
202
202
|
}
|
|
203
|
+
previousHandoff(input) {
|
|
204
|
+
if (!input.idempotencyKey || input.idempotencyKey.length > 200)
|
|
205
|
+
throw new TodoError('缺少有效的请求标识');
|
|
206
|
+
const previous = this.doc.requests[`handoff:${input.idempotencyKey}`];
|
|
207
|
+
if (!previous)
|
|
208
|
+
return;
|
|
209
|
+
if (previous.hash !== this.handoffHash(input))
|
|
210
|
+
throw new TodoError('同一请求标识的内容不一致', 409);
|
|
211
|
+
return this.run(previous.id);
|
|
212
|
+
}
|
|
213
|
+
beginHandoff(input, config, sessionName) {
|
|
214
|
+
const todos = input.todoIds.map(id => this.get(id));
|
|
215
|
+
if (todos.some(todo => todo.status !== 'open'))
|
|
216
|
+
throw new TodoError('请先重新打开已完成或忽略的待办', 409);
|
|
217
|
+
if (this.doc.runs.some(run => run.status === 'launching' && input.todoIds.some(id => run.todoId === id || run.handoff?.todoIds.includes(id))))
|
|
218
|
+
throw new TodoError('这些待办正在发送,请稍候', 409);
|
|
219
|
+
return this.transaction(doc => {
|
|
220
|
+
const now = Date.now();
|
|
221
|
+
const run = { id: randomUUID(), kind: 'execute', todoId: todos[0].id, collectorId: null,
|
|
222
|
+
name: todos.length === 1 ? todos[0].title : `${todos.length} 条待办`, config, createdAt: now, updatedAt: now,
|
|
223
|
+
status: 'launching', sessionId: input.sessionId ?? null, result: '', error: '',
|
|
224
|
+
handoff: { todoIds: input.todoIds, note: input.note, targetSessionId: input.sessionId ?? null, sessionName } };
|
|
225
|
+
doc.runs.push(run);
|
|
226
|
+
doc.requests[`handoff:${input.idempotencyKey}`] = { hash: this.handoffHash(input), id: run.id };
|
|
227
|
+
return run;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
handoffHash(input) {
|
|
231
|
+
return this.hash({ todoIds: input.todoIds, note: input.note, sessionId: input.sessionId ?? null, config: input.sessionId ? null : input.config });
|
|
232
|
+
}
|
|
203
233
|
mark(id, update) {
|
|
204
234
|
return this.transaction(doc => {
|
|
205
235
|
const run = doc.runs.find(r => r.id === id);
|
|
@@ -1,293 +1,63 @@
|
|
|
1
1
|
import { ensureNodePty } from './ensureNodePty.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* 1. node-pty : 实际 spawn 测试 → 失败则从源码重编译
|
|
10
|
-
* 2. tmux : 检测是否安装 → 缺失则尝试自动安装
|
|
11
|
-
*
|
|
12
|
-
* —— 如何新增检查项 ——
|
|
13
|
-
* 在 BootChecks 接口加字段,在 runBootChecks() 加 step,
|
|
14
|
-
* 在 formatBootCheckReport() 加对应的输出行。
|
|
15
|
-
*/
|
|
16
|
-
import { execSync, spawnSync } from 'child_process';
|
|
17
|
-
import fs from 'fs';
|
|
18
|
-
import os from 'os';
|
|
19
|
-
import path from 'path';
|
|
20
|
-
import { createRequire } from 'module';
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
// Helpers
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const tools = require('../../../scripts/install-utils.cjs');
|
|
8
|
+
const { rebuildNodePty } = require('../../../scripts/ensure-node-pty.cjs');
|
|
24
9
|
const MARKER_FILE = path.join(os.homedir(), '.termdock', '.boot-check-ok');
|
|
25
|
-
function which(bin) {
|
|
26
|
-
// 先查 PATH
|
|
27
|
-
try {
|
|
28
|
-
const result = execSync(`command -v ${bin} 2>/dev/null`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
29
|
-
if (result)
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
catch { /* not in PATH */ }
|
|
33
|
-
// macOS non-interactive SSH 的 PATH 不包含 Homebrew 路径,手动检查
|
|
34
|
-
const extraPaths = [
|
|
35
|
-
'/opt/homebrew/bin',
|
|
36
|
-
'/usr/local/bin',
|
|
37
|
-
'/opt/local/bin', // MacPorts
|
|
38
|
-
];
|
|
39
|
-
for (const dir of extraPaths) {
|
|
40
|
-
const fullPath = path.join(dir, bin);
|
|
41
|
-
try {
|
|
42
|
-
fs.accessSync(fullPath, fs.constants.X_OK);
|
|
43
|
-
return fullPath;
|
|
44
|
-
}
|
|
45
|
-
catch { /* not here */ }
|
|
46
|
-
}
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
function runQuiet(cmd, timeoutMs = 30_000) {
|
|
50
|
-
try {
|
|
51
|
-
const r = spawnSync(cmd, [], {
|
|
52
|
-
shell: true,
|
|
53
|
-
timeout: timeoutMs,
|
|
54
|
-
encoding: 'utf-8',
|
|
55
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
56
|
-
});
|
|
57
|
-
return { ok: r.status === 0, stdout: r.stdout, stderr: r.stderr };
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
return { ok: false, stdout: '', stderr: '' };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
// 1. node-pty 验证 + 重建
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
10
|
function checkNodePty() {
|
|
67
|
-
|
|
11
|
+
let ptyPath;
|
|
68
12
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
ptyPath = require_.resolve('node-pty/package.json').replace('/package.json', '');
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
result.error = 'node-pty not found in module resolution path';
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
const pty = require_(ptyPath);
|
|
79
|
-
// 修复 spawn-helper 可能因 npm 安装丢失的执行权限
|
|
80
|
-
try {
|
|
81
|
-
const prebuildsDir = path.join(ptyPath, 'prebuilds');
|
|
82
|
-
if (fs.existsSync(prebuildsDir)) {
|
|
83
|
-
for (const entry of fs.readdirSync(prebuildsDir, { withFileTypes: true })) {
|
|
84
|
-
if (!entry.isDirectory())
|
|
85
|
-
continue;
|
|
86
|
-
const helperPath = path.join(prebuildsDir, entry.name, 'spawn-helper');
|
|
87
|
-
if (!fs.existsSync(helperPath))
|
|
88
|
-
continue;
|
|
89
|
-
try {
|
|
90
|
-
const mode = fs.statSync(helperPath).mode;
|
|
91
|
-
if ((mode & 0o111) === 0)
|
|
92
|
-
fs.chmodSync(helperPath, mode | 0o111);
|
|
93
|
-
}
|
|
94
|
-
catch { /* skip */ }
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
catch { /* prebuilds dir may not exist (compiled from source) */ }
|
|
99
|
-
// 实际 spawn 测试(不仅仅是 require,macOS ARM 预编译包可能 require 成功但 spawn 失败)
|
|
100
|
-
const proc = pty.spawn(process.env.SHELL || '/bin/bash', [], { name: 'xterm', cols: 80, rows: 24 });
|
|
101
|
-
proc.kill();
|
|
102
|
-
result.ok = true;
|
|
103
|
-
return result;
|
|
13
|
+
// Never bypass the Darwin FD patch after a repair failure.
|
|
14
|
+
ensureNodePty();
|
|
15
|
+
ptyPath = path.dirname(require.resolve('node-pty/package.json'));
|
|
104
16
|
}
|
|
105
|
-
catch (
|
|
106
|
-
|
|
17
|
+
catch (error) {
|
|
18
|
+
return { ok: false, rebuilt: false, error: String(error) };
|
|
107
19
|
}
|
|
108
20
|
try {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
ptyPath = require_.resolve('node-pty/package.json').replace('/package.json', '');
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
result.error = 'node-pty not found in module resolution path';
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
// 清除预编译二进制缓存
|
|
119
|
-
const prebuildsDir = path.join(ptyPath, 'prebuilds');
|
|
120
|
-
if (fs.existsSync(prebuildsDir)) {
|
|
121
|
-
fs.rmSync(prebuildsDir, { recursive: true, force: true });
|
|
122
|
-
}
|
|
123
|
-
const rebuild = runQuiet(`cd ${ptyPath} && npx --yes node-gyp rebuild`, 120_000);
|
|
124
|
-
if (rebuild.ok) {
|
|
125
|
-
// 重试 spawn
|
|
126
|
-
try {
|
|
127
|
-
const pty = require_(ptyPath);
|
|
128
|
-
const proc = pty.spawn(process.env.SHELL || '/bin/bash', [], { name: 'xterm', cols: 80, rows: 24 });
|
|
129
|
-
proc.kill();
|
|
130
|
-
result.ok = true;
|
|
131
|
-
result.rebuilt = true;
|
|
132
|
-
return result;
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
result.error = 'node-pty 重编译成功但 spawn 仍然失败';
|
|
136
|
-
return result;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
result.error = `node-pty 重编译失败: ${rebuild.stderr.slice(0, 200)}`;
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
catch (e) {
|
|
143
|
-
result.error = `node-pty 未找到或无法初始化: ${String(e).slice(0, 200)}`;
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// ---------------------------------------------------------------------------
|
|
148
|
-
// 2. tmux 检测 + 自动安装
|
|
149
|
-
// ---------------------------------------------------------------------------
|
|
150
|
-
function checkTmux() {
|
|
151
|
-
const result = { ok: false, installed: false };
|
|
152
|
-
// 先检查是否已安装
|
|
153
|
-
const tmuxPath = which('tmux');
|
|
154
|
-
if (tmuxPath) {
|
|
155
|
-
try {
|
|
156
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
157
|
-
}
|
|
158
|
-
catch { /* ignore */ }
|
|
159
|
-
result.ok = true;
|
|
160
|
-
result.installed = false; // 没有新安装
|
|
161
|
-
return result;
|
|
21
|
+
tools.probeNodePty(ptyPath);
|
|
22
|
+
return { ok: true, rebuilt: false };
|
|
162
23
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (r.ok || which('tmux')) {
|
|
171
|
-
try {
|
|
172
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
173
|
-
}
|
|
174
|
-
catch { /* ignore */ }
|
|
175
|
-
result.ok = true;
|
|
176
|
-
result.installed = true;
|
|
177
|
-
return result;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const port = which('port'); // MacPorts
|
|
181
|
-
if (port) {
|
|
182
|
-
const r = runQuiet(`${port} install tmux 2>&1`, 120_000);
|
|
183
|
-
if (r.ok || which('tmux')) {
|
|
184
|
-
try {
|
|
185
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
186
|
-
}
|
|
187
|
-
catch { /* ignore */ }
|
|
188
|
-
result.ok = true;
|
|
189
|
-
result.installed = true;
|
|
190
|
-
return result;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
const nixEnv = which('nix-env');
|
|
194
|
-
if (nixEnv) {
|
|
195
|
-
const r = runQuiet(`${nixEnv} -iA nixpkgs.tmux 2>&1`, 120_000);
|
|
196
|
-
if (r.ok || which('tmux')) {
|
|
197
|
-
try {
|
|
198
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
199
|
-
}
|
|
200
|
-
catch { /* ignore */ }
|
|
201
|
-
result.ok = true;
|
|
202
|
-
result.installed = true;
|
|
203
|
-
return result;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
result.error = 'tmux 未安装且未找到包管理器 (brew/port/nix)。请安装 Homebrew: https://brew.sh';
|
|
207
|
-
return result;
|
|
24
|
+
catch { /* An incompatible addon needs a rebuild in a non-global npx. */ }
|
|
25
|
+
try {
|
|
26
|
+
fs.rmSync(path.join(ptyPath, 'prebuilds'), { recursive: true, force: true });
|
|
27
|
+
rebuildNodePty(ptyPath, { timeout: 120_000 });
|
|
28
|
+
tools.clearPtyModuleCache(ptyPath);
|
|
29
|
+
tools.probeNodePty(ptyPath);
|
|
30
|
+
return { ok: true, rebuilt: true };
|
|
208
31
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const managers = [
|
|
212
|
-
{ bin: 'apt-get', cmd: 'apt-get install -y tmux' },
|
|
213
|
-
{ bin: 'dnf', cmd: 'dnf install -y tmux' },
|
|
214
|
-
{ bin: 'yum', cmd: 'yum install -y tmux' },
|
|
215
|
-
{ bin: 'apk', cmd: 'apk add tmux' },
|
|
216
|
-
{ bin: 'pacman', cmd: 'pacman -S --noconfirm tmux' },
|
|
217
|
-
{ bin: 'zypper', cmd: 'zypper install -y tmux' },
|
|
218
|
-
];
|
|
219
|
-
for (const m of managers) {
|
|
220
|
-
if (!which(m.bin))
|
|
221
|
-
continue;
|
|
222
|
-
// 需要 root 权限
|
|
223
|
-
const r = runQuiet(`sudo ${m.cmd} 2>&1`, 120_000);
|
|
224
|
-
if (r.ok || which('tmux')) {
|
|
225
|
-
try {
|
|
226
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
227
|
-
}
|
|
228
|
-
catch { /* ignore */ }
|
|
229
|
-
result.ok = true;
|
|
230
|
-
result.installed = true;
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
// 也试一下不用 sudo
|
|
234
|
-
const r2 = runQuiet(`${m.cmd} 2>&1`, 120_000);
|
|
235
|
-
if (r2.ok || which('tmux')) {
|
|
236
|
-
try {
|
|
237
|
-
result.version = execSync('tmux -V', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
238
|
-
}
|
|
239
|
-
catch { /* ignore */ }
|
|
240
|
-
result.ok = true;
|
|
241
|
-
result.installed = true;
|
|
242
|
-
return result;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
result.error = 'tmux 未安装。请用系统包管理器安装,例如: sudo apt install tmux';
|
|
246
|
-
return result;
|
|
32
|
+
catch (error) {
|
|
33
|
+
return { ok: false, rebuilt: false, error: String(error) };
|
|
247
34
|
}
|
|
248
|
-
// 其他平台
|
|
249
|
-
result.error = `不支持在 ${platform} 上自动安装 tmux。请手动安装。`;
|
|
250
|
-
return result;
|
|
251
35
|
}
|
|
252
|
-
|
|
253
|
-
// 主入口
|
|
254
|
-
// ---------------------------------------------------------------------------
|
|
255
|
-
let _cachedResult = null;
|
|
36
|
+
let cachedResult = null;
|
|
256
37
|
export function runBootChecks() {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
//
|
|
261
|
-
|
|
38
|
+
if (cachedResult)
|
|
39
|
+
return cachedResult;
|
|
40
|
+
// The on-disk marker is diagnostic only. Node upgrades, a removed tmux, or
|
|
41
|
+
// another installation must never be accepted solely because it says "ok".
|
|
42
|
+
const nodePty = checkNodePty(), tmux = tools.checkTmux();
|
|
43
|
+
cachedResult = { nodePty, tmux };
|
|
44
|
+
if (nodePty.ok && tmux.ok) {
|
|
262
45
|
try {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
nodePty: cached.nodePty,
|
|
267
|
-
tmux: cached.tmux,
|
|
268
|
-
};
|
|
269
|
-
return _cachedResult;
|
|
270
|
-
}
|
|
271
|
-
// marker 存在但状态不完整(例如 postinstall 部分失败)→ 重新检查
|
|
46
|
+
fs.mkdirSync(path.dirname(MARKER_FILE), { recursive: true, mode: 0o700 });
|
|
47
|
+
fs.writeFileSync(MARKER_FILE, JSON.stringify({ checkedAt: new Date().toISOString(), nodePty, tmux,
|
|
48
|
+
runtime: { node: process.version, abi: process.versions.modules, platform: process.platform, arch: process.arch } }), { mode: 0o600 });
|
|
272
49
|
}
|
|
273
|
-
catch { /*
|
|
50
|
+
catch { /* A read-only home does not prevent running the terminal. */ }
|
|
274
51
|
}
|
|
275
|
-
|
|
276
|
-
const tmux = checkTmux();
|
|
277
|
-
_cachedResult = { nodePty, tmux };
|
|
278
|
-
// 全部通过则写 marker
|
|
279
|
-
if (nodePty.ok && tmux.ok) {
|
|
52
|
+
else {
|
|
280
53
|
try {
|
|
281
|
-
fs.
|
|
282
|
-
fs.writeFileSync(MARKER_FILE, JSON.stringify({ checkedAt: new Date().toISOString(), nodePty, tmux }), 'utf-8');
|
|
54
|
+
fs.rmSync(MARKER_FILE, { force: true });
|
|
283
55
|
}
|
|
284
|
-
catch { /*
|
|
56
|
+
catch { /* Diagnostic only. */ }
|
|
285
57
|
}
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
export function getBootChecks() {
|
|
289
|
-
return _cachedResult ?? runBootChecks();
|
|
58
|
+
return cachedResult;
|
|
290
59
|
}
|
|
60
|
+
export function getBootChecks() { return cachedResult ?? runBootChecks(); }
|
|
291
61
|
/**
|
|
292
62
|
* 格式化启动检查报告,用于 CLI 启动时显示给用户。
|
|
293
63
|
*/
|