termdock 1.4.356 → 1.4.358

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.
Files changed (490) hide show
  1. package/README.md +22 -4
  2. package/dist/client/assets/AndroidMirrorView-COoPljXi.js +3 -0
  3. package/dist/client/assets/AndroidMirrorView-COoPljXi.js.br +0 -0
  4. package/dist/client/assets/AndroidMirrorView-COoPljXi.js.gz +0 -0
  5. package/dist/client/assets/App-7BA7Jt-V.js +178 -0
  6. package/dist/client/assets/App-7BA7Jt-V.js.br +0 -0
  7. package/dist/client/assets/App-7BA7Jt-V.js.gz +0 -0
  8. package/dist/client/assets/ArchitecturePanel-B51eVL3I.js +9 -0
  9. package/dist/client/assets/ArchitecturePanel-B51eVL3I.js.br +0 -0
  10. package/dist/client/assets/ArchitecturePanel-B51eVL3I.js.gz +0 -0
  11. package/dist/client/assets/{ChangeWalkthroughPanel-DO_zJfZr.js → ChangeWalkthroughPanel-ZGMybE0m.js} +2 -2
  12. package/dist/client/assets/ChangeWalkthroughPanel-ZGMybE0m.js.br +0 -0
  13. package/dist/client/assets/ChangeWalkthroughPanel-ZGMybE0m.js.gz +0 -0
  14. package/dist/client/assets/{ChatRichContent-Cu1E1cJ8.js → ChatRichContent-KkN7aIGv.js} +29 -29
  15. package/dist/client/assets/ChatRichContent-KkN7aIGv.js.br +0 -0
  16. package/dist/client/assets/ChatRichContent-KkN7aIGv.js.gz +0 -0
  17. package/dist/client/assets/CollaborationMainWorkspace-BVeBgGMT.js +1 -0
  18. package/dist/client/assets/CollaborationMainWorkspace-BVeBgGMT.js.br +0 -0
  19. package/dist/client/assets/CollaborationMainWorkspace-BVeBgGMT.js.gz +0 -0
  20. package/dist/client/assets/CollaborationTaskContent-C3Od6xQy.js +1 -0
  21. package/dist/client/assets/ComputerControlView-CnaeZBuh.js +6 -0
  22. package/dist/client/assets/ComputerControlView-CnaeZBuh.js.br +0 -0
  23. package/dist/client/assets/ComputerControlView-CnaeZBuh.js.gz +0 -0
  24. package/dist/client/assets/{DagPlayground-CPYwfryM.js → DagPlayground-E7wKGgTF.js} +1 -1
  25. package/dist/client/assets/DagPlayground-E7wKGgTF.js.br +0 -0
  26. package/dist/client/assets/DagPlayground-E7wKGgTF.js.gz +0 -0
  27. package/dist/client/assets/{DiffLab-ptw96Q_4.js → DiffLab-BMXY4mRl.js} +1 -1
  28. package/dist/client/assets/DiffLab-BMXY4mRl.js.br +0 -0
  29. package/dist/client/assets/DiffLab-BMXY4mRl.js.gz +0 -0
  30. package/dist/client/assets/DiffReview-DHi_V-SX.js +1 -0
  31. package/dist/client/assets/DiffReview-DHi_V-SX.js.br +0 -0
  32. package/dist/client/assets/DiffReview-DHi_V-SX.js.gz +0 -0
  33. package/dist/client/assets/{DiffReviewLab-eEi3y-0G.js → DiffReviewLab-nhoosNZM.js} +1 -1
  34. package/dist/client/assets/DiffReviewLab-nhoosNZM.js.br +0 -0
  35. package/dist/client/assets/DiffReviewLab-nhoosNZM.js.gz +0 -0
  36. package/dist/client/assets/{DiffViewer-DqcQxp4Q.js → DiffViewer-CyDc8WOB.js} +1 -1
  37. package/dist/client/assets/DiffViewer-CyDc8WOB.js.br +0 -0
  38. package/dist/client/assets/DiffViewer-CyDc8WOB.js.gz +0 -0
  39. package/dist/client/assets/{GitLoadingSkeleton-DYrDIDF1.js → GitLoadingSkeleton-RRbTeMuA.js} +1 -1
  40. package/dist/client/assets/GitLoadingSkeleton-RRbTeMuA.js.br +0 -0
  41. package/dist/client/assets/GitLoadingSkeleton-RRbTeMuA.js.gz +0 -0
  42. package/dist/client/assets/Markdown-DKQhs57e.css +1 -0
  43. package/dist/client/assets/Markdown-DKQhs57e.css.br +0 -0
  44. package/dist/client/assets/Markdown-DKQhs57e.css.gz +0 -0
  45. package/dist/client/assets/Markdown-Ip0FYCJ1.js +23 -0
  46. package/dist/client/assets/Markdown-Ip0FYCJ1.js.br +0 -0
  47. package/dist/client/assets/Markdown-Ip0FYCJ1.js.gz +0 -0
  48. package/dist/client/assets/{ModelPreview-DjtHLlqP.js → ModelPreview-DuwBl4st.js} +3 -3
  49. package/dist/client/assets/ModelPreview-DuwBl4st.js.br +0 -0
  50. package/dist/client/assets/ModelPreview-DuwBl4st.js.gz +0 -0
  51. package/dist/client/assets/RecordingSaveDialog-Czkjuaeu.js +1 -0
  52. package/dist/client/assets/RecordingSaveDialog-Czkjuaeu.js.br +0 -0
  53. package/dist/client/assets/RecordingSaveDialog-Czkjuaeu.js.gz +0 -0
  54. package/dist/client/assets/RightSidebar-BvYh2_n2.js +1662 -0
  55. package/dist/client/assets/RightSidebar-BvYh2_n2.js.br +0 -0
  56. package/dist/client/assets/RightSidebar-BvYh2_n2.js.gz +0 -0
  57. package/dist/client/assets/SessionChatView-hFOVLdHC.js +13 -0
  58. package/dist/client/assets/SessionChatView-hFOVLdHC.js.br +0 -0
  59. package/dist/client/assets/SessionChatView-hFOVLdHC.js.gz +0 -0
  60. package/dist/client/assets/SessionResourceSidebar-D-VXNdmE.js +2 -0
  61. package/dist/client/assets/SessionResourceSidebar-D-VXNdmE.js.br +0 -0
  62. package/dist/client/assets/SessionResourceSidebar-D-VXNdmE.js.gz +0 -0
  63. package/dist/client/assets/TodoWorkspace-CCL-wZTu.js +1 -0
  64. package/dist/client/assets/TodoWorkspace-CCL-wZTu.js.br +0 -0
  65. package/dist/client/assets/TodoWorkspace-CCL-wZTu.js.gz +0 -0
  66. package/dist/client/assets/{abnfDiagram-VCTEODGH-Cvf_KWZ0.js → abnfDiagram-VCTEODGH-CdEUK_s_.js} +1 -1
  67. package/dist/client/assets/abnfDiagram-VCTEODGH-CdEUK_s_.js.br +0 -0
  68. package/dist/client/assets/abnfDiagram-VCTEODGH-CdEUK_s_.js.gz +0 -0
  69. package/dist/client/assets/app-DZ6mCJiW.js +37 -0
  70. package/dist/client/assets/app-DZ6mCJiW.js.br +0 -0
  71. package/dist/client/assets/app-DZ6mCJiW.js.gz +0 -0
  72. package/dist/client/assets/{arc-UvdowQOf.js → arc-Dmbeqzc-.js} +1 -1
  73. package/dist/client/assets/arc-Dmbeqzc-.js.br +0 -0
  74. package/dist/client/assets/arc-Dmbeqzc-.js.gz +0 -0
  75. package/dist/client/assets/{architectureDiagram-5GKGNRK7-DotsbCCA.js → architectureDiagram-5GKGNRK7-CZcdXQrP.js} +1 -1
  76. package/dist/client/assets/architectureDiagram-5GKGNRK7-CZcdXQrP.js.br +0 -0
  77. package/dist/client/assets/{architectureDiagram-5GKGNRK7-DotsbCCA.js.gz → architectureDiagram-5GKGNRK7-CZcdXQrP.js.gz} +0 -0
  78. package/dist/client/assets/{arrow-down-FGzRy9D-.js → arrow-down-Ty3zwcgl.js} +1 -1
  79. package/dist/client/assets/{blockDiagram-I7D4REHJ-CoOfSG4k.js → blockDiagram-I7D4REHJ-D9jFhXcb.js} +1 -1
  80. package/dist/client/assets/blockDiagram-I7D4REHJ-D9jFhXcb.js.br +0 -0
  81. package/dist/client/assets/blockDiagram-I7D4REHJ-D9jFhXcb.js.gz +0 -0
  82. package/dist/client/assets/{c4Diagram-7LVT6UL2-BAfjgs8B.js → c4Diagram-7LVT6UL2-c9o0rNTP.js} +1 -1
  83. package/dist/client/assets/c4Diagram-7LVT6UL2-c9o0rNTP.js.br +0 -0
  84. package/dist/client/assets/c4Diagram-7LVT6UL2-c9o0rNTP.js.gz +0 -0
  85. package/dist/client/assets/channel-BzD84hIE.js +1 -0
  86. package/dist/client/assets/{chevron-left-xqARwD-7.js → chevron-left-CVjGQZf0.js} +1 -1
  87. package/dist/client/assets/{chunk-2Q5K7J3B-DiiQ7BvG.js → chunk-2Q5K7J3B-Bl_5wWZ4.js} +1 -1
  88. package/dist/client/assets/{chunk-5VM5RSS4-CczSK8wW.js → chunk-5VM5RSS4-D9XQn27m.js} +1 -1
  89. package/dist/client/assets/{chunk-F27PBJKO-BI3Di4Ve.js → chunk-F27PBJKO-DWyskKWD.js} +1 -1
  90. package/dist/client/assets/chunk-F27PBJKO-DWyskKWD.js.br +0 -0
  91. package/dist/client/assets/chunk-F27PBJKO-DWyskKWD.js.gz +0 -0
  92. package/dist/client/assets/{chunk-IMKFNOWR-Cvvs1wmn.js → chunk-IMKFNOWR-DrWbExPc.js} +1 -1
  93. package/dist/client/assets/chunk-IMKFNOWR-DrWbExPc.js.br +0 -0
  94. package/dist/client/assets/chunk-IMKFNOWR-DrWbExPc.js.gz +0 -0
  95. package/dist/client/assets/{chunk-JWPE2WC7-lrJRD9WA.js → chunk-JWPE2WC7-B7O1zrh6.js} +1 -1
  96. package/dist/client/assets/{chunk-POPQ4Y6H-CnPC9D8B.js → chunk-POPQ4Y6H-D7TlizKK.js} +1 -1
  97. package/dist/client/assets/{chunk-SVP7TREG-BZfMhm64.js → chunk-SVP7TREG-DNK10F6v.js} +1 -1
  98. package/dist/client/assets/chunk-SVP7TREG-DNK10F6v.js.br +0 -0
  99. package/dist/client/assets/chunk-SVP7TREG-DNK10F6v.js.gz +0 -0
  100. package/dist/client/assets/{chunk-TICWLB2K-DmkEaRK3.js → chunk-TICWLB2K-zVD9YIYY.js} +1 -1
  101. package/dist/client/assets/chunk-TICWLB2K-zVD9YIYY.js.br +0 -0
  102. package/dist/client/assets/chunk-TICWLB2K-zVD9YIYY.js.gz +0 -0
  103. package/dist/client/assets/{chunk-XXDRQBXY-BP9Lccpe.js → chunk-XXDRQBXY-bRScHSGz.js} +1 -1
  104. package/dist/client/assets/{circle-DGZOpG8V.js → circle-BIJQEbCa.js} +1 -1
  105. package/dist/client/assets/classDiagram-ZZMXUADV-DNwfONVW.js +1 -0
  106. package/dist/client/assets/classDiagram-v2-VYDZK3BY-DNwfONVW.js +1 -0
  107. package/dist/client/assets/{clipboard-rLx5CzbY.js → clipboard-DV8t7tww.js} +1 -1
  108. package/dist/client/assets/clipboardText-C4QKbGHg.css +1 -0
  109. package/dist/client/assets/clipboardText-C4QKbGHg.css.br +0 -0
  110. package/dist/client/assets/clipboardText-C4QKbGHg.css.gz +0 -0
  111. package/dist/client/assets/clipboardText-DoB9NjH8.js +1 -0
  112. package/dist/client/assets/clipboardText-DoB9NjH8.js.br +0 -0
  113. package/dist/client/assets/clipboardText-DoB9NjH8.js.gz +0 -0
  114. package/dist/client/assets/{cose-bilkent-JH36ORCC-0xPYMc2z.js → cose-bilkent-JH36ORCC-Bf6IObhf.js} +1 -1
  115. package/dist/client/assets/cose-bilkent-JH36ORCC-Bf6IObhf.js.br +0 -0
  116. package/dist/client/assets/cose-bilkent-JH36ORCC-Bf6IObhf.js.gz +0 -0
  117. package/dist/client/assets/{cynefin-OW5HDTMX-BQ7-lCHm.js → cynefin-OW5HDTMX-DAtjde93.js} +1 -1
  118. package/dist/client/assets/cynefin-OW5HDTMX-DAtjde93.js.br +0 -0
  119. package/dist/client/assets/cynefin-OW5HDTMX-DAtjde93.js.gz +0 -0
  120. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CazHuSj1.js → cynefinDiagram-5FMLGOSQ-Bwoin99V.js} +1 -1
  121. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Bwoin99V.js.br +0 -0
  122. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Bwoin99V.js.gz +0 -0
  123. package/dist/client/assets/{dagre-GXQ25YYZ-CJNgsyHQ.js → dagre-GXQ25YYZ-dxPzSob9.js} +1 -1
  124. package/dist/client/assets/dagre-GXQ25YYZ-dxPzSob9.js.br +0 -0
  125. package/dist/client/assets/dagre-GXQ25YYZ-dxPzSob9.js.gz +0 -0
  126. package/dist/client/assets/{diagram-S7CK7UJ4-D4xXIj1P.js → diagram-S7CK7UJ4-BXdiLivz.js} +1 -1
  127. package/dist/client/assets/diagram-S7CK7UJ4-BXdiLivz.js.br +0 -0
  128. package/dist/client/assets/diagram-S7CK7UJ4-BXdiLivz.js.gz +0 -0
  129. package/dist/client/assets/{diagram-UQ7AKVKN-BWhpL-35.js → diagram-UQ7AKVKN-DXveP3fg.js} +1 -1
  130. package/dist/client/assets/diagram-UQ7AKVKN-DXveP3fg.js.br +0 -0
  131. package/dist/client/assets/diagram-UQ7AKVKN-DXveP3fg.js.gz +0 -0
  132. package/dist/client/assets/{diagram-VSXAHHWV-DG9A7EgJ.js → diagram-VSXAHHWV-BAZtoQue.js} +1 -1
  133. package/dist/client/assets/diagram-VSXAHHWV-BAZtoQue.js.br +0 -0
  134. package/dist/client/assets/diagram-VSXAHHWV-BAZtoQue.js.gz +0 -0
  135. package/dist/client/assets/{diagram-VX7I27RA-L5PSvynM.js → diagram-VX7I27RA-Bhc7cKpk.js} +1 -1
  136. package/dist/client/assets/diagram-VX7I27RA-Bhc7cKpk.js.br +0 -0
  137. package/dist/client/assets/diagram-VX7I27RA-Bhc7cKpk.js.gz +0 -0
  138. package/dist/client/assets/{diagram-Z3DM3KII-moBH7ruR.js → diagram-Z3DM3KII-DWIa_F-y.js} +1 -1
  139. package/dist/client/assets/diagram-Z3DM3KII-DWIa_F-y.js.br +0 -0
  140. package/dist/client/assets/diagram-Z3DM3KII-DWIa_F-y.js.gz +0 -0
  141. package/dist/client/assets/{ebnfDiagram-PWID7BFC-DEiGgcRP.js → ebnfDiagram-PWID7BFC-B3LDILSm.js} +1 -1
  142. package/dist/client/assets/ebnfDiagram-PWID7BFC-B3LDILSm.js.br +0 -0
  143. package/dist/client/assets/ebnfDiagram-PWID7BFC-B3LDILSm.js.gz +0 -0
  144. package/dist/client/assets/{erDiagram-RLTQ6QDP-BboIleYi.js → erDiagram-RLTQ6QDP-Cfu95bMX.js} +1 -1
  145. package/dist/client/assets/erDiagram-RLTQ6QDP-Cfu95bMX.js.br +0 -0
  146. package/dist/client/assets/erDiagram-RLTQ6QDP-Cfu95bMX.js.gz +0 -0
  147. package/dist/client/assets/{external-link-AZ3wjUg5.js → external-link-DodqgrCc.js} +1 -1
  148. package/dist/client/assets/{flowDiagram-HODETNUW-COxz7Rda.js → flowDiagram-HODETNUW-DVtO6aQE.js} +1 -1
  149. package/dist/client/assets/flowDiagram-HODETNUW-DVtO6aQE.js.br +0 -0
  150. package/dist/client/assets/flowDiagram-HODETNUW-DVtO6aQE.js.gz +0 -0
  151. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-_XdRvgyZ.js → ganttDiagram-EL5Y4UJY-Bh1TvYzb.js} +1 -1
  152. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bh1TvYzb.js.br +0 -0
  153. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bh1TvYzb.js.gz +0 -0
  154. package/dist/client/assets/{git-compare-90v75Jal.js → git-compare-KkbucDhN.js} +1 -1
  155. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-CBb9xBNW.js → gitGraphDiagram-WWUBYQGX-BKbRxPsF.js} +1 -1
  156. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BKbRxPsF.js.br +0 -0
  157. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BKbRxPsF.js.gz +0 -0
  158. package/dist/client/assets/index-DEAMSl55.css +1 -0
  159. package/dist/client/assets/index-DEAMSl55.css.br +0 -0
  160. package/dist/client/assets/index-DEAMSl55.css.gz +0 -0
  161. package/dist/client/assets/{infoDiagram-27XIBGKW-DjLdeNZi.js → infoDiagram-27XIBGKW-CLhO8B16.js} +1 -1
  162. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bcr-lhIE.js → ishikawaDiagram-5VMMS53U-BwchGTP9.js} +1 -1
  163. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BwchGTP9.js.br +0 -0
  164. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BwchGTP9.js.gz +0 -0
  165. package/dist/client/assets/{journeyDiagram-3NMN7TZE-3vK6s9Pq.js → journeyDiagram-3NMN7TZE-eWBpuyMm.js} +1 -1
  166. package/dist/client/assets/journeyDiagram-3NMN7TZE-eWBpuyMm.js.br +0 -0
  167. package/dist/client/assets/journeyDiagram-3NMN7TZE-eWBpuyMm.js.gz +0 -0
  168. package/dist/client/assets/{kanban-definition-UXKFOSKX-DqDYDca0.js → kanban-definition-UXKFOSKX-Sik-RHYc.js} +1 -1
  169. package/dist/client/assets/kanban-definition-UXKFOSKX-Sik-RHYc.js.br +0 -0
  170. package/dist/client/assets/kanban-definition-UXKFOSKX-Sik-RHYc.js.gz +0 -0
  171. package/dist/client/assets/{layout-C7_WwzCP.js → layout-BJX2CDWF.js} +1 -1
  172. package/dist/client/assets/layout-BJX2CDWF.js.br +0 -0
  173. package/dist/client/assets/layout-BJX2CDWF.js.gz +0 -0
  174. package/dist/client/assets/{linear-BQCRhl6P.js → linear-0FKHr918.js} +1 -1
  175. package/dist/client/assets/{linear-BQCRhl6P.js.br → linear-0FKHr918.js.br} +0 -0
  176. package/dist/client/assets/linear-0FKHr918.js.gz +0 -0
  177. package/dist/client/assets/{link-Cq14tNBm.js → link-DWUQqMDL.js} +3 -3
  178. package/dist/client/assets/link-DWUQqMDL.js.br +0 -0
  179. package/dist/client/assets/link-DWUQqMDL.js.gz +0 -0
  180. package/dist/client/assets/{list-tree-C281zrdg.js → list-tree-DxdLnXUB.js} +1 -1
  181. package/dist/client/assets/{maximize-2-CovPxWdw.js → maximize-2-Clx4ktqB.js} +1 -1
  182. package/dist/client/assets/{mermaid.core-DGsccxt-.js → mermaid.core-DWoaNsig.js} +5 -5
  183. package/dist/client/assets/mermaid.core-DWoaNsig.js.br +0 -0
  184. package/dist/client/assets/mermaid.core-DWoaNsig.js.gz +0 -0
  185. package/dist/client/assets/{mindmap-definition-YA3MSWOX-l0eF1PQE.js → mindmap-definition-YA3MSWOX-kFqW8-1C.js} +1 -1
  186. package/dist/client/assets/mindmap-definition-YA3MSWOX-kFqW8-1C.js.br +0 -0
  187. package/dist/client/assets/mindmap-definition-YA3MSWOX-kFqW8-1C.js.gz +0 -0
  188. package/dist/client/assets/{passwordBootstrap-B5VzheZz.js → passwordBootstrap-ZDVK8UPE.js} +1 -1
  189. package/dist/client/assets/passwordBootstrap-ZDVK8UPE.js.br +0 -0
  190. package/dist/client/assets/passwordBootstrap-ZDVK8UPE.js.gz +0 -0
  191. package/dist/client/assets/{pegDiagram-XKGWAZYB-fRrxGIDM.js → pegDiagram-XKGWAZYB-CndGmUtZ.js} +1 -1
  192. package/dist/client/assets/pegDiagram-XKGWAZYB-CndGmUtZ.js.br +0 -0
  193. package/dist/client/assets/pegDiagram-XKGWAZYB-CndGmUtZ.js.gz +0 -0
  194. package/dist/client/assets/{pieDiagram-E7YTZNPT-B-EBa3qN.js → pieDiagram-E7YTZNPT-Q550203T.js} +1 -1
  195. package/dist/client/assets/pieDiagram-E7YTZNPT-Q550203T.js.br +0 -0
  196. package/dist/client/assets/pieDiagram-E7YTZNPT-Q550203T.js.gz +0 -0
  197. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Dj4e6f4h.js → quadrantDiagram-AXDQQJYC-BrjlUGzZ.js} +1 -1
  198. package/dist/client/assets/quadrantDiagram-AXDQQJYC-BrjlUGzZ.js.br +0 -0
  199. package/dist/client/assets/quadrantDiagram-AXDQQJYC-BrjlUGzZ.js.gz +0 -0
  200. package/dist/client/assets/{quote-COQfrXhi.js → quote-B9G-yF_k.js} +1 -1
  201. package/dist/client/assets/{railroadDiagram-O6MQD6OU-CEMppxTC.js → railroadDiagram-O6MQD6OU-CSqOaX_w.js} +1 -1
  202. package/dist/client/assets/railroadDiagram-O6MQD6OU-CSqOaX_w.js.br +0 -0
  203. package/dist/client/assets/railroadDiagram-O6MQD6OU-CSqOaX_w.js.gz +0 -0
  204. package/dist/client/assets/rdpSession-DdqSmi-Z.js +1 -0
  205. package/dist/client/assets/rdpSession-DdqSmi-Z.js.br +0 -0
  206. package/dist/client/assets/rdpSession-DdqSmi-Z.js.gz +0 -0
  207. package/dist/client/assets/referenceSelection-0uCpJjt2.js +4 -0
  208. package/dist/client/assets/referenceSelection-0uCpJjt2.js.br +0 -0
  209. package/dist/client/assets/referenceSelection-0uCpJjt2.js.gz +0 -0
  210. package/dist/client/assets/{requirementDiagram-BXWQKSXE-Dri1k4_x.js → requirementDiagram-BXWQKSXE-NGPth3Pf.js} +1 -1
  211. package/dist/client/assets/requirementDiagram-BXWQKSXE-NGPth3Pf.js.br +0 -0
  212. package/dist/client/assets/requirementDiagram-BXWQKSXE-NGPth3Pf.js.gz +0 -0
  213. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CMsL_tYL.js → sankeyDiagram-P5KCCOFB-CbxpJ6iI.js} +1 -1
  214. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CbxpJ6iI.js.br +0 -0
  215. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CbxpJ6iI.js.gz +0 -0
  216. package/dist/client/assets/{search-Dg6HWygj.js → search-DAQ_AOVP.js} +1 -1
  217. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-4_4hZtOd.js → sequenceDiagram-WJ2MYXX4-D3gJOK25.js} +1 -1
  218. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D3gJOK25.js.br +0 -0
  219. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D3gJOK25.js.gz +0 -0
  220. package/dist/client/assets/{sizeCapture-INFHLROL-3QA6qj2j.js → sizeCapture-INFHLROL-D4D1KI0n.js} +1 -1
  221. package/dist/client/assets/sizeCapture-INFHLROL-D4D1KI0n.js.br +0 -0
  222. package/dist/client/assets/sizeCapture-INFHLROL-D4D1KI0n.js.gz +0 -0
  223. package/dist/client/assets/{stateDiagram-D77RDMKH-90IFPhD9.js → stateDiagram-D77RDMKH-BjtgjBg5.js} +1 -1
  224. package/dist/client/assets/stateDiagram-D77RDMKH-BjtgjBg5.js.br +0 -0
  225. package/dist/client/assets/stateDiagram-D77RDMKH-BjtgjBg5.js.gz +0 -0
  226. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BkFsvhZ0.js +1 -0
  227. package/dist/client/assets/{sun-BAMMjiA8.js → sun-DvwMJkda.js} +1 -1
  228. package/dist/client/assets/{swimlanes-42K2YHIH-BuHieVWC.js → swimlanes-42K2YHIH-C17jwdFo.js} +1 -1
  229. package/dist/client/assets/swimlanes-42K2YHIH-C17jwdFo.js.br +0 -0
  230. package/dist/client/assets/swimlanes-42K2YHIH-C17jwdFo.js.gz +0 -0
  231. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-Bcw2hbFj.js +8 -0
  232. package/dist/client/assets/swiper-BaumVgFd.js +1 -0
  233. package/dist/client/assets/swiper-BaumVgFd.js.br +0 -0
  234. package/dist/client/assets/swiper-BaumVgFd.js.gz +0 -0
  235. package/dist/client/assets/{terminal-Dea8wJF3.js → terminal-DaiFCKy_.js} +7 -7
  236. package/dist/client/assets/terminal-DaiFCKy_.js.br +0 -0
  237. package/dist/client/assets/terminal-DaiFCKy_.js.gz +0 -0
  238. package/dist/client/assets/{timeline-definition-24CTP7MA-C7FpaNwf.js → timeline-definition-24CTP7MA-CtdHmPoC.js} +1 -1
  239. package/dist/client/assets/timeline-definition-24CTP7MA-CtdHmPoC.js.br +0 -0
  240. package/dist/client/assets/timeline-definition-24CTP7MA-CtdHmPoC.js.gz +0 -0
  241. package/dist/client/assets/triangle-alert-D-tt7pA2.js +1 -0
  242. package/dist/client/assets/{unplug-DN2SNXUL.js → unplug-BQxOculv.js} +1 -1
  243. package/dist/client/assets/use-gesture-react.esm-CM42s15B.js +1 -0
  244. package/dist/client/assets/use-gesture-react.esm-CM42s15B.js.br +0 -0
  245. package/dist/client/assets/use-gesture-react.esm-CM42s15B.js.gz +0 -0
  246. package/dist/client/assets/{vennDiagram-4TSXK5OY-CxoHHVcs.js → vennDiagram-4TSXK5OY-DhwCFaVe.js} +1 -1
  247. package/dist/client/assets/vennDiagram-4TSXK5OY-DhwCFaVe.js.br +0 -0
  248. package/dist/client/assets/vennDiagram-4TSXK5OY-DhwCFaVe.js.gz +0 -0
  249. package/dist/client/assets/{videoCompression-rr2lu3uy.js → videoCompression-BFhMaMl7.js} +1 -1
  250. package/dist/client/assets/videoCompression-BFhMaMl7.js.br +0 -0
  251. package/dist/client/assets/videoCompression-BFhMaMl7.js.gz +0 -0
  252. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-B4Hsh-Ad.js → wardleyDiagram-VM6X3IG4-BP4Z-QQ4.js} +1 -1
  253. package/dist/client/assets/wardleyDiagram-VM6X3IG4-BP4Z-QQ4.js.br +0 -0
  254. package/dist/client/assets/wardleyDiagram-VM6X3IG4-BP4Z-QQ4.js.gz +0 -0
  255. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-CghzsxQv.js → xychartDiagram-S5SC5T6Z-CEPWf1tk.js} +1 -1
  256. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CEPWf1tk.js.br +0 -0
  257. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CEPWf1tk.js.gz +0 -0
  258. package/dist/client/index.html +3 -3
  259. package/dist/client/index.html.br +0 -0
  260. package/dist/client/index.html.gz +0 -0
  261. package/dist/client/sw-encrypted-background.js +1 -1
  262. package/dist/client/sw-encrypted-background.js.br +0 -0
  263. package/dist/client/sw-encrypted-background.js.gz +0 -0
  264. package/dist/client/sw.js +1 -1
  265. package/dist/client/sw.js.br +0 -0
  266. package/dist/client/sw.js.gz +0 -0
  267. package/dist/server/agent/collaborationPeerTransport.js +14 -69
  268. package/dist/server/agent/collaborationStore.js +5 -0
  269. package/dist/server/agent/installers.js +89 -33
  270. package/dist/server/agent/integrationServer.js +31 -2
  271. package/dist/server/agent/pluginPackages.js +51 -22
  272. package/dist/server/agent/sessionChatRoutes.js +45 -7
  273. package/dist/server/agentHook.js +56 -12
  274. package/dist/server/android/adb.js +24 -31
  275. package/dist/server/cli.js +52 -110
  276. package/dist/server/entry.js +17 -23
  277. package/dist/server/federation/cli.js +13 -47
  278. package/dist/server/federation/connectionErrors.js +37 -0
  279. package/dist/server/federation/connectionModel.js +83 -0
  280. package/dist/server/federation/desktopTargets.js +35 -13
  281. package/dist/server/federation/directRoutes.js +28 -36
  282. package/dist/server/federation/directTargetRegistry.js +106 -0
  283. package/dist/server/federation/httpUploadLimit.js +8 -0
  284. package/dist/server/federation/relay.js +13 -6
  285. package/dist/server/federation/relayTransport.js +147 -0
  286. package/dist/server/federation/routeAccess.js +5 -3
  287. package/dist/server/federation/runtime.js +4 -2
  288. package/dist/server/federation/selfRelay.js +10 -59
  289. package/dist/server/federation/serviceTransport.js +123 -0
  290. package/dist/server/federation/streamLimits.js +3 -0
  291. package/dist/server/federation/trustedCa.js +61 -0
  292. package/dist/server/routes/android.js +5 -7
  293. package/dist/server/routes/terminal.js +149 -111
  294. package/dist/server/shared/androidDevices.js +64 -0
  295. package/dist/server/shared/programStatus.js +174 -0
  296. package/dist/server/shared/shareResources.js +3 -2
  297. package/dist/server/todos/routes.js +36 -0
  298. package/dist/server/todos/store.js +31 -1
  299. package/dist/server/utils/bootCheck.js +41 -271
  300. package/dist/server/utils/localHttpsSetup.js +257 -0
  301. package/dist/server/utils/oscBuffer.js +9 -0
  302. package/dist/server/utils/sessionDisplayName.js +11 -9
  303. package/dist/server/utils/settings.js +6 -3
  304. package/dist/server/utils/tmuxDisplayGeometry.js +54 -0
  305. package/dist/server/utils/tmuxObserverSize.js +26 -0
  306. package/docs/integrations.md +2 -1
  307. package/package.json +6 -1
  308. package/runtime-manifest.json +3 -3
  309. package/scripts/install-utils.cjs +81 -0
  310. package/scripts/postinstall.mjs +19 -106
  311. package/dist/client/assets/AndroidMirrorView-DW9oRr0w.js +0 -3
  312. package/dist/client/assets/AndroidMirrorView-DW9oRr0w.js.br +0 -0
  313. package/dist/client/assets/AndroidMirrorView-DW9oRr0w.js.gz +0 -0
  314. package/dist/client/assets/App-DEZ2i9ZZ.js +0 -178
  315. package/dist/client/assets/App-DEZ2i9ZZ.js.br +0 -0
  316. package/dist/client/assets/App-DEZ2i9ZZ.js.gz +0 -0
  317. package/dist/client/assets/ArchitecturePanel-Bf4b-6An.js +0 -9
  318. package/dist/client/assets/ArchitecturePanel-Bf4b-6An.js.br +0 -0
  319. package/dist/client/assets/ArchitecturePanel-Bf4b-6An.js.gz +0 -0
  320. package/dist/client/assets/ChangeWalkthroughPanel-DO_zJfZr.js.br +0 -0
  321. package/dist/client/assets/ChangeWalkthroughPanel-DO_zJfZr.js.gz +0 -0
  322. package/dist/client/assets/ChatRichContent-Cu1E1cJ8.js.br +0 -0
  323. package/dist/client/assets/ChatRichContent-Cu1E1cJ8.js.gz +0 -0
  324. package/dist/client/assets/CollaborationMainWorkspace-BhmpSEbf.js +0 -1
  325. package/dist/client/assets/CollaborationMainWorkspace-BhmpSEbf.js.br +0 -0
  326. package/dist/client/assets/CollaborationMainWorkspace-BhmpSEbf.js.gz +0 -0
  327. package/dist/client/assets/CollaborationTaskContent-CX0Aqdi2.js +0 -2
  328. package/dist/client/assets/ComputerControlView-DjQLzn10.js +0 -6
  329. package/dist/client/assets/ComputerControlView-DjQLzn10.js.br +0 -0
  330. package/dist/client/assets/ComputerControlView-DjQLzn10.js.gz +0 -0
  331. package/dist/client/assets/DagPlayground-CPYwfryM.js.br +0 -0
  332. package/dist/client/assets/DagPlayground-CPYwfryM.js.gz +0 -0
  333. package/dist/client/assets/DiffLab-ptw96Q_4.js.br +0 -0
  334. package/dist/client/assets/DiffLab-ptw96Q_4.js.gz +0 -0
  335. package/dist/client/assets/DiffReview-12E2zWyL.js +0 -1
  336. package/dist/client/assets/DiffReview-12E2zWyL.js.br +0 -0
  337. package/dist/client/assets/DiffReview-12E2zWyL.js.gz +0 -0
  338. package/dist/client/assets/DiffReviewLab-eEi3y-0G.js.br +0 -0
  339. package/dist/client/assets/DiffReviewLab-eEi3y-0G.js.gz +0 -0
  340. package/dist/client/assets/DiffViewer-DqcQxp4Q.js.br +0 -0
  341. package/dist/client/assets/DiffViewer-DqcQxp4Q.js.gz +0 -0
  342. package/dist/client/assets/GitLoadingSkeleton-DYrDIDF1.js.br +0 -0
  343. package/dist/client/assets/GitLoadingSkeleton-DYrDIDF1.js.gz +0 -0
  344. package/dist/client/assets/MarkdownPreview-CsJGsDRL.js +0 -19
  345. package/dist/client/assets/MarkdownPreview-CsJGsDRL.js.br +0 -0
  346. package/dist/client/assets/MarkdownPreview-CsJGsDRL.js.gz +0 -0
  347. package/dist/client/assets/ModelPreview-DjtHLlqP.js.br +0 -0
  348. package/dist/client/assets/ModelPreview-DjtHLlqP.js.gz +0 -0
  349. package/dist/client/assets/RecordingSaveDialog-DUtwgIME.js +0 -1
  350. package/dist/client/assets/RecordingSaveDialog-DUtwgIME.js.br +0 -0
  351. package/dist/client/assets/RecordingSaveDialog-DUtwgIME.js.gz +0 -0
  352. package/dist/client/assets/RightSidebar-BltjUFwI.js +0 -1662
  353. package/dist/client/assets/RightSidebar-BltjUFwI.js.br +0 -0
  354. package/dist/client/assets/RightSidebar-BltjUFwI.js.gz +0 -0
  355. package/dist/client/assets/SessionChatView-CdKfHRp8.js +0 -13
  356. package/dist/client/assets/SessionChatView-CdKfHRp8.js.br +0 -0
  357. package/dist/client/assets/SessionChatView-CdKfHRp8.js.gz +0 -0
  358. package/dist/client/assets/SessionChatView-D8GoESjb.css +0 -1
  359. package/dist/client/assets/SessionChatView-D8GoESjb.css.br +0 -0
  360. package/dist/client/assets/SessionChatView-D8GoESjb.css.gz +0 -0
  361. package/dist/client/assets/SessionResourceSidebar-DmQOydhf.js +0 -2
  362. package/dist/client/assets/SessionResourceSidebar-DmQOydhf.js.br +0 -0
  363. package/dist/client/assets/SessionResourceSidebar-DmQOydhf.js.gz +0 -0
  364. package/dist/client/assets/TodoWorkspace-Bh1C035B.js +0 -1
  365. package/dist/client/assets/TodoWorkspace-Bh1C035B.js.br +0 -0
  366. package/dist/client/assets/TodoWorkspace-Bh1C035B.js.gz +0 -0
  367. package/dist/client/assets/abnfDiagram-VCTEODGH-Cvf_KWZ0.js.br +0 -0
  368. package/dist/client/assets/abnfDiagram-VCTEODGH-Cvf_KWZ0.js.gz +0 -0
  369. package/dist/client/assets/app-DuUnqxq-.js +0 -37
  370. package/dist/client/assets/app-DuUnqxq-.js.br +0 -0
  371. package/dist/client/assets/app-DuUnqxq-.js.gz +0 -0
  372. package/dist/client/assets/arc-UvdowQOf.js.br +0 -0
  373. package/dist/client/assets/arc-UvdowQOf.js.gz +0 -0
  374. package/dist/client/assets/architectureDiagram-5GKGNRK7-DotsbCCA.js.br +0 -0
  375. package/dist/client/assets/arrow-up-DNkfesW0.js +0 -1
  376. package/dist/client/assets/blockDiagram-I7D4REHJ-CoOfSG4k.js.br +0 -0
  377. package/dist/client/assets/blockDiagram-I7D4REHJ-CoOfSG4k.js.gz +0 -0
  378. package/dist/client/assets/c4Diagram-7LVT6UL2-BAfjgs8B.js.br +0 -0
  379. package/dist/client/assets/c4Diagram-7LVT6UL2-BAfjgs8B.js.gz +0 -0
  380. package/dist/client/assets/channel-BzMU9Wks.js +0 -1
  381. package/dist/client/assets/chunk-F27PBJKO-BI3Di4Ve.js.br +0 -0
  382. package/dist/client/assets/chunk-F27PBJKO-BI3Di4Ve.js.gz +0 -0
  383. package/dist/client/assets/chunk-IMKFNOWR-Cvvs1wmn.js.br +0 -0
  384. package/dist/client/assets/chunk-IMKFNOWR-Cvvs1wmn.js.gz +0 -0
  385. package/dist/client/assets/chunk-SVP7TREG-BZfMhm64.js.br +0 -0
  386. package/dist/client/assets/chunk-SVP7TREG-BZfMhm64.js.gz +0 -0
  387. package/dist/client/assets/chunk-TICWLB2K-DmkEaRK3.js.br +0 -0
  388. package/dist/client/assets/chunk-TICWLB2K-DmkEaRK3.js.gz +0 -0
  389. package/dist/client/assets/classDiagram-ZZMXUADV-DtAtEoWU.js +0 -1
  390. package/dist/client/assets/classDiagram-v2-VYDZK3BY-DtAtEoWU.js +0 -1
  391. package/dist/client/assets/clipboardText-cZXParp1.js +0 -1
  392. package/dist/client/assets/clipboardText-cZXParp1.js.br +0 -0
  393. package/dist/client/assets/clipboardText-cZXParp1.js.gz +0 -0
  394. package/dist/client/assets/cose-bilkent-JH36ORCC-0xPYMc2z.js.br +0 -0
  395. package/dist/client/assets/cose-bilkent-JH36ORCC-0xPYMc2z.js.gz +0 -0
  396. package/dist/client/assets/cynefin-OW5HDTMX-BQ7-lCHm.js.br +0 -0
  397. package/dist/client/assets/cynefin-OW5HDTMX-BQ7-lCHm.js.gz +0 -0
  398. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CazHuSj1.js.br +0 -0
  399. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CazHuSj1.js.gz +0 -0
  400. package/dist/client/assets/dagre-GXQ25YYZ-CJNgsyHQ.js.br +0 -0
  401. package/dist/client/assets/dagre-GXQ25YYZ-CJNgsyHQ.js.gz +0 -0
  402. package/dist/client/assets/diagram-S7CK7UJ4-D4xXIj1P.js.br +0 -0
  403. package/dist/client/assets/diagram-S7CK7UJ4-D4xXIj1P.js.gz +0 -0
  404. package/dist/client/assets/diagram-UQ7AKVKN-BWhpL-35.js.br +0 -0
  405. package/dist/client/assets/diagram-UQ7AKVKN-BWhpL-35.js.gz +0 -0
  406. package/dist/client/assets/diagram-VSXAHHWV-DG9A7EgJ.js.br +0 -0
  407. package/dist/client/assets/diagram-VSXAHHWV-DG9A7EgJ.js.gz +0 -0
  408. package/dist/client/assets/diagram-VX7I27RA-L5PSvynM.js.br +0 -0
  409. package/dist/client/assets/diagram-VX7I27RA-L5PSvynM.js.gz +0 -0
  410. package/dist/client/assets/diagram-Z3DM3KII-moBH7ruR.js.br +0 -0
  411. package/dist/client/assets/diagram-Z3DM3KII-moBH7ruR.js.gz +0 -0
  412. package/dist/client/assets/ebnfDiagram-PWID7BFC-DEiGgcRP.js.br +0 -0
  413. package/dist/client/assets/ebnfDiagram-PWID7BFC-DEiGgcRP.js.gz +0 -0
  414. package/dist/client/assets/erDiagram-RLTQ6QDP-BboIleYi.js.br +0 -0
  415. package/dist/client/assets/erDiagram-RLTQ6QDP-BboIleYi.js.gz +0 -0
  416. package/dist/client/assets/flowDiagram-HODETNUW-COxz7Rda.js.br +0 -0
  417. package/dist/client/assets/flowDiagram-HODETNUW-COxz7Rda.js.gz +0 -0
  418. package/dist/client/assets/ganttDiagram-EL5Y4UJY-_XdRvgyZ.js.br +0 -0
  419. package/dist/client/assets/ganttDiagram-EL5Y4UJY-_XdRvgyZ.js.gz +0 -0
  420. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-CBb9xBNW.js.br +0 -0
  421. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-CBb9xBNW.js.gz +0 -0
  422. package/dist/client/assets/index-nIgxJ6I3.css +0 -1
  423. package/dist/client/assets/index-nIgxJ6I3.css.br +0 -0
  424. package/dist/client/assets/index-nIgxJ6I3.css.gz +0 -0
  425. package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bcr-lhIE.js.br +0 -0
  426. package/dist/client/assets/ishikawaDiagram-5VMMS53U-Bcr-lhIE.js.gz +0 -0
  427. package/dist/client/assets/journeyDiagram-3NMN7TZE-3vK6s9Pq.js.br +0 -0
  428. package/dist/client/assets/journeyDiagram-3NMN7TZE-3vK6s9Pq.js.gz +0 -0
  429. package/dist/client/assets/kanban-definition-UXKFOSKX-DqDYDca0.js.br +0 -0
  430. package/dist/client/assets/kanban-definition-UXKFOSKX-DqDYDca0.js.gz +0 -0
  431. package/dist/client/assets/layout-C7_WwzCP.js.br +0 -0
  432. package/dist/client/assets/layout-C7_WwzCP.js.gz +0 -0
  433. package/dist/client/assets/linear-BQCRhl6P.js.gz +0 -0
  434. package/dist/client/assets/link-Cq14tNBm.js.br +0 -0
  435. package/dist/client/assets/link-Cq14tNBm.js.gz +0 -0
  436. package/dist/client/assets/loader-circle-Df0zpx5N.js +0 -1
  437. package/dist/client/assets/mermaid.core-DGsccxt-.js.br +0 -0
  438. package/dist/client/assets/mermaid.core-DGsccxt-.js.gz +0 -0
  439. package/dist/client/assets/mindmap-definition-YA3MSWOX-l0eF1PQE.js.br +0 -0
  440. package/dist/client/assets/mindmap-definition-YA3MSWOX-l0eF1PQE.js.gz +0 -0
  441. package/dist/client/assets/passwordBootstrap-B5VzheZz.js.br +0 -0
  442. package/dist/client/assets/passwordBootstrap-B5VzheZz.js.gz +0 -0
  443. package/dist/client/assets/pegDiagram-XKGWAZYB-fRrxGIDM.js.br +0 -0
  444. package/dist/client/assets/pegDiagram-XKGWAZYB-fRrxGIDM.js.gz +0 -0
  445. package/dist/client/assets/pieDiagram-E7YTZNPT-B-EBa3qN.js.br +0 -0
  446. package/dist/client/assets/pieDiagram-E7YTZNPT-B-EBa3qN.js.gz +0 -0
  447. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Dj4e6f4h.js.br +0 -0
  448. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Dj4e6f4h.js.gz +0 -0
  449. package/dist/client/assets/railroadDiagram-O6MQD6OU-CEMppxTC.js.br +0 -0
  450. package/dist/client/assets/railroadDiagram-O6MQD6OU-CEMppxTC.js.gz +0 -0
  451. package/dist/client/assets/rdpSession-C5rS-ImV.js +0 -1
  452. package/dist/client/assets/rdpSession-C5rS-ImV.js.br +0 -0
  453. package/dist/client/assets/rdpSession-C5rS-ImV.js.gz +0 -0
  454. package/dist/client/assets/requirementDiagram-BXWQKSXE-Dri1k4_x.js.br +0 -0
  455. package/dist/client/assets/requirementDiagram-BXWQKSXE-Dri1k4_x.js.gz +0 -0
  456. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CMsL_tYL.js.br +0 -0
  457. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CMsL_tYL.js.gz +0 -0
  458. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-4_4hZtOd.js.br +0 -0
  459. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-4_4hZtOd.js.gz +0 -0
  460. package/dist/client/assets/settings-2-iGqzPez0.js +0 -1
  461. package/dist/client/assets/sizeCapture-INFHLROL-3QA6qj2j.js.br +0 -0
  462. package/dist/client/assets/sizeCapture-INFHLROL-3QA6qj2j.js.gz +0 -0
  463. package/dist/client/assets/stateDiagram-D77RDMKH-90IFPhD9.js.br +0 -0
  464. package/dist/client/assets/stateDiagram-D77RDMKH-90IFPhD9.js.gz +0 -0
  465. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CH-yvmL4.js +0 -1
  466. package/dist/client/assets/swimlanes-42K2YHIH-BuHieVWC.js.br +0 -0
  467. package/dist/client/assets/swimlanes-42K2YHIH-BuHieVWC.js.gz +0 -0
  468. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-P_rDqbtg.js +0 -8
  469. package/dist/client/assets/swiper-DJjq1TYT.js +0 -1
  470. package/dist/client/assets/swiper-DJjq1TYT.js.br +0 -0
  471. package/dist/client/assets/swiper-DJjq1TYT.js.gz +0 -0
  472. package/dist/client/assets/syntaxHighlight-Cz6TPDW9.js +0 -4
  473. package/dist/client/assets/syntaxHighlight-Cz6TPDW9.js.br +0 -0
  474. package/dist/client/assets/syntaxHighlight-Cz6TPDW9.js.gz +0 -0
  475. package/dist/client/assets/terminal-Dea8wJF3.js.br +0 -0
  476. package/dist/client/assets/terminal-Dea8wJF3.js.gz +0 -0
  477. package/dist/client/assets/timeline-definition-24CTP7MA-C7FpaNwf.js.br +0 -0
  478. package/dist/client/assets/timeline-definition-24CTP7MA-C7FpaNwf.js.gz +0 -0
  479. package/dist/client/assets/triangle-alert-Oj-OsZDw.js +0 -1
  480. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js +0 -1
  481. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.br +0 -0
  482. package/dist/client/assets/use-gesture-react.esm-DYpdiE_k.js.gz +0 -0
  483. package/dist/client/assets/vennDiagram-4TSXK5OY-CxoHHVcs.js.br +0 -0
  484. package/dist/client/assets/vennDiagram-4TSXK5OY-CxoHHVcs.js.gz +0 -0
  485. package/dist/client/assets/videoCompression-rr2lu3uy.js.br +0 -0
  486. package/dist/client/assets/videoCompression-rr2lu3uy.js.gz +0 -0
  487. package/dist/client/assets/wardleyDiagram-VM6X3IG4-B4Hsh-Ad.js.br +0 -0
  488. package/dist/client/assets/wardleyDiagram-VM6X3IG4-B4Hsh-Ad.js.gz +0 -0
  489. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CghzsxQv.js.br +0 -0
  490. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CghzsxQv.js.gz +0 -0
