termdock 1.4.174 → 1.4.175
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/.desktop-dist/main.js +154 -7
- package/dist/client/assets/App-BXYZyI_k.js +150 -0
- package/dist/client/assets/App-BXYZyI_k.js.br +0 -0
- package/dist/client/assets/App-BXYZyI_k.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-DeVtCf73.js +2 -0
- package/dist/client/assets/ChangeWalkthroughPanel-DeVtCf73.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-DeVtCf73.js.gz +0 -0
- package/dist/client/assets/DagPlayground-ZIqLZoMo.js +1 -0
- package/dist/client/assets/DagPlayground-ZIqLZoMo.js.br +0 -0
- package/dist/client/assets/DagPlayground-ZIqLZoMo.js.gz +0 -0
- package/dist/client/assets/{DiffLab-CdbPsjKS.js → DiffLab-CSMf8So2.js} +2 -2
- package/dist/client/assets/DiffLab-CSMf8So2.js.br +0 -0
- package/dist/client/assets/DiffLab-CSMf8So2.js.gz +0 -0
- package/dist/client/assets/DiffReview-CE5lW1zQ.js +1 -0
- package/dist/client/assets/DiffReview-CE5lW1zQ.js.br +0 -0
- package/dist/client/assets/DiffReview-CE5lW1zQ.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-CpUW75fZ.js +2 -0
- package/dist/client/assets/DiffReviewLab-CpUW75fZ.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-CpUW75fZ.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-hdxcM9yF.js → DiffViewer-BomvZ4kq.js} +5 -5
- package/dist/client/assets/DiffViewer-BomvZ4kq.js.br +0 -0
- package/dist/client/assets/DiffViewer-BomvZ4kq.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-BZ454pgM.js → ModelPreview-BWdZFyhh.js} +3 -3
- package/dist/client/assets/ModelPreview-BWdZFyhh.js.br +0 -0
- package/dist/client/assets/ModelPreview-BWdZFyhh.js.gz +0 -0
- package/dist/client/assets/RightSidebar-CYVwFbOc.js +79 -0
- package/dist/client/assets/RightSidebar-CYVwFbOc.js.br +0 -0
- package/dist/client/assets/RightSidebar-CYVwFbOc.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-C185Omck.js → abnfDiagram-VCTEODGH-BIPsLStE.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-BIPsLStE.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BIPsLStE.js.gz +0 -0
- package/dist/client/assets/app-D6KzR8B3.js +34 -0
- package/dist/client/assets/app-D6KzR8B3.js.br +0 -0
- package/dist/client/assets/app-D6KzR8B3.js.gz +0 -0
- package/dist/client/assets/{arc-DNt-DTCl.js → arc-DzeT6hBj.js} +1 -1
- package/dist/client/assets/arc-DzeT6hBj.js.br +0 -0
- package/dist/client/assets/arc-DzeT6hBj.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-C5Nwm_Qz.js → architectureDiagram-5GKGNRK7-B1qsxd_5.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-B1qsxd_5.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-B1qsxd_5.js.gz +0 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-C5aR_7V9.js → blockDiagram-I7D4REHJ-NLsa29Jp.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-NLsa29Jp.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-NLsa29Jp.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-DjV6ZNwd.js → c4Diagram-7LVT6UL2-DBAUvou3.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-DBAUvou3.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DBAUvou3.js.gz +0 -0
- package/dist/client/assets/channel-BhwBAWhq.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-Ct7nd4cL.js → chunk-2Q5K7J3B-BsVAXGLa.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-CXem4UYP.js → chunk-5VM5RSS4-BKtILsst.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-DyMNEawE.js → chunk-F27PBJKO-Dn9zcQZG.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-Dn9zcQZG.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-Dn9zcQZG.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-BsW7iIrh.js → chunk-IMKFNOWR-MVtVQeTr.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-MVtVQeTr.js.br +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-BsW7iIrh.js.gz → chunk-IMKFNOWR-MVtVQeTr.js.gz} +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-EO8E1q1J.js → chunk-JWPE2WC7-DliIIMe7.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-0One8T9x.js → chunk-POPQ4Y6H-XBSus3IC.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-CDu41dkj.js → chunk-SVP7TREG-wleSQcJR.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-wleSQcJR.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-wleSQcJR.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-BACjgX9v.js → chunk-TICWLB2K-Dq6LdswN.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-Dq6LdswN.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-Dq6LdswN.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-BJWowF6E.js → chunk-XXDRQBXY-xafyKlM-.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-slQB0ns2.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-slQB0ns2.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-WTwHOCdm.js → cose-bilkent-JH36ORCC-BR7Ohnm_.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-BR7Ohnm_.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-BR7Ohnm_.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX-D4y8TkaO.js → cynefin-OW5HDTMX-CmPjQgER.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-CmPjQgER.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-CmPjQgER.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-BzN8Ggk_.js → cynefinDiagram-5FMLGOSQ-CFyR9RvM.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CFyR9RvM.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CFyR9RvM.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-CwMYtt5E.js → dagre-GXQ25YYZ-D_RVMRO1.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-D_RVMRO1.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-D_RVMRO1.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-BnTeHiAb.js → diagram-S7CK7UJ4-6fr-ZoPj.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-6fr-ZoPj.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-6fr-ZoPj.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-BNlh251g.js → diagram-UQ7AKVKN-CgwiUtz0.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-CgwiUtz0.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-CgwiUtz0.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-B5FftXkQ.js → diagram-VSXAHHWV-CLxzTB9k.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-CLxzTB9k.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-CLxzTB9k.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-C51ZNXR2.js → diagram-VX7I27RA-DjxDAvdZ.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-DjxDAvdZ.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-DjxDAvdZ.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-CXoZH2qf.js → diagram-Z3DM3KII-CDPOjiz4.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-CDPOjiz4.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-CDPOjiz4.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-C7YFLlx4.js → ebnfDiagram-PWID7BFC-BLbwyF1O.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BLbwyF1O.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BLbwyF1O.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-BNQlS7-g.js → erDiagram-RLTQ6QDP-DbjtZnJx.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-DbjtZnJx.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-DbjtZnJx.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-DIQXZ06I.js → flowDiagram-HODETNUW-BirJInAN.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-BirJInAN.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-BirJInAN.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-BaJQfOqD.js → ganttDiagram-EL5Y4UJY-d6Q9vSbv.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-d6Q9vSbv.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-d6Q9vSbv.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-C2J0D0kV.css +1 -0
- package/dist/client/assets/gestureArbiter-C2J0D0kV.css.br +0 -0
- package/dist/client/assets/gestureArbiter-C2J0D0kV.css.gz +0 -0
- package/dist/client/assets/gestureArbiter-D1SNS_gK.js +1 -0
- package/dist/client/assets/gestureArbiter-D1SNS_gK.js.br +0 -0
- package/dist/client/assets/gestureArbiter-D1SNS_gK.js.gz +0 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-tQ4E6pwN.js → gitGraphDiagram-WWUBYQGX-BWBoIeS6.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BWBoIeS6.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BWBoIeS6.js.gz +0 -0
- package/dist/client/assets/{index-DlxiaPv1.css → index-DUI8KRf6.css} +1 -1
- package/dist/client/assets/index-DUI8KRf6.css.br +0 -0
- package/dist/client/assets/index-DUI8KRf6.css.gz +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-DTOUeQrN.js → infoDiagram-27XIBGKW-BH4AynkM.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-8sBi-gla.js → ishikawaDiagram-5VMMS53U-BQw90AKR.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-8sBi-gla.js.br → ishikawaDiagram-5VMMS53U-BQw90AKR.js.br} +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-BQw90AKR.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-ZwikziWh.js → journeyDiagram-3NMN7TZE-DISkQocf.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-DISkQocf.js.br +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-ZwikziWh.js.gz → journeyDiagram-3NMN7TZE-DISkQocf.js.gz} +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-wjuw2jQ4.js → kanban-definition-UXKFOSKX-Qg2LyEVy.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-Qg2LyEVy.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-Qg2LyEVy.js.gz +0 -0
- package/dist/client/assets/{layout-nASMIj-E.js → layout-Cd7-4_Vr.js} +1 -1
- package/dist/client/assets/layout-Cd7-4_Vr.js.br +0 -0
- package/dist/client/assets/layout-Cd7-4_Vr.js.gz +0 -0
- package/dist/client/assets/{linear-pGaQeqW5.js → linear-DFTi2fTn.js} +1 -1
- package/dist/client/assets/linear-DFTi2fTn.js.br +0 -0
- package/dist/client/assets/linear-DFTi2fTn.js.gz +0 -0
- package/dist/client/assets/{mermaid.core-CKEBWbQz.js → mermaid.core-2v726lUU.js} +5 -5
- package/dist/client/assets/mermaid.core-2v726lUU.js.br +0 -0
- package/dist/client/assets/mermaid.core-2v726lUU.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-CBjYcnwd.js → mindmap-definition-YA3MSWOX-_FpwteCy.js} +4 -4
- package/dist/client/assets/mindmap-definition-YA3MSWOX-_FpwteCy.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-_FpwteCy.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-D9Ffc7NY.js +2 -0
- package/dist/client/assets/passwordBootstrap-D9Ffc7NY.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-D9Ffc7NY.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DJqvclIp.js → pegDiagram-XKGWAZYB-DLFf-HmZ.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-DLFf-HmZ.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DLFf-HmZ.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-DLV4WPwc.js → pieDiagram-E7YTZNPT-DqTnfXHG.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-DqTnfXHG.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DqTnfXHG.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BN7Zpsb9.js → quadrantDiagram-AXDQQJYC-B_oBH52Q.js} +1 -1
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-B_oBH52Q.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-B_oBH52Q.js.gz +0 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-DfHX6MUm.js → railroadDiagram-O6MQD6OU-HxFQ7Pce.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-HxFQ7Pce.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-HxFQ7Pce.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-B3NGIjvv.js +1 -0
- package/dist/client/assets/referenceLongPress-B3NGIjvv.js.br +0 -0
- package/dist/client/assets/referenceLongPress-B3NGIjvv.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-tQVSFg_k.js → requirementDiagram-BXWQKSXE-NZdfaZFk.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-NZdfaZFk.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-NZdfaZFk.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-C7JW1-Wh.js → sankeyDiagram-P5KCCOFB-BgCctv6X.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BgCctv6X.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-BgCctv6X.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BVeDiFDI.js → sequenceDiagram-WJ2MYXX4-Br42Za1R.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Br42Za1R.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Br42Za1R.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-CBRaCpeP.js → sizeCapture-INFHLROL-FT4z4S1b.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-FT4z4S1b.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-FT4z4S1b.js.gz +0 -0
- package/dist/client/assets/sparkles-BaGaevME.js +1 -0
- package/dist/client/assets/{stateDiagram-D77RDMKH-CiLpGRuf.js → stateDiagram-D77RDMKH-DD0t9f84.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-DD0t9f84.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-DD0t9f84.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BhvVVB56.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-BkzVtkVY.js → swimlanes-42K2YHIH-DcC8pGLx.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-DcC8pGLx.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-DcC8pGLx.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DSC5lz0i.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-DKyfGITP.js → timeline-definition-24CTP7MA-DnwO_Pxd.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-DnwO_Pxd.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-DnwO_Pxd.js.gz +0 -0
- package/dist/client/assets/triangle-alert-BCQO9Ap9.js +1 -0
- package/dist/client/assets/{vennDiagram-4TSXK5OY-CRgkkrgx.js → vennDiagram-4TSXK5OY-IVNSrZDM.js} +1 -1
- package/dist/client/assets/vennDiagram-4TSXK5OY-IVNSrZDM.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-IVNSrZDM.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-Cr7yS4CZ.js → wardleyDiagram-VM6X3IG4-BnGetaQL.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BnGetaQL.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-BnGetaQL.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DkPYl6E0.js → xychartDiagram-S5SC5T6Z-C01eBN-W.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-C01eBN-W.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-C01eBN-W.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/preview-shell.html +1 -0
- package/dist/client/preview-shell.js +20 -0
- package/dist/client/preview-shell.js.br +0 -0
- package/dist/client/preview-shell.js.gz +0 -0
- package/dist/client/sw-secure-api.js +132 -0
- package/dist/client/sw-secure-api.js.br +0 -0
- package/dist/client/sw-secure-api.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/collaborationCli.js +298 -0
- package/dist/server/agent/collaborationPrompt.js +10 -2
- package/dist/server/agent/collaborationProtocol.js +50 -0
- package/dist/server/agent/collaborationRoutes.js +86 -0
- package/dist/server/agent/collaborationStore.js +249 -21
- package/dist/server/cli.js +28 -168
- package/dist/server/entry.js +114 -51
- package/dist/server/federation/accessPolicy.js +122 -0
- package/dist/server/federation/authorization.js +226 -0
- package/dist/server/federation/bootstrapCors.js +23 -0
- package/dist/server/federation/cli.js +185 -0
- package/dist/server/federation/deviceNames.js +29 -0
- package/dist/server/federation/directRoutes.js +72 -0
- package/dist/server/federation/invitations.js +123 -0
- package/dist/server/federation/openAccess.js +25 -0
- package/dist/server/federation/originPolicy.js +19 -0
- package/dist/server/federation/packets.js +116 -0
- package/dist/server/federation/passwordBootstrap.js +86 -0
- package/dist/server/federation/passwordLoginRoutes.js +98 -0
- package/dist/server/federation/relay.js +346 -0
- package/dist/server/federation/requestContext.js +4 -0
- package/dist/server/federation/routeAccess.js +124 -0
- package/dist/server/federation/routeInvitations.js +160 -0
- package/dist/server/federation/runtime.js +537 -0
- package/dist/server/federation/secureProtocol.js +223 -0
- package/dist/server/federation/socketDuplex.js +42 -0
- package/dist/server/federation/streamLimits.js +5 -0
- package/dist/server/routes/filesystem.js +2 -1
- package/dist/server/routes/terminal.js +40 -72
- package/dist/server/utils/authProtection.js +13 -0
- package/dist/server/utils/csrfProtection.js +3 -0
- package/dist/server/utils/publicSecurity.js +8 -3
- package/package.json +10 -3
- package/runtime-manifest.json +4 -4
- package/dist/client/assets/ChangeWalkthroughPanel-hj8I8Cwy.js +0 -2
- package/dist/client/assets/ChangeWalkthroughPanel-hj8I8Cwy.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-hj8I8Cwy.js.gz +0 -0
- package/dist/client/assets/DagPlayground-BRoB8JX5.js +0 -1
- package/dist/client/assets/DagPlayground-BRoB8JX5.js.br +0 -0
- package/dist/client/assets/DagPlayground-BRoB8JX5.js.gz +0 -0
- package/dist/client/assets/DiffLab-CdbPsjKS.js.br +0 -0
- package/dist/client/assets/DiffLab-CdbPsjKS.js.gz +0 -0
- package/dist/client/assets/DiffReview-MQXjrRsW.js +0 -1
- package/dist/client/assets/DiffReview-MQXjrRsW.js.br +0 -0
- package/dist/client/assets/DiffReview-MQXjrRsW.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-C47CNvDM.js +0 -2
- package/dist/client/assets/DiffReviewLab-C47CNvDM.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-C47CNvDM.js.gz +0 -0
- package/dist/client/assets/DiffViewer-hdxcM9yF.js.br +0 -0
- package/dist/client/assets/DiffViewer-hdxcM9yF.js.gz +0 -0
- package/dist/client/assets/ModelPreview-BZ454pgM.js.br +0 -0
- package/dist/client/assets/ModelPreview-BZ454pgM.js.gz +0 -0
- package/dist/client/assets/RightSidebar-i0Oq68YI.js +0 -55
- package/dist/client/assets/RightSidebar-i0Oq68YI.js.br +0 -0
- package/dist/client/assets/RightSidebar-i0Oq68YI.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-C185Omck.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-C185Omck.js.gz +0 -0
- package/dist/client/assets/app-DAp8rVMc.js +0 -175
- package/dist/client/assets/app-DAp8rVMc.js.br +0 -0
- package/dist/client/assets/app-DAp8rVMc.js.gz +0 -0
- package/dist/client/assets/arc-DNt-DTCl.js.br +0 -0
- package/dist/client/assets/arc-DNt-DTCl.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-C5Nwm_Qz.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-C5Nwm_Qz.js.gz +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-C5aR_7V9.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-C5aR_7V9.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DjV6ZNwd.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DjV6ZNwd.js.gz +0 -0
- package/dist/client/assets/channel-uhLrATdy.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-DyMNEawE.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-DyMNEawE.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BsW7iIrh.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-CDu41dkj.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-CDu41dkj.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-BACjgX9v.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-BACjgX9v.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-CnxFfzm9.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CnxFfzm9.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-WTwHOCdm.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-WTwHOCdm.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-D4y8TkaO.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-D4y8TkaO.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BzN8Ggk_.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BzN8Ggk_.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-CwMYtt5E.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-CwMYtt5E.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BnTeHiAb.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BnTeHiAb.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-BNlh251g.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-BNlh251g.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-B5FftXkQ.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-B5FftXkQ.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C51ZNXR2.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-C51ZNXR2.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-CXoZH2qf.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-CXoZH2qf.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-C7YFLlx4.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-C7YFLlx4.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BNQlS7-g.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-BNQlS7-g.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DIQXZ06I.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-DIQXZ06I.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-BaJQfOqD.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-BaJQfOqD.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-tQ4E6pwN.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-tQ4E6pwN.js.gz +0 -0
- package/dist/client/assets/index-DlxiaPv1.css.br +0 -0
- package/dist/client/assets/index-DlxiaPv1.css.gz +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-8sBi-gla.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-ZwikziWh.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-wjuw2jQ4.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-wjuw2jQ4.js.gz +0 -0
- package/dist/client/assets/layout-nASMIj-E.js.br +0 -0
- package/dist/client/assets/layout-nASMIj-E.js.gz +0 -0
- package/dist/client/assets/linear-pGaQeqW5.js.br +0 -0
- package/dist/client/assets/linear-pGaQeqW5.js.gz +0 -0
- package/dist/client/assets/mermaid.core-CKEBWbQz.js.br +0 -0
- package/dist/client/assets/mermaid.core-CKEBWbQz.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CBjYcnwd.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-CBjYcnwd.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DJqvclIp.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DJqvclIp.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DLV4WPwc.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DLV4WPwc.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BN7Zpsb9.js.br +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BN7Zpsb9.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DfHX6MUm.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DfHX6MUm.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-tQVSFg_k.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-tQVSFg_k.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-C7JW1-Wh.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-C7JW1-Wh.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BVeDiFDI.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BVeDiFDI.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-CBRaCpeP.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-CBRaCpeP.js.gz +0 -0
- package/dist/client/assets/sparkles-D0cwIvB0.js +0 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-CiLpGRuf.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-CiLpGRuf.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BRbS0rv2.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-BkzVtkVY.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-BkzVtkVY.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-CeWFezkt.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-DKyfGITP.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-DKyfGITP.js.gz +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-CRgkkrgx.js.br +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-CRgkkrgx.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cr7yS4CZ.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cr7yS4CZ.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DkPYl6E0.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-DkPYl6E0.js.gz +0 -0
package/.desktop-dist/main.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { CollaborationFederation, sessionAddress } from './collaborationFederation.js';
|
|
2
|
+
import { prepareBundledFrontend } from './bundledFrontend.js';
|
|
3
|
+
import { serviceConnection, serviceConnectionKeys, importServiceConnection, upsertServiceConnection, invitationForService } from './serviceConnections.js';
|
|
4
|
+
const pendingServiceInvitations = new WeakMap();
|
|
2
5
|
import { app, BrowserWindow, clipboard, dialog, ipcMain, Menu, net, nativeImage, Notification, powerMonitor, screen, session, shell, Tray, } from 'electron';
|
|
3
6
|
import { execFile, spawn } from 'node:child_process';
|
|
4
7
|
import crypto from 'node:crypto';
|
|
@@ -17,6 +20,7 @@ import { isExternalLinkStagingUrl, isSafeExternalUrl } from './externalLinks.js'
|
|
|
17
20
|
import { shouldThrottleDesktopRenderer } from './windowPolicy.js';
|
|
18
21
|
import { checkConnectedServiceRuntime, getConnectedServiceRuntimeState, restartConnectedServiceRuntime, } from './connectedServiceRuntime.js';
|
|
19
22
|
import { isOwnedDesktopRuntimeTarget } from './runtimeTarget.js';
|
|
23
|
+
import { canReadLocalInvite } from './localInviteGuard.js';
|
|
20
24
|
import { serviceDocumentNeedsReload } from './serviceWindowRecovery.js';
|
|
21
25
|
import { CertificateTrustRequests, resolveServiceCertificateTrust, canOfferCertificateTrust, downloadCertificateAuthority, isCertificateTrustError, isLocalNetworkHostname, matchManagedLocalCertificate, } from './certificateTrust.js';
|
|
22
26
|
const execFileAsync = promisify(execFile);
|
|
@@ -26,6 +30,7 @@ const termdockDir = path.join(os.homedir(), '.termdock');
|
|
|
26
30
|
const desktopConfigPath = path.join(termdockDir, 'desktop.json');
|
|
27
31
|
const serverStatePath = path.join(termdockDir, 'server.json');
|
|
28
32
|
const desktopRuntimeOwnerSocketPath = path.join(termdockDir, 'desktop-runtime-owner.sock');
|
|
33
|
+
let federationRelayProcess = null;
|
|
29
34
|
const DEFAULT_LOCAL_URL = 'http://localhost:9834';
|
|
30
35
|
const PROTOCOL_VERSION = 1;
|
|
31
36
|
const HEALTH_TIMEOUT_MS = 3_500;
|
|
@@ -484,6 +489,8 @@ function readManagedLocalCertificateFingerprint() {
|
|
|
484
489
|
}
|
|
485
490
|
function installCertificateVerifyProcedure(targetSession = session.defaultSession, serviceOrigin) {
|
|
486
491
|
targetSession.setCertificateVerifyProc((request, callback) => {
|
|
492
|
+
const routeOrigins = serviceOrigin ? readDesktopConfig().connections.flatMap(item => item.routes || []).map(route => route.url) : [];
|
|
493
|
+
const requestedOrigin = [serviceOrigin, ...routeOrigins].find(origin => origin && new URL(origin).hostname.replace(/^\[|\]$/g, '').toLowerCase() === request.hostname.replace(/^\[|\]$/g, '').toLowerCase());
|
|
487
494
|
let isLocalTarget = false;
|
|
488
495
|
try {
|
|
489
496
|
isLocalTarget = isLocalNetworkTarget(new URL(`https://${request.hostname}`));
|
|
@@ -500,9 +507,7 @@ function installCertificateVerifyProcedure(targetSession = session.defaultSessio
|
|
|
500
507
|
}
|
|
501
508
|
const explicitlyTrustedTarget = presentedFingerprint
|
|
502
509
|
? serviceOrigin
|
|
503
|
-
?
|
|
504
|
-
=== request.hostname.replace(/^\[|\]$/g, '').toLowerCase()
|
|
505
|
-
&& sessionTrustedLeafByOrigin.get(serviceOrigin) === presentedFingerprint
|
|
510
|
+
? !!requestedOrigin && sessionTrustedLeafByOrigin.get(requestedOrigin) === presentedFingerprint
|
|
506
511
|
: sessionTrustedCertificateTargets.has(certificateTrustKey(request.hostname, presentedFingerprint))
|
|
507
512
|
: false;
|
|
508
513
|
const managedMatch = isLocalTarget
|
|
@@ -514,11 +519,11 @@ function installCertificateVerifyProcedure(targetSession = session.defaultSessio
|
|
|
514
519
|
callback(0);
|
|
515
520
|
return;
|
|
516
521
|
}
|
|
517
|
-
if (
|
|
522
|
+
if (requestedOrigin && canOfferCertificateTrust(requestedOrigin)
|
|
518
523
|
&& isCertificateTrustError(request.verificationResult)) {
|
|
519
524
|
// Resolve trust before Chromium caches a rejection. This covers fetch,
|
|
520
525
|
// WebSocket and navigation requests, not only the initial Node probe.
|
|
521
|
-
void resolveServiceCertificateTrust(
|
|
526
|
+
void resolveServiceCertificateTrust(requestedOrigin, request.hostname, request.certificate.data, () => requestCertificateTrust(requestedOrigin)).then((trusted) => callback(trusted ? 0 : -3), (error) => {
|
|
522
527
|
console.warn(`[desktop-certificate] ${serviceOrigin}: ${networkErrorDetails(error)}`);
|
|
523
528
|
callback(-3);
|
|
524
529
|
});
|
|
@@ -688,6 +693,7 @@ function readDesktopConfig() {
|
|
|
688
693
|
const lastConnectionUrl = typeof parsed.lastConnectionUrl === 'string' ? parsed.lastConnectionUrl : null;
|
|
689
694
|
return {
|
|
690
695
|
version: 1,
|
|
696
|
+
removedServiceKeys: Array.isArray(parsed.removedServiceKeys) ? parsed.removedServiceKeys.filter((key) => typeof key === 'string').slice(-768) : [],
|
|
691
697
|
connections: parsed.connections.filter((entry) => Boolean(entry)
|
|
692
698
|
&& typeof entry.id === 'string'
|
|
693
699
|
&& typeof entry.label === 'string'
|
|
@@ -971,6 +977,41 @@ function runtimePaths() {
|
|
|
971
977
|
source: 'development',
|
|
972
978
|
};
|
|
973
979
|
}
|
|
980
|
+
/** Explicit opt-in only; all routing and reconnect behavior lives in the shared CLI. */
|
|
981
|
+
function startConfiguredFederationRelay() {
|
|
982
|
+
const configPath = path.join(termdockDir, 'federation', 'relay.json');
|
|
983
|
+
if (federationRelayProcess || !fs.existsSync(configPath))
|
|
984
|
+
return;
|
|
985
|
+
let logFd;
|
|
986
|
+
try {
|
|
987
|
+
const runtime = runtimePaths();
|
|
988
|
+
if (!fs.existsSync(runtime.cli))
|
|
989
|
+
throw new Error('Runtime unavailable');
|
|
990
|
+
const logPath = path.join(termdockDir, 'federation', 'relay.log');
|
|
991
|
+
logFd = fs.openSync(logPath, 'a', 0o600);
|
|
992
|
+
fs.fchmodSync(logFd, 0o600);
|
|
993
|
+
const child = spawn(runtime.node, [runtime.cli, '--federation-relay', configPath], {
|
|
994
|
+
detached: false,
|
|
995
|
+
stdio: ['ignore', logFd, logFd],
|
|
996
|
+
env: desktopRuntimeEnv(runtime),
|
|
997
|
+
});
|
|
998
|
+
federationRelayProcess = child;
|
|
999
|
+
child.once('error', () => {
|
|
1000
|
+
if (federationRelayProcess === child)
|
|
1001
|
+
federationRelayProcess = null;
|
|
1002
|
+
console.error('[federation] Configured relay failed to start; inspect the private relay log.');
|
|
1003
|
+
});
|
|
1004
|
+
child.once('exit', () => { if (federationRelayProcess === child)
|
|
1005
|
+
federationRelayProcess = null; });
|
|
1006
|
+
}
|
|
1007
|
+
catch {
|
|
1008
|
+
console.error('[federation] Unable to start configured relay; verify the runtime and private configuration.');
|
|
1009
|
+
}
|
|
1010
|
+
finally {
|
|
1011
|
+
if (logFd !== undefined)
|
|
1012
|
+
fs.closeSync(logFd);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
974
1015
|
async function executableVersion(executable) {
|
|
975
1016
|
try {
|
|
976
1017
|
const { stdout } = await execFileAsync(executable, ['--version'], {
|
|
@@ -1394,7 +1435,8 @@ async function connectWindow(rawUrl, options = {}) {
|
|
|
1394
1435
|
return await probeService(rawUrl);
|
|
1395
1436
|
}
|
|
1396
1437
|
}
|
|
1397
|
-
|
|
1438
|
+
const known = readDesktopConfig().connections.find(item => (item.serviceOrigin || item.url) === normalizeServiceUrl(rawUrl));
|
|
1439
|
+
let probe = known?.targetPeerId ? { ok: true, url: normalizeServiceUrl(rawUrl) } : await probeServiceWithLocalNetworkPermission(rawUrl, {
|
|
1398
1440
|
interactive: options.focus !== false,
|
|
1399
1441
|
});
|
|
1400
1442
|
if (!probe.ok)
|
|
@@ -1423,7 +1465,9 @@ async function connectWindow(rawUrl, options = {}) {
|
|
|
1423
1465
|
existing.lastConnectedAt = Date.now();
|
|
1424
1466
|
writeDesktopConfig(config);
|
|
1425
1467
|
}
|
|
1426
|
-
if (await serviceDocumentNeedsReload(existingWindow.webContents, key)) {
|
|
1468
|
+
if (options.invitation || await serviceDocumentNeedsReload(existingWindow.webContents, key)) {
|
|
1469
|
+
if (options.invitation)
|
|
1470
|
+
pendingServiceInvitations.set(existingWindow, options.invitation);
|
|
1427
1471
|
await existingWindow.loadURL(probe.url);
|
|
1428
1472
|
}
|
|
1429
1473
|
if (options.focus !== false) {
|
|
@@ -1436,6 +1480,9 @@ async function connectWindow(rawUrl, options = {}) {
|
|
|
1436
1480
|
return probe;
|
|
1437
1481
|
}
|
|
1438
1482
|
const workspaceWindow = createDesktopWindow({ serviceOrigin: key, label: serviceLabel(probe.url) });
|
|
1483
|
+
await prepareBundledFrontend(workspaceWindow.webContents.session, key, path.join(runtimePaths().serverRoot, 'dist', 'client'));
|
|
1484
|
+
if (options.invitation)
|
|
1485
|
+
pendingServiceInvitations.set(workspaceWindow, options.invitation);
|
|
1439
1486
|
serviceWindows.set(key, workspaceWindow);
|
|
1440
1487
|
broadcastServiceActivity();
|
|
1441
1488
|
while (!workspaceWindow.isDestroyed()) {
|
|
@@ -1835,6 +1882,67 @@ function installIpcHandlers() {
|
|
|
1835
1882
|
collaborationPollTimer = setInterval(() => void collaborationFederation.refresh().catch(() => { }), 2000);
|
|
1836
1883
|
collaborationPollTimer.unref();
|
|
1837
1884
|
ipcMain.handle('desktop:snapshot', () => snapshot());
|
|
1885
|
+
const directorySender = (event) => {
|
|
1886
|
+
const window = BrowserWindow.fromWebContents(event.sender);
|
|
1887
|
+
if (!window || event.senderFrame !== event.sender.mainFrame)
|
|
1888
|
+
throw new Error('无法访问服务列表。');
|
|
1889
|
+
const origin = windowServiceOrigins.get(window);
|
|
1890
|
+
const url = new URL(event.senderFrame.url);
|
|
1891
|
+
if (origin ? url.origin !== origin || url.pathname !== '/' : window !== mainWindow || url.protocol !== 'file:')
|
|
1892
|
+
throw new Error('无法访问服务列表。');
|
|
1893
|
+
return window;
|
|
1894
|
+
};
|
|
1895
|
+
const directoryChanged = () => {
|
|
1896
|
+
installMenu();
|
|
1897
|
+
for (const window of BrowserWindow.getAllWindows())
|
|
1898
|
+
window.webContents.send('desktop:service-connections-changed');
|
|
1899
|
+
broadcastServiceActivity();
|
|
1900
|
+
};
|
|
1901
|
+
ipcMain.handle('desktop:service-connections', event => { directorySender(event); return readDesktopConfig().connections; });
|
|
1902
|
+
ipcMain.handle('desktop:save-service-connection', (event, input) => {
|
|
1903
|
+
directorySender(event);
|
|
1904
|
+
const config = readDesktopConfig();
|
|
1905
|
+
config.connections = upsertServiceConnection(config.connections, input);
|
|
1906
|
+
writeDesktopConfig(config);
|
|
1907
|
+
directoryChanged();
|
|
1908
|
+
return config.connections;
|
|
1909
|
+
});
|
|
1910
|
+
ipcMain.handle('desktop:import-service-connection', (event, input) => {
|
|
1911
|
+
directorySender(event);
|
|
1912
|
+
const config = readDesktopConfig();
|
|
1913
|
+
config.connections = importServiceConnection(config.connections, config.removedServiceKeys || [], input);
|
|
1914
|
+
writeDesktopConfig(config);
|
|
1915
|
+
directoryChanged();
|
|
1916
|
+
return config.connections;
|
|
1917
|
+
});
|
|
1918
|
+
ipcMain.handle('desktop:remove-service-connection', (event, id) => {
|
|
1919
|
+
directorySender(event);
|
|
1920
|
+
const config = readDesktopConfig();
|
|
1921
|
+
const removed = config.connections.find(item => item.id === id);
|
|
1922
|
+
if (removed)
|
|
1923
|
+
config.removedServiceKeys = [...new Set([...(config.removedServiceKeys || []), ...serviceConnectionKeys(removed)])].slice(-768);
|
|
1924
|
+
config.connections = config.connections.filter(item => item.id !== id);
|
|
1925
|
+
writeDesktopConfig(config);
|
|
1926
|
+
directoryChanged();
|
|
1927
|
+
return config.connections;
|
|
1928
|
+
});
|
|
1929
|
+
ipcMain.handle('desktop:current-service-connection', event => {
|
|
1930
|
+
const window = directorySender(event), origin = windowServiceOrigins.get(window);
|
|
1931
|
+
const connection = readDesktopConfig().connections.find(item => (item.serviceOrigin || item.url) === origin);
|
|
1932
|
+
const invitation = pendingServiceInvitations.get(window);
|
|
1933
|
+
pendingServiceInvitations.delete(window);
|
|
1934
|
+
return connection ? { ...connection, ...(invitation ? { invitation } : {}) } : null;
|
|
1935
|
+
});
|
|
1936
|
+
ipcMain.handle('desktop:open-service-connection', async (event, input, rawInvitation) => {
|
|
1937
|
+
directorySender(event);
|
|
1938
|
+
const connection = serviceConnection(input), invitation = invitationForService(rawInvitation, connection);
|
|
1939
|
+
// A bookmark pin is connection metadata, never authorization to the service.
|
|
1940
|
+
const config = readDesktopConfig();
|
|
1941
|
+
config.connections = upsertServiceConnection(config.connections, connection);
|
|
1942
|
+
writeDesktopConfig(config);
|
|
1943
|
+
directoryChanged();
|
|
1944
|
+
return connectWindow(connection.serviceOrigin || connection.url, { invitation });
|
|
1945
|
+
});
|
|
1838
1946
|
ipcMain.handle('desktop:probe', (_event, url) => {
|
|
1839
1947
|
try {
|
|
1840
1948
|
certificateTrustRequests.retry(new URL(normalizeServiceUrl(url)).origin);
|
|
@@ -1910,6 +2018,42 @@ function installIpcHandlers() {
|
|
|
1910
2018
|
broadcastServiceActivity();
|
|
1911
2019
|
return true;
|
|
1912
2020
|
});
|
|
2021
|
+
ipcMain.handle('desktop:local-invite', async (event) => {
|
|
2022
|
+
const sourceWindow = BrowserWindow.fromWebContents(event.sender);
|
|
2023
|
+
if (!sourceWindow || sourceWindow.isDestroyed() || event.senderFrame !== event.sender.mainFrame)
|
|
2024
|
+
return null;
|
|
2025
|
+
const registeredOrigin = windowServiceOrigins.get(sourceWindow);
|
|
2026
|
+
const initialUrl = event.sender.getURL();
|
|
2027
|
+
// First reject remote/preview callers before any asynchronous local probing.
|
|
2028
|
+
let callerPort;
|
|
2029
|
+
try {
|
|
2030
|
+
const url = new URL(initialUrl);
|
|
2031
|
+
callerPort = Number(url.port || (url.protocol === 'https:' ? 443 : 80));
|
|
2032
|
+
}
|
|
2033
|
+
catch {
|
|
2034
|
+
return null;
|
|
2035
|
+
}
|
|
2036
|
+
if (!canReadLocalInvite({ registeredOrigin, currentUrl: initialUrl, mainFrame: true, running: true, desktopManaged: true, servicePort: callerPort }))
|
|
2037
|
+
return null;
|
|
2038
|
+
const status = await getLocalServiceStatus().catch(() => null);
|
|
2039
|
+
if (!status || !status.state || sourceWindow.isDestroyed() || event.sender.isDestroyed()
|
|
2040
|
+
|| event.senderFrame !== event.sender.mainFrame || event.sender.getURL() !== initialUrl
|
|
2041
|
+
|| windowServiceOrigins.get(sourceWindow) !== registeredOrigin
|
|
2042
|
+
|| !canReadLocalInvite({ registeredOrigin, currentUrl: event.sender.getURL(), mainFrame: true,
|
|
2043
|
+
running: status.running, desktopManaged: status.probe?.desktopManaged === true, servicePort: status.state.port })
|
|
2044
|
+
|| !isOwnedDesktopRuntimeWindow(sourceWindow, status))
|
|
2045
|
+
return null;
|
|
2046
|
+
try {
|
|
2047
|
+
const data = JSON.parse(fs.readFileSync(path.join(termdockDir, 'federation', 'pairing.json'), 'utf8'));
|
|
2048
|
+
if (typeof data.serviceId !== 'string' || !/^12D3KooW[1-9A-HJ-NP-Za-km-z]{44}$/.test(data.serviceId)
|
|
2049
|
+
|| typeof data.pairingCode !== 'string' || !/^[A-Za-z0-9_-]{32,128}$/.test(data.pairingCode))
|
|
2050
|
+
return null;
|
|
2051
|
+
return { url: registeredOrigin, targetPeerId: data.serviceId, pairingCode: data.pairingCode, serviceName: '本机 Termdock' };
|
|
2052
|
+
}
|
|
2053
|
+
catch {
|
|
2054
|
+
return null;
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
1913
2057
|
ipcMain.handle('desktop:start-local', () => startLocalService());
|
|
1914
2058
|
ipcMain.handle('desktop:update-preferences', async (_event, preferences) => {
|
|
1915
2059
|
updateDesktopPreferences({
|
|
@@ -2247,6 +2391,7 @@ app.whenReady().then(async () => {
|
|
|
2247
2391
|
});
|
|
2248
2392
|
});
|
|
2249
2393
|
startConnectedServiceRuntimePolling();
|
|
2394
|
+
startConfiguredFederationRelay();
|
|
2250
2395
|
const startupConfig = readDesktopConfig();
|
|
2251
2396
|
const restoreUrls = startupConfig.openConnectionUrls;
|
|
2252
2397
|
startupRestoreActive = true;
|
|
@@ -2305,6 +2450,8 @@ app.on('window-all-closed', () => {
|
|
|
2305
2450
|
});
|
|
2306
2451
|
app.on('before-quit', () => {
|
|
2307
2452
|
isQuitting = true;
|
|
2453
|
+
federationRelayProcess?.kill('SIGTERM');
|
|
2454
|
+
federationRelayProcess = null;
|
|
2308
2455
|
desktopRuntimeOwnerServer?.close();
|
|
2309
2456
|
desktopRuntimeOwnerServer = null;
|
|
2310
2457
|
if (collaborationPollTimer)
|