termdock 1.4.322 → 1.4.324

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 (364) hide show
  1. package/dist/client/assets/App-7IUcmCLC.js +186 -0
  2. package/dist/client/assets/App-7IUcmCLC.js.br +0 -0
  3. package/dist/client/assets/App-7IUcmCLC.js.gz +0 -0
  4. package/dist/client/assets/{ArchitecturePanel-VDM6hrwp.js → ArchitecturePanel-CUAB0wFe.js} +6 -6
  5. package/dist/client/assets/ArchitecturePanel-CUAB0wFe.js.br +0 -0
  6. package/dist/client/assets/ArchitecturePanel-CUAB0wFe.js.gz +0 -0
  7. package/dist/client/assets/{ChangeWalkthroughPanel-B64j3i8o.js → ChangeWalkthroughPanel-CKIG8diY.js} +2 -2
  8. package/dist/client/assets/ChangeWalkthroughPanel-CKIG8diY.js.br +0 -0
  9. package/dist/client/assets/ChangeWalkthroughPanel-CKIG8diY.js.gz +0 -0
  10. package/dist/client/assets/CollaborationMainWorkspace-CIq-JAbF.js +1 -0
  11. package/dist/client/assets/CollaborationMainWorkspace-CIq-JAbF.js.br +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-CIq-JAbF.js.gz +0 -0
  13. package/dist/client/assets/CollaborationTaskContent-7vWDzH-d.js +2 -0
  14. package/dist/client/assets/{ComputerControlView-Co-TTYas.js → ComputerControlView-CPSI-M86.js} +2 -2
  15. package/dist/client/assets/ComputerControlView-CPSI-M86.js.br +0 -0
  16. package/dist/client/assets/ComputerControlView-CPSI-M86.js.gz +0 -0
  17. package/dist/client/assets/{DagPlayground-kJczdJ6J.js → DagPlayground-BxocNRPm.js} +1 -1
  18. package/dist/client/assets/DagPlayground-BxocNRPm.js.br +0 -0
  19. package/dist/client/assets/DagPlayground-BxocNRPm.js.gz +0 -0
  20. package/dist/client/assets/{DiffLab-BaaioC-q.js → DiffLab-COGOFO0s.js} +2 -2
  21. package/dist/client/assets/DiffLab-COGOFO0s.js.br +0 -0
  22. package/dist/client/assets/DiffLab-COGOFO0s.js.gz +0 -0
  23. package/dist/client/assets/{DiffReview-Wfck3RIS.js → DiffReview-5ERdwz1C.js} +1 -1
  24. package/dist/client/assets/DiffReview-5ERdwz1C.js.br +0 -0
  25. package/dist/client/assets/DiffReview-5ERdwz1C.js.gz +0 -0
  26. package/dist/client/assets/{DiffReviewLab-Dblr3wgw.js → DiffReviewLab-BSz9IND6.js} +1 -1
  27. package/dist/client/assets/DiffReviewLab-BSz9IND6.js.br +0 -0
  28. package/dist/client/assets/DiffReviewLab-BSz9IND6.js.gz +0 -0
  29. package/dist/client/assets/{DiffViewer-C-utC5Ga.js → DiffViewer-RT-p-ZBo.js} +8 -8
  30. package/dist/client/assets/DiffViewer-RT-p-ZBo.js.br +0 -0
  31. package/dist/client/assets/DiffViewer-RT-p-ZBo.js.gz +0 -0
  32. package/dist/client/assets/{ModelPreview-BBLnHWVQ.js → ModelPreview-DI9anVWA.js} +1 -1
  33. package/dist/client/assets/ModelPreview-DI9anVWA.js.br +0 -0
  34. package/dist/client/assets/ModelPreview-DI9anVWA.js.gz +0 -0
  35. package/dist/client/assets/{RightSidebar-CUHSFkmZ.js → RightSidebar-DOLn8R7c.js} +36 -36
  36. package/dist/client/assets/RightSidebar-DOLn8R7c.js.br +0 -0
  37. package/dist/client/assets/RightSidebar-DOLn8R7c.js.gz +0 -0
  38. package/dist/client/assets/{abnfDiagram-VCTEODGH-DDd99QpA.js → abnfDiagram-VCTEODGH-CXd0unH5.js} +1 -1
  39. package/dist/client/assets/abnfDiagram-VCTEODGH-CXd0unH5.js.br +0 -0
  40. package/dist/client/assets/abnfDiagram-VCTEODGH-CXd0unH5.js.gz +0 -0
  41. package/dist/client/assets/app-DCFOZi_L.js +35 -0
  42. package/dist/client/assets/app-DCFOZi_L.js.br +0 -0
  43. package/dist/client/assets/app-DCFOZi_L.js.gz +0 -0
  44. package/dist/client/assets/{arc-C3dck_E0.js → arc-DCqJmX8M.js} +1 -1
  45. package/dist/client/assets/arc-DCqJmX8M.js.br +0 -0
  46. package/dist/client/assets/arc-DCqJmX8M.js.gz +0 -0
  47. package/dist/client/assets/{architectureDiagram-5GKGNRK7-C3bCQc2w.js → architectureDiagram-5GKGNRK7-DGu_m54H.js} +1 -1
  48. package/dist/client/assets/architectureDiagram-5GKGNRK7-DGu_m54H.js.br +0 -0
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-DGu_m54H.js.gz +0 -0
  50. package/dist/client/assets/{blockDiagram-I7D4REHJ-znMn6iCQ.js → blockDiagram-I7D4REHJ-BI0gsxDN.js} +1 -1
  51. package/dist/client/assets/blockDiagram-I7D4REHJ-BI0gsxDN.js.br +0 -0
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-BI0gsxDN.js.gz +0 -0
  53. package/dist/client/assets/{c4Diagram-7LVT6UL2-C0sopIsj.js → c4Diagram-7LVT6UL2-Ct3xzGtD.js} +1 -1
  54. package/dist/client/assets/c4Diagram-7LVT6UL2-Ct3xzGtD.js.br +0 -0
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-Ct3xzGtD.js.gz +0 -0
  56. package/dist/client/assets/channel-BLSCUksA.js +1 -0
  57. package/dist/client/assets/{chunk-2Q5K7J3B-f7USyccJ.js → chunk-2Q5K7J3B-BPd2UShA.js} +1 -1
  58. package/dist/client/assets/{chunk-5VM5RSS4-Ck2xirDs.js → chunk-5VM5RSS4-CoFZ5Fo3.js} +1 -1
  59. package/dist/client/assets/{chunk-F27PBJKO-DaDCIj30.js → chunk-F27PBJKO-C5gZrGp4.js} +1 -1
  60. package/dist/client/assets/chunk-F27PBJKO-C5gZrGp4.js.br +0 -0
  61. package/dist/client/assets/chunk-F27PBJKO-C5gZrGp4.js.gz +0 -0
  62. package/dist/client/assets/{chunk-IMKFNOWR-DEC_On5x.js → chunk-IMKFNOWR-GW8b9ya-.js} +1 -1
  63. package/dist/client/assets/chunk-IMKFNOWR-GW8b9ya-.js.br +0 -0
  64. package/dist/client/assets/chunk-IMKFNOWR-GW8b9ya-.js.gz +0 -0
  65. package/dist/client/assets/{chunk-JWPE2WC7-BrswC3n2.js → chunk-JWPE2WC7-GpMoViQf.js} +1 -1
  66. package/dist/client/assets/{chunk-POPQ4Y6H-ClMbDV47.js → chunk-POPQ4Y6H-C_vgVPaw.js} +1 -1
  67. package/dist/client/assets/{chunk-SVP7TREG-D7_1VwC5.js → chunk-SVP7TREG-bA7RXwWn.js} +1 -1
  68. package/dist/client/assets/chunk-SVP7TREG-bA7RXwWn.js.br +0 -0
  69. package/dist/client/assets/chunk-SVP7TREG-bA7RXwWn.js.gz +0 -0
  70. package/dist/client/assets/{chunk-TICWLB2K-D5jzVTZ8.js → chunk-TICWLB2K-BG8DAtll.js} +1 -1
  71. package/dist/client/assets/chunk-TICWLB2K-BG8DAtll.js.br +0 -0
  72. package/dist/client/assets/chunk-TICWLB2K-BG8DAtll.js.gz +0 -0
  73. package/dist/client/assets/{chunk-XXDRQBXY-DOhaoLcX.js → chunk-XXDRQBXY-Ces56sud.js} +1 -1
  74. package/dist/client/assets/classDiagram-ZZMXUADV-DkVIqOvw.js +1 -0
  75. package/dist/client/assets/classDiagram-v2-VYDZK3BY-DkVIqOvw.js +1 -0
  76. package/dist/client/assets/{cose-bilkent-JH36ORCC-DOsaKgiX.js → cose-bilkent-JH36ORCC-Bwch0qL5.js} +1 -1
  77. package/dist/client/assets/cose-bilkent-JH36ORCC-Bwch0qL5.js.br +0 -0
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-Bwch0qL5.js.gz +0 -0
  79. package/dist/client/assets/{cynefin-OW5HDTMX-CMcLh_wh.js → cynefin-OW5HDTMX-CrAXyA2Z.js} +1 -1
  80. package/dist/client/assets/cynefin-OW5HDTMX-CrAXyA2Z.js.br +0 -0
  81. package/dist/client/assets/cynefin-OW5HDTMX-CrAXyA2Z.js.gz +0 -0
  82. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js → cynefinDiagram-5FMLGOSQ-YlP0Q93l.js} +1 -1
  83. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-YlP0Q93l.js.br +0 -0
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-YlP0Q93l.js.gz +0 -0
  85. package/dist/client/assets/{dagre-GXQ25YYZ-BlW7fAi0.js → dagre-GXQ25YYZ-CZ4XcPK9.js} +1 -1
  86. package/dist/client/assets/dagre-GXQ25YYZ-CZ4XcPK9.js.br +0 -0
  87. package/dist/client/assets/dagre-GXQ25YYZ-CZ4XcPK9.js.gz +0 -0
  88. package/dist/client/assets/{diagram-S7CK7UJ4-B0-tKahG.js → diagram-S7CK7UJ4-c_8HfHGA.js} +1 -1
  89. package/dist/client/assets/{diagram-S7CK7UJ4-B0-tKahG.js.br → diagram-S7CK7UJ4-c_8HfHGA.js.br} +0 -0
  90. package/dist/client/assets/diagram-S7CK7UJ4-c_8HfHGA.js.gz +0 -0
  91. package/dist/client/assets/{diagram-UQ7AKVKN-BQumj4Dw.js → diagram-UQ7AKVKN-BGtRfxMR.js} +1 -1
  92. package/dist/client/assets/diagram-UQ7AKVKN-BGtRfxMR.js.br +0 -0
  93. package/dist/client/assets/diagram-UQ7AKVKN-BGtRfxMR.js.gz +0 -0
  94. package/dist/client/assets/{diagram-VSXAHHWV-Zx_FLmPP.js → diagram-VSXAHHWV-_9yZnhuv.js} +1 -1
  95. package/dist/client/assets/diagram-VSXAHHWV-_9yZnhuv.js.br +0 -0
  96. package/dist/client/assets/diagram-VSXAHHWV-_9yZnhuv.js.gz +0 -0
  97. package/dist/client/assets/{diagram-VX7I27RA-CEZvatNH.js → diagram-VX7I27RA-C_mnc4_u.js} +1 -1
  98. package/dist/client/assets/diagram-VX7I27RA-C_mnc4_u.js.br +0 -0
  99. package/dist/client/assets/diagram-VX7I27RA-C_mnc4_u.js.gz +0 -0
  100. package/dist/client/assets/{diagram-Z3DM3KII-CJ9IEQ8j.js → diagram-Z3DM3KII-sZ_AiSpj.js} +1 -1
  101. package/dist/client/assets/diagram-Z3DM3KII-sZ_AiSpj.js.br +0 -0
  102. package/dist/client/assets/diagram-Z3DM3KII-sZ_AiSpj.js.gz +0 -0
  103. package/dist/client/assets/{ebnfDiagram-PWID7BFC-sQQMv3ea.js → ebnfDiagram-PWID7BFC-Dm-BXeqS.js} +1 -1
  104. package/dist/client/assets/ebnfDiagram-PWID7BFC-Dm-BXeqS.js.br +0 -0
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-Dm-BXeqS.js.gz +0 -0
  106. package/dist/client/assets/{erDiagram-RLTQ6QDP-D3rMpj7M.js → erDiagram-RLTQ6QDP-Dz4cBepd.js} +1 -1
  107. package/dist/client/assets/erDiagram-RLTQ6QDP-Dz4cBepd.js.br +0 -0
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-Dz4cBepd.js.gz +0 -0
  109. package/dist/client/assets/{flowDiagram-HODETNUW-B6QZiE0-.js → flowDiagram-HODETNUW-CbRG8-WW.js} +1 -1
  110. package/dist/client/assets/flowDiagram-HODETNUW-CbRG8-WW.js.br +0 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-CbRG8-WW.js.gz +0 -0
  112. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-Bw9bltcu.js → ganttDiagram-EL5Y4UJY-CmBXWlr0.js} +1 -1
  113. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CmBXWlr0.js.br +0 -0
  114. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CmBXWlr0.js.gz +0 -0
  115. package/dist/client/assets/{gestureArbiter-Cczz34oI.js → gestureArbiter-B26W6rS7.js} +1 -1
  116. package/dist/client/assets/gestureArbiter-B26W6rS7.js.br +0 -0
  117. package/dist/client/assets/gestureArbiter-B26W6rS7.js.gz +0 -0
  118. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-mdnkxjeD.js → gitGraphDiagram-WWUBYQGX-JW5QMYEk.js} +1 -1
  119. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-JW5QMYEk.js.br +0 -0
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-JW5QMYEk.js.gz +0 -0
  121. package/dist/client/assets/index-Ctz-IDjR.css +1 -0
  122. package/dist/client/assets/index-Ctz-IDjR.css.br +0 -0
  123. package/dist/client/assets/{index-B4bEMUyn.css.gz → index-Ctz-IDjR.css.gz} +0 -0
  124. package/dist/client/assets/{infoDiagram-27XIBGKW-DyrPP3Yf.js → infoDiagram-27XIBGKW-CsA6WdPn.js} +1 -1
  125. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-CEPH_ePM.js → ishikawaDiagram-5VMMS53U-CsKPUwTw.js} +1 -1
  126. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CsKPUwTw.js.br +0 -0
  127. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CsKPUwTw.js.gz +0 -0
  128. package/dist/client/assets/{journeyDiagram-3NMN7TZE-CQ0PjBy7.js → journeyDiagram-3NMN7TZE-DpN98gN0.js} +1 -1
  129. package/dist/client/assets/journeyDiagram-3NMN7TZE-DpN98gN0.js.br +0 -0
  130. package/dist/client/assets/journeyDiagram-3NMN7TZE-DpN98gN0.js.gz +0 -0
  131. package/dist/client/assets/{kanban-definition-UXKFOSKX-BpQUXA60.js → kanban-definition-UXKFOSKX-RHO--43O.js} +1 -1
  132. package/dist/client/assets/kanban-definition-UXKFOSKX-RHO--43O.js.br +0 -0
  133. package/dist/client/assets/kanban-definition-UXKFOSKX-RHO--43O.js.gz +0 -0
  134. package/dist/client/assets/{layout-BdptC7rq.js → layout-Cm_prknW.js} +1 -1
  135. package/dist/client/assets/layout-Cm_prknW.js.br +0 -0
  136. package/dist/client/assets/layout-Cm_prknW.js.gz +0 -0
  137. package/dist/client/assets/{linear-C2cSRCxu.js → linear-BVAsPkvS.js} +1 -1
  138. package/dist/client/assets/linear-BVAsPkvS.js.br +0 -0
  139. package/dist/client/assets/linear-BVAsPkvS.js.gz +0 -0
  140. package/dist/client/assets/{mermaid.core-ClVMFyAU.js → mermaid.core-ufe77Xaz.js} +5 -5
  141. package/dist/client/assets/mermaid.core-ufe77Xaz.js.br +0 -0
  142. package/dist/client/assets/mermaid.core-ufe77Xaz.js.gz +0 -0
  143. package/dist/client/assets/{mindmap-definition-YA3MSWOX-D0AFCmsY.js → mindmap-definition-YA3MSWOX-CRyy1U2d.js} +1 -1
  144. package/dist/client/assets/mindmap-definition-YA3MSWOX-CRyy1U2d.js.br +0 -0
  145. package/dist/client/assets/mindmap-definition-YA3MSWOX-CRyy1U2d.js.gz +0 -0
  146. package/dist/client/assets/passwordBootstrap-3_SIzSH7.js +2 -0
  147. package/dist/client/assets/passwordBootstrap-3_SIzSH7.js.br +0 -0
  148. package/dist/client/assets/passwordBootstrap-3_SIzSH7.js.gz +0 -0
  149. package/dist/client/assets/{pegDiagram-XKGWAZYB-BGAh0bwg.js → pegDiagram-XKGWAZYB-DSHgdU9q.js} +1 -1
  150. package/dist/client/assets/pegDiagram-XKGWAZYB-DSHgdU9q.js.br +0 -0
  151. package/dist/client/assets/pegDiagram-XKGWAZYB-DSHgdU9q.js.gz +0 -0
  152. package/dist/client/assets/{pieDiagram-E7YTZNPT-CDOZUF44.js → pieDiagram-E7YTZNPT-lIUeAuhN.js} +1 -1
  153. package/dist/client/assets/pieDiagram-E7YTZNPT-lIUeAuhN.js.br +0 -0
  154. package/dist/client/assets/pieDiagram-E7YTZNPT-lIUeAuhN.js.gz +0 -0
  155. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-D_Qn6NTU.js → quadrantDiagram-AXDQQJYC-CIgG9vBX.js} +1 -1
  156. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CIgG9vBX.js.br +0 -0
  157. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CIgG9vBX.js.gz +0 -0
  158. package/dist/client/assets/{railroadDiagram-O6MQD6OU-qUVGWhJN.js → railroadDiagram-O6MQD6OU-DjP8oesA.js} +1 -1
  159. package/dist/client/assets/railroadDiagram-O6MQD6OU-DjP8oesA.js.br +0 -0
  160. package/dist/client/assets/railroadDiagram-O6MQD6OU-DjP8oesA.js.gz +0 -0
  161. package/dist/client/assets/{rdpSession-hgCM4i-j.js → rdpSession-BshIobdj.js} +1 -1
  162. package/dist/client/assets/rdpSession-BshIobdj.js.br +0 -0
  163. package/dist/client/assets/rdpSession-BshIobdj.js.gz +0 -0
  164. package/dist/client/assets/{referenceLongPress-BEMsP11a.js → referenceLongPress-DBJnfFHa.js} +1 -1
  165. package/dist/client/assets/referenceLongPress-DBJnfFHa.js.br +0 -0
  166. package/dist/client/assets/referenceLongPress-DBJnfFHa.js.gz +0 -0
  167. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BBQMQuVZ.js → requirementDiagram-BXWQKSXE-Dbvu6IC_.js} +1 -1
  168. package/dist/client/assets/requirementDiagram-BXWQKSXE-Dbvu6IC_.js.br +0 -0
  169. package/dist/client/assets/requirementDiagram-BXWQKSXE-Dbvu6IC_.js.gz +0 -0
  170. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CeEExsqW.js → sankeyDiagram-P5KCCOFB-1mZ4s-lv.js} +1 -1
  171. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CeEExsqW.js.br → sankeyDiagram-P5KCCOFB-1mZ4s-lv.js.br} +0 -0
  172. package/dist/client/assets/sankeyDiagram-P5KCCOFB-1mZ4s-lv.js.gz +0 -0
  173. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js → sequenceDiagram-WJ2MYXX4-Cu3hhzlV.js} +1 -1
  174. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Cu3hhzlV.js.br +0 -0
  175. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-Cu3hhzlV.js.gz +0 -0
  176. package/dist/client/assets/{sizeCapture-INFHLROL-MBjz7Snm.js → sizeCapture-INFHLROL-xfm69HlR.js} +1 -1
  177. package/dist/client/assets/sizeCapture-INFHLROL-xfm69HlR.js.br +0 -0
  178. package/dist/client/assets/sizeCapture-INFHLROL-xfm69HlR.js.gz +0 -0
  179. package/dist/client/assets/{sparkles-C9ShmGPf.js → sparkles-CDonlwGu.js} +1 -1
  180. package/dist/client/assets/{stateDiagram-D77RDMKH-DtLp89uP.js → stateDiagram-D77RDMKH-u-bh6mDK.js} +1 -1
  181. package/dist/client/assets/stateDiagram-D77RDMKH-u-bh6mDK.js.br +0 -0
  182. package/dist/client/assets/stateDiagram-D77RDMKH-u-bh6mDK.js.gz +0 -0
  183. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BQ_m8Gzd.js +1 -0
  184. package/dist/client/assets/{swimlanes-42K2YHIH-Bc02S1q-.js → swimlanes-42K2YHIH-U8WN__SO.js} +1 -1
  185. package/dist/client/assets/swimlanes-42K2YHIH-U8WN__SO.js.br +0 -0
  186. package/dist/client/assets/swimlanes-42K2YHIH-U8WN__SO.js.gz +0 -0
  187. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-FDEo3QWw.js +8 -0
  188. package/dist/client/assets/{timeline-definition-24CTP7MA-BLLwbOm5.js → timeline-definition-24CTP7MA-CMsoNo4F.js} +1 -1
  189. package/dist/client/assets/timeline-definition-24CTP7MA-CMsoNo4F.js.br +0 -0
  190. package/dist/client/assets/timeline-definition-24CTP7MA-CMsoNo4F.js.gz +0 -0
  191. package/dist/client/assets/{triangle-alert-i_L8ws6U.js → triangle-alert-BgErMO2V.js} +1 -1
  192. package/dist/client/assets/{vennDiagram-4TSXK5OY-8FcrAdbk.js → vennDiagram-4TSXK5OY-CPE6pVwh.js} +1 -1
  193. package/dist/client/assets/{vennDiagram-4TSXK5OY-8FcrAdbk.js.br → vennDiagram-4TSXK5OY-CPE6pVwh.js.br} +0 -0
  194. package/dist/client/assets/vennDiagram-4TSXK5OY-CPE6pVwh.js.gz +0 -0
  195. package/dist/client/assets/{videoCompression-RIaDabW4.js → videoCompression-BWkZvEjM.js} +1 -1
  196. package/dist/client/assets/videoCompression-BWkZvEjM.js.br +0 -0
  197. package/dist/client/assets/videoCompression-BWkZvEjM.js.gz +0 -0
  198. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-paL2wRrJ.js → wardleyDiagram-VM6X3IG4-4lWd-R4N.js} +1 -1
  199. package/dist/client/assets/wardleyDiagram-VM6X3IG4-4lWd-R4N.js.br +0 -0
  200. package/dist/client/assets/wardleyDiagram-VM6X3IG4-4lWd-R4N.js.gz +0 -0
  201. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-BM5qJ4E7.js → xychartDiagram-S5SC5T6Z-CpKJMCWV.js} +1 -1
  202. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CpKJMCWV.js.br +0 -0
  203. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CpKJMCWV.js.gz +0 -0
  204. package/dist/client/index.html +2 -2
  205. package/dist/client/index.html.br +0 -0
  206. package/dist/client/index.html.gz +0 -0
  207. package/dist/client/sw-encrypted-background.js +1 -1
  208. package/dist/client/sw-encrypted-background.js.br +0 -0
  209. package/dist/client/sw-encrypted-background.js.gz +0 -0
  210. package/dist/client/sw.js +1 -1
  211. package/dist/client/sw.js.br +0 -0
  212. package/dist/client/sw.js.gz +0 -0
  213. package/dist/server/agent/collaborationGroupRoutes.js +15 -0
  214. package/dist/server/agent/collaborationStore.js +63 -2
  215. package/dist/server/agent/collaborationTaskRoutes.js +5 -1
  216. package/dist/server/agent/integrationCli.js +38 -20
  217. package/dist/server/agent/integrationServer.js +18 -1
  218. package/dist/server/federation/packets.js +179 -28
  219. package/dist/server/federation/requestContext.js +6 -1
  220. package/dist/server/federation/runtime.js +19 -8
  221. package/dist/server/routes/terminal.js +60 -20
  222. package/dist/server/utils/autoUpdate.js +55 -8
  223. package/dist/server/utils/npmUpdate.js +84 -8
  224. package/dist/server/utils/terminalPasteBuffer.js +66 -0
  225. package/dist/server/utils/tmuxClientCapabilities.js +4 -0
  226. package/dist/server/utils/tmuxCopySelection.js +94 -0
  227. package/dist/server/utils/tmuxEmptyServerProbe.js +15 -0
  228. package/docs/integrations.md +36 -0
  229. package/package.json +5 -2
  230. package/runtime-manifest.json +3 -3
  231. package/.desktop-dist/main.js +0 -1989
  232. package/dist/client/assets/App-DEKo4SNL.js +0 -186
  233. package/dist/client/assets/App-DEKo4SNL.js.br +0 -0
  234. package/dist/client/assets/App-DEKo4SNL.js.gz +0 -0
  235. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.br +0 -0
  236. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.gz +0 -0
  237. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.br +0 -0
  238. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.gz +0 -0
  239. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js +0 -1
  240. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.br +0 -0
  241. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.gz +0 -0
  242. package/dist/client/assets/CollaborationTaskContent-msQsgVaI.js +0 -2
  243. package/dist/client/assets/ComputerControlView-Co-TTYas.js.br +0 -0
  244. package/dist/client/assets/ComputerControlView-Co-TTYas.js.gz +0 -0
  245. package/dist/client/assets/DagPlayground-kJczdJ6J.js.br +0 -0
  246. package/dist/client/assets/DagPlayground-kJczdJ6J.js.gz +0 -0
  247. package/dist/client/assets/DiffLab-BaaioC-q.js.br +0 -0
  248. package/dist/client/assets/DiffLab-BaaioC-q.js.gz +0 -0
  249. package/dist/client/assets/DiffReview-Wfck3RIS.js.br +0 -0
  250. package/dist/client/assets/DiffReview-Wfck3RIS.js.gz +0 -0
  251. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.br +0 -0
  252. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.gz +0 -0
  253. package/dist/client/assets/DiffViewer-C-utC5Ga.js.br +0 -0
  254. package/dist/client/assets/DiffViewer-C-utC5Ga.js.gz +0 -0
  255. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.br +0 -0
  256. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.gz +0 -0
  257. package/dist/client/assets/RightSidebar-CUHSFkmZ.js.br +0 -0
  258. package/dist/client/assets/RightSidebar-CUHSFkmZ.js.gz +0 -0
  259. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.br +0 -0
  260. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.gz +0 -0
  261. package/dist/client/assets/app-CfqF7_nh.js +0 -35
  262. package/dist/client/assets/app-CfqF7_nh.js.br +0 -0
  263. package/dist/client/assets/app-CfqF7_nh.js.gz +0 -0
  264. package/dist/client/assets/arc-C3dck_E0.js.br +0 -0
  265. package/dist/client/assets/arc-C3dck_E0.js.gz +0 -0
  266. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.br +0 -0
  267. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.gz +0 -0
  268. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.br +0 -0
  269. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.gz +0 -0
  270. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.br +0 -0
  271. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.gz +0 -0
  272. package/dist/client/assets/channel-CMC8t83j.js +0 -1
  273. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.br +0 -0
  274. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.gz +0 -0
  275. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.br +0 -0
  276. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.gz +0 -0
  277. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.br +0 -0
  278. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.gz +0 -0
  279. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.br +0 -0
  280. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.gz +0 -0
  281. package/dist/client/assets/classDiagram-ZZMXUADV-ElMHzA-E.js +0 -1
  282. package/dist/client/assets/classDiagram-v2-VYDZK3BY-ElMHzA-E.js +0 -1
  283. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.br +0 -0
  284. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.gz +0 -0
  285. package/dist/client/assets/cynefin-OW5HDTMX-CMcLh_wh.js.br +0 -0
  286. package/dist/client/assets/cynefin-OW5HDTMX-CMcLh_wh.js.gz +0 -0
  287. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.br +0 -0
  288. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.gz +0 -0
  289. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.br +0 -0
  290. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.gz +0 -0
  291. package/dist/client/assets/diagram-S7CK7UJ4-B0-tKahG.js.gz +0 -0
  292. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.br +0 -0
  293. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.gz +0 -0
  294. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.br +0 -0
  295. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.gz +0 -0
  296. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.br +0 -0
  297. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.gz +0 -0
  298. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.br +0 -0
  299. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.gz +0 -0
  300. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.br +0 -0
  301. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.gz +0 -0
  302. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.br +0 -0
  303. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.gz +0 -0
  304. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.br +0 -0
  305. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.gz +0 -0
  306. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.br +0 -0
  307. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.gz +0 -0
  308. package/dist/client/assets/gestureArbiter-Cczz34oI.js.br +0 -0
  309. package/dist/client/assets/gestureArbiter-Cczz34oI.js.gz +0 -0
  310. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.br +0 -0
  311. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.gz +0 -0
  312. package/dist/client/assets/index-B4bEMUyn.css +0 -1
  313. package/dist/client/assets/index-B4bEMUyn.css.br +0 -0
  314. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.br +0 -0
  315. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.gz +0 -0
  316. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.br +0 -0
  317. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.gz +0 -0
  318. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.br +0 -0
  319. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.gz +0 -0
  320. package/dist/client/assets/layout-BdptC7rq.js.br +0 -0
  321. package/dist/client/assets/layout-BdptC7rq.js.gz +0 -0
  322. package/dist/client/assets/linear-C2cSRCxu.js.br +0 -0
  323. package/dist/client/assets/linear-C2cSRCxu.js.gz +0 -0
  324. package/dist/client/assets/mermaid.core-ClVMFyAU.js.br +0 -0
  325. package/dist/client/assets/mermaid.core-ClVMFyAU.js.gz +0 -0
  326. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.br +0 -0
  327. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.gz +0 -0
  328. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js +0 -2
  329. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.br +0 -0
  330. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.gz +0 -0
  331. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.br +0 -0
  332. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.gz +0 -0
  333. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.br +0 -0
  334. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.gz +0 -0
  335. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.br +0 -0
  336. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.gz +0 -0
  337. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.br +0 -0
  338. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.gz +0 -0
  339. package/dist/client/assets/rdpSession-hgCM4i-j.js.br +0 -0
  340. package/dist/client/assets/rdpSession-hgCM4i-j.js.gz +0 -0
  341. package/dist/client/assets/referenceLongPress-BEMsP11a.js.br +0 -0
  342. package/dist/client/assets/referenceLongPress-BEMsP11a.js.gz +0 -0
  343. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.br +0 -0
  344. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.gz +0 -0
  345. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CeEExsqW.js.gz +0 -0
  346. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.br +0 -0
  347. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.gz +0 -0
  348. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.br +0 -0
  349. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.gz +0 -0
  350. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.br +0 -0
  351. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.gz +0 -0
  352. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CIQb4Dp7.js +0 -1
  353. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.br +0 -0
  354. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.gz +0 -0
  355. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-RiKL7eXI.js +0 -8
  356. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.br +0 -0
  357. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.gz +0 -0
  358. package/dist/client/assets/vennDiagram-4TSXK5OY-8FcrAdbk.js.gz +0 -0
  359. package/dist/client/assets/videoCompression-RIaDabW4.js.br +0 -0
  360. package/dist/client/assets/videoCompression-RIaDabW4.js.gz +0 -0
  361. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.br +0 -0
  362. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.gz +0 -0
  363. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.br +0 -0
  364. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.gz +0 -0