@@ -4,15 +4,15 @@ import { dirname, resolve } from 'node:path';
4
4
  import WebSocket from 'ws';
5
5
  import QRCode from 'qrcode';
6
6
  import { RelayClient } from './relay.js';
7
+ import { openServiceSocket } from './serviceTransport.js';
8
+ import { serviceEndpoint } from './connectionModel.js';
7
9
  function secureEndpoint(value, endpoint) {
8
10
  const url = new URL(value);
9
11
  if (!['https:', 'wss:'].includes(url.protocol) || url.username || url.password || url.search || url.hash)
10
12
  throw new Error('Federation relay URLs must use HTTPS/WSS without credentials, query or fragment');
11
13
  if (url.pathname !== '/' && url.pathname !== endpoint)
12
14
  throw new Error('Federation relay URL must be a service origin or the exact tunnel endpoint');
13
- url.protocol = 'wss:';
14
- url.pathname = endpoint;
15
- return url.toString();
15
+ return serviceEndpoint(url.origin, endpoint === '/api/federation/relay' ? 'relay' : 'secure').href;
16
16
  }
17
17
  export function parseRelayConfig(value) {
18
18
  if (!value || typeof value !== 'object' || Array.isArray(value))
@@ -30,47 +30,12 @@ export function parseRelayConfig(value) {
30
30
  }
31
31
  return structuredClone(v);
32
32
  }
