termdock 1.4.327 → 1.4.329
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/{App-C0c83Pxp.js → App-D9G1XjRn.js} +54 -54
- package/dist/client/assets/App-D9G1XjRn.js.br +0 -0
- package/dist/client/assets/App-D9G1XjRn.js.gz +0 -0
- package/dist/client/assets/{ArchitecturePanel-znWmrZsF.js → ArchitecturePanel-Db0No7hm.js} +2 -2
- package/dist/client/assets/ArchitecturePanel-Db0No7hm.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-Db0No7hm.js.gz +0 -0
- package/dist/client/assets/{ChangeWalkthroughPanel-Bt4fjEoD.js → ChangeWalkthroughPanel-iNaVjdNU.js} +1 -1
- package/dist/client/assets/ChangeWalkthroughPanel-iNaVjdNU.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-iNaVjdNU.js.gz +0 -0
- package/dist/client/assets/{CollaborationMainWorkspace-0s90d39f.js → CollaborationMainWorkspace-Qek-VG70.js} +1 -1
- package/dist/client/assets/CollaborationMainWorkspace-Qek-VG70.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-Qek-VG70.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-BuRZBZGa.js +2 -0
- package/dist/client/assets/ComputerControlView-CzooFU9V.js +6 -0
- package/dist/client/assets/ComputerControlView-CzooFU9V.js.br +0 -0
- package/dist/client/assets/ComputerControlView-CzooFU9V.js.gz +0 -0
- package/dist/client/assets/{DagPlayground-311LPbK_.js → DagPlayground-BfcGoLqt.js} +1 -1
- package/dist/client/assets/DagPlayground-BfcGoLqt.js.br +0 -0
- package/dist/client/assets/DagPlayground-BfcGoLqt.js.gz +0 -0
- package/dist/client/assets/{DiffLab-CHZ0EL2E.js → DiffLab-5lLS4TTe.js} +1 -1
- package/dist/client/assets/DiffLab-5lLS4TTe.js.br +0 -0
- package/dist/client/assets/DiffLab-5lLS4TTe.js.gz +0 -0
- package/dist/client/assets/{DiffReview-BA7zArOA.js → DiffReview-Bm5VsO_2.js} +1 -1
- package/dist/client/assets/DiffReview-Bm5VsO_2.js.br +0 -0
- package/dist/client/assets/DiffReview-Bm5VsO_2.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-C_6SxWtH.js → DiffReviewLab-CokJ4CU0.js} +1 -1
- package/dist/client/assets/DiffReviewLab-CokJ4CU0.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-CokJ4CU0.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-B0YoRCEi.js → DiffViewer-CYl7f8Ni.js} +1 -1
- package/dist/client/assets/DiffViewer-CYl7f8Ni.js.br +0 -0
- package/dist/client/assets/DiffViewer-CYl7f8Ni.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-BboTxu4_.js → ModelPreview-GyVcgKyk.js} +1 -1
- package/dist/client/assets/ModelPreview-GyVcgKyk.js.br +0 -0
- package/dist/client/assets/ModelPreview-GyVcgKyk.js.gz +0 -0
- package/dist/client/assets/{RightSidebar-TFRZlsFX.js → RightSidebar-BVTTEpbi.js} +3 -3
- package/dist/client/assets/RightSidebar-BVTTEpbi.js.br +0 -0
- package/dist/client/assets/RightSidebar-BVTTEpbi.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-BK2-PKkq.js → abnfDiagram-VCTEODGH-Bn3DRY7x.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-Bn3DRY7x.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-Bn3DRY7x.js.gz +0 -0
- package/dist/client/assets/{app-D2yRvfNE.js → app-D5VZp8rc.js} +10 -10
- package/dist/client/assets/app-D5VZp8rc.js.br +0 -0
- package/dist/client/assets/app-D5VZp8rc.js.gz +0 -0
- package/dist/client/assets/{arc-DqI6rAeJ.js → arc-Du7GNk7G.js} +1 -1
- package/dist/client/assets/{arc-DqI6rAeJ.js.br → arc-Du7GNk7G.js.br} +0 -0
- package/dist/client/assets/arc-Du7GNk7G.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-CZBYAIxt.js → architectureDiagram-5GKGNRK7-DhxS0QdH.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DhxS0QdH.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DhxS0QdH.js.gz +0 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-BAZ4LopQ.js → blockDiagram-I7D4REHJ-Wv6QW34G.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-Wv6QW34G.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-Wv6QW34G.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-Boh80g9D.js → c4Diagram-7LVT6UL2-BX7uuZf8.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-BX7uuZf8.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-BX7uuZf8.js.gz +0 -0
- package/dist/client/assets/channel-DRDG9HMw.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-CQtYmkXv.js → chunk-2Q5K7J3B-DUyA5Q_x.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-lfjEsOLd.js → chunk-5VM5RSS4-CsqOe_v4.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-B3iWUfsu.js → chunk-F27PBJKO-CcO_-Kak.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-CcO_-Kak.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-CcO_-Kak.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-BV8W69Xy.js → chunk-IMKFNOWR-CQJ1dzSN.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-CQJ1dzSN.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-CQJ1dzSN.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-BHn7J2ij.js → chunk-JWPE2WC7-oUpFzQDX.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-1UAKkjro.js → chunk-POPQ4Y6H-C1YXcY1K.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DMDJrwWD.js → chunk-SVP7TREG-BWjHeocC.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-BWjHeocC.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-BWjHeocC.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-DViVpzs1.js → chunk-TICWLB2K-DQ0mCrXn.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-DQ0mCrXn.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DQ0mCrXn.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-Cyg6qo-b.js → chunk-XXDRQBXY-SHYrjdLW.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-CjINloiI.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CjINloiI.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-Dq6PJ-un.js → cose-bilkent-JH36ORCC-BBhGCaX-.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-BBhGCaX-.js.br +0 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-Dq6PJ-un.js.gz → cose-bilkent-JH36ORCC-BBhGCaX-.js.gz} +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX--pc9zClZ.js → cynefin-OW5HDTMX-7coImPkF.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-7coImPkF.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-7coImPkF.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-1whKia5t.js → cynefinDiagram-5FMLGOSQ-Cnoxl1HL.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Cnoxl1HL.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Cnoxl1HL.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-8TjGkCEP.js → dagre-GXQ25YYZ-B6fpGrH1.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-B6fpGrH1.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-B6fpGrH1.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-BTgsveUu.js → diagram-S7CK7UJ4-Sprx3hA_.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-Sprx3hA_.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-Sprx3hA_.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-CPxoDqq7.js → diagram-UQ7AKVKN-BOXGQUJw.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-BOXGQUJw.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-BOXGQUJw.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-BtNBFyC3.js → diagram-VSXAHHWV-kPY7jhp2.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-kPY7jhp2.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-kPY7jhp2.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-DLfdx0dh.js → diagram-VX7I27RA-07j7wunW.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-07j7wunW.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-07j7wunW.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-C9FdZJ41.js → diagram-Z3DM3KII-CbWJovUP.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-CbWJovUP.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-CbWJovUP.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-CAxaqCAJ.js → ebnfDiagram-PWID7BFC-CqoHnUPd.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CqoHnUPd.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CqoHnUPd.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-BBO2Iz-B.js → erDiagram-RLTQ6QDP-eJuQs4se.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-eJuQs4se.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-eJuQs4se.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-DQ-nPGNL.js → flowDiagram-HODETNUW-DSgseCP6.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-DSgseCP6.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DSgseCP6.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-C4bKdSCF.js → ganttDiagram-EL5Y4UJY-Ca5MVluD.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-Ca5MVluD.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-Ca5MVluD.js.gz +0 -0
- package/dist/client/assets/{gestureArbiter-miROLzXb.js → gestureArbiter-CGaUInum.js} +1 -1
- package/dist/client/assets/gestureArbiter-CGaUInum.js.br +0 -0
- package/dist/client/assets/gestureArbiter-CGaUInum.js.gz +0 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-cAbsg4ei.js → gitGraphDiagram-WWUBYQGX-BgAMalup.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BgAMalup.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BgAMalup.js.gz +0 -0
- package/dist/client/assets/{index-Dd_3ISCb.css → index-C6xPtOPw.css} +1 -1
- package/dist/client/assets/index-C6xPtOPw.css.br +0 -0
- package/dist/client/assets/{index-Dd_3ISCb.css.gz → index-C6xPtOPw.css.gz} +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-EV88OFTf.js → infoDiagram-27XIBGKW-DvrmPX6I.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bi-60w6U.js → ishikawaDiagram-5VMMS53U-BIxEg0pl.js} +1 -1
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BIxEg0pl.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BIxEg0pl.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bgbk61sp.js → journeyDiagram-3NMN7TZE-BI8B1o2v.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-BI8B1o2v.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-BI8B1o2v.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-Ly6IeL8s.js → kanban-definition-UXKFOSKX-tBgvPAXx.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-tBgvPAXx.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-tBgvPAXx.js.gz +0 -0
- package/dist/client/assets/{layout-CEjMszLD.js → layout-F6rDt84Y.js} +1 -1
- package/dist/client/assets/layout-F6rDt84Y.js.br +0 -0
- package/dist/client/assets/layout-F6rDt84Y.js.gz +0 -0
- package/dist/client/assets/{linear-BCB67kKS.js → linear-QaUhDwi6.js} +1 -1
- package/dist/client/assets/linear-QaUhDwi6.js.br +0 -0
- package/dist/client/assets/linear-QaUhDwi6.js.gz +0 -0
- package/dist/client/assets/{mermaid.core-BmSOfxMH.js → mermaid.core-BHNVcgJG.js} +5 -5
- package/dist/client/assets/mermaid.core-BHNVcgJG.js.br +0 -0
- package/dist/client/assets/mermaid.core-BHNVcgJG.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-VEZ7qGHM.js → mindmap-definition-YA3MSWOX-CW_qv6SM.js} +1 -1
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CW_qv6SM.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CW_qv6SM.js.gz +0 -0
- package/dist/client/assets/{passwordBootstrap-BUV0AT5k.js → passwordBootstrap-xwlVHcmC.js} +1 -1
- package/dist/client/assets/passwordBootstrap-xwlVHcmC.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-xwlVHcmC.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DtFnROHy.js → pegDiagram-XKGWAZYB-DN89bpor.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-DN89bpor.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DN89bpor.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-CrRFKgsg.js → pieDiagram-E7YTZNPT-DIxGatjK.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-DIxGatjK.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DIxGatjK.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-DrxOcCWy.js → quadrantDiagram-AXDQQJYC-hA4Rk-Iv.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-hA4Rk-Iv.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-hA4Rk-Iv.js.gz +0 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BaXzskST.js → railroadDiagram-O6MQD6OU-CQft_cg4.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-CQft_cg4.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-CQft_cg4.js.gz +0 -0
- package/dist/client/assets/rdpSession-_Wi6QGVy.js +1 -0
- package/dist/client/assets/rdpSession-_Wi6QGVy.js.br +0 -0
- package/dist/client/assets/rdpSession-_Wi6QGVy.js.gz +0 -0
- package/dist/client/assets/{referenceLongPress-DqibFmuj.js → referenceLongPress-CHQPhmmv.js} +1 -1
- package/dist/client/assets/referenceLongPress-CHQPhmmv.js.br +0 -0
- package/dist/client/assets/referenceLongPress-CHQPhmmv.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-BdwuNHm0.js → requirementDiagram-BXWQKSXE-CAMtoGH8.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CAMtoGH8.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-CAMtoGH8.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-L8-WTgQS.js → sankeyDiagram-P5KCCOFB-USLSjs28.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-USLSjs28.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-USLSjs28.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-Hloa_AO5.js → sequenceDiagram-WJ2MYXX4-D22gyoMc.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D22gyoMc.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D22gyoMc.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-0sRpfplV.js → sizeCapture-INFHLROL-BAWAxmev.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-BAWAxmev.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-BAWAxmev.js.gz +0 -0
- package/dist/client/assets/{sparkles-CgDDXr95.js → sparkles-BK6dvO4C.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-DqT3kcLM.js → stateDiagram-D77RDMKH-Dd8Kz_3m.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-Dd8Kz_3m.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-Dd8Kz_3m.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-b4HSZCSL.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-BH5xHrJq.js → swimlanes-42K2YHIH-BjLw9hF1.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-BjLw9hF1.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-BjLw9hF1.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-C2ZVrP3k.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-D3Ez5FZh.js → timeline-definition-24CTP7MA-DVis9e2K.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-DVis9e2K.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-DVis9e2K.js.gz +0 -0
- package/dist/client/assets/{triangle-alert-DqUvQ_x8.js → triangle-alert-CiksAjZK.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-DEGLdtyy.js → vennDiagram-4TSXK5OY-CNwJhMgu.js} +1 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-CNwJhMgu.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-CNwJhMgu.js.gz +0 -0
- package/dist/client/assets/{videoCompression-DIBRptEJ.js → videoCompression-CeWiTlti.js} +1 -1
- package/dist/client/assets/videoCompression-CeWiTlti.js.br +0 -0
- package/dist/client/assets/videoCompression-CeWiTlti.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-BWXojK8h.js → wardleyDiagram-VM6X3IG4-COCAMRlj.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-COCAMRlj.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-COCAMRlj.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-CI95cYmG.js → xychartDiagram-S5SC5T6Z-BUmr1Xe8.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-BUmr1Xe8.js.br +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-CI95cYmG.js.gz → xychartDiagram-S5SC5T6Z-BUmr1Xe8.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.js +1 -1
- package/dist/client/sw.js.br +0 -0
- package/dist/client/sw.js.gz +0 -0
- package/dist/server/agent/collaborationCli.js +3 -0
- package/dist/server/agent/integrationRecoveryBinding.js +34 -0
- package/dist/server/agent/integrationServer.js +1 -0
- package/dist/server/agent/integrationSessions.js +79 -3
- package/dist/server/entry.js +4 -0
- package/dist/server/routes/rdp.js +1 -1
- package/dist/server/routes/terminal.js +134 -24
- package/dist/server/utils/tmuxClientCapabilities.js +1 -1
- package/dist/server/utils/tmuxSizeOwnership.js +18 -0
- package/docs/integrations.md +27 -0
- package/package.json +1 -1
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/App-C0c83Pxp.js.br +0 -0
- package/dist/client/assets/App-C0c83Pxp.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-znWmrZsF.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-znWmrZsF.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-Bt4fjEoD.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-Bt4fjEoD.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-0s90d39f.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-0s90d39f.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-CHVGId4O.js +0 -2
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js +0 -5
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js.br +0 -0
- package/dist/client/assets/ComputerControlView-BxLiNZeK.js.gz +0 -0
- package/dist/client/assets/DagPlayground-311LPbK_.js.br +0 -0
- package/dist/client/assets/DagPlayground-311LPbK_.js.gz +0 -0
- package/dist/client/assets/DiffLab-CHZ0EL2E.js.br +0 -0
- package/dist/client/assets/DiffLab-CHZ0EL2E.js.gz +0 -0
- package/dist/client/assets/DiffReview-BA7zArOA.js.br +0 -0
- package/dist/client/assets/DiffReview-BA7zArOA.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-C_6SxWtH.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-C_6SxWtH.js.gz +0 -0
- package/dist/client/assets/DiffViewer-B0YoRCEi.js.br +0 -0
- package/dist/client/assets/DiffViewer-B0YoRCEi.js.gz +0 -0
- package/dist/client/assets/ModelPreview-BboTxu4_.js.br +0 -0
- package/dist/client/assets/ModelPreview-BboTxu4_.js.gz +0 -0
- package/dist/client/assets/RightSidebar-TFRZlsFX.js.br +0 -0
- package/dist/client/assets/RightSidebar-TFRZlsFX.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BK2-PKkq.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BK2-PKkq.js.gz +0 -0
- package/dist/client/assets/app-D2yRvfNE.js.br +0 -0
- package/dist/client/assets/app-D2yRvfNE.js.gz +0 -0
- package/dist/client/assets/arc-DqI6rAeJ.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CZBYAIxt.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-CZBYAIxt.js.gz +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BAZ4LopQ.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BAZ4LopQ.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-Boh80g9D.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-Boh80g9D.js.gz +0 -0
- package/dist/client/assets/channel-B3pP90yO.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-B3iWUfsu.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-B3iWUfsu.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BV8W69Xy.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BV8W69Xy.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMDJrwWD.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMDJrwWD.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DViVpzs1.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-DViVpzs1.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-CcfJXXoP.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CcfJXXoP.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-Dq6PJ-un.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX--pc9zClZ.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX--pc9zClZ.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-1whKia5t.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-1whKia5t.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-8TjGkCEP.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-8TjGkCEP.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BTgsveUu.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BTgsveUu.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CPxoDqq7.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CPxoDqq7.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-BtNBFyC3.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-BtNBFyC3.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-DLfdx0dh.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-DLfdx0dh.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-C9FdZJ41.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-C9FdZJ41.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CAxaqCAJ.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-CAxaqCAJ.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BBO2Iz-B.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BBO2Iz-B.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DQ-nPGNL.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DQ-nPGNL.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-C4bKdSCF.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-C4bKdSCF.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-miROLzXb.js.br +0 -0
- package/dist/client/assets/gestureArbiter-miROLzXb.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-cAbsg4ei.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-cAbsg4ei.js.gz +0 -0
- package/dist/client/assets/index-Dd_3ISCb.css.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bi-60w6U.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bi-60w6U.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Bgbk61sp.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-Bgbk61sp.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Ly6IeL8s.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Ly6IeL8s.js.gz +0 -0
- package/dist/client/assets/layout-CEjMszLD.js.br +0 -0
- package/dist/client/assets/layout-CEjMszLD.js.gz +0 -0
- package/dist/client/assets/linear-BCB67kKS.js.br +0 -0
- package/dist/client/assets/linear-BCB67kKS.js.gz +0 -0
- package/dist/client/assets/mermaid.core-BmSOfxMH.js.br +0 -0
- package/dist/client/assets/mermaid.core-BmSOfxMH.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-VEZ7qGHM.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-VEZ7qGHM.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-BUV0AT5k.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-BUV0AT5k.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DtFnROHy.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DtFnROHy.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrRFKgsg.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-CrRFKgsg.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DrxOcCWy.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-DrxOcCWy.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BaXzskST.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BaXzskST.js.gz +0 -0
- package/dist/client/assets/rdpSession-DtIeoTyy.js +0 -1
- package/dist/client/assets/rdpSession-DtIeoTyy.js.br +0 -0
- package/dist/client/assets/rdpSession-DtIeoTyy.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-DqibFmuj.js.br +0 -0
- package/dist/client/assets/referenceLongPress-DqibFmuj.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BdwuNHm0.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BdwuNHm0.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-L8-WTgQS.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-L8-WTgQS.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Hloa_AO5.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Hloa_AO5.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-0sRpfplV.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-0sRpfplV.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DqT3kcLM.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DqT3kcLM.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-DjkkxZUN.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-BH5xHrJq.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-BH5xHrJq.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DpLhj_Dx.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-D3Ez5FZh.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-D3Ez5FZh.js.gz +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DEGLdtyy.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-DEGLdtyy.js.gz +0 -0
- package/dist/client/assets/videoCompression-DIBRptEJ.js.br +0 -0
- package/dist/client/assets/videoCompression-DIBRptEJ.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BWXojK8h.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BWXojK8h.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-CI95cYmG.js.br +0 -0
|
@@ -61,6 +61,7 @@ export class IntegrationSessions {
|
|
|
61
61
|
lifecycle = new SessionLifecycleCoordinator();
|
|
62
62
|
mutations = new Map();
|
|
63
63
|
coldRetries = new Set();
|
|
64
|
+
reconcilingBindings = new Set();
|
|
64
65
|
closingOperations = new Set();
|
|
65
66
|
timers = new Set();
|
|
66
67
|
stopObservation;
|
|
@@ -302,7 +303,13 @@ export class IntegrationSessions {
|
|
|
302
303
|
return record;
|
|
303
304
|
}
|
|
304
305
|
async restore(principal, id, key) {
|
|
305
|
-
return this.mutate(principal, key, ['restore', id],
|
|
306
|
+
return this.mutate(principal, key, ['restore', id], async () => {
|
|
307
|
+
// A get can reconcile a proven tmux-recovery binding before restore takes
|
|
308
|
+
// the per-session lifecycle lock. restoreOnce then sees the exact live
|
|
309
|
+
// native owner and remains a no-op instead of launching a second Agent.
|
|
310
|
+
await this.get(principal, id);
|
|
311
|
+
return this.lifecycle.run(id, () => this.restoreOnce(principal, id, key));
|
|
312
|
+
});
|
|
306
313
|
}
|
|
307
314
|
async retryCold(principal, id, generation, key) {
|
|
308
315
|
return this.mutate(principal, key, ['retry-cold', id, generation], () => this.lifecycle.run(id, async () => {
|
|
@@ -690,7 +697,7 @@ export class IntegrationSessions {
|
|
|
690
697
|
return record;
|
|
691
698
|
}));
|
|
692
699
|
}
|
|
693
|
-
async refresh(id) {
|
|
700
|
+
async refresh(id, allowBindingReconciliation = true) {
|
|
694
701
|
const record = structuredClone(this.doc.sessions.find(s => s.session_id === id));
|
|
695
702
|
if (!record)
|
|
696
703
|
return;
|
|
@@ -781,8 +788,19 @@ export class IntegrationSessions {
|
|
|
781
788
|
const current = this.doc.sessions.find(s => s.session_id === id);
|
|
782
789
|
if (JSON.stringify(current) !== JSON.stringify(record))
|
|
783
790
|
return;
|
|
791
|
+
if (this.lifecycle.active(id) || this.pending.has(id))
|
|
792
|
+
return;
|
|
784
793
|
const code = error.code;
|
|
785
794
|
const errorCode = typeof code === 'string' ? code : 'SESSION_OBSERVATION_FAILED';
|
|
795
|
+
if (allowBindingReconciliation && errorCode === 'SESSION_IDENTITY_MISMATCH' && this.adapter.reconcileRecoveryBinding
|
|
796
|
+
&& ['ready', 'failed'].includes(record.state) && (record.runtime_present === true || record.state === 'failed')
|
|
797
|
+
&& (!record.error_code || record.error_code === 'SESSION_IDENTITY_MISMATCH')
|
|
798
|
+
&& record.agent_native_session_id && record.terminal_binding && !record.operation_uncertain
|
|
799
|
+
&& !record.close_intent && !record.rename_pending && !record.cold_retry_pending
|
|
800
|
+
&& !this.pending.has(id) && !this.lifecycle.active(id)) {
|
|
801
|
+
if (await this.reconcileRecoveredBinding(record))
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
786
804
|
if (record.state !== 'failed' || record.error_code !== errorCode)
|
|
787
805
|
this.saveRecord({ ...record, state: 'failed', error_code: errorCode,
|
|
788
806
|
launch_diagnostics: record.launch_diagnostics ? launchFailure(record.launch_diagnostics, error, errorCode) : undefined, updated_at: Date.now() });
|
|
@@ -871,11 +889,66 @@ export class IntegrationSessions {
|
|
|
871
889
|
this.saveRecord(next);
|
|
872
890
|
}
|
|
873
891
|
}
|
|
892
|
+
async reconcileRecoveredBinding(expected) {
|
|
893
|
+
const id = expected.session_id;
|
|
894
|
+
const reconcile = this.adapter.reconcileRecoveryBinding;
|
|
895
|
+
if (!reconcile || this.lifecycle.active(id) || this.pending.has(id))
|
|
896
|
+
return false;
|
|
897
|
+
let committed = false;
|
|
898
|
+
try {
|
|
899
|
+
await this.lifecycle.run(id, async () => {
|
|
900
|
+
const current = this.doc.sessions.find(record => record.session_id === id);
|
|
901
|
+
if (!current || JSON.stringify(current) !== JSON.stringify(expected) || this.pending.has(id)
|
|
902
|
+
|| !['ready', 'failed'].includes(current.state) || !(current.runtime_present === true || current.state === 'failed')
|
|
903
|
+
|| (current.error_code && current.error_code !== 'SESSION_IDENTITY_MISMATCH')
|
|
904
|
+
|| current.operation_uncertain || current.close_intent || current.rename_pending || current.cold_retry_pending
|
|
905
|
+
|| !current.agent_native_session_id || !current.terminal_binding)
|
|
906
|
+
return;
|
|
907
|
+
this.reconcilingBindings.add(id);
|
|
908
|
+
let reconciled;
|
|
909
|
+
try {
|
|
910
|
+
reconciled = await reconcile.call(this.adapter, current);
|
|
911
|
+
}
|
|
912
|
+
catch {
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
if (!reconciled || JSON.stringify(reconciled.binding) === JSON.stringify(current.terminal_binding))
|
|
916
|
+
return;
|
|
917
|
+
const latest = this.doc.sessions.find(record => record.session_id === id);
|
|
918
|
+
if (!latest || JSON.stringify(latest) !== JSON.stringify(current))
|
|
919
|
+
return;
|
|
920
|
+
const now = Date.now();
|
|
921
|
+
const next = { ...current, terminal_binding: structuredClone(reconciled.binding), state: 'ready',
|
|
922
|
+
runtime_present: true, error_code: null, operation_uncertain: false, generation: (current.generation ?? 1) + 1,
|
|
923
|
+
operation_id: randomUUID(), updated_at: now,
|
|
924
|
+
binding_reconciliation: { at: now, recovery_operation_id: reconciled.recoveryOperationId,
|
|
925
|
+
previous_binding: structuredClone(current.terminal_binding) },
|
|
926
|
+
startup_input: startupInput(current, now) };
|
|
927
|
+
this.saveRecord(next);
|
|
928
|
+
committed = true;
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
catch {
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
finally {
|
|
935
|
+
this.reconcilingBindings.delete(id);
|
|
936
|
+
}
|
|
937
|
+
if (committed) {
|
|
938
|
+
try {
|
|
939
|
+
this.adapter.recoveryBindingReconciled?.(id);
|
|
940
|
+
}
|
|
941
|
+
catch { /* The worker also retries on its normal tick. */ }
|
|
942
|
+
}
|
|
943
|
+
return committed;
|
|
944
|
+
}
|
|
874
945
|
/** Only gates configured launches. Native UUID and Agent turn state are not input prerequisites. */
|
|
875
946
|
async deliveryReadiness(id) {
|
|
876
947
|
const existing = this.doc.sessions.find(record => record.session_id === id);
|
|
877
948
|
if (!existing)
|
|
878
949
|
return null;
|
|
950
|
+
if (this.reconcilingBindings.has(id))
|
|
951
|
+
return { allowed: false, reason: 'SESSION_BINDING_RECONCILIATION_PENDING' };
|
|
879
952
|
if (this.closingOperations.has(id))
|
|
880
953
|
return { allowed: false, reason: 'SESSION_OPERATION_IN_PROGRESS' };
|
|
881
954
|
if (existing.state === 'closed')
|
|
@@ -886,7 +959,10 @@ export class IntegrationSessions {
|
|
|
886
959
|
return { allowed: false, reason: existing.state === 'released' ? 'SESSION_RELEASED' : 'SESSION_OPERATION_IN_PROGRESS' };
|
|
887
960
|
if (!existing.startup_input)
|
|
888
961
|
return null;
|
|
889
|
-
|
|
962
|
+
// This callback can run inside the delivery worker's own queue. Binding
|
|
963
|
+
// reconciliation must enter that queue from get/observation, never wait on
|
|
964
|
+
// the worker from within itself.
|
|
965
|
+
await this.refresh(id, false);
|
|
890
966
|
const record = this.doc.sessions.find(record => record.session_id === id);
|
|
891
967
|
if (record.error_code && record.error_code !== 'SESSION_BINDING_TIMEOUT')
|
|
892
968
|
return { allowed: false, reason: record.error_code };
|
package/dist/server/entry.js
CHANGED
|
@@ -116,6 +116,10 @@ function shouldWriteClientLog(level, message) {
|
|
|
116
116
|
clientLogSuppressedCount += 1;
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
|
+
// Motion trace records share a label but contain different ordered samples.
|
|
120
|
+
// Preserve every chunk while retaining the global rate limit above.
|
|
121
|
+
if (message === 'COMPUTER_MOTION_TRACE')
|
|
122
|
+
return true;
|
|
119
123
|
const key = `${String(level ?? 'info')}\u0000${String(message ?? '')}`;
|
|
120
124
|
const last = clientLogRecent.get(key);
|
|
121
125
|
if (last && now - last < CLIENT_LOG_DEDUP_WINDOW_MS) {
|
|
@@ -119,7 +119,7 @@ export function handleRdpWebSocket(socket, host, port) {
|
|
|
119
119
|
width: String(Math.max(640, Math.min(2560, Number(message.width) || 1280))),
|
|
120
120
|
height: String(Math.max(480, Math.min(1600, Number(message.height) || 800))),
|
|
121
121
|
'color-depth': '32', 'disable-audio': 'true', 'enable-drive': 'false',
|
|
122
|
-
'disable-copy': '
|
|
122
|
+
'disable-copy': 'false', 'disable-paste': 'false', 'server-layout': 'en-us-qwerty', 'resize-method': 'display-update',
|
|
123
123
|
};
|
|
124
124
|
void resolveComputerHost(host).then(async (address) => {
|
|
125
125
|
if (closed)
|
|
@@ -20,6 +20,7 @@ import { TerminalPasteBuffer } from '../utils/terminalPasteBuffer.js';
|
|
|
20
20
|
import { SharedSessionSampler, SharedSnapshotCache } from '../utils/sharedSampling.js';
|
|
21
21
|
import { batchTmuxOptions, TmuxMetadataWriter } from '../utils/tmuxMetadataWriter.js';
|
|
22
22
|
import { redrawTmuxClient } from '../utils/tmuxClientRedraw.js';
|
|
23
|
+
import { claimTmuxSize } from '../utils/tmuxSizeOwnership.js';
|
|
23
24
|
import { TmuxInitialScreen } from '../utils/tmuxInitialScreen.js';
|
|
24
25
|
import { TerminalOutputDelivery, resolveTerminalReplayCursor } from '../utils/terminalOutputDelivery.js';
|
|
25
26
|
import express from 'express';
|
|
@@ -73,6 +74,7 @@ import { NativeSessionSearch } from '../agent/nativeSessionSearch.js';
|
|
|
73
74
|
import { CollaborationError } from '../agent/collaborationProtocol.js';
|
|
74
75
|
import { resolveCollaborationBackend, resolveCollaborationSessionId } from '../agent/sessionBindingRecovery.js';
|
|
75
76
|
import { CollaborationRoutingStore, selectCollaborationPane, selectDrivePane, assessCollaborationRouteIdentity } from '../agent/collaborationRouting.js';
|
|
77
|
+
import { selectRecoveredIntegrationBinding } from '../agent/integrationRecoveryBinding.js';
|
|
76
78
|
import { CollaborationDeliveryWorker } from '../agent/collaborationDeliveryWorker.js';
|
|
77
79
|
import { approveCollaborationDialog, captureTmuxPaneHistory, captureTmuxPaneText, sendTmuxPaneKey, writeCollaborationTmuxPane } from '../agent/collaborationTmuxDelivery.js';
|
|
78
80
|
import { listAllHookAgents, refreshStaleHooksAtLaunch, installHooksForSlug, uninstallHooksForSlug, } from '../agent/installers.js';
|
|
@@ -170,6 +172,7 @@ const TERMDOCK_FRONTEND_SESSION_ID_OPTION = '@termdock-frontend-session-id';
|
|
|
170
172
|
const wsClients = new Map();
|
|
171
173
|
const outputDeliveries = new WeakMap();
|
|
172
174
|
const independentTmuxClients = new WeakSet();
|
|
175
|
+
const tmuxAttachments = new WeakMap();
|
|
173
176
|
const independentTmuxReplays = new WeakMap();
|
|
174
177
|
const TERMINAL_STREAM_EPOCH = crypto.randomUUID();
|
|
175
178
|
// Sessions where copy-mode -e just auto-exited at the bottom.
|
|
@@ -2072,6 +2075,28 @@ function integrationTerminalRecord(record) {
|
|
|
2072
2075
|
integrationError('SESSION_IDENTITY_MISMATCH', 'Owned TD terminal binding changed', 409);
|
|
2073
2076
|
return terminal;
|
|
2074
2077
|
}
|
|
2078
|
+
async function integrationRecoveryOwnership(record) {
|
|
2079
|
+
const root = `${TERMDOCK_DIR}/integration-state`;
|
|
2080
|
+
const directories = await fs.promises.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
2081
|
+
const descriptorOwners = [];
|
|
2082
|
+
const principalOwners = [];
|
|
2083
|
+
for (const directory of directories) {
|
|
2084
|
+
if (!directory.isDirectory())
|
|
2085
|
+
continue;
|
|
2086
|
+
const directoryPath = path.join(root, directory.name);
|
|
2087
|
+
const sessions = await readJsonFileIfExists(path.join(directoryPath, 'integration-sessions.json'));
|
|
2088
|
+
for (const session of sessions?.sessions ?? [])
|
|
2089
|
+
if (session.session_id === record.session_id) {
|
|
2090
|
+
descriptorOwners.push({ sessionId: String(session.session_id), groupId: String(session.group_id ?? ''), principalId: String(session.principal_id ?? '') });
|
|
2091
|
+
}
|
|
2092
|
+
const integrations = await readJsonFileIfExists(path.join(directoryPath, 'integrations.json'));
|
|
2093
|
+
for (const principal of integrations?.principals ?? [])
|
|
2094
|
+
if (principal.id === record.principal_id) {
|
|
2095
|
+
principalOwners.push({ principalId: String(principal.id), groupId: String(principal.groupId ?? ''), revoked: principal.revoked === true });
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
return { descriptorOwners, principalOwners };
|
|
2099
|
+
}
|
|
2075
2100
|
async function integrationTmuxPresent(record) {
|
|
2076
2101
|
try {
|
|
2077
2102
|
await runTmux(['has-session', '-t', `=wt-integration-${record.session_id}`]);
|
|
@@ -2299,6 +2324,73 @@ export const integrationSessionAdapter = {
|
|
|
2299
2324
|
collaborationRouting.bind({ ...route, nativeSessionId: nativeId, pane: { ...route.pane, nativeSessionId: nativeId } });
|
|
2300
2325
|
return { exists: true, running: Boolean(pane.agentSlug), shell: await integrationPaneIsIdleShell(pane), agentSlug: pane.agentSlug || null, nativeId };
|
|
2301
2326
|
},
|
|
2327
|
+
async reconcileRecoveryBinding(record) {
|
|
2328
|
+
if (process.platform !== 'linux' || !record.agent_native_session_id || !record.terminal_binding)
|
|
2329
|
+
return null;
|
|
2330
|
+
const expectedNativeSessionId = record.agent_native_session_id;
|
|
2331
|
+
let reconciled = null;
|
|
2332
|
+
const collect = async () => {
|
|
2333
|
+
const sessionName = `wt-integration-${record.session_id}`;
|
|
2334
|
+
const recoveryAfter = Math.max(record.created_at, record.binding_reconciliation?.at ?? 0);
|
|
2335
|
+
const matchingRecovery = tmuxRecoveryOperations.all().reverse().find(operation => operation.items.some(item => item.sessionId === record.session_id && item.state === 'succeeded'
|
|
2336
|
+
&& Number.isSafeInteger(item.completedAt) && item.completedAt > recoveryAfter));
|
|
2337
|
+
const owners = await integrationRecoveryOwnership(record);
|
|
2338
|
+
const groupOwners = collaborationStore.list().filter(group => !group.deleted && group.sessionIds.includes(record.session_id)).map(group => group.id);
|
|
2339
|
+
const globalOwners = globalSessionState.sessions.filter(session => session.sessionId === record.session_id || session.tmuxSessionName === sessionName);
|
|
2340
|
+
const terminal = globalSessionState.sessions.find(session => session.sessionId === record.session_id);
|
|
2341
|
+
const backendMatches = [...terminalSessions].filter(([, backend]) => backend.mode === 'tmux' && backend.tmuxSessionName === sessionName);
|
|
2342
|
+
const backendOwnershipVerified = !!terminal && terminal.mode === 'tmux' && terminal.tmuxSessionName === sessionName
|
|
2343
|
+
&& terminal.agentResume?.slug === record.agent_slug && terminal.agentResume.sessionId === expectedNativeSessionId
|
|
2344
|
+
&& backendMatches.length === 1 && !globalSessionState.sessions.some(other => other.sessionId !== record.session_id
|
|
2345
|
+
&& (other.tmuxSessionName === sessionName || other.backendSessionId === backendMatches[0]?.[0]))
|
|
2346
|
+
&& [null, record.session_id].includes(collaborationRouting.ownerOfBackend(backendMatches[0]?.[0] ?? ''));
|
|
2347
|
+
let panes = [];
|
|
2348
|
+
if (backendOwnershipVerified && backendMatches.length === 1) {
|
|
2349
|
+
await runTmux(['has-session', '-t', `=${sessionName}`]);
|
|
2350
|
+
const layout = await getTmuxLayout(sessionName);
|
|
2351
|
+
if (layout.sessionName === sessionName && layout.windows.flatMap(window => window.panes).length === 1) {
|
|
2352
|
+
const [backendSessionId] = backendMatches[0];
|
|
2353
|
+
const unpinned = { sessionId: record.session_id, backendSessionId, mode: 'tmux',
|
|
2354
|
+
tmuxSessionName: sessionName, agentSlug: record.agent_slug, nativeSessionId: expectedNativeSessionId, pane: null };
|
|
2355
|
+
const inspected = await inspectCollaborationTmux(unpinned, null, false, true, true, true);
|
|
2356
|
+
panes = (inspected.candidates ?? []).map(pane => ({ tmuxSessionName: sessionName,
|
|
2357
|
+
agentSlug: pane.agentSlug, nativeSessionId: pane.nativeSessionId,
|
|
2358
|
+
nativeIdentitySource: pane.nativeIdentitySource ?? null, nativeIdentityVerified: pane.nativeIdentityVerified === true,
|
|
2359
|
+
binding: { serverPid: pane.serverPid, sessionId: pane.sessionId, paneId: pane.paneId, panePid: pane.panePid,
|
|
2360
|
+
agentSlug: pane.agentSlug, nativeSessionId: pane.nativeSessionId } }));
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
const selected = selectRecoveredIntegrationBinding({ sessionId: record.session_id, groupId: record.group_id, principalId: record.principal_id,
|
|
2364
|
+
agentSlug: record.agent_slug, nativeSessionId: expectedNativeSessionId, tmuxSessionName: sessionName,
|
|
2365
|
+
descriptorOwners: owners.descriptorOwners, principalOwners: owners.principalOwners, groupOwners,
|
|
2366
|
+
terminalOwners: globalOwners.map(session => session.sessionId), backendOwnershipVerified,
|
|
2367
|
+
recoveryOperationId: matchingRecovery?.id ?? null, panes });
|
|
2368
|
+
return selected && backendMatches.length === 1 ? { ...selected, backendSessionId: backendMatches[0][0] } : null;
|
|
2369
|
+
};
|
|
2370
|
+
await collaborationDeliveryWorker.reconfigure(record.session_id, async () => {
|
|
2371
|
+
if (routeHasUnconfirmedWrite(record.session_id))
|
|
2372
|
+
throw Object.assign(new Error('A previous terminal write has an uncertain outcome'), { code: 'ROUTE_DELIVERY_OUTCOME_UNCONFIRMED' });
|
|
2373
|
+
const first = await collect();
|
|
2374
|
+
if (!first)
|
|
2375
|
+
throw Object.assign(new Error('Recovery binding evidence is incomplete, ambiguous, or does not match the exact native identity'), { code: 'SESSION_RECOVERY_BINDING_UNCONFIRMED' });
|
|
2376
|
+
const second = await collect();
|
|
2377
|
+
if (!second || first.recoveryOperationId !== second.recoveryOperationId || first.backendSessionId !== second.backendSessionId
|
|
2378
|
+
|| JSON.stringify(first.binding) !== JSON.stringify(second.binding)) {
|
|
2379
|
+
throw Object.assign(new Error('Integration runtime changed while recovery binding was being verified'), { code: 'SESSION_RECOVERY_BINDING_CHANGED' });
|
|
2380
|
+
}
|
|
2381
|
+
if (routeHasUnconfirmedWrite(record.session_id) || collaborationRouting.hasOtherPaneOwner(record.session_id, second.binding)) {
|
|
2382
|
+
throw Object.assign(new Error('A previous write or another route owner prevents automatic binding reconciliation'), { code: 'ROUTE_DELIVERY_OUTCOME_UNCONFIRMED' });
|
|
2383
|
+
}
|
|
2384
|
+
const previous = collaborationRouting.get(record.session_id);
|
|
2385
|
+
collaborationRouting.bind({ sessionId: record.session_id, backendSessionId: second.backendSessionId,
|
|
2386
|
+
mode: 'tmux', tmuxSessionName: `wt-integration-${record.session_id}`, agentSlug: record.agent_slug,
|
|
2387
|
+
nativeSessionId: record.agent_native_session_id, pane: second.binding, routeRevision: crypto.randomUUID(),
|
|
2388
|
+
lastRecovery: { kind: 'native-identity', at: Date.now(), previousPane: previous?.pane ?? record.terminal_binding ?? null } });
|
|
2389
|
+
reconciled = { binding: second.binding, recoveryOperationId: second.recoveryOperationId };
|
|
2390
|
+
});
|
|
2391
|
+
return reconciled;
|
|
2392
|
+
},
|
|
2393
|
+
recoveryBindingReconciled(sessionId) { collaborationDeliveryWorker.wake(sessionId); },
|
|
2302
2394
|
async create(record, prepared, progress) {
|
|
2303
2395
|
await listDetectedAgentLaunchers();
|
|
2304
2396
|
if (!agentBySlug(record.agent_slug))
|
|
@@ -5279,7 +5371,7 @@ function cleanupSession(sessionId, options) {
|
|
|
5279
5371
|
}
|
|
5280
5372
|
}
|
|
5281
5373
|
}
|
|
5282
|
-
function broadcastToWs(sessionId, data, excludeClientId, output
|
|
5374
|
+
function broadcastToWs(sessionId, data, excludeClientId, output) {
|
|
5283
5375
|
const clients = wsClients.get(sessionId);
|
|
5284
5376
|
const session = terminalSessions.get(sessionId);
|
|
5285
5377
|
if (!clients)
|
|
@@ -5287,7 +5379,7 @@ function broadcastToWs(sessionId, data, excludeClientId, output, eventType) {
|
|
|
5287
5379
|
for (const [clientId, ws] of clients.entries()) {
|
|
5288
5380
|
if (excludeClientId && clientId === excludeClientId)
|
|
5289
5381
|
continue;
|
|
5290
|
-
if (independentTmuxClients.has(ws) &&
|
|
5382
|
+
if (independentTmuxClients.has(ws) && output)
|
|
5291
5383
|
continue;
|
|
5292
5384
|
try {
|
|
5293
5385
|
if (ws.readyState !== ws.OPEN)
|
|
@@ -5311,7 +5403,7 @@ function broadcastToWs(sessionId, data, excludeClientId, output, eventType) {
|
|
|
5311
5403
|
}
|
|
5312
5404
|
function broadcastJsonWs(sessionId, payload, excludeClientId) {
|
|
5313
5405
|
const output = payload?.type === 'data' ? payload : undefined;
|
|
5314
|
-
broadcastToWs(sessionId, JSON.stringify(payload), excludeClientId, output
|
|
5406
|
+
broadcastToWs(sessionId, JSON.stringify(payload), excludeClientId, output);
|
|
5315
5407
|
}
|
|
5316
5408
|
// 统一的 pty resize 入口:调用 ptyProcess.resize 改变 pty size 之后,把
|
|
5317
5409
|
// 真实尺寸广播给除发起方之外的所有 ws client。多端场景下,B 端把 pty
|
|
@@ -8922,6 +9014,7 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
|
|
|
8922
9014
|
let clientCols = session.cols;
|
|
8923
9015
|
let clientRows = session.rows;
|
|
8924
9016
|
let initialAttachmentResize = true;
|
|
9017
|
+
let tmuxSizeOwnershipSupported = false;
|
|
8925
9018
|
let initialScreen = null;
|
|
8926
9019
|
if (initialDimensions && options.independentTmux) {
|
|
8927
9020
|
clientCols = initialDimensions.cols;
|
|
@@ -8935,6 +9028,7 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
|
|
|
8935
9028
|
const provider = await getPtyProvider();
|
|
8936
9029
|
const tmuxBinary = getTmuxBinary();
|
|
8937
9030
|
const supportsFeatures = await supportsTmuxClientFeatures(tmuxBinary);
|
|
9031
|
+
tmuxSizeOwnershipSupported = supportsFeatures;
|
|
8938
9032
|
// The metadata observer must not choose the pane size while a browser
|
|
8939
9033
|
// owns an attached client. Resolve by exact PID, never another client.
|
|
8940
9034
|
const raw = await runTmux(['list-clients', '-t', session.tmuxSessionName, '-F', '#{client_pid} #{client_tty}']);
|
|
@@ -8961,6 +9055,8 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
|
|
|
8961
9055
|
delivery.enqueue({ type: 'data', data: liveData });
|
|
8962
9056
|
}, () => { if (ws.readyState === ws.OPEN)
|
|
8963
9057
|
ws.close(1012, 'Tmux display client detached'); }) : null;
|
|
9058
|
+
if (attachment)
|
|
9059
|
+
tmuxAttachments.set(ws, attachment);
|
|
8964
9060
|
// Register client
|
|
8965
9061
|
let clients = wsClients.get(sessionId);
|
|
8966
9062
|
if (!clients) {
|
|
@@ -9198,27 +9294,41 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
|
|
|
9198
9294
|
const rows = Number(msg.rows);
|
|
9199
9295
|
if (Number.isFinite(cols) && Number.isFinite(rows) && cols > 0 && rows > 0) {
|
|
9200
9296
|
if (attachment) {
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
if (
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9297
|
+
await enqueueTmuxIo(session, async () => {
|
|
9298
|
+
const cleanCols = Math.floor(cols), cleanRows = Math.floor(rows);
|
|
9299
|
+
const displayPids = new Set();
|
|
9300
|
+
for (const client of wsClients.get(sessionId)?.values() ?? []) {
|
|
9301
|
+
const pid = tmuxAttachments.get(client)?.pid;
|
|
9302
|
+
if (pid !== undefined)
|
|
9303
|
+
displayPids.add(pid);
|
|
9304
|
+
}
|
|
9305
|
+
if (tmuxSizeOwnershipSupported) {
|
|
9306
|
+
await claimTmuxSize(runTmux, session.tmuxSessionName, attachment.pid, displayPids);
|
|
9307
|
+
}
|
|
9308
|
+
const sameSize = clientCols === cleanCols && clientRows === cleanRows;
|
|
9309
|
+
const ok = sameSize ? attachment.attached : attachment.resize(cleanCols, cleanRows);
|
|
9310
|
+
if (ok) {
|
|
9311
|
+
// The first resize confirms the grid supplied at attachment.
|
|
9312
|
+
// Its PTY is already drawing that grid; forcing refresh-client
|
|
9313
|
+
// here repeats the initial clear/full redraw. Later same-size
|
|
9314
|
+
// requests remain explicit display recovery requests.
|
|
9315
|
+
const needsRedraw = sameSize && !initialAttachmentResize;
|
|
9316
|
+
initialAttachmentResize = false;
|
|
9317
|
+
clientCols = cleanCols;
|
|
9318
|
+
clientRows = cleanRows;
|
|
9319
|
+
session.lastActivity = Date.now();
|
|
9320
|
+
broadcastJsonWs(sessionId, {
|
|
9321
|
+
type: 'pty-size', cols: clientCols, rows: clientRows, source: `ws-resize:${clientId}`,
|
|
9322
|
+
}, clientId);
|
|
9323
|
+
if (needsRedraw)
|
|
9324
|
+
await redrawTmuxClient(runTmux, session.tmuxSessionName, attachment.pid);
|
|
9325
|
+
}
|
|
9326
|
+
if (ws.readyState === ws.OPEN)
|
|
9327
|
+
ws.send(JSON.stringify({
|
|
9328
|
+
type: 'resize-ack', seq: typeof msg.seq === 'number' ? msg.seq : undefined,
|
|
9329
|
+
ok, cols: clientCols, rows: clientRows, screenSyncPending: false,
|
|
9330
|
+
}));
|
|
9331
|
+
});
|
|
9222
9332
|
break;
|
|
9223
9333
|
}
|
|
9224
9334
|
const sameSize = session.cols === Math.floor(cols) && session.rows === Math.floor(rows);
|
|
@@ -20,6 +20,6 @@ export function buildTmuxAttachArgs(sessionName, supportsFeatures) {
|
|
|
20
20
|
// non-ASCII cells before the encrypted output ever reaches the renderer.
|
|
21
21
|
'-u',
|
|
22
22
|
...(supportsFeatures ? ['-T', 'RGB,sync'] : []),
|
|
23
|
-
'attach-session', '-t', sessionName,
|
|
23
|
+
'attach-session', ...(supportsFeatures ? ['-f', 'ignore-size'] : []), '-t', sessionName,
|
|
24
24
|
];
|
|
25
25
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Only an explicitly selected display may influence tmux's window size.
|
|
2
|
+
* Terminal replies and focus events also count as activity for window-size
|
|
3
|
+
* latest, so leaving every display eligible makes idle viewers fight.
|
|
4
|
+
*/
|
|
5
|
+
export async function claimTmuxSize(run, session, pid, displayPids) {
|
|
6
|
+
if (pid === undefined)
|
|
7
|
+
return;
|
|
8
|
+
const clients = (await run(['list-clients', '-t', session, '-F', '#{client_pid} #{client_tty}']))
|
|
9
|
+
.trim().split('\n').map(line => line.trim().split(/\s+/));
|
|
10
|
+
const target = clients.find(([value]) => value === String(pid));
|
|
11
|
+
if (!target?.[1])
|
|
12
|
+
return;
|
|
13
|
+
const commands = clients
|
|
14
|
+
.filter(([value, tty]) => tty && value !== String(pid) && displayPids.has(Number(value)))
|
|
15
|
+
.map(([, tty]) => ['refresh-client', '-t', tty, '-f', 'ignore-size']);
|
|
16
|
+
commands.push(['refresh-client', '-t', target[1], '-f', '!ignore-size']);
|
|
17
|
+
await run(commands.flatMap((command, index) => index ? [';', ...command] : command));
|
|
18
|
+
}
|
package/docs/integrations.md
CHANGED
|
@@ -1327,3 +1327,30 @@ TD/native session、运行承载、消息/reply、consumer 游标或历史;不
|
|
|
1327
1327
|
`GROUP_ARCHIVE_STATE_UNCONFIRMED`,不会猜测或重建。只允许本机非 federated、未删除
|
|
1328
1328
|
组;删除组、跨服务组和不确定的目标分别返回 `GROUP_NOT_FOUND`、`GROUP_NOT_LOCAL`、
|
|
1329
1329
|
`GROUP_ARCHIVE_TARGET_UNAVAILABLE`。归档不延长消息历史保留期。
|
|
1330
|
+
|
|
1331
|
+
## 1.4.328:IntegrationSession 对账 tmux recovery 的新承载
|
|
1332
|
+
|
|
1333
|
+
最低 CLI / 实际服务 **1.4.328**,能力回读字段为
|
|
1334
|
+
`session_recovery_binding_reconcile=true` 与
|
|
1335
|
+
`session_recovery_binding_reconcile_min_version=1.4.328`。该自动对账目前只在 Linux
|
|
1336
|
+
提供;其它平台返回 capability=false,因为没有同等的当前 writer-lock 身份证明。
|
|
1337
|
+
|
|
1338
|
+
所属 principal 调用现有 `session get` 时,如果 IntegrationSession 因
|
|
1339
|
+
`SESSION_IDENTITY_MISMATCH` 指向旧 pane,而 TD 持久恢复 operation 已成功恢复该逻辑
|
|
1340
|
+
session,服务会尝试受限对账。它要求当前唯一受管终端名严格为
|
|
1341
|
+
`wt-integration-<session_id>`,IntegrationSession 与有效 principal/group 的持久归属唯一,
|
|
1342
|
+
当前组和全局终端记录唯一,只有一个 tmux pane/backend,且该前台 Agent 的当前 Linux
|
|
1343
|
+
flock-owner 身份独立核验出原 agent slug 与原生 UUID。目标元组会连续采样确认未变,
|
|
1344
|
+
并在现有投递 worker 屏障内更新绑定。
|
|
1345
|
+
|
|
1346
|
+
成功后保留逻辑 `session_id`、group、principal、原生 UUID、消息与历史,只更新
|
|
1347
|
+
`terminal_binding`、状态和 `generation`,并在 `binding_reconciliation` 记录旧绑定及
|
|
1348
|
+
对应 `recovery_operation_id`。不会启动或恢复第二个 Agent,也不创建 task、发送正文或
|
|
1349
|
+
重放已写入的消息。此前写入结果不明时不会自动改绑;已写入的消息保持原 receipt,
|
|
1350
|
+
尚未写入的 pending 消息由原 worker 继续处理。
|
|
1351
|
+
|
|
1352
|
+
任一 owner 缺失/重复、tmux 名或 pane 不唯一、native UUID 不同、writer-lock 不可核验、
|
|
1353
|
+
没有该 session 成功的恢复 operation,或绑定在双重采样间再次变化时,服务保持
|
|
1354
|
+
fail-closed,旧绑定与原消息保留,`session get` 仍报告身份错误;不会按 tmux 名称、PID
|
|
1355
|
+
缓存、cwd、argv 中的 resume 参数或显示名猜测认领。此 capability 不新增权限;仅通过
|
|
1356
|
+
`session.read` 认证的所属 principal 可触发其自身记录的对账。
|
package/package.json
CHANGED
package/runtime-manifest.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "termdock",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.329",
|
|
5
5
|
"runtimeProtocolVersion": 1,
|
|
6
6
|
"minimumDesktopVersion": "1.4.46",
|
|
7
7
|
"nodeMajor": 22,
|
|
8
8
|
"dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
|
|
9
|
-
"serverBundleHash": "sha256-
|
|
10
|
-
"clientBundleHash": "sha256-
|
|
9
|
+
"serverBundleHash": "sha256-R3DBIQv0z+SBN+LCWHRsFbWHqQ92u8mBkCkfn1MJdok=",
|
|
10
|
+
"clientBundleHash": "sha256-GLTHYP07SNJ24my1kl9LAFyEV1xLXDYzMzPHumxvQSo=",
|
|
11
11
|
"entrypoint": "dist/server/cli.js",
|
|
12
12
|
"clientEntrypoint": "dist/client/index.html"
|
|
13
13
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{bA as r}from"./app-D2yRvfNE.js";import{b as m}from"./dnd-BCFAPC0L.js";import{b as n}from"./RightSidebar-TFRZlsFX.js";import"./react-XDCjal2T.js";import"./terminal-C7X98Amf.js";import"./App-C0c83Pxp.js";import"./gestureArbiter-miROLzXb.js";import"./triangle-alert-DqUvQ_x8.js";import"./referenceLongPress-DqibFmuj.js";import"./DiffReview-BA7zArOA.js";import"./sparkles-CgDDXr95.js";import"./DiffViewer-B0YoRCEi.js";import"./ChangeWalkthroughPanel-Bt4fjEoD.js";function g({content:o}){const e=m.useMemo(()=>n(o.split(`
|
|
2
|
-
`),null,null),[o]);return r.jsx("div",{className:"min-w-0 space-y-3 break-words text-sm leading-6 text-foreground [&_h1]:text-lg [&_h2]:text-base [&_h3]:text-sm [&_pre]:max-w-full [&_table]:text-xs",children:e.map((t,i)=>r.jsx("div",{className:"min-w-0",children:typeof t.content=="function"?t.content(null):t.content},i))})}export{g as default};
|