@@ -24,12 +24,14 @@ class LogicalSocket extends EventEmitter {
24
24
  canRead;
25
25
  OPEN = 1;
26
26
  readyState = 1;
27
- bufferedAmount = 0;
28
- constructor(channel, id, canRead) {
27
+ get bufferedAmount() { return this.channel.queuedBytesFor(this.id); }
28
+ maxQueuedBytes;
29
+ constructor(channel, id, canRead, maxQueuedBytes = 4 * 1024 * 1024) {
29
30
  super();
30
31
  this.channel = channel;
31
32
  this.id = id;
32
33
  this.canRead = canRead;
34
+ this.maxQueuedBytes = maxQueuedBytes;
33
35
  }
34
36
  send(data) {
35
37
  if (this.readyState !== 1)
@@ -38,12 +40,18 @@ class LogicalSocket extends EventEmitter {
38
40
  this.close(4003, 'Authorization revoked');
39
41
  return;
40
42
  }
43
+ // Apply the terminal backlog threshold to bytes already queued, leaving a
44
+ // single protocol-valid record (up to MAX_PACKET) intact. Other logical
45
+ // streams retain the shared channel budget and its own backpressure guard.
46
+ if (this.channel.queuedBytesFor(this.id) > this.maxQueuedBytes) {
47
+ this.close(1013, 'Output consumer is too slow');
48
+ return;
49
+ }
41
50
  try {
42
51
  this.channel.send({ type: 'ws-data', id: this.id, data });
43
52
  }
44
- catch (error) {
45
- this.channel.close(error instanceof Error ? error : new Error('Output transport failed'));
46
- this.close();
53
+ catch {
54
+ this.close(1013, 'Output consumer is too slow');
47
55
  }
48
56
  }
49
57
  close(code = 1000, reason = '') {
@@ -100,7 +108,9 @@ export async function createFederationRuntime(app, directory, handlers, options
100
108
  delete request.headers['x-termdock-inner'];
101
109
  const subject = request.headers['x-termdock-device'];
102
110
  delete request.headers['x-termdock-device'];
103
- markEncryptedRequest(request, typeof subject === 'string' ? subject : undefined);
111
+ const fullService = request.headers['x-termdock-full-service'] === '1';
112
+ delete request.headers['x-termdock-full-service'];
113
+ markEncryptedRequest(request, typeof subject === 'string' ? subject : undefined, fullService);
104
114
  app(request, response);
105
115
  });
106
116
  await new Promise((resolve, reject) => { internal.once('error', reject); internal.listen(0, '127.0.0.1', resolve); });
@@ -177,7 +187,8 @@ export async function createFederationRuntime(app, directory, handlers, options
177
187
  };
178
188
  try {
179
189
  httpAllowed(operation.head);
180
- const headers = new Headers({ 'x-termdock-inner': internalToken, 'x-termdock-device': subjectId });
190
+ const headers = new Headers({ 'x-termdock-inner': internalToken, 'x-termdock-device': subjectId,
191
+ 'x-termdock-full-service': full(subjectId) ? '1' : '0' });
181
192
  const supplied = operation.head.headers;
182
193
  if (supplied && typeof supplied === 'object')
183
194
  for (const [name, value] of Object.entries(supplied)) {
@@ -580,7 +591,7 @@ export async function createFederationRuntime(app, directory, handlers, options
580
591
  }
581
592
  else
582
593
  throw new Error('API_NOT_ALLOWED');
583
- const logical = new LogicalSocket(channel, packet.id, () => (androidMatch || computer) ? full(subjectId) : allowed(subjectId, match ? 'session.view' : 'service.view', match?.[1]));
594
+ const logical = new LogicalSocket(channel, packet.id, () => (androidMatch || computer) ? full(subjectId) : allowed(subjectId, match ? 'session.view' : 'service.view', match?.[1]), match ? 1024 * 1024 : undefined);
584
595
  sockets.set(packet.id, { socket: logical, sessionId: match?.[1], android: Boolean(androidMatch), computer,
585
596
  computerProtocol: computer ? url.searchParams.get('protocol') ?? 'vnc' : undefined });
586
597
  logical.once('close', () => sockets.delete(packet.id));
@@ -1,3 +1,5 @@
1
+ import { copyTmuxSelection } from '../utils/tmuxCopySelection.js';
2
+ import { isConfirmedEmptyTmuxServer } from '../utils/tmuxEmptyServerProbe.js';
1
3
  import { collaborationSessionDisplayName } from '../utils/sessionDisplayName.js';
2
4
  import { integrationError } from '../agent/integrationStore.js';
3
5
  import { assertNativeResumeAvailable, collectNativeResumeOwnerCandidates } from '../agent/nativeResumeOwner.js';
@@ -14,6 +16,7 @@ import { ensureNodePty } from '../utils/ensureNodePty.js';
14
16
  import { PtySpawnBackoff, PtySpawnDeferredError } from '../utils/ptySpawnBackoff.js';
15
17
  import { collaborationGroupRoutes } from '../agent/collaborationGroupRoutes.js';
16
18
  import { TerminalClientAttachment } from '../utils/terminalClientAttachment.js';
19
+ import { TerminalPasteBuffer } from '../utils/terminalPasteBuffer.js';
17
20
  import { SharedSessionSampler, SharedSnapshotCache } from '../utils/sharedSampling.js';
18
21
  import { batchTmuxOptions, TmuxMetadataWriter } from '../utils/tmuxMetadataWriter.js';
19
22
  import { redrawTmuxClient } from '../utils/tmuxClientRedraw.js';
@@ -2522,10 +2525,10 @@ function getTmuxBinary() {
2522
2525
  }
2523
2526
  return 'tmux'; // fallback to PATH
2524
2527
  }
2525
- async function runTmux(args) {
2528
+ async function runTmux(args, options) {
2526
2529
  const { stdout } = await execFileAsync(getTmuxBinary(), args, {
2527
2530
  timeout: 5000,
2528
- maxBuffer: 2 * 1024 * 1024,
2531
+ maxBuffer: options?.maxBuffer ?? 2 * 1024 * 1024,
2529
2532
  env: buildInteractiveColorEnvironment(process.env),
2530
2533
  });
2531
2534
  return stdout;
@@ -4684,19 +4687,26 @@ async function resolveTmuxClientTty(sessionName, preferredClientPid) {
4684
4687
  }
4685
4688
  async function ensureTmuxSessionExists(sessionName, cwd) {
4686
4689
  let serverWasMissing = false;
4690
+ let serverIsEmpty = false;
4691
+ let sessionExists = false;
4687
4692
  try {
4688
4693
  await runTmux(['has-session', '-t', sessionName]);
4689
- await ensureTmuxColorEnvironment(sessionName);
4690
- return;
4694
+ sessionExists = true;
4691
4695
  }
4692
4696
  catch (error) {
4693
4697
  const errorMessage = getErrorMessage(error);
4694
4698
  serverWasMissing = isTmuxServerMissingMessage(errorMessage);
4695
4699
  if (!isTmuxSessionMissingMessage(errorMessage)) {
4696
- throw error;
4700
+ serverIsEmpty = await isConfirmedEmptyTmuxServer(error, sessionName, runTmux);
4701
+ if (!serverIsEmpty)
4702
+ throw error;
4697
4703
  }
4698
4704
  }
4699
- if (!serverWasMissing) {
4705
+ if (sessionExists) {
4706
+ await ensureTmuxColorEnvironment(sessionName);
4707
+ return;
4708
+ }
4709
+ if (!serverWasMissing && !serverIsEmpty) {
4700
4710
  await ensureTmuxColorEnvironment();
4701
4711
  }
4702
4712
  const innerTerm = await resolveTmuxInnerTerm();
@@ -8306,7 +8316,10 @@ router.post('/:sessionId/input', express.text({ type: '*/*' }), (req, res) => {
8306
8316
  }
8307
8317
  const data = typeof req.body === 'string' ? req.body : '';
8308
8318
  try {
8309
- session.ptyProcess.write(data);
8319
+ const paste = new TerminalPasteBuffer(() => { });
8320
+ const parts = paste.complete(data);
8321
+ for (const part of parts)
8322
+ session.ptyProcess.write(part);
8310
8323
  session.lastActivity = Date.now();
8311
8324
  res.json({ success: true });
8312
8325
  }
@@ -8475,7 +8488,7 @@ router.post('/:sessionId/tmux', async (req, res) => {
8475
8488
  broadcastEvent(sessionId, { type: 'tmux-layout', layout });
8476
8489
  return res.json({ success: true, layout });
8477
8490
  }
8478
- return res.json({ success: true });
8491
+ return res.json({ success: true, ...(result.selection ? { selection: result.selection } : {}) });
8479
8492
  }
8480
8493
  catch (error) {
8481
8494
  const errorMessage = getErrorMessage(error);
@@ -8570,6 +8583,10 @@ router.post('/force-kill', (req, res) => {
8570
8583
  async function executeTmuxAction(tmuxTarget, action, body, control) {
8571
8584
  let shouldBroadcastLayout = true;
8572
8585
  switch (action) {
8586
+ case 'copy-selection': {
8587
+ const selection = await copyTmuxSelection(tmuxTarget, runTmux);
8588
+ return { shouldBroadcastLayout: false, selection };
8589
+ }
8573
8590
  case 'select-pane': {
8574
8591
  const paneId = typeof body.paneId === 'string' ? body.paneId : '';
8575
8592
  if (!paneId)
@@ -8960,6 +8977,12 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
8960
8977
  if (ws.readyState === ws.OPEN)
8961
8978
  ws.send(JSON.stringify(event));
8962
8979
  });
8980
+ const pasteInput = new TerminalPasteBuffer(error => {
8981
+ if (ws.readyState === ws.OPEN) {
8982
+ ws.send(JSON.stringify({ type: 'error', error }));
8983
+ ws.close(1008, 'Incomplete terminal paste');
8984
+ }
8985
+ });
8963
8986
  // Handle client → server messages
8964
8987
  ws.on('message', async (raw) => {
8965
8988
  const messageReceivedAt = performance.now();
@@ -8974,20 +8997,30 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
8974
8997
  switch (msg.type) {
8975
8998
  case 'input': {
8976
8999
  if (typeof msg.data === 'string' && msg.data.length > 0) {
8977
- const data = msg.data;
8978
- if (attachment) {
8979
- session.lastActivity = Date.now();
8980
- attachment.write(data);
9000
+ let parts;
9001
+ try {
9002
+ parts = pasteInput.push(msg.data);
9003
+ }
9004
+ catch (error) {
9005
+ ws.send(JSON.stringify({ type: 'error', error: getErrorMessage(error) }));
9006
+ ws.close(1008, 'Invalid terminal paste');
9007
+ return;
8981
9008
  }
8982
- else if (session.mode === 'tmux') {
8983
- await enqueueTmuxIo(session, async () => {
9009
+ for (const data of parts) {
9010
+ if (attachment) {
9011
+ session.lastActivity = Date.now();
9012
+ attachment.write(data);
9013
+ }
9014
+ else if (session.mode === 'tmux') {
9015
+ await enqueueTmuxIo(session, async () => {
9016
+ session.lastActivity = Date.now();
9017
+ session.ptyProcess.write(data);
9018
+ });
9019
+ }
9020
+ else {
8984
9021
  session.lastActivity = Date.now();
8985
9022
  session.ptyProcess.write(data);
8986
- });
8987
- }
8988
- else {
8989
- session.lastActivity = Date.now();
8990
- session.ptyProcess.write(data);
9023
+ }
8991
9024
  }
8992
9025
  }
8993
9026
  break;
@@ -9055,8 +9088,14 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
9055
9088
  }
9056
9089
  const result = await enqueueTmuxIo(session, async () => {
9057
9090
  return executeTmuxAction(session.tmuxSessionName, msg.action, msg, session.tmuxControl);
9091
+ }).catch((error) => {
9092
+ // A correlated copy failure must settle this socket's request, not
9093
+ // become an unrelated terminal error followed by a 30-second wait.
9094
+ if (msg.action !== 'copy-selection')
9095
+ throw error;
9096
+ return { shouldBroadcastLayout: false, error: getErrorMessage(error) || 'Tmux selection copy failed' };
9058
9097
  });
9059
- ws.send(JSON.stringify({ type: 'tmux-result', reqId, success: !result.error, error: result.error }));
9098
+ ws.send(JSON.stringify({ type: 'tmux-result', reqId, success: !result.error, error: result.error, ...(result.selection ? { selection: result.selection } : {}) }));
9060
9099
  if (result.shouldBroadcastLayout && session.tmuxSessionName) {
9061
9100
  try {
9062
9101
  const layout = await getTmuxLayout(session.tmuxSessionName);
@@ -9154,6 +9193,7 @@ export function handleTerminalWebSocket(ws, sessionId, clientId, options = {}, i
9154
9193
  });
9155
9194
  // Cleanup on close
9156
9195
  ws.on('close', () => {
9196
+ pasteInput.clear();
9157
9197
  initialScreen?.cancel();
9158
9198
  initialScreen = null;
9159
9199
  attachment?.close();
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { compareVersions, updateTermdockFromOfficialRegistry, } from './npmUpdate.js';
3
+ import { compareVersions, verifyRunningTermdockInstallation, updateTermdockFromOfficialRegistry, } from './npmUpdate.js';
4
4
  export const AUTO_UPDATE_INITIAL_DELAY_MS = 15_000;
5
5
  export const AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1_000;
6
6
  function initialState(currentVersion) {
@@ -44,11 +44,11 @@ export class TermdockAutoUpdateManager {
44
44
  return;
45
45
  this.initialTimer = setTimeout(() => {
46
46
  this.initialTimer = null;
47
- void this.checkNow();
47
+ void this.checkNow(false);
48
48
  }, AUTO_UPDATE_INITIAL_DELAY_MS);
49
49
  this.initialTimer.unref?.();
50
50
  this.intervalTimer = setInterval(() => {
51
- void this.checkNow();
51
+ void this.checkNow(false);
52
52
  }, AUTO_UPDATE_INTERVAL_MS);
53
53
  this.intervalTimer.unref?.();
54
54
  }
@@ -60,12 +60,24 @@ export class TermdockAutoUpdateManager {
60
60
  this.initialTimer = null;
61
61
  this.intervalTimer = null;
62
62
  }
63
- checkNow() {
63
+ checkNow(explicit = true) {
64
+ // Failed installation validation requires a user-requested check, not a timer retry.
65
+ if (!explicit && this.state.status === 'error' && hasPendingTermdockUpdate(this.state))
66
+ return Promise.resolve(this.getState());
64
67
  // Once an installed update is waiting for explicit confirmation, periodic
65
68
  // checks must never turn any external state change into implicit consent.
66
69
  // Keep the reminder until the user confirms or restarts manually.
67
70
  if (this.state.status === 'ready' && hasPendingTermdockUpdate(this.state)) {
68
- return Promise.resolve(this.getState());
71
+ try {
72
+ this.verifyInstalled(this.state.latestVersion);
73
+ return Promise.resolve(this.getState());
74
+ }
75
+ catch (error) {
76
+ this.installationError(error);
77
+ if (!explicit)
78
+ return Promise.resolve(this.getState());
79
+ }
80
+ // Only the explicit check repairs an invalid pending installation; never restart here.
69
81
  }
70
82
  if (this.checkPromise)
71
83
  return this.checkPromise;
@@ -78,10 +90,33 @@ export class TermdockAutoUpdateManager {
78
90
  if (this.state.status !== 'ready' || !hasPendingTermdockUpdate(this.state)) {
79
91
  throw new Error('No installed Termdock update is waiting for restart.');
80
92
  }
93
+ try {
94
+ this.verifyInstalled(this.state.latestVersion);
95
+ if (process.env.TERMDOCK_SUPERVISED !== '1' || !process.connected)
96
+ throw new Error('Automatic restart requires the verified supervised Termdock entry; restart manually.');
97
+ this.dependencies.verifyRestartEntry?.();
98
+ }
99
+ catch (error) {
100
+ this.installationError(error);
101
+ throw error;
102
+ }
81
103
  this.setState({ ...this.state, status: 'restarting', error: null });
82
- this.dependencies.requestRestart();
104
+ try {
105
+ this.dependencies.requestRestart();
106
+ }
107
+ catch (error) {
108
+ this.installationError(error);
109
+ throw error;
110
+ }
83
111
  return this.getState();
84
112
  }
113
+ verifyInstalled(version) {
114
+ (this.dependencies.verifyInstalled ?? verifyRunningTermdockInstallation)(version);
115
+ }
116
+ installationError(error) {
117
+ const detail = error instanceof Error ? error.message : String(error);
118
+ this.setState({ ...this.state, status: 'error', error: detail });
119
+ }
85
120
  async runCheck() {
86
121
  this.setState({ ...this.state, status: 'checking', checkedAt: Date.now(), error: null });
87
122
  try {
@@ -110,6 +145,7 @@ export class TermdockAutoUpdateManager {
110
145
  });
111
146
  return this.getState();
112
147
  }
148
+ this.verifyInstalled(result.latestVersion);
113
149
  this.setState({
114
150
  status: 'ready',
115
151
  currentVersion: result.currentVersion,
@@ -145,13 +181,24 @@ export class TermdockAutoUpdateManager {
145
181
  return fallback;
146
182
  if (value.status !== 'ready' && value.status !== 'restarting' && value.status !== 'error')
147
183
  return fallback;
184
+ let restoredStatus = value.status === 'restarting' ? 'ready' : value.status;
185
+ let restoredError = typeof value.error === 'string' ? value.error : null;
186
+ if (restoredStatus === 'ready') {
187
+ try {
188
+ this.verifyInstalled(value.latestVersion);
189
+ }
190
+ catch (error) {
191
+ restoredStatus = 'error';
192
+ restoredError = error instanceof Error ? error.message : String(error);
193
+ }
194
+ }
148
195
  return {
149
- status: value.status === 'restarting' ? 'ready' : value.status,
196
+ status: restoredStatus,
150
197
  currentVersion: this.dependencies.currentVersion,
151
198
  latestVersion: value.latestVersion,
152
199
  source: value.source === 'configured' ? 'configured' : 'official',
153
200
  checkedAt: typeof value.checkedAt === 'number' ? value.checkedAt : null,
154
- error: typeof value.error === 'string' ? value.error : null,
201
+ error: restoredError,
155
202
  };
156
203
  }
157
204
  catch {
@@ -1,5 +1,8 @@
1
1
  import { execFile, spawn } from 'node:child_process';
2
2
  import { promisify } from 'node:util';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
3
6
  const execFileAsync = promisify(execFile);
4
7
  export const OFFICIAL_NPM_REGISTRY = 'https://registry.npmjs.org';
5
8
  const TERMDOCK_PACKAGE = 'termdock';
@@ -41,7 +44,7 @@ export function buildNpmViewArgs(registry = OFFICIAL_NPM_REGISTRY) {
41
44
  args.push('--registry', registry);
42
45
  return args;
43
46
  }
44
- export function buildNpmInstallArgs(version, registry = OFFICIAL_NPM_REGISTRY) {
47
+ export function buildNpmInstallArgs(version, registry = OFFICIAL_NPM_REGISTRY, prefix) {
45
48
  if (!parseVersion(version))
46
49
  throw new Error(`Invalid Termdock version from npm: ${version}`);
47
50
  const args = [
@@ -49,11 +52,56 @@ export function buildNpmInstallArgs(version, registry = OFFICIAL_NPM_REGISTRY) {
49
52
  '--global',
50
53
  `${TERMDOCK_PACKAGE}@${version}`,
51
54
  ];
55
+ if (prefix)
56
+ args.push('--prefix', prefix);
52
57
  if (registry)
53
58
  args.push('--registry', registry);
54
59
  args.push('--foreground-scripts');
55
60
  return args;
56
61
  }
62
+ function installedVersion(installation) {
63
+ // Fresh filesystem reads: npm replaces this package while this process keeps
64
+ // running old JS. Neither require/import caches nor TERMDOCK_VERSION attest it.
65
+ if (fs.realpathSync(installation.packageRoot) !== installation.packageRoot) {
66
+ throw new Error('Running Termdock installation changed location; check for updates again.');
67
+ }
68
+ const value = JSON.parse(fs.readFileSync(path.join(installation.packageRoot, 'package.json'), 'utf8'));
69
+ if (!value || typeof value !== 'object' || !('name' in value) || value.name !== TERMDOCK_PACKAGE
70
+ || !('version' in value) || typeof value.version !== 'string' || !parseVersion(value.version)) {
71
+ throw new Error('Running Termdock installation has invalid package metadata.');
72
+ }
73
+ return value.version;
74
+ }
75
+ /** Resolve the module which is actually running, never PATH's unrelated npm root. */
76
+ export function resolveRunningTermdockInstallation(moduleUrl = import.meta.url, runningEntry = process.argv[1]) {
77
+ const moduleFile = fs.realpathSync(fileURLToPath(moduleUrl));
78
+ const packageRoot = path.resolve(path.dirname(moduleFile), '../../..');
79
+ const nodeModules = path.dirname(packageRoot);
80
+ if (path.basename(packageRoot) !== TERMDOCK_PACKAGE || path.basename(nodeModules) !== 'node_modules') {
81
+ throw new Error('Automatic updates require a supported global Termdock installation.');
82
+ }
83
+ const parent = path.dirname(nodeModules);
84
+ let prefix;
85
+ if (process.platform === 'win32')
86
+ prefix = parent;
87
+ else if (path.basename(parent) === 'lib')
88
+ prefix = path.dirname(parent);
89
+ else
90
+ throw new Error('Automatic updates require a supported global Termdock installation.');
91
+ const installation = { packageRoot, prefix };
92
+ // supervisor resolves and reuses this child's argv entry. A module loaded
93
+ // from another installation must never approve that different restart root.
94
+ if (!runningEntry || fs.realpathSync(runningEntry) !== path.join(packageRoot, 'dist/server/cli.js')) {
95
+ throw new Error('Running Termdock entry does not match its update installation.');
96
+ }
97
+ installedVersion(installation);
98
+ return installation;
99
+ }
100
+ export function verifyRunningTermdockInstallation(version, installation = resolveRunningTermdockInstallation()) {
101
+ if (compareVersions(installedVersion(installation), version) < 0) {
102
+ throw new Error('Running Termdock installation has not completed this update; check for updates again.');
103
+ }
104
+ }
57
105
  export function parseNpmVersionOutput(output) {
58
106
  let value;
59
107
  try {
@@ -67,6 +115,26 @@ export function parseNpmVersionOutput(output) {
67
115
  }
68
116
  return value;
69
117
  }
118
+ export function npmRuntimeEnvironment(execPath = process.execPath, env = process.env, platform = process.platform) {
119
+ const systemBins = platform === 'darwin' ? ['/opt/homebrew/bin', '/usr/local/bin'] : [];
120
+ return { ...env, PATH: [path.dirname(execPath), ...systemBins, env.PATH].filter(Boolean).join(path.delimiter) };
121
+ }
122
+ async function installEnvironment() {
123
+ const env = npmRuntimeEnvironment();
124
+ if (process.platform === 'darwin') {
125
+ // New CLT releases can leave node-gyp's implicit libc++ search path stale.
126
+ // Use the SDK selected by xcrun without changing the user's global setup.
127
+ const { stdout } = await execFileAsync('/usr/bin/xcrun', ['--show-sdk-path'], { timeout: 5000, env });
128
+ const sdk = stdout.trim();
129
+ const headers = path.join(sdk, 'usr/include/c++/v1');
130
+ if (!path.isAbsolute(sdk) || !fs.existsSync(path.join(headers, 'functional'))) {
131
+ throw new Error('macOS C++ SDK headers are unavailable. Install or repair Command Line Tools, then retry.');
132
+ }
133
+ env.SDKROOT = sdk;
134
+ env.CPLUS_INCLUDE_PATH = [headers, env.CPLUS_INCLUDE_PATH].filter(Boolean).join(path.delimiter);
135
+ }
136
+ return env;
137
+ }
70
138
  function npmExecutable() {
71
139
  return process.platform === 'win32' ? 'npm.cmd' : 'npm';
72
140
  }
@@ -76,7 +144,7 @@ async function fetchLatestVersion(registry) {
76
144
  const result = await execFileAsync(npmExecutable(), buildNpmViewArgs(registry), {
77
145
  timeout: NPM_QUERY_TIMEOUT_MS,
78
146
  maxBuffer: 256 * 1024,
79
- env: process.env,
147
+ env: npmRuntimeEnvironment(),
80
148
  });
81
149
  stdout = result.stdout;
82
150
  }
@@ -87,11 +155,15 @@ async function fetchLatestVersion(registry) {
87
155
  }
88
156
  return parseNpmVersionOutput(stdout);
89
157
  }
90
- function installVersion(version, registry) {
91
- return new Promise((resolve, reject) => {
92
- const child = spawn(npmExecutable(), buildNpmInstallArgs(version, registry), {
158
+ export async function installTermdockVersion(version, registry, installation, executable = npmExecutable()) {
159
+ if (compareVersions(installedVersion(installation), version) > 0) {
160
+ throw new Error('Running Termdock location already contains a newer version; restart that installation manually.');
161
+ }
162
+ const env = await installEnvironment();
163
+ await new Promise((resolve, reject) => {
164
+ const child = spawn(executable, buildNpmInstallArgs(version, registry, installation.prefix), {
93
165
  stdio: 'inherit',
94
- env: process.env,
166
+ env,
95
167
  });
96
168
  child.once('error', reject);
97
169
  child.once('exit', (code, signal) => {
@@ -103,6 +175,9 @@ function installVersion(version, registry) {
103
175
  reject(new Error(`npm failed to install Termdock (${reason}).`));
104
176
  });
105
177
  });
178
+ if (installedVersion(installation) !== version) {
179
+ throw new Error('npm did not install the requested version at the running Termdock location.');
180
+ }
106
181
  }
107
182
  export async function updateTermdockFromOfficialRegistry(currentVersion, onFallback, onLatest) {
108
183
  if (!parseVersion(currentVersion))
@@ -124,8 +199,9 @@ export async function updateTermdockFromOfficialRegistry(currentVersion, onFallb
124
199
  return { status: 'current', currentVersion, latestVersion, source };
125
200
  if (comparison > 0)
126
201
  return { status: 'newer-than-registry', currentVersion, latestVersion, source };
202
+ const installation = resolveRunningTermdockInstallation();
127
203
  try {
128
- await installVersion(latestVersion, source === 'official' ? OFFICIAL_NPM_REGISTRY : null);
204
+ await installTermdockVersion(latestVersion, source === 'official' ? OFFICIAL_NPM_REGISTRY : null, installation);
129
205
  }
130
206
  catch (error) {
131
207
  if (source === 'configured')
@@ -133,7 +209,7 @@ export async function updateTermdockFromOfficialRegistry(currentVersion, onFallb
133
209
  const cause = error instanceof Error ? error : new Error(String(error));
134
210
  onFallback?.('install', cause);
135
211
  source = 'configured';
136
- await installVersion(latestVersion, null);
212
+ await installTermdockVersion(latestVersion, null, installation);
137
213
  }
138
214
  return { status: 'updated', currentVersion, latestVersion, source };
139
215
  }
@@ -0,0 +1,66 @@
1
+ const START = '\x1b[200~';
2
+ const END = '\x1b[201~';
3
+ const MAX_BYTES = 1024 * 1024;
4
+ const TIMEOUT_MS = 10_000;
5
+ const INCOMPLETE = '粘贴内容未完整送达,已取消,请重新粘贴。';
6
+ /** A socket owns its pending paste. Never expose its opening delimiter to the
7
+ * PTY until the closing delimiter has arrived, even across input records.
8
+ * Ordinary keyboard/mouse records remain synchronous and unbuffered. */
9
+ export class TerminalPasteBuffer {
10
+ onTimeout;
11
+ pending = '';
12
+ startedAt = 0;
13
+ timer;
14
+ constructor(onTimeout) {
15
+ this.onTimeout = onTimeout;
16
+ }
17
+ push(data) {
18
+ const previousStart = this.startedAt;
19
+ const continuing = this.pending.length > 0;
20
+ const input = this.pending + data;
21
+ const output = [];
22
+ this.clear();
23
+ let offset = 0;
24
+ while (offset < input.length) {
25
+ const start = input.indexOf(START, offset);
26
+ if (start < 0) {
27
+ output.push(input.slice(offset));
28
+ break;
29
+ }
30
+ if (start > offset)
31
+ output.push(input.slice(offset, start));
32
+ const end = input.indexOf(END, start + START.length);
33
+ const nested = input.indexOf(START, start + START.length);
34
+ if (nested >= 0 && (end < 0 || nested < end))
35
+ throw new Error(INCOMPLETE);
36
+ const paste = input.slice(start, end < 0 ? undefined : end + END.length);
37
+ if (Buffer.byteLength(paste) > MAX_BYTES)
38
+ throw new Error('粘贴内容超过 1 MiB,请分段粘贴。');
39
+ if (end < 0) {
40
+ this.pending = paste;
41
+ this.startedAt = continuing && start === 0 ? previousStart : Date.now();
42
+ this.timer = setTimeout(() => { this.clear(); this.onTimeout(INCOMPLETE); }, Math.max(0, this.startedAt + TIMEOUT_MS - Date.now()));
43
+ this.timer.unref();
44
+ break;
45
+ }
46
+ output.push(paste);
47
+ offset = end + END.length;
48
+ }
49
+ return output;
50
+ }
51
+ /** HTTP input has no continuation stream. Reject its entire body on failure. */
52
+ complete(data) {
53
+ const output = this.push(data);
54
+ if (this.pending) {
55
+ this.clear();
56
+ throw new Error(INCOMPLETE);
57
+ }
58
+ return output;
59
+ }
60
+ clear() {
61
+ clearTimeout(this.timer);
62
+ this.timer = undefined;
63
+ this.pending = '';
64
+ this.startedAt = 0;
65
+ }
66
+ }
@@ -15,6 +15,10 @@ export async function supportsTmuxClientFeatures(binary) {
15
15
  }
16
16
  export function buildTmuxAttachArgs(sessionName, supportsFeatures) {
17
17
  return [
18
+ // The Web/native terminal consumes UTF-8 regardless of the server launcher's
19
+ // locale. GUI-launched services may inherit C; tmux otherwise emits _ for
20
+ // non-ASCII cells before the encrypted output ever reaches the renderer.
21
+ '-u',
18
22
  ...(supportsFeatures ? ['-T', 'RGB,sync'] : []),
19
23
  'attach-session', '-t', sessionName,
20
24
  ];