33
- function connect(url, ca, sockets, token, readyHandshake = false) {
34
- return new Promise((accept, reject) => {
35
- const ws = new WebSocket(url, { ca, rejectUnauthorized: true, followRedirects: false, handshakeTimeout: 10_000, maxPayload: 256 * 1024, ...(token ? { headers: { Authorization: `Bearer ${token}` } } : {}) });
36
- sockets.add(ws);
37
- ws.once('close', () => sockets.delete(ws));
38
- const failed = () => { ws.terminate(); reject(new Error('Secure relay connection failed')); };
39
- ws.once('error', failed);
40
- ws.once('close', failed);
41
- ws.once('open', () => {
42
- ws.off('error', failed);
43
- ws.off('close', failed);
44
- ws.on('error', () => ws.terminate());
45
- if (readyHandshake)
46
- void awaitReady(ws).then(() => accept(ws), reject);
47
- else
48
- accept(ws);
49
- });
50
- });
51
- }
52
- async function awaitReady(ws) {
53
- return new Promise((accept, reject) => {
54
- const timer = setTimeout(() => fail(), 10_000);
55
- const cleanup = () => { clearTimeout(timer); ws.off('message', ready); ws.off('close', fail); };
56
- const fail = () => { cleanup(); ws.terminate(); reject(new Error('Relay authentication failed')); };
57
- const ready = (raw) => {
58
- try {
59
- const frame = JSON.parse(raw.toString());
60
- if (frame.type !== 'ready') {
61
- fail();
62
- return;
63
- }
64
- cleanup();
65
- accept();
66
- }
67
- catch {
68
- fail();
69
- }
70
- };
71
- ws.once('message', ready);
72
- ws.once('close', fail);
73
- });
33
+ async function connect(url, ca, sockets, token, readyHandshake = false, signal) {
34
+ const ws = await openServiceSocket(url, { ca }, { maxPayload: 256 * 1024, handshakeTimeout: 10_000, relayReady: readyHandshake, signal,
35
+ ...(token ? { headers: { Authorization: `Bearer ${token}` } } : {}) });
36
+ sockets.add(ws);
37
+ ws.once('close', () => sockets.delete(ws));
38
+ return ws;
74
39
  }
75
40
  export function pairingInviteUrl(serviceId, code, value) {
76
41
  const url = new URL(value);
@@ -131,11 +96,12 @@ export async function runFederationCli(args) {
131
96
  const loadCa = (file) => file ? readFileSync(resolve(dirname(configPath), file)) : undefined;
132
97
  const entryCa = loadCa(config.caPath);
133
98
  const targets = config.targets.map(t => ({ ...t, ca: loadCa(t.caPath ?? config.caPath) }));
99
+ const lifetime = new AbortController();
134
100
  const sockets = new Set();
135
101
  let stopped = false;
136
102
  let client;
137
103
  let wake;
138
- const stop = () => { stopped = true; wake?.(); client?.close(); for (const socket of sockets)
104
+ const stop = () => { stopped = true; lifetime.abort(); wake?.(); client?.close(); for (const socket of sockets)
139
105
  socket.terminate(); };
140
106
  process.once('SIGINT', stop);
141
107
  process.once('SIGTERM', stop);
@@ -143,12 +109,12 @@ export async function runFederationCli(args) {
143
109
  try {
144
110
  while (!stopped) {
145
111
  try {
146
- const upstream = await connect(secureEndpoint(config.entryUrl, '/api/federation/relay'), entryCa, sockets, config.relayToken, true);
112
+ const upstream = await connect(secureEndpoint(config.entryUrl, '/api/federation/relay'), entryCa, sockets, config.relayToken, true, lifetime.signal);
147
113
  if (stopped) {
148
114
  upstream.terminate();
149
115
  break;
150
116
  }
151
- client = new RelayClient(upstream, { targets: new Map(targets.map(t => [t.serviceId, () => connect(secureEndpoint(t.url, '/api/federation/secure'), t.ca, sockets)])) });
117
+ client = new RelayClient(upstream, { targets: new Map(targets.map(t => [t.serviceId, (signal) => connect(secureEndpoint(t.url, '/api/federation/secure'), t.ca, sockets, undefined, false, AbortSignal.any([signal, lifetime.signal]))])) });
152
118
  process.stderr.write('加密中继已连接。\n');
153
119
  delay = 1000;
154
120
  await new Promise(done => { if (upstream.readyState !== WebSocket.OPEN)
@@ -0,0 +1,37 @@
1
+ const messages = {
2
+ RELAY_AUTHORIZATION_REQUIRED: '没有有效中转授权', TARGET_AUTHORIZATION_REQUIRED: '目标服务需要重新登录',
3
+ PERMISSION_DENIED: '当前权限不允许此操作', TARGET_IDENTITY_MISMATCH: '服务身份与保存的身份不一致',
4
+ RELAY_SELF_TARGET: '不能通过服务中转到其自身;同一服务的其它地址请添加为备用地址。',
5
+ };
6
+ export class ConnectionAccessError extends Error {
7
+ code;
8
+ context;
9
+ name = 'ConnectionAccessError';
10
+ constructor(code, context = {}) {
11
+ super(messages[code]);
12
+ this.code = code;
13
+ this.context = context;
14
+ }
15
+ }
16
+ export function connectionAccessError(error, context = {}) {
17
+ if (error instanceof ConnectionAccessError) {
18
+ Object.assign(error.context, { ...context, ...error.context });
19
+ return error;
20
+ }
21
+ // Retained workspaces/test module reloads can carry the same protocol error
22
+ // from another module instance. Never accept arbitrary messages as a code.
23
+ if (error instanceof Error && error.name === 'ConnectionAccessError' && 'code' in error
24
+ && typeof error.code === 'string' && Object.hasOwn(messages, error.code)) {
25
+ return new ConnectionAccessError(error.code, context);
26
+ }
27
+ if (error instanceof Error && error.name === 'UnexpectedPeerError')
28
+ return new ConnectionAccessError('TARGET_IDENTITY_MISMATCH', context);
29
+ return undefined;
30
+ }
31
+ export function relayAuthorizationError(error, context) {
32
+ if (error instanceof Error && (error.message === 'AUTHORIZATION_DENIED'
33
+ || error instanceof ConnectionAccessError && error.code === 'PERMISSION_DENIED')) {
34
+ return new ConnectionAccessError('RELAY_AUTHORIZATION_REQUIRED', context);
35
+ }
36
+ return error instanceof Error ? error : new Error('中转连接暂不可用');
37
+ }
@@ -0,0 +1,83 @@
1
+ import { ConnectionAccessError } from './connectionErrors.js';
2
+ export const MAX_SAVED_ROUTES = 4;
3
+ export function normalizeServiceAddress(value) {
4
+ if (typeof value !== 'string' || !value.trim() || value.length > 2048)
5
+ throw new Error('请输入服务地址。');
6
+ const raw = value.trim();
7
+ const url = new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(raw) ? raw : `https://${raw}`);
8
+ if (url.protocol === 'wss:')
9
+ url.protocol = 'https:';
10
+ if (url.protocol === 'ws:')
11
+ url.protocol = 'http:';
12
+ const loopback = ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname);
13
+ if (!['https:', 'http:'].includes(url.protocol) || url.protocol === 'http:' && !loopback)
14
+ throw new Error('请使用 HTTPS 服务地址。');
15
+ if (url.username || url.password || url.search || url.hash || !['/', '/api/federation/secure'].includes(url.pathname))
16
+ throw new Error('请输入服务首页地址,不要包含账号或额外参数。');
17
+ return url.origin;
18
+ }
19
+ export function normalizedRoutes(record) {
20
+ if (record.entryServiceId && record.entryServiceId === record.targetPeerId)
21
+ throw new ConnectionAccessError('RELAY_SELF_TARGET', { entryServiceId: record.entryServiceId, targetServiceId: record.targetPeerId });
22
+ const candidates = Array.isArray(record.routes) ? record.routes.slice(0, 64) : [];
23
+ if (record.entryServiceId)
24
+ candidates.unshift({ url: record.url, targetPeerId: record.entryServiceId });
25
+ const seen = new Set();
26
+ return candidates.flatMap(route => {
27
+ try {
28
+ if (!route || typeof route.targetPeerId !== 'string' || !/^[a-zA-Z0-9_.:-]{1,160}$/.test(route.targetPeerId))
29
+ return [];
30
+ const url = normalizeServiceAddress(route.url), key = JSON.stringify([route.targetPeerId, url]);
31
+ if (seen.has(key))
32
+ return [];
33
+ seen.add(key);
34
+ return [{ url, targetPeerId: route.targetPeerId }];
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ }).slice(0, MAX_SAVED_ROUTES);
40
+ }
41
+ export function relayConnectionRoutes(record) {
42
+ return normalizedRoutes(record).filter(route => route.targetPeerId !== record.targetPeerId);
43
+ }
44
+ export function directConnectionAddresses(record) {
45
+ const routes = normalizedRoutes(record);
46
+ const entryUrls = new Set(routes.filter(route => route.targetPeerId !== record.targetPeerId).map(route => route.url));
47
+ const candidates = [record.serviceOrigin || record.url, ...routes.filter(route => route.targetPeerId === record.targetPeerId).map(route => route.url)];
48
+ const result = new Set();
49
+ for (const value of candidates)
50
+ try {
51
+ const address = normalizeServiceAddress(value);
52
+ if (!entryUrls.has(address))
53
+ result.add(address);
54
+ }
55
+ catch { /* An invalid address cannot substitute for a saved identity. */ }
56
+ return [...result];
57
+ }
58
+ export function hasIndependentConnectionRoute(record, deniedEntryServiceId, excludedEntries = new Set()) {
59
+ return directConnectionAddresses(record).length > 0
60
+ || !!deniedEntryServiceId && relayConnectionRoutes(record).some(route => route.targetPeerId !== deniedEntryServiceId && !excludedEntries.has(route.targetPeerId));
61
+ }
62
+ /** Run after merges, including imports from old native clients. Otherwise an
63
+ * omitted serviceOrigin can retain an old entry URL from the previous record. */
64
+ export function canonicalConnectionRouting(record) {
65
+ const result = { ...record, url: normalizeServiceAddress(record.url) };
66
+ const routes = normalizedRoutes(record);
67
+ if (record.routes !== undefined)
68
+ result.routes = routes;
69
+ if (record.serviceOrigin) {
70
+ const origin = normalizeServiceAddress(record.serviceOrigin);
71
+ if (routes.some(route => route.targetPeerId !== record.targetPeerId && route.url === origin))
72
+ delete result.serviceOrigin;
73
+ else
74
+ result.serviceOrigin = origin;
75
+ }
76
+ return result;
77
+ }
78
+ export function serviceEndpoint(address, kind = 'secure') {
79
+ const url = new URL(normalizeServiceAddress(address));
80
+ url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
81
+ url.pathname = `/api/federation/${kind}`;
82
+ return url;
83
+ }
@@ -1,4 +1,6 @@
1
1
  import { readFileSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { directConnectionAddresses } from './connectionModel.js';
2
4
  const peer = (value) => typeof value === 'string' && /^[a-zA-Z0-9_.:-]{1,160}$/.test(value);
3
5
  const fingerprint = (value) => typeof value === 'string' && /^(?:[\da-f]{2}:){31}[\da-f]{2}$/i.test(value);
4
6
  function origin(value) {
@@ -18,7 +20,7 @@ function origin(value) {
18
20
  * have been pinned there before its administrator can discover other entries.
19
21
  * This supplies addresses, never the Desktop client's device authorization.
20
22
  */
21
- export function desktopDirectTargets(file, localServiceId) {
23
+ export function desktopDirectTargets(file, localServiceId, format = 'electron') {
22
24
  if (!localServiceId)
23
25
  return [];
24
26
  try {
@@ -27,7 +29,8 @@ export function desktopDirectTargets(file, localServiceId) {
27
29
  const data = JSON.parse(readFileSync(file, 'utf8'));
28
30
  if (data?.version !== 1 || !Array.isArray(data.connections) || data.connections.length > 256)
29
31
  return [];
30
- const removed = new Set(Array.isArray(data.removedServiceKeys) ? data.removedServiceKeys : []);
32
+ const removedKeys = format === 'preview' ? data.removedKeys : data.removedServiceKeys;
33
+ const removed = new Set(Array.isArray(removedKeys) ? removedKeys : []);
31
34
  const connections = data.connections.filter((item) => item && ![item.id, item.targetPeerId, item.serviceOrigin || item.url].some(key => removed.has(key)));
32
35
  if (!connections.some((item) => item.targetPeerId === localServiceId))
33
36
  return [];
@@ -42,17 +45,23 @@ export function desktopDirectTargets(file, localServiceId) {
42
45
  for (const item of connections) {
43
46
  if (!peer(item.targetPeerId) || item.targetPeerId === localServiceId)
44
47
  continue;
45
- const url = origin(item.serviceOrigin || item.url);
46
- if (!url)
47
- continue;
48
- // An entry-only bookmark does not supply a direct address for its target.
49
- if ((!item.serviceOrigin && item.entryServiceId && item.entryServiceId !== item.targetPeerId)
50
- || (Array.isArray(item.routes) && item.routes.some((route) => route && route.targetPeerId !== item.targetPeerId && origin(route.url) === url)))
51
- continue;
52
- const caFingerprint256 = trusts.get(url);
53
- targets.set(item.targetPeerId, { serviceId: item.targetPeerId, url,
54
- ...(typeof item.label === 'string' && item.label.trim() ? { label: item.label.trim().slice(0, 120) } : {}),
55
- ...(caFingerprint256 ? { caFingerprint256 } : {}) });
48
+ for (const address of directConnectionAddresses(item)) {
49
+ const url = origin(address);
50
+ if (!url)
51
+ continue;
52
+ const caFingerprint256 = trusts.get(url);
53
+ const pin = format === 'preview' ? data.certificatePins?.[url] : undefined;
54
+ // Preview pins the leaf certificate, whereas Electron approves a CA.
55
+ // Never reinterpret one as the other or discard an invalid saved pin.
56
+ if (pin !== undefined && (typeof pin !== 'string' || !/^[\da-f]{64}$/i.test(pin)))
57
+ continue;
58
+ targets.set(JSON.stringify([item.targetPeerId, url]), { serviceId: item.targetPeerId, url,
59
+ ...(typeof item.label === 'string' && item.label.trim() ? { label: item.label.trim().slice(0, 120) } : {}),
60
+ ...(format === 'electron' && caFingerprint256 ? { caFingerprint256 } : {}),
61
+ ...(pin ? { certificateFingerprint256: pin.toUpperCase() } : {}) });
62
+ if (targets.size >= 64)
63
+ break;
64
+ }
56
65
  if (targets.size >= 64)
57
66
  break;
58
67
  }
@@ -62,3 +71,16 @@ export function desktopDirectTargets(file, localServiceId) {
62
71
  return [];
63
72
  }
64
73
  }
74
+ /** Both installations keep their own bookmarks and trust. Reading Preview's
75
+ * native directory also supports already-installed Preview apps, without
76
+ * copying credentials or overwriting the Electron configuration. */
77
+ export function desktopServiceTargets(home, localServiceId, platform = process.platform) {
78
+ const previewRoot = platform === 'darwin' ? join(home, 'Library', 'Application Support')
79
+ : platform === 'win32' ? process.env.APPDATA || join(home, 'AppData', 'Roaming')
80
+ : process.env.XDG_CONFIG_HOME || join(home, '.config');
81
+ const key = (target) => JSON.stringify([target.serviceId, target.url]);
82
+ const targets = new Map(desktopDirectTargets(join(home, '.termdock', 'desktop.json'), localServiceId).map(target => [key(target), target]));
83
+ for (const target of desktopDirectTargets(join(previewRoot, 'com.jovines.termdock.preview', 'connections.json'), localServiceId, 'preview'))
84
+ targets.set(key(target), target);
85
+ return [...targets.values()].slice(0, 64);
86
+ }
@@ -1,20 +1,19 @@
1
- import { readPinnedCertificateAuthority } from './trustedCa.js';
2
1
  import { createIdentity, secureConnection } from './secureProtocol.js';
3
2
  import { socketDuplex } from './socketDuplex.js';
4
- import { readFileSync } from 'node:fs';
5
- import { resolve } from 'node:path';
6
- import WebSocket from 'ws';
3
+ import { openServiceSocket } from './serviceTransport.js';
4
+ import { serviceEndpoint } from './connectionModel.js';
7
5
  function endpoint(config) {
8
- if (!config || typeof config !== 'object' || Object.keys(config).some(key => !['serviceId', 'url', 'caPath', 'caFingerprint256', 'label'].includes(key)) || !/^[a-zA-Z0-9_.:-]{1,160}$/.test(config.serviceId) || typeof config.url !== 'string' || (config.caPath !== undefined && typeof config.caPath !== 'string'))
6
+ if (!config || typeof config !== 'object' || Object.keys(config).some(key => !['serviceId', 'url', 'caPath', 'caFingerprint256', 'certificateFingerprint256', 'label'].includes(key)) || !/^[a-zA-Z0-9_.:-]{1,160}$/.test(config.serviceId) || typeof config.url !== 'string' || (config.caPath !== undefined && typeof config.caPath !== 'string'))
9
7
  throw new Error('Invalid direct target configuration');
10
8
  if ((config.caFingerprint256 !== undefined && (typeof config.caFingerprint256 !== 'string' || !/^(?:[\da-f]{2}:){31}[\da-f]{2}$/i.test(config.caFingerprint256))) || (config.caPath && config.caFingerprint256) || (config.label !== undefined && (typeof config.label !== 'string' || config.label.length > 120)))
11
9
  throw new Error('Invalid direct target metadata');
10
+ if (config.certificateFingerprint256 !== undefined && (typeof config.certificateFingerprint256 !== 'string' || !/^[\da-f]{64}$/i.test(config.certificateFingerprint256)
11
+ || config.caPath !== undefined || config.caFingerprint256 !== undefined))
12
+ throw new Error('Invalid direct target certificate pin');
12
13
  const url = new URL(config.url);
13
14
  if (!['https:', 'wss:'].includes(url.protocol) || url.username || url.password || url.search || url.hash || !['/', '/api/federation/secure'].includes(url.pathname))
14
15
  throw new Error('Direct targets require a verified HTTPS/WSS origin');
15
- url.protocol = 'wss:';
16
- url.pathname = '/api/federation/secure';
17
- return url.toString();
16
+ return serviceEndpoint(url.origin).href;
18
17
  }
19
18
  /** Registers only administrator-configured destinations. TLS validation and redirect
20
19
  * refusal apply even though the inner session also has end-to-end encryption. */
@@ -24,37 +23,32 @@ export function attachRegisteredDirectTargets(router, configs, baseDir = process
24
23
  const ids = new Set();
25
24
  const targets = configs.map(config => {
26
25
  const url = endpoint(config);
27
- if (ids.has(config.serviceId))
28
- throw new Error('Duplicate direct target');
29
- ids.add(config.serviceId);
30
- return { serviceId: config.serviceId, url, caFingerprint256: config.caFingerprint256, ca: config.caPath ? readFileSync(resolve(baseDir, config.caPath)) : undefined };
26
+ const key = JSON.stringify([config.serviceId, url]);
27
+ if (ids.has(key))
28
+ throw new Error('Duplicate direct target address');
29
+ ids.add(key);
30
+ return { config, serviceId: config.serviceId, url };
31
31
  });
32
32
  let stopped = false;
33
33
  const sockets = new Set();
34
34
  const cleanups = [];
35
- const cleanup = () => { stopped = true; for (const close of cleanups.splice(0))
35
+ const lifetime = new AbortController();
36
+ const cleanup = () => { stopped = true; lifetime.abort(); for (const close of cleanups.splice(0))
36
37
  close(); for (const ws of sockets)
37
38
  ws.terminate(); };
38
39
  try {
39
40
  for (const target of targets)
40
- cleanups.push(router.registerDirect(target.serviceId, async () => {
41
- const ca = target.caFingerprint256 ? await readPinnedCertificateAuthority(target.url.replace(/^wss:/, 'https:'), target.caFingerprint256) : target.ca;
42
- return new Promise((accept, reject) => {
43
- if (stopped) {
44
- reject(new Error('Direct target stopped'));
45
- return;
46
- }
47
- const ws = new WebSocket(target.url, { ca, rejectUnauthorized: true, followRedirects: false, handshakeTimeout: 10000, maxPayload: 256 * 1024 });
48
- sockets.add(ws);
49
- ws.once('close', () => sockets.delete(ws));
50
- const failed = () => { reject(new Error('Direct target unavailable')); ws.terminate(); };
51
- ws.once('error', failed);
52
- ws.once('close', failed);
53
- ws.once('open', () => { ws.off('error', failed); ws.off('close', failed); ws.on('error', () => ws.terminate()); if (stopped)
54
- failed();
55
- else
56
- accept(ws); });
57
- });
41
+ cleanups.push(router.registerDirect(target.serviceId, async (signal) => {
42
+ if (stopped)
43
+ throw new Error('Direct target stopped');
44
+ const ws = await openServiceSocket(target.url, target.config, { baseDir, maxPayload: 256 * 1024, handshakeTimeout: 10000, signal: AbortSignal.any([signal, lifetime.signal]) });
45
+ if (stopped) {
46
+ ws.terminate();
47
+ throw new Error('Direct target stopped');
48
+ }
49
+ sockets.add(ws);
50
+ ws.once('close', () => sockets.delete(ws));
51
+ return ws;
58
52
  }));
59
53
  }
60
54
  catch (error) {
@@ -65,14 +59,12 @@ export function attachRegisteredDirectTargets(router, configs, baseDir = process
65
59
  }
66
60
  /** An administrator enabling a new backup first proves the target's pinned
67
61
  * identity; HTTPS validation remains enabled throughout. */
68
- export async function verifyDirectTarget(config) {
62
+ export async function verifyDirectTarget(config, baseDir = process.cwd(), signal) {
69
63
  const url = endpoint(config);
70
- const ca = config.caFingerprint256 ? await readPinnedCertificateAuthority(url.replace(/^wss:/, 'https:'), config.caFingerprint256) : config.caPath ? readFileSync(config.caPath) : undefined;
71
- const ws = new WebSocket(url, { ca, rejectUnauthorized: true, followRedirects: false, handshakeTimeout: 5000, maxPayload: 256 * 1024 });
64
+ const ws = await openServiceSocket(url, config, { baseDir, maxPayload: 256 * 1024, signal });
72
65
  const duplex = socketDuplex(ws);
73
66
  try {
74
- await new Promise((resolve, reject) => { ws.once('open', resolve); ws.once('error', reject); ws.once('close', () => reject(new Error('Target closed'))); });
75
- await secureConnection({ identity: await createIdentity(), initiator: true, targetPinnedPeerId: config.serviceId, duplex, signal: AbortSignal.timeout(5000) });
67
+ await secureConnection({ identity: await createIdentity(), initiator: true, targetPinnedPeerId: config.serviceId, duplex, signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(5000)]) : AbortSignal.timeout(5000) });
76
68
  }
77
69
  finally {
78
70
  ws.close();
@@ -0,0 +1,106 @@
1
+ import { attachRegisteredDirectTargets, verifyDirectTarget } from './directRoutes.js';
2
+ import { normalizeServiceAddress } from './connectionModel.js';
3
+ /** A static configuration is a claim, not proof that its URL serves its ID.
4
+ * Advertise direct providers only after a real TLS + pinned Noise handshake.
5
+ * Reverse providers remain independent and keep working during these checks. */
6
+ export class DirectTargetRegistry {
7
+ router;
8
+ baseDir;
9
+ now;
10
+ states = new Map();
11
+ stopped = false;
12
+ activeChecks = 0;
13
+ constructor(router, baseDir, now = () => performance.now()) {
14
+ this.router = router;
15
+ this.baseDir = baseDir;
16
+ this.now = now;
17
+ }
18
+ refresh(targets) {
19
+ if (this.stopped)
20
+ return;
21
+ const desired = new Map(targets.map(target => [this.key(target), target]));
22
+ const signature = (target) => JSON.stringify([target.url, target.caPath, target.caFingerprint256, target.certificateFingerprint256]);
23
+ for (const [id, state] of this.states) {
24
+ const target = desired.get(id);
25
+ if (!target || signature(target) !== state.signature) {
26
+ state.controller?.abort();
27
+ state.close?.();
28
+ this.states.delete(id);
29
+ }
30
+ }
31
+ for (const [id, target] of desired) {
32
+ let state = this.states.get(id);
33
+ if (!state) {
34
+ state = { target, signature: signature(target), checking: false, nextCheck: 0, error: 'TARGET_CHECKING' };
35
+ this.states.set(id, state);
36
+ }
37
+ state.target = target;
38
+ }
39
+ this.pump();
40
+ }
41
+ key(target) { return JSON.stringify([target.serviceId, normalizeServiceAddress(target.url)]); }
42
+ providers(serviceId) { return [...this.states.values()].filter(state => state.target.serviceId === serviceId); }
43
+ pump() {
44
+ if (this.stopped)
45
+ return;
46
+ for (const state of this.states.values()) {
47
+ if (this.activeChecks >= 4)
48
+ break;
49
+ if (!state.checking && this.now() >= state.nextCheck)
50
+ void this.check(state.target, state);
51
+ }
52
+ }
53
+ error(serviceId) {
54
+ const states = this.providers(serviceId);
55
+ if (states.some(state => state.close))
56
+ return;
57
+ return ['TARGET_CHECKING', 'TARGET_IDENTITY_MISMATCH', 'TARGET_UNREACHABLE'].find(error => states.some(state => state.error === error));
58
+ }
59
+ describe(target) {
60
+ const state = this.providers(target.serviceId).find(provider => provider.close);
61
+ const available = this.router.hasRoute(target.serviceId);
62
+ // A valid reverse tunnel may coexist with an incorrect static URL. Do not
63
+ // borrow the unverified URL/name and make A look like the entry B.
64
+ const metadata = state ? { serviceId: target.serviceId, url: normalizeServiceAddress(state.target.url), ...(state.target.label ? { label: state.target.label } : {}) }
65
+ : target.url ? { serviceId: target.serviceId } : target;
66
+ const error = this.error(target.serviceId);
67
+ return { ...metadata, available, ...(!available && error ? { error } : {}) };
68
+ }
69
+ async check(target, state) {
70
+ state.checking = true;
71
+ this.activeChecks++;
72
+ const controller = new AbortController();
73
+ state.controller = controller;
74
+ const current = () => !this.stopped && this.states.get(this.key(target)) === state;
75
+ try {
76
+ await verifyDirectTarget(target, this.baseDir, controller.signal);
77
+ if (!current())
78
+ return;
79
+ state.close ??= attachRegisteredDirectTargets(this.router, [target], this.baseDir);
80
+ state.error = undefined;
81
+ state.nextCheck = this.now() + 30_000;
82
+ }
83
+ catch (error) {
84
+ if (!current())
85
+ return;
86
+ state.close?.();
87
+ state.close = undefined;
88
+ state.error = error instanceof Error && error.name === 'UnexpectedPeerError' ? 'TARGET_IDENTITY_MISMATCH' : 'TARGET_UNREACHABLE';
89
+ state.nextCheck = this.now() + 5000;
90
+ }
91
+ finally {
92
+ state.checking = false;
93
+ state.controller = undefined;
94
+ this.activeChecks--;
95
+ this.pump();
96
+ }
97
+ }
98
+ close() {
99
+ this.stopped = true;
100
+ for (const state of this.states.values()) {
101
+ state.controller?.abort();
102
+ state.close?.();
103
+ }
104
+ this.states.clear();
105
+ }
106
+ }
@@ -0,0 +1,8 @@
1
+ const MIB = 1024 * 1024;
2
+ /** File bodies include multipart framing; filesystem handlers still enforce
3
+ * the 100 MiB attachment limit. This budget never grants endpoint access. */
4
+ export function httpUploadLimit(pathname) {
5
+ const fileUpload = pathname === '/api/terminal/fs/upload'
6
+ || /^\/api\/terminal\/[^/]+\/chat\/attachments$/.test(pathname);
7
+ return (fileUpload ? 110 : 5) * MIB;
8
+ }
@@ -1,7 +1,7 @@
1
- import { RELAY_PROVIDER_CONNECT_TIMEOUT_MS, RELAY_ROUTE_OPEN_TIMEOUT_MS } from './streamLimits.js';
1
+ import { RELAY_PROVIDER_CONNECT_TIMEOUT_MS, RELAY_ROUTE_OPEN_TIMEOUT_MS, RELAY_MAX_FRAME_BYTES, RELAY_MAX_BUFFERED_BYTES } from './streamLimits.js';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { EventEmitter } from 'node:events';
4
- const defaults = { maxFrameBytes: 256 * 1024, maxBufferedBytes: 1024 * 1024,
4
+ const defaults = { maxFrameBytes: RELAY_MAX_FRAME_BYTES, maxBufferedBytes: RELAY_MAX_BUFFERED_BYTES,
5
5
  maxStreams: 128, heartbeatMs: 30_000, maxRouteTtlMs: 90_000, connectTimeoutMs: RELAY_PROVIDER_CONNECT_TIMEOUT_MS, routeTimeoutMs: RELAY_ROUTE_OPEN_TIMEOUT_MS };
6
6
  const identifier = (v) => typeof v === 'string' && /^[a-zA-Z0-9_.:-]{1,160}$/.test(v);
7
7
  function parse(raw, limits) {
@@ -118,15 +118,16 @@ export class RelayRouter {
118
118
  .map(([peer]) => peer);
119
119
  }
120
120
  hasRoute(serviceId) {
121
- return !this.stopped && this.providers(serviceId).length > 0;
121
+ return this.providerCount(serviceId) > 0;
122
122
  }
123
+ providerCount(serviceId) { return this.stopped ? 0 : this.providers(serviceId).length; }
123
124
  activeRouteIds() {
124
125
  return [...this.routes.keys()].filter(serviceId => this.hasRoute(serviceId));
125
126
  }
126
127
  /** Trusted local configuration only. Clients never supply a target URL or factory. */
127
128
  registerDirect(serviceId, connect) {
128
- if (this.stopped || !identifier(serviceId) || typeof connect !== 'function' || [...this.peers].some(peer => this.directPeers.get(peer) === serviceId))
129
- throw new Error('Invalid or already registered direct target');
129
+ if (this.stopped || !identifier(serviceId) || typeof connect !== 'function')
130
+ throw new Error('Invalid direct target');
130
131
  const [routerWire, clientWire] = memoryPair();
131
132
  // The private WeakMap marks this peer; its placeholder principal is never
132
133
  // passed to externally supplied authentication/authorization callbacks.
@@ -342,6 +343,7 @@ export class RelayClient {
342
343
  streams = new Map();
343
344
  renewal;
344
345
  pending = new Map();
346
+ connecting = new Map();
345
347
  stopped = false;
346
348
  constructor(upstream, options) {
347
349
  this.upstream = upstream;
@@ -358,6 +360,8 @@ export class RelayClient {
358
360
  drop(id, reason) {
359
361
  clearTimeout(this.pending.get(id));
360
362
  this.pending.delete(id);
363
+ this.connecting.get(id)?.abort();
364
+ this.connecting.delete(id);
361
365
  const target = this.streams.get(id);
362
366
  this.streams.delete(id);
363
367
  target?.close();
@@ -379,9 +383,11 @@ export class RelayClient {
379
383
  const timer = setTimeout(() => { this.drop(f.streamId, 'Target timeout'); }, this.limits.connectTimeoutMs);
380
384
  timer.unref?.();
381
385
  this.pending.set(f.streamId, timer);
386
+ const controller = new AbortController();
387
+ this.connecting.set(f.streamId, controller);
382
388
  let target;
383
389
  try {
384
- target = await connect();
390
+ target = await connect(controller.signal);
385
391
  }
386
392
  catch {
387
393
  if (this.pending.get(f.streamId) === timer)
@@ -395,6 +401,7 @@ export class RelayClient {
395
401
  }
396
402
  clearTimeout(timer);
397
403
  this.pending.delete(f.streamId);
404
+ this.connecting.delete(f.streamId);
398
405
  if (target.readyState !== 1) {
399
406
  target.close();
400
407
  this.drop(f.streamId, 'Target not ready');