termdock 1.4.330 → 1.4.332

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 (377) hide show
  1. package/THIRD_PARTY_NOTICES.md +12 -0
  2. package/dist/client/assets/{App-JL8Fd8uO.js → App-BB9Zns7R.js} +37 -37
  3. package/dist/client/assets/App-BB9Zns7R.js.br +0 -0
  4. package/dist/client/assets/App-BB9Zns7R.js.gz +0 -0
  5. package/dist/client/assets/ArchitecturePanel-DCxpe1Bj.js +9 -0
  6. package/dist/client/assets/ArchitecturePanel-DCxpe1Bj.js.br +0 -0
  7. package/dist/client/assets/ArchitecturePanel-DCxpe1Bj.js.gz +0 -0
  8. package/dist/client/assets/{ChangeWalkthroughPanel-BF3p_M6Y.js → ChangeWalkthroughPanel-CAyVfccZ.js} +1 -1
  9. package/dist/client/assets/ChangeWalkthroughPanel-CAyVfccZ.js.br +0 -0
  10. package/dist/client/assets/ChangeWalkthroughPanel-CAyVfccZ.js.gz +0 -0
  11. package/dist/client/assets/CollaborationMainWorkspace-Bey7tYQF.js +1 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-Bey7tYQF.js.br +0 -0
  13. package/dist/client/assets/CollaborationMainWorkspace-Bey7tYQF.js.gz +0 -0
  14. package/dist/client/assets/CollaborationTaskContent-Q5KzPAOz.js +2 -0
  15. package/dist/client/assets/{ComputerControlView-DWlZmlCH.js → ComputerControlView-CojIu02o.js} +3 -3
  16. package/dist/client/assets/ComputerControlView-CojIu02o.js.br +0 -0
  17. package/dist/client/assets/ComputerControlView-CojIu02o.js.gz +0 -0
  18. package/dist/client/assets/{DagPlayground-IbzlcDVX.js → DagPlayground-BeyWYMaL.js} +1 -1
  19. package/dist/client/assets/DagPlayground-BeyWYMaL.js.br +0 -0
  20. package/dist/client/assets/DagPlayground-BeyWYMaL.js.gz +0 -0
  21. package/dist/client/assets/{DiffLab-DEAYEwfY.js → DiffLab-DW3LP4Zk.js} +1 -1
  22. package/dist/client/assets/DiffLab-DW3LP4Zk.js.br +0 -0
  23. package/dist/client/assets/DiffLab-DW3LP4Zk.js.gz +0 -0
  24. package/dist/client/assets/{DiffReview-BPHfC8nZ.js → DiffReview-CsQjyKYd.js} +1 -1
  25. package/dist/client/assets/DiffReview-CsQjyKYd.js.br +0 -0
  26. package/dist/client/assets/DiffReview-CsQjyKYd.js.gz +0 -0
  27. package/dist/client/assets/{DiffReviewLab-2iKu20Ik.js → DiffReviewLab-DRvhZLgu.js} +1 -1
  28. package/dist/client/assets/DiffReviewLab-DRvhZLgu.js.br +0 -0
  29. package/dist/client/assets/DiffReviewLab-DRvhZLgu.js.gz +0 -0
  30. package/dist/client/assets/{DiffViewer-C4S3oEQV.js → DiffViewer-CwTOIjTT.js} +1 -1
  31. package/dist/client/assets/DiffViewer-CwTOIjTT.js.br +0 -0
  32. package/dist/client/assets/DiffViewer-CwTOIjTT.js.gz +0 -0
  33. package/dist/client/assets/{ModelPreview-D_KABt7i.js → ModelPreview-BHmMm0Pj.js} +1 -1
  34. package/dist/client/assets/ModelPreview-BHmMm0Pj.js.br +0 -0
  35. package/dist/client/assets/ModelPreview-BHmMm0Pj.js.gz +0 -0
  36. package/dist/client/assets/RightSidebar-Coc7x6Q-.js +1677 -0
  37. package/dist/client/assets/RightSidebar-Coc7x6Q-.js.br +0 -0
  38. package/dist/client/assets/RightSidebar-Coc7x6Q-.js.gz +0 -0
  39. package/dist/client/assets/{abnfDiagram-VCTEODGH-OAQJcJ5a.js → abnfDiagram-VCTEODGH-wY9KgDKQ.js} +1 -1
  40. package/dist/client/assets/abnfDiagram-VCTEODGH-wY9KgDKQ.js.br +0 -0
  41. package/dist/client/assets/abnfDiagram-VCTEODGH-wY9KgDKQ.js.gz +0 -0
  42. package/dist/client/assets/app-D-AilvVY.js +35 -0
  43. package/dist/client/assets/app-D-AilvVY.js.br +0 -0
  44. package/dist/client/assets/app-D-AilvVY.js.gz +0 -0
  45. package/dist/client/assets/{arc-B29HLhod.js → arc-DVBtoEGf.js} +1 -1
  46. package/dist/client/assets/arc-DVBtoEGf.js.br +0 -0
  47. package/dist/client/assets/arc-DVBtoEGf.js.gz +0 -0
  48. package/dist/client/assets/{architectureDiagram-5GKGNRK7-CQeKeLzl.js → architectureDiagram-5GKGNRK7-CQPsSdTB.js} +1 -1
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-CQPsSdTB.js.br +0 -0
  50. package/dist/client/assets/architectureDiagram-5GKGNRK7-CQPsSdTB.js.gz +0 -0
  51. package/dist/client/assets/{blockDiagram-I7D4REHJ-CgQQGQN_.js → blockDiagram-I7D4REHJ-OB_hCQwv.js} +1 -1
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-OB_hCQwv.js.br +0 -0
  53. package/dist/client/assets/blockDiagram-I7D4REHJ-OB_hCQwv.js.gz +0 -0
  54. package/dist/client/assets/{c4Diagram-7LVT6UL2-BTeUIAS9.js → c4Diagram-7LVT6UL2-Cp72_koy.js} +1 -1
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-Cp72_koy.js.br +0 -0
  56. package/dist/client/assets/c4Diagram-7LVT6UL2-Cp72_koy.js.gz +0 -0
  57. package/dist/client/assets/channel-CYCNCfSN.js +1 -0
  58. package/dist/client/assets/{chunk-2Q5K7J3B-Bao8D59Y.js → chunk-2Q5K7J3B-wZpiUjnH.js} +1 -1
  59. package/dist/client/assets/{chunk-5VM5RSS4-RIpn4ucJ.js → chunk-5VM5RSS4-DZA-nY7e.js} +1 -1
  60. package/dist/client/assets/{chunk-F27PBJKO-Cu3ypVNN.js → chunk-F27PBJKO-DWjLrbpP.js} +1 -1
  61. package/dist/client/assets/chunk-F27PBJKO-DWjLrbpP.js.br +0 -0
  62. package/dist/client/assets/chunk-F27PBJKO-DWjLrbpP.js.gz +0 -0
  63. package/dist/client/assets/{chunk-IMKFNOWR-BioTa0jG.js → chunk-IMKFNOWR-Dmq185X2.js} +1 -1
  64. package/dist/client/assets/chunk-IMKFNOWR-Dmq185X2.js.br +0 -0
  65. package/dist/client/assets/chunk-IMKFNOWR-Dmq185X2.js.gz +0 -0
  66. package/dist/client/assets/{chunk-JWPE2WC7-BPE5l-1s.js → chunk-JWPE2WC7-Bw9j-pi5.js} +1 -1
  67. package/dist/client/assets/{chunk-POPQ4Y6H-DUF-0HB1.js → chunk-POPQ4Y6H-BjWtrh1M.js} +1 -1
  68. package/dist/client/assets/{chunk-SVP7TREG-BHaV6_ki.js → chunk-SVP7TREG-VIH7H3Pr.js} +1 -1
  69. package/dist/client/assets/chunk-SVP7TREG-VIH7H3Pr.js.br +0 -0
  70. package/dist/client/assets/chunk-SVP7TREG-VIH7H3Pr.js.gz +0 -0
  71. package/dist/client/assets/{chunk-TICWLB2K-SU15adqY.js → chunk-TICWLB2K-D8lo3HVO.js} +1 -1
  72. package/dist/client/assets/chunk-TICWLB2K-D8lo3HVO.js.br +0 -0
  73. package/dist/client/assets/chunk-TICWLB2K-D8lo3HVO.js.gz +0 -0
  74. package/dist/client/assets/{chunk-XXDRQBXY-oLy1dZJs.js → chunk-XXDRQBXY-DTbG8Qn9.js} +1 -1
  75. package/dist/client/assets/classDiagram-ZZMXUADV-CV6z7LP1.js +1 -0
  76. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CV6z7LP1.js +1 -0
  77. package/dist/client/assets/{cose-bilkent-JH36ORCC-EE27IbbX.js → cose-bilkent-JH36ORCC-Cey1iRcB.js} +1 -1
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-Cey1iRcB.js.br +0 -0
  79. package/dist/client/assets/cose-bilkent-JH36ORCC-Cey1iRcB.js.gz +0 -0
  80. package/dist/client/assets/{cynefin-OW5HDTMX-CpY9J9iu.js → cynefin-OW5HDTMX-BSP2A8yQ.js} +1 -1
  81. package/dist/client/assets/cynefin-OW5HDTMX-BSP2A8yQ.js.br +0 -0
  82. package/dist/client/assets/cynefin-OW5HDTMX-BSP2A8yQ.js.gz +0 -0
  83. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-mJxcQnkp.js → cynefinDiagram-5FMLGOSQ-Wq4INzwW.js} +1 -1
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Wq4INzwW.js.br +0 -0
  85. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Wq4INzwW.js.gz +0 -0
  86. package/dist/client/assets/{dagre-GXQ25YYZ-DAUZrxwq.js → dagre-GXQ25YYZ-UgOLsTAJ.js} +1 -1
  87. package/dist/client/assets/dagre-GXQ25YYZ-UgOLsTAJ.js.br +0 -0
  88. package/dist/client/assets/dagre-GXQ25YYZ-UgOLsTAJ.js.gz +0 -0
  89. package/dist/client/assets/{diagram-S7CK7UJ4-3rquuCu6.js → diagram-S7CK7UJ4-CXi8ez4a.js} +1 -1
  90. package/dist/client/assets/diagram-S7CK7UJ4-CXi8ez4a.js.br +0 -0
  91. package/dist/client/assets/diagram-S7CK7UJ4-CXi8ez4a.js.gz +0 -0
  92. package/dist/client/assets/{diagram-UQ7AKVKN-CZWjaDbi.js → diagram-UQ7AKVKN-WD44iVkL.js} +1 -1
  93. package/dist/client/assets/diagram-UQ7AKVKN-WD44iVkL.js.br +0 -0
  94. package/dist/client/assets/diagram-UQ7AKVKN-WD44iVkL.js.gz +0 -0
  95. package/dist/client/assets/{diagram-VSXAHHWV-CNQEg3jR.js → diagram-VSXAHHWV-DeeTr7nX.js} +1 -1
  96. package/dist/client/assets/diagram-VSXAHHWV-DeeTr7nX.js.br +0 -0
  97. package/dist/client/assets/diagram-VSXAHHWV-DeeTr7nX.js.gz +0 -0
  98. package/dist/client/assets/{diagram-VX7I27RA-DYorDR1n.js → diagram-VX7I27RA-r3wdM6Nm.js} +1 -1
  99. package/dist/client/assets/diagram-VX7I27RA-r3wdM6Nm.js.br +0 -0
  100. package/dist/client/assets/diagram-VX7I27RA-r3wdM6Nm.js.gz +0 -0
  101. package/dist/client/assets/{diagram-Z3DM3KII-BPgvVftJ.js → diagram-Z3DM3KII-q2jyvUdh.js} +1 -1
  102. package/dist/client/assets/diagram-Z3DM3KII-q2jyvUdh.js.br +0 -0
  103. package/dist/client/assets/diagram-Z3DM3KII-q2jyvUdh.js.gz +0 -0
  104. package/dist/client/assets/{ebnfDiagram-PWID7BFC-KqpJv-fX.js → ebnfDiagram-PWID7BFC-Cb7oWq7z.js} +1 -1
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-Cb7oWq7z.js.br +0 -0
  106. package/dist/client/assets/ebnfDiagram-PWID7BFC-Cb7oWq7z.js.gz +0 -0
  107. package/dist/client/assets/{erDiagram-RLTQ6QDP-Bwj_TPoi.js → erDiagram-RLTQ6QDP-CNuNvK3_.js} +1 -1
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-CNuNvK3_.js.br +0 -0
  109. package/dist/client/assets/erDiagram-RLTQ6QDP-CNuNvK3_.js.gz +0 -0
  110. package/dist/client/assets/{flowDiagram-HODETNUW-BYALZ5I6.js → flowDiagram-HODETNUW-BYdnedTN.js} +1 -1
  111. package/dist/client/assets/flowDiagram-HODETNUW-BYdnedTN.js.br +0 -0
  112. package/dist/client/assets/flowDiagram-HODETNUW-BYdnedTN.js.gz +0 -0
  113. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DwrR8yW_.js → ganttDiagram-EL5Y4UJY-CaxdXqhz.js} +1 -1
  114. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CaxdXqhz.js.br +0 -0
  115. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CaxdXqhz.js.gz +0 -0
  116. package/dist/client/assets/{gestureArbiter-4NWfZprH.js → gestureArbiter-DPJowqRM.js} +1 -1
  117. package/dist/client/assets/gestureArbiter-DPJowqRM.js.br +0 -0
  118. package/dist/client/assets/{gestureArbiter-4NWfZprH.js.gz → gestureArbiter-DPJowqRM.js.gz} +0 -0
  119. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-C3pH5ZGR.js → gitGraphDiagram-WWUBYQGX-DRO8nFRo.js} +1 -1
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DRO8nFRo.js.br +0 -0
  121. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DRO8nFRo.js.gz +0 -0
  122. package/dist/client/assets/index-CRxcDATF.css +1 -0
  123. package/dist/client/assets/index-CRxcDATF.css.br +0 -0
  124. package/dist/client/assets/index-CRxcDATF.css.gz +0 -0
  125. package/dist/client/assets/{infoDiagram-27XIBGKW-DpnbClE9.js → infoDiagram-27XIBGKW-D8154Axl.js} +1 -1
  126. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BFhiY6uy.js → ishikawaDiagram-5VMMS53U-C-m2YcvO.js} +1 -1
  127. package/dist/client/assets/ishikawaDiagram-5VMMS53U-C-m2YcvO.js.br +0 -0
  128. package/dist/client/assets/ishikawaDiagram-5VMMS53U-C-m2YcvO.js.gz +0 -0
  129. package/dist/client/assets/{journeyDiagram-3NMN7TZE-Beg2Cmg4.js → journeyDiagram-3NMN7TZE-BaYbc4fI.js} +1 -1
  130. package/dist/client/assets/journeyDiagram-3NMN7TZE-BaYbc4fI.js.br +0 -0
  131. package/dist/client/assets/journeyDiagram-3NMN7TZE-BaYbc4fI.js.gz +0 -0
  132. package/dist/client/assets/{kanban-definition-UXKFOSKX-CNb51-_F.js → kanban-definition-UXKFOSKX-C4ZmM3W8.js} +1 -1
  133. package/dist/client/assets/kanban-definition-UXKFOSKX-C4ZmM3W8.js.br +0 -0
  134. package/dist/client/assets/kanban-definition-UXKFOSKX-C4ZmM3W8.js.gz +0 -0
  135. package/dist/client/assets/{layout-B07GM-uc.js → layout-TUsrKU-t.js} +1 -1
  136. package/dist/client/assets/layout-TUsrKU-t.js.br +0 -0
  137. package/dist/client/assets/layout-TUsrKU-t.js.gz +0 -0
  138. package/dist/client/assets/{linear-DRJlaLbJ.js → linear-nScEH6bm.js} +1 -1
  139. package/dist/client/assets/linear-nScEH6bm.js.br +0 -0
  140. package/dist/client/assets/linear-nScEH6bm.js.gz +0 -0
  141. package/dist/client/assets/{mermaid.core-BySznxI_.js → mermaid.core-WM_j9CSC.js} +5 -5
  142. package/dist/client/assets/mermaid.core-WM_j9CSC.js.br +0 -0
  143. package/dist/client/assets/mermaid.core-WM_j9CSC.js.gz +0 -0
  144. package/dist/client/assets/{mindmap-definition-YA3MSWOX-BtStMFHK.js → mindmap-definition-YA3MSWOX-D5bLjroL.js} +1 -1
  145. package/dist/client/assets/mindmap-definition-YA3MSWOX-D5bLjroL.js.br +0 -0
  146. package/dist/client/assets/mindmap-definition-YA3MSWOX-D5bLjroL.js.gz +0 -0
  147. package/dist/client/assets/{passwordBootstrap-B-T8YSfQ.js → passwordBootstrap-BHUt4zht.js} +1 -1
  148. package/dist/client/assets/passwordBootstrap-BHUt4zht.js.br +0 -0
  149. package/dist/client/assets/passwordBootstrap-BHUt4zht.js.gz +0 -0
  150. package/dist/client/assets/{pegDiagram-XKGWAZYB-BNJzxFGK.js → pegDiagram-XKGWAZYB-BCJ-HO-6.js} +1 -1
  151. package/dist/client/assets/pegDiagram-XKGWAZYB-BCJ-HO-6.js.br +0 -0
  152. package/dist/client/assets/pegDiagram-XKGWAZYB-BCJ-HO-6.js.gz +0 -0
  153. package/dist/client/assets/{pieDiagram-E7YTZNPT-Df1Y6zou.js → pieDiagram-E7YTZNPT-Dg3u_zy9.js} +1 -1
  154. package/dist/client/assets/pieDiagram-E7YTZNPT-Dg3u_zy9.js.br +0 -0
  155. package/dist/client/assets/pieDiagram-E7YTZNPT-Dg3u_zy9.js.gz +0 -0
  156. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Q3jN6--F.js → quadrantDiagram-AXDQQJYC-Bi9SzqYi.js} +1 -1
  157. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Bi9SzqYi.js.br +0 -0
  158. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Bi9SzqYi.js.gz +0 -0
  159. package/dist/client/assets/{railroadDiagram-O6MQD6OU-c-1SN7pC.js → railroadDiagram-O6MQD6OU-Kbg4uhta.js} +1 -1
  160. package/dist/client/assets/railroadDiagram-O6MQD6OU-Kbg4uhta.js.br +0 -0
  161. package/dist/client/assets/railroadDiagram-O6MQD6OU-Kbg4uhta.js.gz +0 -0
  162. package/dist/client/assets/{rdpSession-B6j6_C4D.js → rdpSession-D_TLn9lr.js} +1 -1
  163. package/dist/client/assets/rdpSession-D_TLn9lr.js.br +0 -0
  164. package/dist/client/assets/rdpSession-D_TLn9lr.js.gz +0 -0
  165. package/dist/client/assets/{referenceLongPress-Bln9X6SW.js → referenceLongPress-CalVNheA.js} +1 -1
  166. package/dist/client/assets/referenceLongPress-CalVNheA.js.br +0 -0
  167. package/dist/client/assets/referenceLongPress-CalVNheA.js.gz +0 -0
  168. package/dist/client/assets/{requirementDiagram-BXWQKSXE-wcsUZu82.js → requirementDiagram-BXWQKSXE-DY1nJYdk.js} +1 -1
  169. package/dist/client/assets/requirementDiagram-BXWQKSXE-DY1nJYdk.js.br +0 -0
  170. package/dist/client/assets/requirementDiagram-BXWQKSXE-DY1nJYdk.js.gz +0 -0
  171. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CfXyROPC.js → sankeyDiagram-P5KCCOFB-Ch9oVvbH.js} +1 -1
  172. package/dist/client/assets/sankeyDiagram-P5KCCOFB-Ch9oVvbH.js.br +0 -0
  173. package/dist/client/assets/sankeyDiagram-P5KCCOFB-Ch9oVvbH.js.gz +0 -0
  174. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-D-IasKbj.js → sequenceDiagram-WJ2MYXX4-BXQhyqVP.js} +1 -1
  175. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BXQhyqVP.js.br +0 -0
  176. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BXQhyqVP.js.gz +0 -0
  177. package/dist/client/assets/{sizeCapture-INFHLROL-Cyoh7jyx.js → sizeCapture-INFHLROL-CHCCkDzJ.js} +1 -1
  178. package/dist/client/assets/sizeCapture-INFHLROL-CHCCkDzJ.js.br +0 -0
  179. package/dist/client/assets/sizeCapture-INFHLROL-CHCCkDzJ.js.gz +0 -0
  180. package/dist/client/assets/{sparkles-kooHQYLJ.js → sparkles-CbQl9qpO.js} +1 -1
  181. package/dist/client/assets/{stateDiagram-D77RDMKH-BFeLYGOW.js → stateDiagram-D77RDMKH-BsAiJFKS.js} +1 -1
  182. package/dist/client/assets/stateDiagram-D77RDMKH-BsAiJFKS.js.br +0 -0
  183. package/dist/client/assets/stateDiagram-D77RDMKH-BsAiJFKS.js.gz +0 -0
  184. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-joTNV3tX.js +1 -0
  185. package/dist/client/assets/{swimlanes-42K2YHIH-BtMhgPB2.js → swimlanes-42K2YHIH-9JFTgCXC.js} +1 -1
  186. package/dist/client/assets/swimlanes-42K2YHIH-9JFTgCXC.js.br +0 -0
  187. package/dist/client/assets/swimlanes-42K2YHIH-9JFTgCXC.js.gz +0 -0
  188. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-C-2Ixi86.js +8 -0
  189. package/dist/client/assets/{timeline-definition-24CTP7MA-BccUO5W0.js → timeline-definition-24CTP7MA-tkuoWWzM.js} +1 -1
  190. package/dist/client/assets/timeline-definition-24CTP7MA-tkuoWWzM.js.br +0 -0
  191. package/dist/client/assets/timeline-definition-24CTP7MA-tkuoWWzM.js.gz +0 -0
  192. package/dist/client/assets/{triangle-alert-rgLWcpfP.js → triangle-alert-DTiOfHLO.js} +1 -1
  193. package/dist/client/assets/{vennDiagram-4TSXK5OY-hNN_O594.js → vennDiagram-4TSXK5OY-CEnwO3RG.js} +1 -1
  194. package/dist/client/assets/vennDiagram-4TSXK5OY-CEnwO3RG.js.br +0 -0
  195. package/dist/client/assets/vennDiagram-4TSXK5OY-CEnwO3RG.js.gz +0 -0
  196. package/dist/client/assets/{videoCompression-DS0r00L6.js → videoCompression-q9AAJQ5R.js} +1 -1
  197. package/dist/client/assets/videoCompression-q9AAJQ5R.js.br +0 -0
  198. package/dist/client/assets/videoCompression-q9AAJQ5R.js.gz +0 -0
  199. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-C6h02bPv.js → wardleyDiagram-VM6X3IG4-BFLZVXWw.js} +1 -1
  200. package/dist/client/assets/wardleyDiagram-VM6X3IG4-BFLZVXWw.js.br +0 -0
  201. package/dist/client/assets/wardleyDiagram-VM6X3IG4-BFLZVXWw.js.gz +0 -0
  202. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DvNnLmXs.js → xychartDiagram-S5SC5T6Z-CyZtg8vv.js} +1 -1
  203. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CyZtg8vv.js.br +0 -0
  204. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CyZtg8vv.js.gz +0 -0
  205. package/dist/client/fonts/MapleMono-Bold.woff2 +0 -0
  206. package/dist/client/fonts/MapleMono-BoldItalic.woff2 +0 -0
  207. package/dist/client/fonts/MapleMono-Italic.woff2 +0 -0
  208. package/dist/client/fonts/MapleMono-OFL.txt +94 -0
  209. package/dist/client/fonts/MapleMono-OFL.txt.br +0 -0
  210. package/dist/client/fonts/MapleMono-OFL.txt.gz +0 -0
  211. package/dist/client/fonts/MapleMono-Regular.woff2 +0 -0
  212. package/dist/client/fonts/terminal/TermdockMaple-Bold-ascii-71449796b4f8.woff2 +0 -0
  213. package/dist/client/fonts/terminal/TermdockMaple-Bold-text-57c71f86a6f8.woff2 +0 -0
  214. package/dist/client/fonts/terminal/TermdockMaple-BoldItalic-ascii-6b6deb59a8cd.woff2 +0 -0
  215. package/dist/client/fonts/terminal/TermdockMaple-BoldItalic-text-b2e1a12c67be.woff2 +0 -0
  216. package/dist/client/fonts/terminal/TermdockMaple-Italic-ascii-cd2f6088ed50.woff2 +0 -0
  217. package/dist/client/fonts/terminal/TermdockMaple-Italic-text-a346c77141da.woff2 +0 -0
  218. package/dist/client/fonts/terminal/TermdockMaple-Regular-ascii-9a80fd4a5743.woff2 +0 -0
  219. package/dist/client/fonts/terminal/TermdockMaple-Regular-text-58438803bf4c.woff2 +0 -0
  220. package/dist/client/fonts/terminal/TermdockPromptIcons-Bold-icons-fa87935d39d0.woff2 +0 -0
  221. package/dist/client/fonts/terminal/TermdockPromptIcons-Regular-icons-0d64d12759b8.woff2 +0 -0
  222. package/dist/client/fonts/terminal/manifest.json +98 -0
  223. package/dist/client/fonts/terminal/manifest.json.br +0 -0
  224. package/dist/client/fonts/terminal/manifest.json.gz +0 -0
  225. package/dist/client/index.html +12 -11
  226. package/dist/client/index.html.br +0 -0
  227. package/dist/client/index.html.gz +0 -0
  228. package/dist/client/sw-encrypted-background.js +1 -1
  229. package/dist/client/sw-encrypted-background.js.br +0 -0
  230. package/dist/client/sw-encrypted-background.js.gz +0 -0
  231. package/dist/client/sw.js +1 -1
  232. package/dist/client/sw.js.br +0 -0
  233. package/dist/client/sw.js.gz +0 -0
  234. package/dist/server/agent/collaborationPeerTransport.js +4 -3
  235. package/dist/server/entry.js +2 -1
  236. package/dist/server/federation/relay.js +121 -37
  237. package/dist/server/federation/selfRelay.js +12 -8
  238. package/dist/server/federation/streamLimits.js +5 -0
  239. package/package.json +1 -1
  240. package/runtime-manifest.json +3 -3
  241. package/scripts/generate-font-subsets.py +64 -9
  242. package/dist/client/assets/App-JL8Fd8uO.js.br +0 -0
  243. package/dist/client/assets/App-JL8Fd8uO.js.gz +0 -0
  244. package/dist/client/assets/ArchitecturePanel-CwvZXpvS.js +0 -9
  245. package/dist/client/assets/ArchitecturePanel-CwvZXpvS.js.br +0 -0
  246. package/dist/client/assets/ArchitecturePanel-CwvZXpvS.js.gz +0 -0
  247. package/dist/client/assets/ChangeWalkthroughPanel-BF3p_M6Y.js.br +0 -0
  248. package/dist/client/assets/ChangeWalkthroughPanel-BF3p_M6Y.js.gz +0 -0
  249. package/dist/client/assets/CollaborationMainWorkspace-CYpn4j_x.js +0 -1
  250. package/dist/client/assets/CollaborationMainWorkspace-CYpn4j_x.js.br +0 -0
  251. package/dist/client/assets/CollaborationMainWorkspace-CYpn4j_x.js.gz +0 -0
  252. package/dist/client/assets/CollaborationTaskContent-BjjX05Cv.js +0 -2
  253. package/dist/client/assets/ComputerControlView-DWlZmlCH.js.br +0 -0
  254. package/dist/client/assets/ComputerControlView-DWlZmlCH.js.gz +0 -0
  255. package/dist/client/assets/DagPlayground-IbzlcDVX.js.br +0 -0
  256. package/dist/client/assets/DagPlayground-IbzlcDVX.js.gz +0 -0
  257. package/dist/client/assets/DiffLab-DEAYEwfY.js.br +0 -0
  258. package/dist/client/assets/DiffLab-DEAYEwfY.js.gz +0 -0
  259. package/dist/client/assets/DiffReview-BPHfC8nZ.js.br +0 -0
  260. package/dist/client/assets/DiffReview-BPHfC8nZ.js.gz +0 -0
  261. package/dist/client/assets/DiffReviewLab-2iKu20Ik.js.br +0 -0
  262. package/dist/client/assets/DiffReviewLab-2iKu20Ik.js.gz +0 -0
  263. package/dist/client/assets/DiffViewer-C4S3oEQV.js.br +0 -0
  264. package/dist/client/assets/DiffViewer-C4S3oEQV.js.gz +0 -0
  265. package/dist/client/assets/ModelPreview-D_KABt7i.js.br +0 -0
  266. package/dist/client/assets/ModelPreview-D_KABt7i.js.gz +0 -0
  267. package/dist/client/assets/RightSidebar-scaBEaFJ.js +0 -1677
  268. package/dist/client/assets/RightSidebar-scaBEaFJ.js.br +0 -0
  269. package/dist/client/assets/RightSidebar-scaBEaFJ.js.gz +0 -0
  270. package/dist/client/assets/abnfDiagram-VCTEODGH-OAQJcJ5a.js.br +0 -0
  271. package/dist/client/assets/abnfDiagram-VCTEODGH-OAQJcJ5a.js.gz +0 -0
  272. package/dist/client/assets/app-aNkllBsm.js +0 -35
  273. package/dist/client/assets/app-aNkllBsm.js.br +0 -0
  274. package/dist/client/assets/app-aNkllBsm.js.gz +0 -0
  275. package/dist/client/assets/arc-B29HLhod.js.br +0 -0
  276. package/dist/client/assets/arc-B29HLhod.js.gz +0 -0
  277. package/dist/client/assets/architectureDiagram-5GKGNRK7-CQeKeLzl.js.br +0 -0
  278. package/dist/client/assets/architectureDiagram-5GKGNRK7-CQeKeLzl.js.gz +0 -0
  279. package/dist/client/assets/blockDiagram-I7D4REHJ-CgQQGQN_.js.br +0 -0
  280. package/dist/client/assets/blockDiagram-I7D4REHJ-CgQQGQN_.js.gz +0 -0
  281. package/dist/client/assets/c4Diagram-7LVT6UL2-BTeUIAS9.js.br +0 -0
  282. package/dist/client/assets/c4Diagram-7LVT6UL2-BTeUIAS9.js.gz +0 -0
  283. package/dist/client/assets/channel-DPAqeRss.js +0 -1
  284. package/dist/client/assets/chunk-F27PBJKO-Cu3ypVNN.js.br +0 -0
  285. package/dist/client/assets/chunk-F27PBJKO-Cu3ypVNN.js.gz +0 -0
  286. package/dist/client/assets/chunk-IMKFNOWR-BioTa0jG.js.br +0 -0
  287. package/dist/client/assets/chunk-IMKFNOWR-BioTa0jG.js.gz +0 -0
  288. package/dist/client/assets/chunk-SVP7TREG-BHaV6_ki.js.br +0 -0
  289. package/dist/client/assets/chunk-SVP7TREG-BHaV6_ki.js.gz +0 -0
  290. package/dist/client/assets/chunk-TICWLB2K-SU15adqY.js.br +0 -0
  291. package/dist/client/assets/chunk-TICWLB2K-SU15adqY.js.gz +0 -0
  292. package/dist/client/assets/classDiagram-ZZMXUADV-kQeU2Z7d.js +0 -1
  293. package/dist/client/assets/classDiagram-v2-VYDZK3BY-kQeU2Z7d.js +0 -1
  294. package/dist/client/assets/cose-bilkent-JH36ORCC-EE27IbbX.js.br +0 -0
  295. package/dist/client/assets/cose-bilkent-JH36ORCC-EE27IbbX.js.gz +0 -0
  296. package/dist/client/assets/cynefin-OW5HDTMX-CpY9J9iu.js.br +0 -0
  297. package/dist/client/assets/cynefin-OW5HDTMX-CpY9J9iu.js.gz +0 -0
  298. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-mJxcQnkp.js.br +0 -0
  299. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-mJxcQnkp.js.gz +0 -0
  300. package/dist/client/assets/dagre-GXQ25YYZ-DAUZrxwq.js.br +0 -0
  301. package/dist/client/assets/dagre-GXQ25YYZ-DAUZrxwq.js.gz +0 -0
  302. package/dist/client/assets/diagram-S7CK7UJ4-3rquuCu6.js.br +0 -0
  303. package/dist/client/assets/diagram-S7CK7UJ4-3rquuCu6.js.gz +0 -0
  304. package/dist/client/assets/diagram-UQ7AKVKN-CZWjaDbi.js.br +0 -0
  305. package/dist/client/assets/diagram-UQ7AKVKN-CZWjaDbi.js.gz +0 -0
  306. package/dist/client/assets/diagram-VSXAHHWV-CNQEg3jR.js.br +0 -0
  307. package/dist/client/assets/diagram-VSXAHHWV-CNQEg3jR.js.gz +0 -0
  308. package/dist/client/assets/diagram-VX7I27RA-DYorDR1n.js.br +0 -0
  309. package/dist/client/assets/diagram-VX7I27RA-DYorDR1n.js.gz +0 -0
  310. package/dist/client/assets/diagram-Z3DM3KII-BPgvVftJ.js.br +0 -0
  311. package/dist/client/assets/diagram-Z3DM3KII-BPgvVftJ.js.gz +0 -0
  312. package/dist/client/assets/ebnfDiagram-PWID7BFC-KqpJv-fX.js.br +0 -0
  313. package/dist/client/assets/ebnfDiagram-PWID7BFC-KqpJv-fX.js.gz +0 -0
  314. package/dist/client/assets/erDiagram-RLTQ6QDP-Bwj_TPoi.js.br +0 -0
  315. package/dist/client/assets/erDiagram-RLTQ6QDP-Bwj_TPoi.js.gz +0 -0
  316. package/dist/client/assets/flowDiagram-HODETNUW-BYALZ5I6.js.br +0 -0
  317. package/dist/client/assets/flowDiagram-HODETNUW-BYALZ5I6.js.gz +0 -0
  318. package/dist/client/assets/ganttDiagram-EL5Y4UJY-DwrR8yW_.js.br +0 -0
  319. package/dist/client/assets/ganttDiagram-EL5Y4UJY-DwrR8yW_.js.gz +0 -0
  320. package/dist/client/assets/gestureArbiter-4NWfZprH.js.br +0 -0
  321. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-C3pH5ZGR.js.br +0 -0
  322. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-C3pH5ZGR.js.gz +0 -0
  323. package/dist/client/assets/index-e1PkqIqN.css +0 -1
  324. package/dist/client/assets/index-e1PkqIqN.css.br +0 -0
  325. package/dist/client/assets/index-e1PkqIqN.css.gz +0 -0
  326. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BFhiY6uy.js.br +0 -0
  327. package/dist/client/assets/ishikawaDiagram-5VMMS53U-BFhiY6uy.js.gz +0 -0
  328. package/dist/client/assets/journeyDiagram-3NMN7TZE-Beg2Cmg4.js.br +0 -0
  329. package/dist/client/assets/journeyDiagram-3NMN7TZE-Beg2Cmg4.js.gz +0 -0
  330. package/dist/client/assets/kanban-definition-UXKFOSKX-CNb51-_F.js.br +0 -0
  331. package/dist/client/assets/kanban-definition-UXKFOSKX-CNb51-_F.js.gz +0 -0
  332. package/dist/client/assets/layout-B07GM-uc.js.br +0 -0
  333. package/dist/client/assets/layout-B07GM-uc.js.gz +0 -0
  334. package/dist/client/assets/linear-DRJlaLbJ.js.br +0 -0
  335. package/dist/client/assets/linear-DRJlaLbJ.js.gz +0 -0
  336. package/dist/client/assets/mermaid.core-BySznxI_.js.br +0 -0
  337. package/dist/client/assets/mermaid.core-BySznxI_.js.gz +0 -0
  338. package/dist/client/assets/mindmap-definition-YA3MSWOX-BtStMFHK.js.br +0 -0
  339. package/dist/client/assets/mindmap-definition-YA3MSWOX-BtStMFHK.js.gz +0 -0
  340. package/dist/client/assets/passwordBootstrap-B-T8YSfQ.js.br +0 -0
  341. package/dist/client/assets/passwordBootstrap-B-T8YSfQ.js.gz +0 -0
  342. package/dist/client/assets/pegDiagram-XKGWAZYB-BNJzxFGK.js.br +0 -0
  343. package/dist/client/assets/pegDiagram-XKGWAZYB-BNJzxFGK.js.gz +0 -0
  344. package/dist/client/assets/pieDiagram-E7YTZNPT-Df1Y6zou.js.br +0 -0
  345. package/dist/client/assets/pieDiagram-E7YTZNPT-Df1Y6zou.js.gz +0 -0
  346. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Q3jN6--F.js.br +0 -0
  347. package/dist/client/assets/quadrantDiagram-AXDQQJYC-Q3jN6--F.js.gz +0 -0
  348. package/dist/client/assets/railroadDiagram-O6MQD6OU-c-1SN7pC.js.br +0 -0
  349. package/dist/client/assets/railroadDiagram-O6MQD6OU-c-1SN7pC.js.gz +0 -0
  350. package/dist/client/assets/rdpSession-B6j6_C4D.js.br +0 -0
  351. package/dist/client/assets/rdpSession-B6j6_C4D.js.gz +0 -0
  352. package/dist/client/assets/referenceLongPress-Bln9X6SW.js.br +0 -0
  353. package/dist/client/assets/referenceLongPress-Bln9X6SW.js.gz +0 -0
  354. package/dist/client/assets/requirementDiagram-BXWQKSXE-wcsUZu82.js.br +0 -0
  355. package/dist/client/assets/requirementDiagram-BXWQKSXE-wcsUZu82.js.gz +0 -0
  356. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CfXyROPC.js.br +0 -0
  357. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CfXyROPC.js.gz +0 -0
  358. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D-IasKbj.js.br +0 -0
  359. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D-IasKbj.js.gz +0 -0
  360. package/dist/client/assets/sizeCapture-INFHLROL-Cyoh7jyx.js.br +0 -0
  361. package/dist/client/assets/sizeCapture-INFHLROL-Cyoh7jyx.js.gz +0 -0
  362. package/dist/client/assets/stateDiagram-D77RDMKH-BFeLYGOW.js.br +0 -0
  363. package/dist/client/assets/stateDiagram-D77RDMKH-BFeLYGOW.js.gz +0 -0
  364. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Cn5inEsZ.js +0 -1
  365. package/dist/client/assets/swimlanes-42K2YHIH-BtMhgPB2.js.br +0 -0
  366. package/dist/client/assets/swimlanes-42K2YHIH-BtMhgPB2.js.gz +0 -0
  367. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-Di2Vfydj.js +0 -8
  368. package/dist/client/assets/timeline-definition-24CTP7MA-BccUO5W0.js.br +0 -0
  369. package/dist/client/assets/timeline-definition-24CTP7MA-BccUO5W0.js.gz +0 -0
  370. package/dist/client/assets/vennDiagram-4TSXK5OY-hNN_O594.js.br +0 -0
  371. package/dist/client/assets/vennDiagram-4TSXK5OY-hNN_O594.js.gz +0 -0
  372. package/dist/client/assets/videoCompression-DS0r00L6.js.br +0 -0
  373. package/dist/client/assets/videoCompression-DS0r00L6.js.gz +0 -0
  374. package/dist/client/assets/wardleyDiagram-VM6X3IG4-C6h02bPv.js.br +0 -0
  375. package/dist/client/assets/wardleyDiagram-VM6X3IG4-C6h02bPv.js.gz +0 -0
  376. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DvNnLmXs.js.br +0 -0
  377. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DvNnLmXs.js.gz +0 -0
