termdock 1.4.327 → 1.4.329

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