package/dist/client/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let r={};const c=e=>n(e,o),d={module:{uri:o},exports:r,require:c};s[o]=Promise.all(i.map(e=>d[e]||c(e))).then(e=>(a(...e),r))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"5f059a61fad372907e561196e64b3a15"},{url:"assets/app-aNkllBsm.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/index-e1PkqIqN.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
1
+ if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let c={};const r=e=>n(e,o),d={module:{uri:o},exports:c,require:r};s[o]=Promise.all(i.map(e=>d[e]||r(e))).then(e=>(a(...e),c))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"e861e4f0fa06e0ad9bb72cc43ebf650e"},{url:"assets/app-D-AilvVY.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/index-CRxcDATF.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
Binary file
Binary file
@@ -1,3 +1,4 @@
1
+ import { RELAY_CLIENT_CONNECT_TIMEOUT_MS } from '../federation/streamLimits.js';
1
2
  import { encryptedRequestSubject } from '../federation/requestContext.js';
2
3
  import { randomUUID } from 'node:crypto';
3
4
  import { readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
@@ -122,9 +123,9 @@ export class CollaborationRpc {
122
123
  this.pending.clear();
123
124
  }
124
125
  }
125
- export async function connectCollaborationRpc(identity, peer, endpoint, receive) {
126
+ export async function connectCollaborationRpc(identity, peer, endpoint, receive, configuredCa) {
126
127
  validateCollaborationNode(peer);
127
- const ca = peer.caFingerprint256 ? await readPinnedCertificateAuthority(peer.origin, peer.caFingerprint256) : undefined;
128
+ const ca = peer.caFingerprint256 ? await readPinnedCertificateAuthority(peer.origin, peer.caFingerprint256) : configuredCa;
128
129
  const url = endpoint ?? `${peer.origin.replace(/^https:/, 'wss:')}/api/federation/secure`;
129
130
  const socket = new WebSocket(url, { ca, rejectUnauthorized: true, followRedirects: false, handshakeTimeout: 3000, maxPayload: 1024 * 1024 });
130
131
  const relay = endpoint ? relayDuplex(socket, peer.serviceId) : undefined;
@@ -164,7 +165,7 @@ function relayDuplex(socket, target) {
164
165
  let readyResolve, readyReject;
165
166
  const ready = new Promise((resolve, reject) => { readyResolve = resolve; readyReject = reject; });
166
167
  void ready.catch(() => { });
167
- const timer = setTimeout(() => fail(new Error('ROUTE_TIMEOUT')), 5000);
168
+ const timer = setTimeout(() => fail(new Error('ROUTE_TIMEOUT')), RELAY_CLIENT_CONNECT_TIMEOUT_MS);
168
169
  const fail = (error) => { clearTimeout(timer); readyReject(error); queue.end(error); socket.close(); };
169
170
  const send = (frame) => {
170
171
  if (socket.readyState !== 1 || socket.bufferedAmount > 1024 * 1024)
@@ -677,7 +677,8 @@ export function startServer(options = {}) {
677
677
  const localHostname = ['0.0.0.0', '::'].includes(host) ? 'localhost' : host;
678
678
  const localAuthority = localHostname.includes(':') && !localHostname.startsWith('[') ? `[${localHostname}]` : localHostname;
679
679
  const selfRelay = new DesktopSelfRelay({
680
- desktopFile: path.join(homedir(), '.termdock', 'desktop.json'), identity: runtime.identity, serviceId: runtime.serviceId,
680
+ desktopFile: path.join(homedir(), '.termdock', 'desktop.json'),
681
+ targets: () => routeAccess.configuredDirectTargets(), baseDir: path.join(homedir(), '.termdock', 'federation'), identity: runtime.identity, serviceId: runtime.serviceId,
681
682
  localOrigin: `${scheme}://${localAuthority}:${port}`, ...(localCa ? { localCa } : {}),
682
683
  });
683
684
  selfRelay.start();
@@ -1,7 +1,8 @@
1
+ import { RELAY_PROVIDER_CONNECT_TIMEOUT_MS, RELAY_ROUTE_OPEN_TIMEOUT_MS } from './streamLimits.js';
1
2
  import { randomUUID } from 'node:crypto';
2
3
  import { EventEmitter } from 'node:events';
3
4
  const defaults = { maxFrameBytes: 256 * 1024, maxBufferedBytes: 1024 * 1024,
4
- maxStreams: 128, heartbeatMs: 30_000, maxRouteTtlMs: 90_000, connectTimeoutMs: 10_000 };
5
+ maxStreams: 128, heartbeatMs: 30_000, maxRouteTtlMs: 90_000, connectTimeoutMs: RELAY_PROVIDER_CONNECT_TIMEOUT_MS, routeTimeoutMs: RELAY_ROUTE_OPEN_TIMEOUT_MS };
5
6
  const identifier = (v) => typeof v === 'string' && /^[a-zA-Z0-9_.:-]{1,160}$/.test(v);
6
7
  function parse(raw, limits) {
7
8
  if (Buffer.byteLength(raw instanceof Array ? Buffer.concat(raw) : raw) > limits.maxFrameBytes)
@@ -90,9 +91,11 @@ export class RelayRouter {
90
91
  this.options = options;
91
92
  this.limits = { ...defaults, ...options };
92
93
  this.sweep = setInterval(() => {
93
- for (const [id, route] of this.routes)
94
- if (route.expires <= Date.now() || !this.canRegister(route.peer, id))
95
- this.withdraw(id, route.peer);
94
+ for (const [id, routes] of this.routes)
95
+ for (const [peer, route] of routes) {
96
+ if (route.expires <= Date.now() || peer.ws.readyState !== 1 || !this.canRegister(peer, id))
97
+ this.withdraw(id, peer);
98
+ }
96
99
  for (const peer of this.peers)
97
100
  for (const stream of [...peer.streams.values()]) {
98
101
  if (stream.owner === peer && !this.canRoute(peer, stream.serviceId))
@@ -107,16 +110,22 @@ export class RelayRouter {
107
110
  canRoute(peer, serviceId) {
108
111
  return !this.directPeers.has(peer) && this.options.allowRoute(peer.principal, serviceId);
109
112
  }
113
+ providers(serviceId) {
114
+ return [...(this.routes.get(serviceId) || [])]
115
+ .filter(([peer, route]) => route.expires > Date.now() && peer.ws.readyState === 1 && this.canRegister(peer, serviceId))
116
+ // Recent target failures lower priority but never make the only route disappear.
117
+ .sort((a, b) => Math.max(0, a[1].retryAfter - Date.now()) - Math.max(0, b[1].retryAfter - Date.now()))
118
+ .map(([peer]) => peer);
119
+ }
110
120
  hasRoute(serviceId) {
111
- const route = this.routes.get(serviceId);
112
- return !this.stopped && !!route && route.expires > Date.now() && route.peer.ws.readyState === 1 && this.canRegister(route.peer, serviceId);
121
+ return !this.stopped && this.providers(serviceId).length > 0;
113
122
  }
114
123
  activeRouteIds() {
115
124
  return [...this.routes.keys()].filter(serviceId => this.hasRoute(serviceId));
116
125
  }
117
126
  /** Trusted local configuration only. Clients never supply a target URL or factory. */
118
127
  registerDirect(serviceId, connect) {
119
- if (this.stopped || !identifier(serviceId) || typeof connect !== 'function' || this.hasRoute(serviceId))
128
+ if (this.stopped || !identifier(serviceId) || typeof connect !== 'function' || [...this.peers].some(peer => this.directPeers.get(peer) === serviceId))
120
129
  throw new Error('Invalid or already registered direct target');
121
130
  const [routerWire, clientWire] = memoryPair();
122
131
  // The private WeakMap marks this peer; its placeholder principal is never
@@ -139,6 +148,10 @@ export class RelayRouter {
139
148
  }
140
149
  /** Caller awaits attach before completing its application-level ready handshake. */
141
150
  async attach(ws, context) {
151
+ if (this.stopped) {
152
+ ws.close(1001, 'Router stopped');
153
+ return false;
154
+ }
142
155
  // Reject early application frames rather than buffering untrusted traffic while authenticating.
143
156
  let early = false;
144
157
  const rejectEarly = () => { early = true; ws.close(1008, 'Authentication pending'); };
@@ -151,7 +164,7 @@ export class RelayRouter {
151
164
  principal = null;
152
165
  }
153
166
  ws.off('message', rejectEarly);
154
- if (principal === null || early || ws.readyState !== 1) {
167
+ if (this.stopped || principal === null || early || ws.readyState !== 1) {
155
168
  ws.close(1008, 'Relay authentication required');
156
169
  return false;
157
170
  }
@@ -169,72 +182,131 @@ export class RelayRouter {
169
182
  return true;
170
183
  }
171
184
  withdraw(serviceId, peer) {
172
- if (this.routes.get(serviceId)?.peer === peer)
185
+ const routes = this.routes.get(serviceId);
186
+ routes?.delete(peer);
187
+ if (!routes?.size)
173
188
  this.routes.delete(serviceId);
174
189
  for (const stream of [...peer.streams.values()])
175
190
  if (stream.serviceId === serviceId && stream.provider === peer)
176
- this.closeStream(stream, 'Route unavailable');
191
+ this.providerFailed(stream, 'Route unavailable');
177
192
  }
178
193
  remove(peer) {
179
194
  this.peers.delete(peer);
180
- for (const [id, route] of this.routes)
181
- if (route.peer === peer)
195
+ // Consumers cannot fail over after disconnecting; remove them first.
196
+ for (const stream of [...peer.streams.values()])
197
+ if (stream.owner === peer)
198
+ this.closeStream(stream, 'Relay disconnected');
199
+ for (const [id, routes] of this.routes)
200
+ if (routes.has(peer))
182
201
  this.withdraw(id, peer);
183
202
  for (const stream of [...peer.streams.values()])
184
- this.closeStream(stream, 'Relay disconnected');
203
+ this.providerFailed(stream, 'Relay disconnected');
185
204
  }
186
205
  closeStream(s, reason) {
206
+ if (s.owner.streams.get(s.ownerId) !== s)
207
+ return;
208
+ clearTimeout(s.deadline);
187
209
  s.owner.streams.delete(s.ownerId);
188
- s.provider.streams.delete(s.providerId);
210
+ if (s.provider.streams.get(s.providerId) === s) {
211
+ s.provider.streams.delete(s.providerId);
212
+ send(s.provider.ws, { type: 'close', streamId: s.providerId, reason }, this.limits);
213
+ }
189
214
  send(s.owner.ws, { type: 'close', streamId: s.ownerId, reason }, this.limits);
215
+ }
216
+ providerFailed(s, reason) {
217
+ if (s.owner.streams.get(s.ownerId) !== s)
218
+ return;
219
+ clearTimeout(s.deadline);
220
+ s.provider.streams.delete(s.providerId);
190
221
  send(s.provider.ws, { type: 'close', streamId: s.providerId, reason }, this.limits);
222
+ const route = this.routes.get(s.serviceId)?.get(s.provider);
223
+ if (route)
224
+ route.retryAfter = Date.now() + 5000;
225
+ // Never replay ciphertext (or terminal input) onto a replacement transport.
226
+ if (s.opened || !this.openProvider(s))
227
+ this.closeStream(s, reason);
228
+ }
229
+ openProvider(s) {
230
+ if (this.stopped || Date.now() >= s.expires || s.owner.ws.readyState !== 1 || !this.canRoute(s.owner, s.serviceId))
231
+ return false;
232
+ for (const provider of this.providers(s.serviceId)) {
233
+ if (provider === s.owner || s.attempted.has(provider) || provider.streams.size >= this.limits.maxStreams)
234
+ continue;
235
+ s.attempted.add(provider);
236
+ s.provider = provider;
237
+ s.providerId = randomUUID();
238
+ provider.streams.set(s.providerId, s);
239
+ if (!send(provider.ws, { type: 'open', streamId: s.providerId, serviceId: s.serviceId }, this.limits)) {
240
+ provider.streams.delete(s.providerId);
241
+ continue;
242
+ }
243
+ s.deadline = setTimeout(() => this.providerFailed(s, 'Target timeout'), Math.min(this.limits.connectTimeoutMs, s.expires - Date.now()));
244
+ s.deadline.unref?.();
245
+ return true;
246
+ }
247
+ return false;
191
248
  }
192
249
  receive(peer, f) {
193
250
  if (f.type === 'register') {
194
251
  if (!f.serviceIds.every(id => this.canRegister(peer, id)))
195
252
  throw new Error('Registration denied');
253
+ for (const [id, routes] of this.routes)
254
+ if (routes.has(peer) && !f.serviceIds.includes(id))
255
+ this.withdraw(id, peer);
196
256
  for (const id of f.serviceIds) {
197
- const old = this.routes.get(id);
198
- if (old && old.peer !== peer && old.expires > Date.now())
199
- throw new Error('Route already registered');
257
+ let routes = this.routes.get(id);
258
+ if (!routes) {
259
+ routes = new Map();
260
+ this.routes.set(id, routes);
261
+ }
262
+ routes.set(peer, { expires: Date.now() + Math.min(f.ttlMs, this.limits.maxRouteTtlMs), retryAfter: routes.get(peer)?.retryAfter ?? 0 });
200
263
  }
201
- for (const [id, r] of this.routes)
202
- if (r.peer === peer && !f.serviceIds.includes(id))
203
- this.withdraw(id, peer);
204
- for (const id of f.serviceIds)
205
- this.routes.set(id, { peer, expires: Date.now() + Math.min(f.ttlMs, this.limits.maxRouteTtlMs) });
206
264
  return;
207
265
  }
208
266
  if (f.type === 'open') {
209
- const route = this.routes.get(f.serviceId);
210
267
  if (peer.streams.has(f.streamId))
211
268
  throw new Error('Duplicate stream');
212
- if (!this.canRoute(peer, f.serviceId) || !route || route.expires <= Date.now() || route.peer === peer) {
269
+ if (!this.canRoute(peer, f.serviceId) || !this.hasRoute(f.serviceId)) {
213
270
  send(peer.ws, { type: 'close', streamId: f.streamId, reason: 'Route unavailable or denied' }, this.limits);
214
271
  return;
215
272
  }
216
- if (peer.streams.size >= this.limits.maxStreams || route.peer.streams.size >= this.limits.maxStreams)
273
+ if (peer.streams.size >= this.limits.maxStreams)
217
274
  throw new Error('Stream budget exceeded');
218
- const s = { owner: peer, ownerId: f.streamId, provider: route.peer, providerId: randomUUID(), serviceId: f.serviceId };
275
+ const s = { owner: peer, ownerId: f.streamId, provider: peer, providerId: '', serviceId: f.serviceId, opened: false, expires: Date.now() + this.limits.routeTimeoutMs, attempted: new Set() };
219
276
  peer.streams.set(s.ownerId, s);
220
- route.peer.streams.set(s.providerId, s);
221
- if (!send(route.peer.ws, { ...f, streamId: s.providerId }, this.limits))
222
- this.closeStream(s, 'Relay disconnected');
277
+ if (!this.openProvider(s))
278
+ this.closeStream(s, 'Route unavailable or congested');
223
279
  return;
224
280
  }
225
281
  const s = peer.streams.get(f.streamId);
226
282
  if (!s)
227
283
  return;
228
- if (!this.canRoute(s.owner, s.serviceId) || !this.canRegister(s.provider, s.serviceId)) {
284
+ if (!this.canRoute(s.owner, s.serviceId)) {
229
285
  this.closeStream(s, 'Authorization revoked');
230
286
  return;
231
287
  }
288
+ const registration = this.routes.get(s.serviceId)?.get(s.provider);
289
+ if (!registration || registration.expires <= Date.now() || !this.canRegister(s.provider, s.serviceId)) {
290
+ this.withdraw(s.serviceId, s.provider);
291
+ return;
292
+ }
232
293
  if (f.type === 'close') {
233
- this.closeStream(s, 'Channel closed');
294
+ if (peer === s.provider)
295
+ this.providerFailed(s, 'Channel closed');
296
+ else
297
+ this.closeStream(s, 'Channel closed');
234
298
  return;
235
299
  }
236
300
  if (f.type === 'opened' && peer !== s.provider)
237
301
  throw new Error('Invalid channel direction');
302
+ if (f.type === 'opened') {
303
+ if (s.opened)
304
+ throw new Error('Channel already opened');
305
+ clearTimeout(s.deadline);
306
+ s.opened = true;
307
+ }
308
+ else if (!s.opened)
309
+ throw new Error('Channel not ready');
238
310
  const target = peer === s.owner ? s.provider : s.owner;
239
311
  if (!send(target.ws, { ...f, streamId: peer === s.owner ? s.providerId : s.ownerId }, this.limits))
240
312
  this.closeStream(s, 'Relay congestion');
@@ -251,6 +323,7 @@ export class RelayClient {
251
323
  limits;
252
324
  streams = new Map();
253
325
  renewal;
326
+ pending = new Map();
254
327
  stopped = false;
255
328
  constructor(upstream, options) {
256
329
  this.upstream = upstream;
@@ -265,6 +338,8 @@ export class RelayClient {
265
338
  upstream.on('message', raw => { void this.receive(raw).catch(() => upstream.close(1008, 'Invalid relay frame')); });
266
339
  }
267
340
  drop(id, reason) {
341
+ clearTimeout(this.pending.get(id));
342
+ this.pending.delete(id);
268
343
  const target = this.streams.get(id);
269
344
  this.streams.delete(id);
270
345
  target?.close();
@@ -276,26 +351,35 @@ export class RelayClient {
276
351
  throw new Error('Unexpected registration');
277
352
  if (f.type === 'open') {
278
353
  const connect = this.options.targets.get(f.serviceId);
279
- if (!connect || this.streams.has(f.streamId) || this.streams.size >= this.limits.maxStreams) {
354
+ if (this.streams.has(f.streamId))
355
+ throw new Error('Duplicate stream');
356
+ if (!connect || this.streams.size >= this.limits.maxStreams) {
280
357
  this.drop(f.streamId, 'Target unavailable');
281
358
  return;
282
359
  }
283
360
  this.streams.set(f.streamId, null);
284
- let timedOut = false;
285
- const timer = setTimeout(() => { timedOut = true; this.drop(f.streamId, 'Target timeout'); }, this.limits.connectTimeoutMs);
361
+ const timer = setTimeout(() => { this.drop(f.streamId, 'Target timeout'); }, this.limits.connectTimeoutMs);
286
362
  timer.unref?.();
363
+ this.pending.set(f.streamId, timer);
287
364
  let target;
288
365
  try {
289
366
  target = await connect();
290
367
  }
291
368
  catch {
292
- clearTimeout(timer);
293
- this.drop(f.streamId, 'Target unavailable');
369
+ if (this.pending.get(f.streamId) === timer)
370
+ this.drop(f.streamId, 'Target unavailable');
371
+ return;
372
+ }
373
+ // A canceled attempt may complete after the same ID has been reused.
374
+ if (this.pending.get(f.streamId) !== timer || this.stopped) {
375
+ target.close();
294
376
  return;
295
377
  }
296
378
  clearTimeout(timer);
297
- if (timedOut || this.stopped || !this.streams.has(f.streamId)) {
379
+ this.pending.delete(f.streamId);
380
+ if (target.readyState !== 1) {
298
381
  target.close();
382
+ this.drop(f.streamId, 'Target not ready');
299
383
  return;
300
384
  }
301
385
  this.streams.set(f.streamId, target);
@@ -1,4 +1,6 @@
1
1
  import WebSocket from 'ws';
2
+ import { readFileSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
2
4
  import { desktopDirectTargets } from './desktopTargets.js';
3
5
  import { RelayClient } from './relay.js';
4
6
  import { readPinnedCertificateAuthority } from './trustedCa.js';
@@ -57,8 +59,8 @@ function waitForReady(socket) {
57
59
  }
58
60
  /**
59
61
  * A local Termdock service may publish only its own stable identity to other
60
- * services pinned by the same Desktop installation. Desktop supplies addresses
61
- * and CA pins only; the service proves itself with its own Noise identity and
62
+ * administrator-configured peers or services pinned by the same Desktop
63
+ * installation. Configuration supplies addresses and TLS trust only; the service proves itself with its own Noise identity and
62
64
  * no browser/device authorization is copied into this process.
63
65
  */
64
66
  export class DesktopSelfRelay {
@@ -89,11 +91,12 @@ export class DesktopSelfRelay {
89
91
  refresh() {
90
92
  if (this.stopped)
91
93
  return;
92
- const desired = new Map(desktopDirectTargets(this.options.desktopFile, this.options.serviceId)
93
- .map(target => [target.serviceId, target]));
94
+ const desired = new Map([...desktopDirectTargets(this.options.desktopFile, this.options.serviceId), ...(this.options.targets?.() || [])]
95
+ .filter(target => target.serviceId !== this.options.serviceId)
96
+ .map(target => [target.serviceId, { ...target, url: new URL(target.url.replace(/^wss:/, 'https:')).origin }]));
94
97
  for (const [serviceId, state] of this.states) {
95
98
  const target = desired.get(serviceId);
96
- const signature = target && JSON.stringify([target.url, target.caFingerprint256]);
99
+ const signature = target && JSON.stringify([target.url, target.caFingerprint256, target.caPath]);
97
100
  if (!target || signature !== state.signature) {
98
101
  this.stopState(state);
99
102
  this.states.delete(serviceId);
@@ -101,7 +104,7 @@ export class DesktopSelfRelay {
101
104
  }
102
105
  for (const [serviceId, target] of desired)
103
106
  if (!this.states.has(serviceId)) {
104
- const state = { signature: JSON.stringify([target.url, target.caFingerprint256]), stopped: false };
107
+ const state = { signature: JSON.stringify([target.url, target.caFingerprint256, target.caPath]), stopped: false };
105
108
  this.states.set(serviceId, state);
106
109
  void this.run(state, target);
107
110
  }
@@ -137,7 +140,8 @@ export class DesktopSelfRelay {
137
140
  }
138
141
  async connect(state, target) {
139
142
  const peer = { serviceId: target.serviceId, origin: target.url, ...(target.caFingerprint256 ? { caFingerprint256: target.caFingerprint256 } : {}) };
140
- const rpc = await connectCollaborationRpc(this.options.identity, peer);
143
+ const configuredCa = target.caPath ? readFileSync(resolve(this.options.baseDir || process.cwd(), target.caPath)) : undefined;
144
+ const rpc = await connectCollaborationRpc(this.options.identity, peer, undefined, undefined, configuredCa);
141
145
  let selfRelayToken;
142
146
  try {
143
147
  const result = await rpc.request({ type: 'self-relay-ticket' });
@@ -151,7 +155,7 @@ export class DesktopSelfRelay {
151
155
  }
152
156
  if (this.stopped || state.stopped)
153
157
  return;
154
- const ca = target.caFingerprint256 ? await readPinnedCertificateAuthority(target.url, target.caFingerprint256) : undefined;
158
+ const ca = target.caFingerprint256 ? await readPinnedCertificateAuthority(target.url, target.caFingerprint256) : configuredCa;
155
159
  const upstream = await openSocket(relayEndpoint(target.url, selfRelayToken), ca);
156
160
  state.upstream = upstream;
157
161
  try {
@@ -3,3 +3,8 @@
3
3
  export const MAX_ACTIVE_HTTP_REQUESTS = 8;
4
4
  export const MAX_SERVER_HTTP_REQUESTS = 32;
5
5
  export const MAX_OPEN_SECURE_SOCKETS = 128;
6
+ // Relay selection must finish before foreground/background clients abandon the
7
+ // transport, leaving time for the final pinned Noise handshake.
8
+ export const RELAY_PROVIDER_CONNECT_TIMEOUT_MS = 10_000;
9
+ export const RELAY_ROUTE_OPEN_TIMEOUT_MS = 15_000;
10
+ export const RELAY_CLIENT_CONNECT_TIMEOUT_MS = 20_000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termdock",
3
- "version": "1.4.330",
3
+ "version": "1.4.332",
4
4
  "description": "A complete web-based terminal application with modern UI",
5
5
  "type": "module",
6
6
  "main": ".desktop-dist/main.js",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "packageName": "termdock",
4
- "version": "1.4.330",
4
+ "version": "1.4.332",
5
5
  "runtimeProtocolVersion": 1,
6
6
  "minimumDesktopVersion": "1.4.46",
7
7
  "nodeMajor": 22,
8
8
  "dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
9
- "serverBundleHash": "sha256-R3DBIQv0z+SBN+LCWHRsFbWHqQ92u8mBkCkfn1MJdok=",
10
- "clientBundleHash": "sha256-MLNBIgsbEuR7PI6Npn9Zt4OyvUR6y5f88Gic0erRCvE=",
9
+ "serverBundleHash": "sha256-lmN7Or7gUKZy9ehDwSJ+vAJQSDcbNpEVqSGxxotR2c4=",
10
+ "clientBundleHash": "sha256-tvY+AzsMFBHQkZySF87ojAlWXBRrkv6IZIUGHJyllaI=",
11
11
  "entrypoint": "dist/server/cli.js",
12
12
  "clientEntrypoint": "dist/client/index.html"
13
13
  }
@@ -7,6 +7,7 @@ Keep cmap coverage and advance widths exactly equal to the source faces.
7
7
  """
8
8
  from __future__ import annotations
9
9
 
10
+ import argparse
10
11
  import hashlib
11
12
  import io
12
13
  import json
@@ -18,6 +19,12 @@ from fontTools.ttLib import TTFont
18
19
  ROOT = Path(__file__).resolve().parents[1]
19
20
  FONTS = ROOT / "public/fonts"
20
21
  OUTPUT = FONTS / "terminal"
22
+ FAMILY_SOURCES = [
23
+ ("Termdock Prompt Icons", [f"JetBrainsMonoNLNerdFontMono-{w}" for w in ["Regular", "Bold"]]),
24
+ ("Termdock Maple", [f"MapleMono-{w}" for w in ["Regular", "Bold", "Italic", "BoldItalic"]]),
25
+ ("Termdock Mono", [f"JetBrainsMonoNLNerdFontMono-{w}" for w in ["Regular", "Bold", "Italic", "BoldItalic"]]),
26
+ ("Noto Sans Mono CJK SC", ["NotoSansMonoCJKsc-Subset", "NotoSansMonoCJKsc-Bold-Subset"]),
27
+ ]
21
28
 
22
29
 
23
30
  def ranges(points: list[int]) -> str:
@@ -30,22 +37,44 @@ def ranges(points: list[int]) -> str:
30
37
  return ",".join(f"U+{a:X}" if a == b else f"U+{a:X}-{b:X}" for a, b in spans)
31
38
 
32
39
 
33
- def main() -> None:
40
+ def main(families: list[str] | None = None) -> None:
34
41
  OUTPUT.mkdir(exist_ok=True)
35
42
  css: list[str] = ["/* Generated by scripts/generate-font-subsets.py; do not edit. */"]
36
43
  manifest: dict[str, object] = {"schemaVersion": 1, "faces": []}
37
44
  expected: set[str] = set()
38
- for family, stems in [
39
- ("Termdock Mono", [f"JetBrainsMonoNLNerdFontMono-{w}" for w in ["Regular", "Bold", "Italic", "BoldItalic"]]),
40
- ("Noto Sans Mono CJK SC", ["NotoSansMonoCJKsc-Subset", "NotoSansMonoCJKsc-Bold-Subset"]),
41
- ]:
45
+ if families:
46
+ previous = json.loads((OUTPUT / "manifest.json").read_text())
47
+ def stored_family(face: dict) -> str:
48
+ return face.get("family") or ("Termdock Maple" if face["source"].startswith("MapleMono-")
49
+ else "Termdock Mono" if face["source"].startswith("JetBrainsMono")
50
+ else "Noto Sans Mono CJK SC")
51
+ manifest["faces"] = [face for face in previous["faces"] if stored_family(face) not in families]
52
+ expected.update(shard["file"] for face in manifest["faces"] for shard in face["shards"])
53
+ replaced_families = set(families)
54
+ if "Termdock Maple" in replaced_families:
55
+ replaced_families.add("Maple Mono")
56
+ css.extend(line for line in (ROOT / "src/lib/terminal/fontFaces.css").read_text().splitlines()
57
+ if line.startswith("@font-face") and not any(f'font-family:"{family}";' in line for family in replaced_families))
58
+ for family, stems in FAMILY_SOURCES:
59
+ if families and family not in families:
60
+ continue
42
61
  for stem in stems:
43
62
  source = FONTS / f"{stem}.woff2"
44
63
  original = TTFont(source)
45
64
  cmap = original.getBestCmap()
65
+ if family == "Termdock Prompt Icons":
66
+ spec = json.loads((ROOT / "tools/font/terminal-prompt-icons.json").read_text())
67
+ selected = {int(point, 16) for point in spec["codepoints"]}
68
+ for start, end in spec["ranges"]:
69
+ selected.update(range(int(start, 16), int(end, 16) + 1))
70
+ cmap = {cp: glyph for cp, glyph in cmap.items() if cp in selected}
46
71
  groups: dict[str, list[int]] = {}
47
72
  for cp in sorted(cmap):
48
- if family == "Termdock Mono":
73
+ if family == "Termdock Prompt Icons":
74
+ key = "icons"
75
+ elif family == "Termdock Maple":
76
+ key = "ascii" if cp == 0xD or 0x20 <= cp <= 0x7E else "text"
77
+ elif family == "Termdock Mono":
49
78
  key = f"icons-{cp // 1024:x}" if 0xE000 <= cp <= 0xF8FF or 0xF0000 <= cp <= 0x10FFFF else "text"
50
79
  else:
51
80
  key = f"cjk-{cp // 256:x}" if 0x3400 <= cp <= 0x9FFF else "punctuation"
@@ -58,10 +87,30 @@ def main() -> None:
58
87
  subsetter = subset.Subsetter(options=options)
59
88
  subsetter.populate(unicodes=points)
60
89
  subsetter.subset(font)
90
+ if family == "Termdock Maple":
91
+ # Maple Mono is an OFL reserved name. Our web subsets keep
92
+ # its glyphs/metrics but carry their own derivative name.
93
+ for record in font["name"].names:
94
+ if record.nameID not in (1, 3, 4, 6, 16):
95
+ continue
96
+ value = record.toUnicode()
97
+ renamed = value.replace("Maple Mono", "Termdock Maple").replace("MapleMono", "TermdockMaple")
98
+ if renamed != value:
99
+ record.string = renamed.encode(record.getEncoding())
100
+ if family == "Termdock Prompt Icons":
101
+ suffix = "Bold" if "Bold" in stem else "Regular"
102
+ names = {1: family, 16: family, 3: f"TermdockPromptIcons-{suffix}",
103
+ 4: f"{family} {suffix}", 6: f"TermdockPromptIcons-{suffix}"}
104
+ for record in font["name"].names:
105
+ if record.nameID in names:
106
+ record.string = names[record.nameID].encode(record.getEncoding())
61
107
  buffer = io.BytesIO()
62
108
  font.save(buffer)
63
109
  body = buffer.getvalue()
64
- name = f"{stem}-{key}-{hashlib.sha256(body).hexdigest()[:12]}.woff2"
110
+ output_stem = stem.replace("MapleMono", "TermdockMaple")
111
+ if family == "Termdock Prompt Icons":
112
+ output_stem = stem.replace("JetBrainsMonoNLNerdFontMono", "TermdockPromptIcons")
113
+ name = f"{output_stem}-{key}-{hashlib.sha256(body).hexdigest()[:12]}.woff2"
65
114
  (OUTPUT / name).write_bytes(body)
66
115
  expected.add(name)
67
116
  # Verify both coverage and metrics rather than trusting the subsetter.
@@ -74,7 +123,10 @@ def main() -> None:
74
123
  style = "italic" if "Italic" in stem else "normal"
75
124
  css.append(f'@font-face{{font-family:"{family}";src:url("/fonts/terminal/{name}") format("woff2");font-weight:{weight};font-style:{style};font-display:swap;unicode-range:{ranges(points)};}}')
76
125
  records.append({"file": name, "bytes": len(body), "codepoints": len(points), "group": key})
77
- manifest["faces"].append({"source": source.name, "sourceSha256": hashlib.sha256(source.read_bytes()).hexdigest(), "shards": records})
126
+ record = {"source": source.name, "sourceSha256": hashlib.sha256(source.read_bytes()).hexdigest(), "shards": records}
127
+ if family == "Termdock Prompt Icons":
128
+ record["family"] = family
129
+ manifest["faces"].append(record)
78
130
  # Delete only generated font shards; the full source font pack is untouched.
79
131
  for old in OUTPUT.glob("*.woff2"):
80
132
  if old.name not in expected:
@@ -85,4 +137,7 @@ def main() -> None:
85
137
 
86
138
 
87
139
  if __name__ == "__main__":
88
- main()
140
+ parser = argparse.ArgumentParser(description=__doc__)
141
+ parser.add_argument("--family", action="append", choices=[family for family, _ in FAMILY_SOURCES],
142
+ help="Regenerate only this family, retaining other existing shards and manifest entries.")
143
+ main(parser.parse_args().family)