termdock 1.4.312 → 1.4.314

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-ChS2-lkz.js → App-BCTGnwU1.js} +53 -53
  2. package/dist/client/assets/App-BCTGnwU1.js.br +0 -0
  3. package/dist/client/assets/App-BCTGnwU1.js.gz +0 -0
  4. package/dist/client/assets/{ArchitecturePanel-JtjyyJoW.js → ArchitecturePanel-CVTIYbyj.js} +6 -6
  5. package/dist/client/assets/ArchitecturePanel-CVTIYbyj.js.br +0 -0
  6. package/dist/client/assets/ArchitecturePanel-CVTIYbyj.js.gz +0 -0
  7. package/dist/client/assets/{ChangeWalkthroughPanel-BlQ5-VPp.js → ChangeWalkthroughPanel-BKsuofw6.js} +2 -2
  8. package/dist/client/assets/ChangeWalkthroughPanel-BKsuofw6.js.br +0 -0
  9. package/dist/client/assets/ChangeWalkthroughPanel-BKsuofw6.js.gz +0 -0
  10. package/dist/client/assets/{CollaborationMainWorkspace-aFLAMqDr.js → CollaborationMainWorkspace-DZ0qwLUz.js} +1 -1
  11. package/dist/client/assets/CollaborationMainWorkspace-DZ0qwLUz.js.br +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-DZ0qwLUz.js.gz +0 -0
  13. package/dist/client/assets/CollaborationTaskContent-BLQNknOq.js +2 -0
  14. package/dist/client/assets/{ComputerControlView-TAKDbBUl.js → ComputerControlView-DN6cXOnb.js} +2 -2
  15. package/dist/client/assets/ComputerControlView-DN6cXOnb.js.br +0 -0
  16. package/dist/client/assets/ComputerControlView-DN6cXOnb.js.gz +0 -0
  17. package/dist/client/assets/{DagPlayground-CR4uDFOx.js → DagPlayground-ZgszT1TH.js} +1 -1
  18. package/dist/client/assets/DagPlayground-ZgszT1TH.js.br +0 -0
  19. package/dist/client/assets/DagPlayground-ZgszT1TH.js.gz +0 -0
  20. package/dist/client/assets/{DiffLab-BqeHMDOy.js → DiffLab-D_9U-zfZ.js} +1 -1
  21. package/dist/client/assets/DiffLab-D_9U-zfZ.js.br +0 -0
  22. package/dist/client/assets/DiffLab-D_9U-zfZ.js.gz +0 -0
  23. package/dist/client/assets/{DiffReview-DqrOcRfP.js → DiffReview-8Pfe_BNO.js} +1 -1
  24. package/dist/client/assets/DiffReview-8Pfe_BNO.js.br +0 -0
  25. package/dist/client/assets/DiffReview-8Pfe_BNO.js.gz +0 -0
  26. package/dist/client/assets/{DiffReviewLab-CEYpbrL6.js → DiffReviewLab-p3ZSl0P2.js} +1 -1
  27. package/dist/client/assets/DiffReviewLab-p3ZSl0P2.js.br +0 -0
  28. package/dist/client/assets/DiffReviewLab-p3ZSl0P2.js.gz +0 -0
  29. package/dist/client/assets/{DiffViewer-F-uQSmhG.js → DiffViewer-Cz64sLJT.js} +8 -8
  30. package/dist/client/assets/DiffViewer-Cz64sLJT.js.br +0 -0
  31. package/dist/client/assets/DiffViewer-Cz64sLJT.js.gz +0 -0
  32. package/dist/client/assets/{ModelPreview-KmXFkgij.js → ModelPreview-B28x060d.js} +1 -1
  33. package/dist/client/assets/ModelPreview-B28x060d.js.br +0 -0
  34. package/dist/client/assets/ModelPreview-B28x060d.js.gz +0 -0
  35. package/dist/client/assets/{RightSidebar-VMdXpo4h.js → RightSidebar-SIqDjggD.js} +3 -3
  36. package/dist/client/assets/RightSidebar-SIqDjggD.js.br +0 -0
  37. package/dist/client/assets/RightSidebar-SIqDjggD.js.gz +0 -0
  38. package/dist/client/assets/{abnfDiagram-VCTEODGH-CAMk1C0N.js → abnfDiagram-VCTEODGH--t0bQKCQ.js} +1 -1
  39. package/dist/client/assets/abnfDiagram-VCTEODGH--t0bQKCQ.js.br +0 -0
  40. package/dist/client/assets/abnfDiagram-VCTEODGH--t0bQKCQ.js.gz +0 -0
  41. package/dist/client/assets/{app-CHxLSuGQ.js → app-DWidKLU2.js} +13 -13
  42. package/dist/client/assets/app-DWidKLU2.js.br +0 -0
  43. package/dist/client/assets/app-DWidKLU2.js.gz +0 -0
  44. package/dist/client/assets/{arc-CYG_-1vC.js → arc-DMWsmL7t.js} +1 -1
  45. package/dist/client/assets/arc-DMWsmL7t.js.br +0 -0
  46. package/dist/client/assets/arc-DMWsmL7t.js.gz +0 -0
  47. package/dist/client/assets/{architectureDiagram-5GKGNRK7-BqHzezLR.js → architectureDiagram-5GKGNRK7-BYkvSKnR.js} +1 -1
  48. package/dist/client/assets/architectureDiagram-5GKGNRK7-BYkvSKnR.js.br +0 -0
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-BYkvSKnR.js.gz +0 -0
  50. package/dist/client/assets/{blockDiagram-I7D4REHJ-D6GWRO_Z.js → blockDiagram-I7D4REHJ-B574d9TS.js} +1 -1
  51. package/dist/client/assets/blockDiagram-I7D4REHJ-B574d9TS.js.br +0 -0
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-B574d9TS.js.gz +0 -0
  53. package/dist/client/assets/{c4Diagram-7LVT6UL2-CutmGIGb.js → c4Diagram-7LVT6UL2-D__CwUct.js} +1 -1
  54. package/dist/client/assets/c4Diagram-7LVT6UL2-D__CwUct.js.br +0 -0
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-D__CwUct.js.gz +0 -0
  56. package/dist/client/assets/channel-BonXK9tr.js +1 -0
  57. package/dist/client/assets/{chunk-2Q5K7J3B-DwiUpGFu.js → chunk-2Q5K7J3B-BvwmL72I.js} +1 -1
  58. package/dist/client/assets/{chunk-5VM5RSS4-C35gLPSH.js → chunk-5VM5RSS4-BktO-a5l.js} +1 -1
  59. package/dist/client/assets/{chunk-F27PBJKO-CNptP19P.js → chunk-F27PBJKO-DeClqFBe.js} +1 -1
  60. package/dist/client/assets/chunk-F27PBJKO-DeClqFBe.js.br +0 -0
  61. package/dist/client/assets/chunk-F27PBJKO-DeClqFBe.js.gz +0 -0
  62. package/dist/client/assets/{chunk-IMKFNOWR-DHdpB9A0.js → chunk-IMKFNOWR-DBRCslkn.js} +1 -1
  63. package/dist/client/assets/chunk-IMKFNOWR-DBRCslkn.js.br +0 -0
  64. package/dist/client/assets/chunk-IMKFNOWR-DBRCslkn.js.gz +0 -0
  65. package/dist/client/assets/{chunk-JWPE2WC7-CrKSOzdE.js → chunk-JWPE2WC7-BfpbqgrR.js} +1 -1
  66. package/dist/client/assets/{chunk-POPQ4Y6H-CiZGLRSk.js → chunk-POPQ4Y6H-Bw-dqneu.js} +1 -1
  67. package/dist/client/assets/{chunk-SVP7TREG-B70pX8OB.js → chunk-SVP7TREG-BdxOWBjP.js} +1 -1
  68. package/dist/client/assets/chunk-SVP7TREG-BdxOWBjP.js.br +0 -0
  69. package/dist/client/assets/chunk-SVP7TREG-BdxOWBjP.js.gz +0 -0
  70. package/dist/client/assets/{chunk-TICWLB2K-Ba1mI99F.js → chunk-TICWLB2K-BtNXehgz.js} +1 -1
  71. package/dist/client/assets/chunk-TICWLB2K-BtNXehgz.js.br +0 -0
  72. package/dist/client/assets/chunk-TICWLB2K-BtNXehgz.js.gz +0 -0
  73. package/dist/client/assets/{chunk-XXDRQBXY-DmKIl18h.js → chunk-XXDRQBXY-CUxGdImw.js} +1 -1
  74. package/dist/client/assets/classDiagram-ZZMXUADV-CXO_pgVP.js +1 -0
  75. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CXO_pgVP.js +1 -0
  76. package/dist/client/assets/{cose-bilkent-JH36ORCC-C-NMDUHW.js → cose-bilkent-JH36ORCC-Buod2YZ0.js} +1 -1
  77. package/dist/client/assets/cose-bilkent-JH36ORCC-Buod2YZ0.js.br +0 -0
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-Buod2YZ0.js.gz +0 -0
  79. package/dist/client/assets/{cynefin-OW5HDTMX-CZgEc1ab.js → cynefin-OW5HDTMX-i2eiybdj.js} +1 -1
  80. package/dist/client/assets/cynefin-OW5HDTMX-i2eiybdj.js.br +0 -0
  81. package/dist/client/assets/cynefin-OW5HDTMX-i2eiybdj.js.gz +0 -0
  82. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CHQeSNm2.js → cynefinDiagram-5FMLGOSQ-D_YF2Yi3.js} +1 -1
  83. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-D_YF2Yi3.js.br +0 -0
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-D_YF2Yi3.js.gz +0 -0
  85. package/dist/client/assets/{dagre-GXQ25YYZ-B_jkMdPS.js → dagre-GXQ25YYZ-CfLEvt7Z.js} +1 -1
  86. package/dist/client/assets/dagre-GXQ25YYZ-CfLEvt7Z.js.br +0 -0
  87. package/dist/client/assets/dagre-GXQ25YYZ-CfLEvt7Z.js.gz +0 -0
  88. package/dist/client/assets/{diagram-S7CK7UJ4-nv6Lnsrp.js → diagram-S7CK7UJ4-BV0Wackt.js} +1 -1
  89. package/dist/client/assets/diagram-S7CK7UJ4-BV0Wackt.js.br +0 -0
  90. package/dist/client/assets/diagram-S7CK7UJ4-BV0Wackt.js.gz +0 -0
  91. package/dist/client/assets/{diagram-UQ7AKVKN-BZf2fzaA.js → diagram-UQ7AKVKN-jwaoLY_P.js} +1 -1
  92. package/dist/client/assets/diagram-UQ7AKVKN-jwaoLY_P.js.br +0 -0
  93. package/dist/client/assets/diagram-UQ7AKVKN-jwaoLY_P.js.gz +0 -0
  94. package/dist/client/assets/{diagram-VSXAHHWV-CxL0_BH8.js → diagram-VSXAHHWV-CuAFyl0n.js} +1 -1
  95. package/dist/client/assets/diagram-VSXAHHWV-CuAFyl0n.js.br +0 -0
  96. package/dist/client/assets/diagram-VSXAHHWV-CuAFyl0n.js.gz +0 -0
  97. package/dist/client/assets/{diagram-VX7I27RA-Dm9MqpIE.js → diagram-VX7I27RA-bbmA7rRk.js} +1 -1
  98. package/dist/client/assets/diagram-VX7I27RA-bbmA7rRk.js.br +0 -0
  99. package/dist/client/assets/diagram-VX7I27RA-bbmA7rRk.js.gz +0 -0
  100. package/dist/client/assets/{diagram-Z3DM3KII-BIfTa7P5.js → diagram-Z3DM3KII-CX3-Mxwo.js} +1 -1
  101. package/dist/client/assets/diagram-Z3DM3KII-CX3-Mxwo.js.br +0 -0
  102. package/dist/client/assets/diagram-Z3DM3KII-CX3-Mxwo.js.gz +0 -0
  103. package/dist/client/assets/{ebnfDiagram-PWID7BFC-D4XhCDFS.js → ebnfDiagram-PWID7BFC-Pkq6omzy.js} +1 -1
  104. package/dist/client/assets/ebnfDiagram-PWID7BFC-Pkq6omzy.js.br +0 -0
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-Pkq6omzy.js.gz +0 -0
  106. package/dist/client/assets/{erDiagram-RLTQ6QDP-Dxd48dXC.js → erDiagram-RLTQ6QDP-CjdD0JCI.js} +1 -1
  107. package/dist/client/assets/erDiagram-RLTQ6QDP-CjdD0JCI.js.br +0 -0
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-CjdD0JCI.js.gz +0 -0
  109. package/dist/client/assets/{flowDiagram-HODETNUW-BXBMsEmE.js → flowDiagram-HODETNUW-DKECYHVY.js} +1 -1
  110. package/dist/client/assets/flowDiagram-HODETNUW-DKECYHVY.js.br +0 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-DKECYHVY.js.gz +0 -0
  112. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-CBfDd-KZ.js → ganttDiagram-EL5Y4UJY-BPCGT0Kd.js} +1 -1
  113. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BPCGT0Kd.js.br +0 -0
  114. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-CBfDd-KZ.js.gz → ganttDiagram-EL5Y4UJY-BPCGT0Kd.js.gz} +0 -0
  115. package/dist/client/assets/{gestureArbiter-DXLmNGli.js → gestureArbiter-DVPPQnKq.js} +1 -1
  116. package/dist/client/assets/{gestureArbiter-DXLmNGli.js.br → gestureArbiter-DVPPQnKq.js.br} +0 -0
  117. package/dist/client/assets/gestureArbiter-DVPPQnKq.js.gz +0 -0
  118. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-DtLM68fN.js → gitGraphDiagram-WWUBYQGX-DFCvVJ6L.js} +1 -1
  119. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DFCvVJ6L.js.br +0 -0
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DFCvVJ6L.js.gz +0 -0
  121. package/dist/client/assets/{index-KuPaZyuZ.css → index-CSp4mPGE.css} +1 -1
  122. package/dist/client/assets/index-CSp4mPGE.css.br +0 -0
  123. package/dist/client/assets/{index-KuPaZyuZ.css.gz → index-CSp4mPGE.css.gz} +0 -0
  124. package/dist/client/assets/{infoDiagram-27XIBGKW-FRhqdJvW.js → infoDiagram-27XIBGKW-BTL8-sSN.js} +1 -1
  125. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-DAHBvAZ-.js → ishikawaDiagram-5VMMS53U-Xtc0AfGK.js} +1 -1
  126. package/dist/client/assets/ishikawaDiagram-5VMMS53U-Xtc0AfGK.js.br +0 -0
  127. package/dist/client/assets/ishikawaDiagram-5VMMS53U-Xtc0AfGK.js.gz +0 -0
  128. package/dist/client/assets/{journeyDiagram-3NMN7TZE-CVuWuL3Z.js → journeyDiagram-3NMN7TZE-BLtTDKtV.js} +1 -1
  129. package/dist/client/assets/journeyDiagram-3NMN7TZE-BLtTDKtV.js.br +0 -0
  130. package/dist/client/assets/journeyDiagram-3NMN7TZE-BLtTDKtV.js.gz +0 -0
  131. package/dist/client/assets/{kanban-definition-UXKFOSKX-ByQSUVJV.js → kanban-definition-UXKFOSKX-C65azoTU.js} +1 -1
  132. package/dist/client/assets/kanban-definition-UXKFOSKX-C65azoTU.js.br +0 -0
  133. package/dist/client/assets/kanban-definition-UXKFOSKX-C65azoTU.js.gz +0 -0
  134. package/dist/client/assets/{layout-Bb3Nb1c4.js → layout-TEicKqeV.js} +1 -1
  135. package/dist/client/assets/layout-TEicKqeV.js.br +0 -0
  136. package/dist/client/assets/layout-TEicKqeV.js.gz +0 -0
  137. package/dist/client/assets/{linear-DHMMQlOo.js → linear-DQSikGMo.js} +1 -1
  138. package/dist/client/assets/{linear-DHMMQlOo.js.br → linear-DQSikGMo.js.br} +0 -0
  139. package/dist/client/assets/linear-DQSikGMo.js.gz +0 -0
  140. package/dist/client/assets/{mermaid.core-BYfniK0H.js → mermaid.core-vZB1UnWX.js} +5 -5
  141. package/dist/client/assets/mermaid.core-vZB1UnWX.js.br +0 -0
  142. package/dist/client/assets/mermaid.core-vZB1UnWX.js.gz +0 -0
  143. package/dist/client/assets/{mindmap-definition-YA3MSWOX-EDLD5AyH.js → mindmap-definition-YA3MSWOX-B-coBapV.js} +1 -1
  144. package/dist/client/assets/mindmap-definition-YA3MSWOX-B-coBapV.js.br +0 -0
  145. package/dist/client/assets/mindmap-definition-YA3MSWOX-B-coBapV.js.gz +0 -0
  146. package/dist/client/assets/{passwordBootstrap-DCrtirwT.js → passwordBootstrap-LSQpoVpD.js} +1 -1
  147. package/dist/client/assets/passwordBootstrap-LSQpoVpD.js.br +0 -0
  148. package/dist/client/assets/passwordBootstrap-LSQpoVpD.js.gz +0 -0
  149. package/dist/client/assets/{pegDiagram-XKGWAZYB-BHYhkqJN.js → pegDiagram-XKGWAZYB--jWB5n1V.js} +1 -1
  150. package/dist/client/assets/pegDiagram-XKGWAZYB--jWB5n1V.js.br +0 -0
  151. package/dist/client/assets/pegDiagram-XKGWAZYB--jWB5n1V.js.gz +0 -0
  152. package/dist/client/assets/{pieDiagram-E7YTZNPT-BUIJlswC.js → pieDiagram-E7YTZNPT-DmAqsAUK.js} +1 -1
  153. package/dist/client/assets/pieDiagram-E7YTZNPT-DmAqsAUK.js.br +0 -0
  154. package/dist/client/assets/pieDiagram-E7YTZNPT-DmAqsAUK.js.gz +0 -0
  155. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-D8Im-7yC.js → quadrantDiagram-AXDQQJYC-CqsfUApA.js} +1 -1
  156. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CqsfUApA.js.br +0 -0
  157. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CqsfUApA.js.gz +0 -0
  158. package/dist/client/assets/{railroadDiagram-O6MQD6OU-D7n6z2G1.js → railroadDiagram-O6MQD6OU-CzvYijD5.js} +1 -1
  159. package/dist/client/assets/railroadDiagram-O6MQD6OU-CzvYijD5.js.br +0 -0
  160. package/dist/client/assets/railroadDiagram-O6MQD6OU-CzvYijD5.js.gz +0 -0
  161. package/dist/client/assets/{rdpSession-DJlNIbVk.js → rdpSession-DGvDRc95.js} +1 -1
  162. package/dist/client/assets/rdpSession-DGvDRc95.js.br +0 -0
  163. package/dist/client/assets/rdpSession-DGvDRc95.js.gz +0 -0
  164. package/dist/client/assets/{referenceLongPress-DFSrssSr.js → referenceLongPress-BwP_B3l2.js} +1 -1
  165. package/dist/client/assets/referenceLongPress-BwP_B3l2.js.br +0 -0
  166. package/dist/client/assets/referenceLongPress-BwP_B3l2.js.gz +0 -0
  167. package/dist/client/assets/{requirementDiagram-BXWQKSXE-Ki0rR-F7.js → requirementDiagram-BXWQKSXE-E2FSO_hc.js} +1 -1
  168. package/dist/client/assets/requirementDiagram-BXWQKSXE-E2FSO_hc.js.br +0 -0
  169. package/dist/client/assets/requirementDiagram-BXWQKSXE-E2FSO_hc.js.gz +0 -0
  170. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-36NmMqsW.js → sankeyDiagram-P5KCCOFB-uSCR6gDg.js} +1 -1
  171. package/dist/client/assets/sankeyDiagram-P5KCCOFB-uSCR6gDg.js.br +0 -0
  172. package/dist/client/assets/sankeyDiagram-P5KCCOFB-uSCR6gDg.js.gz +0 -0
  173. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-5vsPuFyO.js → sequenceDiagram-WJ2MYXX4-BqxdP03l.js} +1 -1
  174. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BqxdP03l.js.br +0 -0
  175. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BqxdP03l.js.gz +0 -0
  176. package/dist/client/assets/{sizeCapture-INFHLROL-DbAulwBg.js → sizeCapture-INFHLROL-B7GSZxIt.js} +1 -1
  177. package/dist/client/assets/sizeCapture-INFHLROL-B7GSZxIt.js.br +0 -0
  178. package/dist/client/assets/sizeCapture-INFHLROL-B7GSZxIt.js.gz +0 -0
  179. package/dist/client/assets/{sparkles-CapLTKAs.js → sparkles-DBVpVoIl.js} +1 -1
  180. package/dist/client/assets/{stateDiagram-D77RDMKH-Bgwe0g5S.js → stateDiagram-D77RDMKH-DJ9UpQL9.js} +1 -1
  181. package/dist/client/assets/stateDiagram-D77RDMKH-DJ9UpQL9.js.br +0 -0
  182. package/dist/client/assets/stateDiagram-D77RDMKH-DJ9UpQL9.js.gz +0 -0
  183. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-P9vVPNJW.js +1 -0
  184. package/dist/client/assets/{swimlanes-42K2YHIH-COGAWe-g.js → swimlanes-42K2YHIH-B6f_z8xv.js} +1 -1
  185. package/dist/client/assets/swimlanes-42K2YHIH-B6f_z8xv.js.br +0 -0
  186. package/dist/client/assets/swimlanes-42K2YHIH-B6f_z8xv.js.gz +0 -0
  187. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-Deucv-sT.js +8 -0
  188. package/dist/client/assets/{timeline-definition-24CTP7MA-C4gt5z68.js → timeline-definition-24CTP7MA-CMNs0nui.js} +1 -1
  189. package/dist/client/assets/timeline-definition-24CTP7MA-CMNs0nui.js.br +0 -0
  190. package/dist/client/assets/timeline-definition-24CTP7MA-CMNs0nui.js.gz +0 -0
  191. package/dist/client/assets/{triangle-alert-xPHw25jD.js → triangle-alert-CN3m1g76.js} +1 -1
  192. package/dist/client/assets/{vennDiagram-4TSXK5OY-CIEXh9oD.js → vennDiagram-4TSXK5OY-B2glpBlo.js} +1 -1
  193. package/dist/client/assets/vennDiagram-4TSXK5OY-B2glpBlo.js.br +0 -0
  194. package/dist/client/assets/vennDiagram-4TSXK5OY-B2glpBlo.js.gz +0 -0
  195. package/dist/client/assets/{videoCompression-CUkCS2-q.js → videoCompression-DwronsgA.js} +1 -1
  196. package/dist/client/assets/videoCompression-DwronsgA.js.br +0 -0
  197. package/dist/client/assets/videoCompression-DwronsgA.js.gz +0 -0
  198. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-gQhcW1vd.js → wardleyDiagram-VM6X3IG4-DyMNl-ZC.js} +1 -1
  199. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DyMNl-ZC.js.br +0 -0
  200. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DyMNl-ZC.js.gz +0 -0
  201. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-BmIcdejz.js → xychartDiagram-S5SC5T6Z-DhZFXjY5.js} +1 -1
  202. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DhZFXjY5.js.br +0 -0
  203. package/dist/client/assets/xychartDiagram-S5SC5T6Z-DhZFXjY5.js.gz +0 -0
  204. package/dist/client/index.html +3 -2
  205. package/dist/client/index.html.br +0 -0
  206. package/dist/client/index.html.gz +0 -0
  207. package/dist/client/ipad-status-bar.js +12 -0
  208. package/dist/client/sw.js +1 -1
  209. package/dist/client/sw.js.br +0 -0
  210. package/dist/client/sw.js.gz +0 -0
  211. package/dist/server/agent/collaborationCli.js +21 -5
  212. package/dist/server/agent/collaborationStore.js +25 -2
  213. package/dist/server/agent/collaborationTmuxDelivery.js +32 -19
  214. package/dist/server/agent/integrationCli.js +8 -3
  215. package/dist/server/agent/integrationServer.js +5 -1
  216. package/dist/server/agent/integrationSessions.js +147 -13
  217. package/dist/server/agent/promptDelivery.js +12 -8
  218. package/dist/server/agent/sessionLaunchDiagnostics.js +26 -0
  219. package/dist/server/agent/terminalInput.js +44 -0
  220. package/dist/server/routes/terminal.js +140 -53
  221. package/docs/integrations.md +110 -0
  222. package/package.json +1 -1
  223. package/runtime-manifest.json +3 -3
  224. package/dist/client/assets/App-ChS2-lkz.js.br +0 -0
  225. package/dist/client/assets/App-ChS2-lkz.js.gz +0 -0
  226. package/dist/client/assets/ArchitecturePanel-JtjyyJoW.js.br +0 -0
  227. package/dist/client/assets/ArchitecturePanel-JtjyyJoW.js.gz +0 -0
  228. package/dist/client/assets/ChangeWalkthroughPanel-BlQ5-VPp.js.br +0 -0
  229. package/dist/client/assets/ChangeWalkthroughPanel-BlQ5-VPp.js.gz +0 -0
  230. package/dist/client/assets/CollaborationMainWorkspace-aFLAMqDr.js.br +0 -0
  231. package/dist/client/assets/CollaborationMainWorkspace-aFLAMqDr.js.gz +0 -0
  232. package/dist/client/assets/CollaborationTaskContent-BDQMRhU9.js +0 -2
  233. package/dist/client/assets/ComputerControlView-TAKDbBUl.js.br +0 -0
  234. package/dist/client/assets/ComputerControlView-TAKDbBUl.js.gz +0 -0
  235. package/dist/client/assets/DagPlayground-CR4uDFOx.js.br +0 -0
  236. package/dist/client/assets/DagPlayground-CR4uDFOx.js.gz +0 -0
  237. package/dist/client/assets/DiffLab-BqeHMDOy.js.br +0 -0
  238. package/dist/client/assets/DiffLab-BqeHMDOy.js.gz +0 -0
  239. package/dist/client/assets/DiffReview-DqrOcRfP.js.br +0 -0
  240. package/dist/client/assets/DiffReview-DqrOcRfP.js.gz +0 -0
  241. package/dist/client/assets/DiffReviewLab-CEYpbrL6.js.br +0 -0
  242. package/dist/client/assets/DiffReviewLab-CEYpbrL6.js.gz +0 -0
  243. package/dist/client/assets/DiffViewer-F-uQSmhG.js.br +0 -0
  244. package/dist/client/assets/DiffViewer-F-uQSmhG.js.gz +0 -0
  245. package/dist/client/assets/ModelPreview-KmXFkgij.js.br +0 -0
  246. package/dist/client/assets/ModelPreview-KmXFkgij.js.gz +0 -0
  247. package/dist/client/assets/RightSidebar-VMdXpo4h.js.br +0 -0
  248. package/dist/client/assets/RightSidebar-VMdXpo4h.js.gz +0 -0
  249. package/dist/client/assets/abnfDiagram-VCTEODGH-CAMk1C0N.js.br +0 -0
  250. package/dist/client/assets/abnfDiagram-VCTEODGH-CAMk1C0N.js.gz +0 -0
  251. package/dist/client/assets/app-CHxLSuGQ.js.br +0 -0
  252. package/dist/client/assets/app-CHxLSuGQ.js.gz +0 -0
  253. package/dist/client/assets/arc-CYG_-1vC.js.br +0 -0
  254. package/dist/client/assets/arc-CYG_-1vC.js.gz +0 -0
  255. package/dist/client/assets/architectureDiagram-5GKGNRK7-BqHzezLR.js.br +0 -0
  256. package/dist/client/assets/architectureDiagram-5GKGNRK7-BqHzezLR.js.gz +0 -0
  257. package/dist/client/assets/blockDiagram-I7D4REHJ-D6GWRO_Z.js.br +0 -0
  258. package/dist/client/assets/blockDiagram-I7D4REHJ-D6GWRO_Z.js.gz +0 -0
  259. package/dist/client/assets/c4Diagram-7LVT6UL2-CutmGIGb.js.br +0 -0
  260. package/dist/client/assets/c4Diagram-7LVT6UL2-CutmGIGb.js.gz +0 -0
  261. package/dist/client/assets/channel-B3BKM2gg.js +0 -1
  262. package/dist/client/assets/chunk-F27PBJKO-CNptP19P.js.br +0 -0
  263. package/dist/client/assets/chunk-F27PBJKO-CNptP19P.js.gz +0 -0
  264. package/dist/client/assets/chunk-IMKFNOWR-DHdpB9A0.js.br +0 -0
  265. package/dist/client/assets/chunk-IMKFNOWR-DHdpB9A0.js.gz +0 -0
  266. package/dist/client/assets/chunk-SVP7TREG-B70pX8OB.js.br +0 -0
  267. package/dist/client/assets/chunk-SVP7TREG-B70pX8OB.js.gz +0 -0
  268. package/dist/client/assets/chunk-TICWLB2K-Ba1mI99F.js.br +0 -0
  269. package/dist/client/assets/chunk-TICWLB2K-Ba1mI99F.js.gz +0 -0
  270. package/dist/client/assets/classDiagram-ZZMXUADV-CS4V_MQS.js +0 -1
  271. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CS4V_MQS.js +0 -1
  272. package/dist/client/assets/cose-bilkent-JH36ORCC-C-NMDUHW.js.br +0 -0
  273. package/dist/client/assets/cose-bilkent-JH36ORCC-C-NMDUHW.js.gz +0 -0
  274. package/dist/client/assets/cynefin-OW5HDTMX-CZgEc1ab.js.br +0 -0
  275. package/dist/client/assets/cynefin-OW5HDTMX-CZgEc1ab.js.gz +0 -0
  276. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CHQeSNm2.js.br +0 -0
  277. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CHQeSNm2.js.gz +0 -0
  278. package/dist/client/assets/dagre-GXQ25YYZ-B_jkMdPS.js.br +0 -0
  279. package/dist/client/assets/dagre-GXQ25YYZ-B_jkMdPS.js.gz +0 -0
  280. package/dist/client/assets/diagram-S7CK7UJ4-nv6Lnsrp.js.br +0 -0
  281. package/dist/client/assets/diagram-S7CK7UJ4-nv6Lnsrp.js.gz +0 -0
  282. package/dist/client/assets/diagram-UQ7AKVKN-BZf2fzaA.js.br +0 -0
  283. package/dist/client/assets/diagram-UQ7AKVKN-BZf2fzaA.js.gz +0 -0
  284. package/dist/client/assets/diagram-VSXAHHWV-CxL0_BH8.js.br +0 -0
  285. package/dist/client/assets/diagram-VSXAHHWV-CxL0_BH8.js.gz +0 -0
  286. package/dist/client/assets/diagram-VX7I27RA-Dm9MqpIE.js.br +0 -0
  287. package/dist/client/assets/diagram-VX7I27RA-Dm9MqpIE.js.gz +0 -0
  288. package/dist/client/assets/diagram-Z3DM3KII-BIfTa7P5.js.br +0 -0
  289. package/dist/client/assets/diagram-Z3DM3KII-BIfTa7P5.js.gz +0 -0
  290. package/dist/client/assets/ebnfDiagram-PWID7BFC-D4XhCDFS.js.br +0 -0
  291. package/dist/client/assets/ebnfDiagram-PWID7BFC-D4XhCDFS.js.gz +0 -0
  292. package/dist/client/assets/erDiagram-RLTQ6QDP-Dxd48dXC.js.br +0 -0
  293. package/dist/client/assets/erDiagram-RLTQ6QDP-Dxd48dXC.js.gz +0 -0
  294. package/dist/client/assets/flowDiagram-HODETNUW-BXBMsEmE.js.br +0 -0
  295. package/dist/client/assets/flowDiagram-HODETNUW-BXBMsEmE.js.gz +0 -0
  296. package/dist/client/assets/ganttDiagram-EL5Y4UJY-CBfDd-KZ.js.br +0 -0
  297. package/dist/client/assets/gestureArbiter-DXLmNGli.js.gz +0 -0
  298. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DtLM68fN.js.br +0 -0
  299. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DtLM68fN.js.gz +0 -0
  300. package/dist/client/assets/index-KuPaZyuZ.css.br +0 -0
  301. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DAHBvAZ-.js.br +0 -0
  302. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DAHBvAZ-.js.gz +0 -0
  303. package/dist/client/assets/journeyDiagram-3NMN7TZE-CVuWuL3Z.js.br +0 -0
  304. package/dist/client/assets/journeyDiagram-3NMN7TZE-CVuWuL3Z.js.gz +0 -0
  305. package/dist/client/assets/kanban-definition-UXKFOSKX-ByQSUVJV.js.br +0 -0
  306. package/dist/client/assets/kanban-definition-UXKFOSKX-ByQSUVJV.js.gz +0 -0
  307. package/dist/client/assets/layout-Bb3Nb1c4.js.br +0 -0
  308. package/dist/client/assets/layout-Bb3Nb1c4.js.gz +0 -0
  309. package/dist/client/assets/linear-DHMMQlOo.js.gz +0 -0
  310. package/dist/client/assets/mermaid.core-BYfniK0H.js.br +0 -0
  311. package/dist/client/assets/mermaid.core-BYfniK0H.js.gz +0 -0
  312. package/dist/client/assets/mindmap-definition-YA3MSWOX-EDLD5AyH.js.br +0 -0
  313. package/dist/client/assets/mindmap-definition-YA3MSWOX-EDLD5AyH.js.gz +0 -0
  314. package/dist/client/assets/passwordBootstrap-DCrtirwT.js.br +0 -0
  315. package/dist/client/assets/passwordBootstrap-DCrtirwT.js.gz +0 -0
  316. package/dist/client/assets/pegDiagram-XKGWAZYB-BHYhkqJN.js.br +0 -0
  317. package/dist/client/assets/pegDiagram-XKGWAZYB-BHYhkqJN.js.gz +0 -0
  318. package/dist/client/assets/pieDiagram-E7YTZNPT-BUIJlswC.js.br +0 -0
  319. package/dist/client/assets/pieDiagram-E7YTZNPT-BUIJlswC.js.gz +0 -0
  320. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D8Im-7yC.js.br +0 -0
  321. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D8Im-7yC.js.gz +0 -0
  322. package/dist/client/assets/railroadDiagram-O6MQD6OU-D7n6z2G1.js.br +0 -0
  323. package/dist/client/assets/railroadDiagram-O6MQD6OU-D7n6z2G1.js.gz +0 -0
  324. package/dist/client/assets/rdpSession-DJlNIbVk.js.br +0 -0
  325. package/dist/client/assets/rdpSession-DJlNIbVk.js.gz +0 -0
  326. package/dist/client/assets/referenceLongPress-DFSrssSr.js.br +0 -0
  327. package/dist/client/assets/referenceLongPress-DFSrssSr.js.gz +0 -0
  328. package/dist/client/assets/requirementDiagram-BXWQKSXE-Ki0rR-F7.js.br +0 -0
  329. package/dist/client/assets/requirementDiagram-BXWQKSXE-Ki0rR-F7.js.gz +0 -0
  330. package/dist/client/assets/sankeyDiagram-P5KCCOFB-36NmMqsW.js.br +0 -0
  331. package/dist/client/assets/sankeyDiagram-P5KCCOFB-36NmMqsW.js.gz +0 -0
  332. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-5vsPuFyO.js.br +0 -0
  333. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-5vsPuFyO.js.gz +0 -0
  334. package/dist/client/assets/sizeCapture-INFHLROL-DbAulwBg.js.br +0 -0
  335. package/dist/client/assets/sizeCapture-INFHLROL-DbAulwBg.js.gz +0 -0
  336. package/dist/client/assets/stateDiagram-D77RDMKH-Bgwe0g5S.js.br +0 -0
  337. package/dist/client/assets/stateDiagram-D77RDMKH-Bgwe0g5S.js.gz +0 -0
  338. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-Bg6S3Zm0.js +0 -1
  339. package/dist/client/assets/swimlanes-42K2YHIH-COGAWe-g.js.br +0 -0
  340. package/dist/client/assets/swimlanes-42K2YHIH-COGAWe-g.js.gz +0 -0
  341. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DwBBOocG.js +0 -8
  342. package/dist/client/assets/timeline-definition-24CTP7MA-C4gt5z68.js.br +0 -0
  343. package/dist/client/assets/timeline-definition-24CTP7MA-C4gt5z68.js.gz +0 -0
  344. package/dist/client/assets/vennDiagram-4TSXK5OY-CIEXh9oD.js.br +0 -0
  345. package/dist/client/assets/vennDiagram-4TSXK5OY-CIEXh9oD.js.gz +0 -0
  346. package/dist/client/assets/videoCompression-CUkCS2-q.js.br +0 -0
  347. package/dist/client/assets/videoCompression-CUkCS2-q.js.gz +0 -0
  348. package/dist/client/assets/wardleyDiagram-VM6X3IG4-gQhcW1vd.js.br +0 -0
  349. package/dist/client/assets/wardleyDiagram-VM6X3IG4-gQhcW1vd.js.gz +0 -0
  350. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BmIcdejz.js.br +0 -0
  351. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BmIcdejz.js.gz +0 -0
@@ -50,6 +50,7 @@ import { archiveTaskWorkspace, restoreTaskWorkspace, snapshotTaskWorkspace } fro
50
50
  import { isTmuxRecoveryCandidate } from '../utils/tmuxRecoveryCandidate.js';
51
51
  import { AutomationStore, normalizeAutomationSchedule } from '../agent/automationStore.js';
52
52
  import { writeBracketedPrompt, canDeliverPromptToAgent } from '../agent/promptDelivery.js';
53
+ import { captureTerminalInputGuard, waitAndWriteTerminalInput, TerminalInputTargetChangedError } from '../agent/terminalInput.js';
53
54
  import { agentLaunchBlockReason, normalizeAgentLaunchCheck } from '../agent/agentLaunchCheck.js';
54
55
  import { prepareSupervisionEnable } from '../utils/enableSupervision.js';
55
56
  import { buildServerHealthState, dismissServerHealth } from '../utils/serverHealth.js';
@@ -967,6 +968,8 @@ function normalizePersistedClientSession(input) {
967
968
  : null,
968
969
  agentResume: normalizePersistedAgentResumeInfo(candidate.agentResume),
969
970
  agentLaunchCheck: normalizeAgentLaunchCheck(candidate.agentLaunchCheck),
971
+ agentLaunchGeneration: typeof candidate.agentLaunchGeneration === 'string' ? candidate.agentLaunchGeneration
972
+ : normalizeAgentLaunchCheck(candidate.agentLaunchCheck)?.id ?? null,
970
973
  };
971
974
  }
972
975
  function generateTmuxSessionName() {
@@ -1449,14 +1452,12 @@ function searchMetadataForBackend(backendSessionId, session) {
1449
1452
  updatedAt: session.lastActivity,
1450
1453
  };
1451
1454
  }
1452
- function writeTerminalInput(session, value) {
1453
- session.ptyProcess.write(value.replace(/\r?\n/g, '\r'));
1454
- }
1455
1455
  async function beginAgentLaunchCheck(frontendSessionId, agentSlug, nativeSessionId = null) {
1456
1456
  const record = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1457
1457
  if (!record)
1458
1458
  throw new Error('SESSION_REMOVED');
1459
- upsertGlobalSessionRecord({ ...record, agentLaunchCheck: { id: randomUUID(), agentSlug, nativeSessionId, deadline: Date.now() + 120_000 } });
1459
+ const id = randomUUID();
1460
+ upsertGlobalSessionRecord({ ...record, agentLaunchGeneration: id, agentLaunchCheck: { id, agentSlug, nativeSessionId, deadline: Date.now() + 120_000 } });
1460
1461
  await persistGlobalStateNow();
1461
1462
  }
1462
1463
  async function observeAgentLaunchCheck(record, observed) {
@@ -1475,30 +1476,71 @@ async function observeAgentLaunchCheck(record, observed) {
1475
1476
  await persistGlobalStateNow();
1476
1477
  return null;
1477
1478
  }
1478
- async function deliverAutomationPromptWhenReady(backendSessionId, prompt, attempt = 0) {
1479
+ function terminalInputGuard(record) {
1480
+ const frontendSessionId = record.sessionId;
1481
+ const backendSessionId = record.backendSessionId;
1482
+ const launchId = record.agentLaunchGeneration ?? null;
1483
+ const backend = backendSessionId ? terminalSessions.get(backendSessionId) : undefined;
1484
+ return () => {
1485
+ const latest = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1486
+ if (!latest)
1487
+ throw new Error('SESSION_REMOVED');
1488
+ const instanceMatches = !backendSessionId || terminalSessions.get(backendSessionId) === backend;
1489
+ if ((latest.agentLaunchGeneration ?? null) !== launchId || latest.backendSessionId !== backendSessionId || !instanceMatches) {
1490
+ throw new TerminalInputTargetChangedError({ expected_backend_session_id: backendSessionId, current_backend_session_id: latest.backendSessionId,
1491
+ expected_launch_id: launchId, current_launch_id: latest.agentLaunchGeneration ?? null, backend_instance_matches: instanceMatches });
1492
+ }
1493
+ };
1494
+ }
1495
+ /** tmux input always uses the pane queue, including automation and launch commands. */
1496
+ async function automaticTerminalInput(record, assertCurrent = terminalInputGuard(record), progress) {
1497
+ assertCurrent();
1498
+ if (record.mode === 'tmux') {
1499
+ const binding = collaborationRouting.get(record.sessionId) ?? {
1500
+ sessionId: record.sessionId, backendSessionId: record.backendSessionId, mode: record.mode,
1501
+ tmuxSessionName: record.tmuxSessionName, agentSlug: null, nativeSessionId: null, pane: null,
1502
+ };
1503
+ const inspected = await inspectCollaborationTmux(binding, null, true);
1504
+ assertCurrent();
1505
+ if (inspected.state !== 'ready' || !inspected.pane)
1506
+ throw new Error(inspected.reason ?? 'TMUX_PANE_UNAVAILABLE');
1507
+ const pane = inspected.pane;
1508
+ return (prompt) => writeCollaborationTmuxPane(runTmux, pane, prompt, runTmuxStdin, assertCurrent, progress);
1509
+ }
1510
+ const backend = record.backendSessionId ? terminalSessions.get(record.backendSessionId) : null;
1511
+ if (!backend)
1512
+ throw new Error('SHELL_BACKEND_NOT_RUNNING');
1513
+ return (prompt) => writeBracketedPrompt(backend.ptyProcess, prompt, assertCurrent, progress);
1514
+ }
1515
+ async function writeAutomaticTerminalPrompt(frontendSessionId, prompt, progress) {
1516
+ const record = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1517
+ if (!record)
1518
+ throw new Error('SESSION_REMOVED');
1519
+ const write = await automaticTerminalInput(record, terminalInputGuard(record), progress);
1520
+ await write(prompt);
1521
+ }
1522
+ async function deliverAutomationPromptWhenReady(backendSessionId, prompt) {
1479
1523
  const session = terminalSessions.get(backendSessionId);
1480
- if (!session)
1481
- return;
1482
1524
  const record = globalSessionState.sessions.find(candidate => candidate.backendSessionId === backendSessionId);
1483
- if (record?.agentLaunchCheck) {
1484
- await refreshCollaborationAgentIdentity(backendSessionId, session, true);
1485
- const agent = detectAgentFromCommand(session.activeProgram?.rawArgs ?? session.activeProgram?.command ?? '', agentCustomCommands());
1486
- const nativeSessionId = agent && session.activeProgram?.rawArgs ? inferResumeSessionId(agent, splitCommandToArgv(session.activeProgram.rawArgs)) : null;
1487
- const blocked = await observeAgentLaunchCheck(record, { agentSlug: agent?.slug ?? null, nativeSessionId });
1488
- if (blocked) {
1525
+ if (!session || !record)
1526
+ throw new Error('SHELL_BACKEND_NOT_RUNNING');
1527
+ const assertCurrent = terminalInputGuard(record);
1528
+ const write = await automaticTerminalInput(record, assertCurrent);
1529
+ await waitAndWriteTerminalInput({ assertCurrent, write: () => write(prompt), ready: async (attempt) => {
1530
+ const latest = globalSessionState.sessions.find(candidate => candidate.sessionId === record.sessionId);
1531
+ if (!latest.agentLaunchCheck)
1532
+ return canDeliverPromptToAgent(session) || attempt >= 60;
1533
+ await refreshCollaborationAgentIdentity(backendSessionId, session, true);
1534
+ assertCurrent();
1535
+ const agent = detectAgentFromCommand(session.activeProgram?.rawArgs ?? session.activeProgram?.command ?? '', agentCustomCommands());
1536
+ const nativeSessionId = agent && session.activeProgram?.rawArgs ? inferResumeSessionId(agent, splitCommandToArgv(session.activeProgram.rawArgs)) : null;
1537
+ const blocked = await observeAgentLaunchCheck(latest, { agentSlug: agent?.slug ?? null, nativeSessionId });
1538
+ if (!blocked)
1539
+ return true;
1489
1540
  if (blocked.reason !== 'AGENT_LAUNCH_PENDING')
1490
1541
  throw new Error(blocked.reason ?? 'AGENT_LAUNCH_PENDING');
1491
- await new Promise(resolve => setTimeout(resolve, 250));
1492
- return deliverAutomationPromptWhenReady(backendSessionId, prompt, attempt + 1);
1493
- }
1494
- await writeBracketedPrompt(session.ptyProcess, prompt);
1495
- return;
1496
- }
1497
- if (canDeliverPromptToAgent(session) || attempt >= 60) {
1498
- void writeBracketedPrompt(session.ptyProcess, prompt).catch((error) => console.error('[automation] terminal write failed:', getErrorMessage(error)));
1499
- return;
1500
- }
1501
- setTimeout(() => { void deliverAutomationPromptWhenReady(backendSessionId, prompt, attempt + 1).catch(error => console.error('[automation] terminal write failed:', getErrorMessage(error))); }, 250);
1542
+ return false;
1543
+ } });
1502
1544
  }
1503
1545
  async function runAgentAutomation(automation, req) {
1504
1546
  const run = automationStore.beginRun(automation);
@@ -1515,10 +1557,7 @@ async function runAgentAutomation(automation, req) {
1515
1557
  const message = automation.prompt || automation.command;
1516
1558
  if (!message)
1517
1559
  throw new Error('自动任务没有可发送的内容');
1518
- if (record.agentLaunchCheck)
1519
- await deliverAutomationPromptWhenReady(record.backendSessionId, message);
1520
- else
1521
- await writeBracketedPrompt(backend.ptyProcess, message);
1560
+ await deliverAutomationPromptWhenReady(record.backendSessionId, message);
1522
1561
  }
1523
1562
  else {
1524
1563
  const request = req ?? {};
@@ -1536,16 +1575,16 @@ async function runAgentAutomation(automation, req) {
1536
1575
  const agent = detectAgentFromCommand(automation.command, agentCustomCommands());
1537
1576
  if (agent)
1538
1577
  await beginAgentLaunchCheck(frontendSessionId, agent.slug);
1539
- writeTerminalInput(backend, `${automation.command}\r`);
1578
+ await writeAutomaticTerminalPrompt(frontendSessionId, automation.command);
1540
1579
  }
1541
1580
  if (automation.prompt) {
1542
1581
  if (automation.command)
1543
1582
  await deliverAutomationPromptWhenReady(opened.terminalSession.sessionId, automation.prompt);
1544
1583
  else
1545
- await writeBracketedPrompt(backend.ptyProcess, automation.prompt);
1584
+ await writeAutomaticTerminalPrompt(frontendSessionId, automation.prompt);
1546
1585
  }
1547
1586
  }
1548
- automationStore.finishRun(run.id, 'success', frontendSessionId, '任务已投递');
1587
+ automationStore.finishRun(run.id, 'success', frontendSessionId, '已粘贴到终端并发送回车');
1549
1588
  }
1550
1589
  catch (error) {
1551
1590
  automationStore.finishRun(run.id, 'failed', frontendSessionId, getErrorMessage(error));
@@ -1725,6 +1764,7 @@ async function resolveCollaborationRoute(frontendSessionId) {
1725
1764
  const startup = await integrationDeliveryGuard?.(frontendSessionId);
1726
1765
  if (startup && !startup.allowed)
1727
1766
  return { state: 'recovering', reason: startup.reason ?? 'SESSION_STARTUP_INPUT_PENDING' };
1767
+ const assertGeneration = captureTerminalInputGuard(() => globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId)?.agentLaunchGeneration ?? null, record.agentLaunchGeneration ?? null);
1728
1768
  let backend = resolveOrchestrationBackend(record);
1729
1769
  let binding = collaborationRouting.get(frontendSessionId) ?? {
1730
1770
  sessionId: record.sessionId, backendSessionId: null, mode: record.mode, tmuxSessionName: record.tmuxSessionName,
@@ -1732,6 +1772,7 @@ async function resolveCollaborationRoute(frontendSessionId) {
1732
1772
  };
1733
1773
  if (binding.mode === 'tmux') {
1734
1774
  const inspected = await inspectCollaborationTmux(binding, undefined, false, Boolean(record.agentLaunchCheck?.nativeSessionId), Boolean(record.agentLaunchCheck));
1775
+ assertGeneration();
1735
1776
  if (inspected.state !== 'ready' || !inspected.pane)
1736
1777
  return inspected;
1737
1778
  record = globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId);
@@ -1767,17 +1808,21 @@ async function resolveCollaborationRoute(frontendSessionId) {
1767
1808
  }
1768
1809
  if (!backend)
1769
1810
  return { state: 'detached', reason: 'TMUX_BACKEND_UNAVAILABLE' };
1811
+ assertGeneration();
1812
+ const assertCurrent = terminalInputGuard(globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId));
1770
1813
  return { state: 'ready', isShell: pane.isShell, capture: async () => captureTmuxPaneText(runTmux, pinned), write: async (messages) => {
1771
1814
  if (!globalSessionState.sessions.some((candidate) => candidate.sessionId === frontendSessionId))
1772
1815
  throw new Error('SESSION_REMOVED');
1773
- await writeCollaborationTmuxPane(runTmux, pinned, formatLocalCollaborationMessages(frontendSessionId, messages), runTmuxStdin);
1816
+ await writeCollaborationTmuxPane(runTmux, pinned, formatLocalCollaborationMessages(frontendSessionId, messages), runTmuxStdin, () => { assertGeneration(); assertCurrent(); });
1774
1817
  backend.lastActivity = Date.now();
1775
1818
  } };
1776
1819
  }
1777
1820
  if (!backend || !binding.backendSessionId)
1778
1821
  return { state: 'offline', reason: 'SHELL_BACKEND_NOT_RUNNING' };
1779
1822
  await refreshCollaborationAgentIdentity(binding.backendSessionId, backend, Boolean(record.agentLaunchCheck));
1823
+ assertGeneration();
1780
1824
  const target = backend;
1825
+ const assertCurrent = terminalInputGuard(record);
1781
1826
  if (record.agentLaunchCheck) {
1782
1827
  const agent = detectAgentFromCommand(target.activeProgram?.rawArgs ?? target.activeProgram?.command ?? '', agentCustomCommands());
1783
1828
  const nativeSessionId = agent && target.activeProgram?.rawArgs ? inferResumeSessionId(agent, splitCommandToArgv(target.activeProgram.rawArgs)) : null;
@@ -1793,7 +1838,12 @@ async function resolveCollaborationRoute(frontendSessionId) {
1793
1838
  throw new Error('SESSION_REMOVED');
1794
1839
  if (terminalSessions.get(binding.backendSessionId) !== target)
1795
1840
  throw new Error('SHELL_BACKEND_CHANGED');
1796
- await writeBracketedPrompt(target.ptyProcess, formatLocalCollaborationMessages(frontendSessionId, messages));
1841
+ await writeBracketedPrompt(target.ptyProcess, formatLocalCollaborationMessages(frontendSessionId, messages), () => {
1842
+ assertGeneration();
1843
+ assertCurrent();
1844
+ if (terminalSessions.get(binding.backendSessionId) !== target)
1845
+ throw new Error('TERMINAL_INPUT_TARGET_CHANGED');
1846
+ });
1797
1847
  target.lastActivity = Date.now();
1798
1848
  } };
1799
1849
  }
@@ -1874,7 +1924,7 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1874
1924
  collaborationStore.setRole({ groupId: group.id, sessionId: frontendSessionId, role: bootstrapRole });
1875
1925
  if (profile)
1876
1926
  collaborationStore.setMemberLaunchProfile(group.id, frontendSessionId, profile);
1877
- writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: profile?.command ?? launcher.command })}\r`);
1927
+ await writeAutomaticTerminalPrompt(frontendSessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: profile?.command ?? launcher.command }));
1878
1928
  const requestedTask = typeof input.task === 'string' ? input.task.trim().slice(0, 20_000) : '';
1879
1929
  collaborationStore.send({
1880
1930
  groupId: updatedGroup.id,
@@ -1935,6 +1985,7 @@ export const integrationSessionAdapter = {
1935
1985
  registerDeliveryGuard(guard) { integrationDeliveryGuard = guard; return () => { if (integrationDeliveryGuard === guard)
1936
1986
  integrationDeliveryGuard = undefined; }; },
1937
1987
  pendingMessages(id) { return collaborationStore.pendingCount(id); },
1988
+ messageHistory(id) { return collaborationStore.hasTerminalMessageHistory(id); },
1938
1989
  async prepareRelease(record) {
1939
1990
  if (collaborationStore.groupsForSession(record.session_id).some(group => group.id !== record.group_id))
1940
1991
  integrationError('SESSION_SCOPE_CONFLICT', 'Runtime belongs to another collaboration group; administrator must resolve its membership first', 409);
@@ -2026,21 +2077,28 @@ export const integrationSessionAdapter = {
2026
2077
  collaborationRouting.bind({ ...route, nativeSessionId: nativeId, pane: { ...route.pane, nativeSessionId: nativeId } });
2027
2078
  return { exists: true, running: Boolean(pane.agentSlug), shell: await integrationPaneIsIdleShell(pane), agentSlug: pane.agentSlug || null, nativeId };
2028
2079
  },
2029
- async create(record, prepared) {
2080
+ async create(record, prepared, progress) {
2030
2081
  await listDetectedAgentLaunchers();
2031
2082
  if (!agentBySlug(record.agent_slug))
2032
2083
  integrationError('COLLAB_AGENT_UNAVAILABLE', 'Configured agent plugin is not installed');
2033
2084
  if (integrationTerminalRecord(record))
2034
2085
  integrationError('SESSION_CREATE_OUTCOME_UNKNOWN', 'Creation intent already has a terminal; inspect it instead of relaunching', 409);
2035
- await launchIntegrationTerminal(record, false, prepared);
2086
+ await launchIntegrationTerminal(record, false, prepared, progress);
2036
2087
  },
2037
- async restore(record, prepared) {
2088
+ async restore(record, prepared, progress) {
2038
2089
  await listDetectedAgentLaunchers();
2039
2090
  const agent = agentBySlug(record.agent_slug);
2040
2091
  if (!record.agent_native_session_id || !agent || !buildResumeCommand(agent, record.agent_native_session_id, null))
2041
2092
  integrationError('EXACT_RESUME_UNSUPPORTED', 'Agent plugin must support exact native resume');
2093
+ progress?.('native_owner_check');
2042
2094
  await assertIntegrationNativeResumeAvailable(record);
2043
- await launchIntegrationTerminal(record, true, prepared);
2095
+ await launchIntegrationTerminal(record, true, prepared, progress);
2096
+ },
2097
+ async retryCold(record, prepared, progress) {
2098
+ await listDetectedAgentLaunchers();
2099
+ if (!agentBySlug(record.agent_slug))
2100
+ integrationError('COLLAB_AGENT_UNAVAILABLE', 'Configured agent plugin is not installed');
2101
+ await launchIntegrationTerminal(record, false, prepared, progress, true);
2044
2102
  },
2045
2103
  };
2046
2104
  async function assertIntegrationNativeResumeAvailable(record) {
@@ -2091,12 +2149,28 @@ async function assertIntegrationNativeResumeAvailable(record) {
2091
2149
  program: program?.command ?? null, processSource: program?.source, argumentsObserved: !!program?.rawArgs }];
2092
2150
  });
2093
2151
  }
2094
- async function launchIntegrationTerminal(record, restoring, prepared) {
2152
+ async function launchIntegrationTerminal(record, restoring, prepared, progress, retryCold = false) {
2095
2153
  await collaborationDeliveryWorker.reconfigure(record.session_id, async () => {
2154
+ progress?.('runtime_prepare');
2096
2155
  const group = collaborationStore.getGroup(record.group_id);
2097
2156
  if (!group || group.deleted)
2098
2157
  integrationError('TASK_GROUP_NOT_FOUND', 'Integration group no longer exists', 404);
2099
2158
  const original = await integrationSessionAdapter.inspect(record);
2159
+ if (retryCold) {
2160
+ await integrationSessionAdapter.prepareRelease(record);
2161
+ const owned = integrationTerminalRecord(record);
2162
+ if (!owned || globalSessionState.sessions.some(other => other.sessionId !== record.session_id
2163
+ && (other.tmuxSessionName === owned.tmuxSessionName || owned.backendSessionId && other.backendSessionId === owned.backendSessionId))) {
2164
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Cold retry runtime lacks unique logical ownership', 409);
2165
+ }
2166
+ const history = collaborationStore.hasTerminalMessageHistory(record.session_id);
2167
+ if (history === null)
2168
+ integrationError('SESSION_MESSAGE_HISTORY_UNCONFIRMED', 'Message history cannot be verified', 409);
2169
+ if (history || collaborationStore.pendingCount(record.session_id))
2170
+ integrationError('SESSION_MESSAGE_HISTORY_PRESENT', 'TD message history appeared before retry', 409);
2171
+ if (!record.terminal_binding || !original.exists || original.running || !original.shell || original.nativeId)
2172
+ integrationError('SESSION_COLD_RETRY_RUNTIME_UNCONFIRMED', 'Original shell could not be confirmed before retry', 409);
2173
+ }
2100
2174
  if (!original.exists) {
2101
2175
  let tmuxExists = false;
2102
2176
  try {
@@ -2128,6 +2202,7 @@ async function launchIntegrationTerminal(record, restoring, prepared) {
2128
2202
  const pane = inspected.pane;
2129
2203
  const pinned = { serverPid: pane.serverPid, sessionId: pane.sessionId,
2130
2204
  paneId: pane.paneId, panePid: pane.panePid, agentSlug: record.agent_slug, nativeSessionId: record.agent_native_session_id };
2205
+ progress?.('binding_persist');
2131
2206
  prepared(pinned); // Must persist before the command enters the terminal.
2132
2207
  collaborationRouting.bind({ sessionId: record.session_id, backendSessionId: opened.terminalSession.sessionId,
2133
2208
  mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: record.agent_slug, nativeSessionId: record.agent_native_session_id, pane: pinned });
@@ -2145,8 +2220,11 @@ async function launchIntegrationTerminal(record, restoring, prepared) {
2145
2220
  // use an active-pane target which might have changed during preparation.
2146
2221
  if (record.resume_configuration_fingerprint && record.resume_configuration_fingerprint !== await resumeConfigurationFingerprint(record, integrationSessionAdapter))
2147
2222
  integrationError('RESUME_CONFIGURATION_CHANGED', 'Recovery configuration changed before terminal input', 409);
2148
- if (restoring)
2223
+ if (restoring) {
2224
+ progress?.('native_owner_check');
2149
2225
  await assertIntegrationNativeResumeAvailable(record);
2226
+ }
2227
+ progress?.('runtime_verify');
2150
2228
  const shell = await inspectCollaborationTmux({ sessionId: record.session_id, backendSessionId: opened.terminalSession.sessionId,
2151
2229
  mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: null, nativeSessionId: null, pane: pinned });
2152
2230
  if (shell.state !== 'ready' || !shell.pane || !await integrationPaneIsIdleShell(shell.pane))
@@ -2156,9 +2234,9 @@ async function launchIntegrationTerminal(record, restoring, prepared) {
2156
2234
  backend.agentSession = null;
2157
2235
  backend.agent = null;
2158
2236
  backend.agentResumeRecovered = false;
2237
+ progress?.('launch_intent');
2159
2238
  await beginAgentLaunchCheck(record.session_id, record.agent_slug, restoring ? record.agent_native_session_id : null);
2160
- await runTmux(['send-keys', '-t', pinned.paneId, '-l', integrationLaunchCommand(record, restoring)]);
2161
- await runTmux(['send-keys', '-t', pinned.paneId, 'Enter']);
2239
+ await writeAutomaticTerminalPrompt(record.session_id, integrationLaunchCommand(record, restoring), progress);
2162
2240
  broadcastClientState();
2163
2241
  });
2164
2242
  }
@@ -2210,7 +2288,7 @@ export function prepareCollaborationTaskWorker(task, template, dependencies, ser
2210
2288
  const temporary = `${launchFile}.${process.pid}.tmp`;
2211
2289
  await fs.promises.writeFile(temporary, JSON.stringify({ sessionId: record.sessionId, backendId: opened.terminalSession.sessionId }), { mode: 0o600 });
2212
2290
  await fs.promises.rename(temporary, launchFile);
2213
- writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: inheritedProfile?.command ?? launcher.command })}\r`);
2291
+ await writeAutomaticTerminalPrompt(opened.session.sessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: inheritedProfile?.command ?? launcher.command }));
2214
2292
  }
2215
2293
  const group = collaborationStore.getGroup(task.groupId);
2216
2294
  if (!group || group.deleted)
@@ -5866,16 +5944,21 @@ router.post('/tmux/recovery/restore-all', async (_req, res) => {
5866
5944
  continue;
5867
5945
  }
5868
5946
  try {
5869
- await tmuxLifecycle.run(`restore:${record.tmuxSessionName}`, async () => {
5947
+ await collaborationDeliveryWorker.reconfigure(frontendSessionId, () => tmuxLifecycle.run(`restore:${record.tmuxSessionName}`, async () => {
5870
5948
  await prepareManagedTmuxSessionUnlocked(record.tmuxSessionName, record.cwd);
5871
5949
  const metadata = await resolveLiveTmuxMetadata(record.tmuxSessionName);
5872
5950
  const foreground = metadata?.program?.toLowerCase() ?? null;
5873
5951
  if (foreground && !shellNamesBackend.has(foreground)) {
5874
5952
  throw new Error(`pane is busy with ${foreground}`);
5875
5953
  }
5876
- await runTmux(['send-keys', '-t', record.tmuxSessionName, '-l', '--', command]);
5877
- await runTmux(['send-keys', '-t', record.tmuxSessionName, 'Enter']);
5878
- });
5954
+ // Explicit recovery may replace the vanished tmux pane. A pending
5955
+ // message alone must never replace that binding.
5956
+ const previous = collaborationRouting.get(frontendSessionId);
5957
+ if (previous)
5958
+ collaborationRouting.bind({ ...previous, pane: null });
5959
+ await beginAgentLaunchCheck(frontendSessionId, agent.slug, target.nativeSessionId);
5960
+ await writeAutomaticTerminalPrompt(frontendSessionId, command);
5961
+ }));
5879
5962
  outcomes.push({ sessionId: frontendSessionId, restored: true });
5880
5963
  }
5881
5964
  catch (error) {
@@ -6491,7 +6574,7 @@ router.post('/operations/orchestration/cleanup', async (req, res) => {
6491
6574
  // caller, tmux-local only, and `approve` refuses unless an approval dialog is
6492
6575
  // actually showing (Enter on the highlighted option). The dialogs may be
6493
6576
  // approving any command the member agent asked for; the caller is presumed to
6494
- // own that decision (the delivery confirm gate uses the same primitive).
6577
+ // own that decision. Ordinary delivery never invokes approval automatically.
6495
6578
  const DRIVE_KEYS = new Set(['enter', 'escape', 'space', 'left', 'right', 'up', 'down']);
6496
6579
  router.post('/operations/orchestration/drive', async (req, res) => {
6497
6580
  const sourceSessionId = resolveFrontendSessionId(req.body ?? {});
@@ -6514,6 +6597,7 @@ router.post('/operations/orchestration/drive', async (req, res) => {
6514
6597
  return res.status(409).json({ error: '目标会话不是 tmux 会话,无法从 CLI 驱动(模式:' + (record.mode ?? 'unknown') + ')' });
6515
6598
  }
6516
6599
  const binding = collaborationRouting.get(target);
6600
+ const assertCurrent = terminalInputGuard(record);
6517
6601
  let pane = binding?.pane ?? null;
6518
6602
  if (!pane) {
6519
6603
  // No pinned Agent pane: resolve the session's pane directly so a plain
@@ -6541,7 +6625,7 @@ router.post('/operations/orchestration/drive', async (req, res) => {
6541
6625
  }
6542
6626
  try {
6543
6627
  if (action === 'approve') {
6544
- const approved = await approveCollaborationDialog(runTmux, pane);
6628
+ const approved = await approveCollaborationDialog(runTmux, pane, assertCurrent);
6545
6629
  if (!approved)
6546
6630
  return res.status(409).json({ ok: false, code: 'NO_APPROVAL_DIALOG', error: '目标面板当前没有显示审批对话框;未发送任何按键' });
6547
6631
  return res.json({ ok: true, action, sessionId: target, approved: true });
@@ -6562,14 +6646,14 @@ router.post('/operations/orchestration/drive', async (req, res) => {
6562
6646
  return res.status(400).json({ error: 'run 文本过长(上限 10000 字符);需要更多内容请走 td collab send 投递' });
6563
6647
  // Same bracketed-paste write path deliveries use: one line, one submit,
6564
6648
  // embedded newlines stay inside the recipient's editor.
6565
- await writeCollaborationTmuxPane(runTmux, pane, text, runTmuxStdin);
6649
+ await writeCollaborationTmuxPane(runTmux, pane, text, runTmuxStdin, assertCurrent);
6566
6650
  const snapshot = await captureTmuxPaneText(runTmux, pane);
6567
6651
  return res.json({ ok: true, action, sessionId: target, text, snapshot });
6568
6652
  }
6569
6653
  if (!DRIVE_KEYS.has(action)) {
6570
6654
  return res.status(400).json({ error: `未知动作 ${action};可用:approve|enter|escape|space|left|right|up|down|capture|run` });
6571
6655
  }
6572
- await sendTmuxPaneKey(runTmux, pane, action);
6656
+ await sendTmuxPaneKey(runTmux, pane, action, assertCurrent);
6573
6657
  res.json({ ok: true, action, sessionId: target });
6574
6658
  }
6575
6659
  catch (error) {
@@ -6820,7 +6904,7 @@ router.post('/operations/execution-archives/:sessionId/restore', executionArchiv
6820
6904
  throw error;
6821
6905
  }
6822
6906
  await beginAgentLaunchCheck(record.sessionId, target.slug, target.nativeSessionId);
6823
- writeTerminalInput(backend, `${command}\r`);
6907
+ await writeAutomaticTerminalPrompt(opened.session.sessionId, command);
6824
6908
  restoreArchivedMembership(entry, record.sessionId);
6825
6909
  await persistGlobalStateNow();
6826
6910
  broadcastClientState();
@@ -8062,7 +8146,10 @@ router.post('/:sessionId/agent-resume', async (req, res) => {
8062
8146
  const launch = async () => {
8063
8147
  if (frontend)
8064
8148
  await beginAgentLaunchCheck(frontend.sessionId, target.slug, target.nativeSessionId);
8065
- await writeBracketedPrompt(session.ptyProcess, target.command);
8149
+ if (frontend)
8150
+ await writeAutomaticTerminalPrompt(frontend.sessionId, target.command);
8151
+ else
8152
+ await writeBracketedPrompt(session.ptyProcess, target.command, captureTerminalInputGuard(() => terminalSessions.get(sessionId), session));
8066
8153
  };
8067
8154
  if (frontend)
8068
8155
  await collaborationDeliveryWorker.reconfigure(frontend.sessionId, launch);
@@ -519,6 +519,18 @@ no-op restore 不重新开启检查。检查是运行/绑定事实,不表示 T
519
519
  新检查。一旦当前检查解除,后续普通消息沿原终端路由,不重复判断应用就绪/忙闲。
520
520
  已正常 release 的承载登记被移除,下一次 restore 在新承载上重新记录检查。
521
521
 
522
+ 1.4.313 起,定时发送、Agent 启动/恢复命令和普通消息复用实际终端的串行输入队列;
523
+ tmux 的显式 `drive keys/approve` 也在该队列中执行,不插进正文和回车之间。
524
+ 定时发送等待实际写入调用结束后才记录成功。等待或排队中的输入绑定原承载和
525
+ TD 启动代次,代次检查解除后仍保留;承载替换、移除或再次启动时,旧操作报
526
+ `TERMINAL_INPUT_TARGET_CHANGED`(登记删除为 `SESSION_REMOVED`),不会跟随逻辑 ID
527
+ 写入新的承载。该检查在正文写入前及发送回车前执行;如果承载在两步之间变化,
528
+ 正文可能已写入旧终端,回车不会发给新承载。此错误不证明应用是否收到了正文,
529
+ 也不自动补键或重发正文。持久消息 worker 仍沿已有回执/路由重试规则处理失败,
530
+ 可能写入过的消息须由调用者核对。直接键盘输入不进入自动输入队列。
531
+ 能力探测为 `terminal_input_runtime_fence=true`,最低运行服务 1.4.313;CLI 同升
532
+ 可读取完整帮助和 `TERMINAL_INPUT_TARGET_CHANGED` 的诊断文案。
533
+
522
534
  任务完成继续以负责人明确 `report complete` 为准。
523
535
 
524
536
  恢复保留原 TD ID、原生 ID、argv/model/cwd/包装器配置。原会话已经精确运行时直接
@@ -773,6 +785,104 @@ no-op restore 不创建新检查。报告跟随会话保存并可在服务重启
773
785
  - 启动/恢复:`SESSION_CREATE_OUTCOME_UNKNOWN`, `SESSION_OPERATION_IN_PROGRESS`, `SESSION_BINDING_TIMEOUT`, `EXACT_RESUME_UNSUPPORTED`, `NATIVE_SESSION_ALREADY_RUNNING`, `NATIVE_SESSION_OWNER_UNCONFIRMED`, `AGENT_NOT_RUNNING`。
774
786
  - 未分类异常:`SESSION_LAUNCH_FAILED`, `SESSION_OBSERVATION_FAILED`;错误不包含包装器输出、密钥或原始堆栈。
775
787
 
788
+ ## 1.4.314:启动诊断与显式冷启动重试
789
+
790
+ 最低 CLI 和实际运行服务均为 **1.4.314**,协议仍为 1。先回读两者版本及实际服务
791
+ `session_launch_diagnostics=true`、`session_cold_retry=true`;对应
792
+ `*_min_version` 均为 `1.4.314`。CLI 遇到不支持重试的服务返回
793
+ `SESSION_COLD_RETRY_UNSUPPORTED`,不发出重试请求。
794
+
795
+ 管理员沿用 `td integration diagnostics <TD-session-id>`,同一响应新增
796
+ `launch_diagnostics`(可为 null)与 `launch_diagnostics_history`(最多 16 个此前实际
797
+ 启动操作)。旧 `diagnostics` 原生所有者报告字段保持兼容;该入口仅回读持久记录,
798
+ 不重新扫描进程、不挂接终端、不发送输入。313 及更早启动没有新增报告,不能从升级
799
+ 反推旧失败原因。已有失败会话可以在满足下述检查后显式重试,产生新的诊断。
800
+
801
+ 启动报告字段:
802
+
803
+ | 字段 | 含义 |
804
+ | --- | --- |
805
+ | `operation_id / generation / kind` | 此次操作和承载代次;kind 为 `cold_start / cold_retry / native_restore` |
806
+ | `phase / updated_at / steps` | 最后持久阶段和时间;steps 最多最近 24 个阶段,时间是 TD 记录时间 |
807
+ | `error_code / reason_code` | 公开失败码及已分类原因;无法分类为 `UNCLASSIFIED_LAUNCH_ERROR`,不保存原始错误文本 |
808
+ | `paste / submit` | 各自为 `not_attempted / attempted / write_returned`;attempted 在调用输入前持久保存,write_returned 表示调用返回 |
809
+ | `runtime_exists` | 最后观察是否存在原承载;没有观察时为 null,不代表读取时的实时进程 |
810
+ | `target_change` | 仅发生承载 fencing 冲突时可有:期望/当前 backend ID、期望/当前 launch ID、backend 实例是否相同 |
811
+
812
+ 阶段清单:`configuration`、`runtime_prepare`、`binding_persist`、
813
+ `native_owner_check`(精确恢复)、`runtime_verify`、`launch_intent`、
814
+ `queue_wait`、`queue_acquired`、`paste_attempted`、`paste_written`、
815
+ `submit_attempted`、`submit_written`、`binding_observe`;中断冷重试回读到原 shell 时
816
+ 另记 `reconciled_shell`。阶段只表示 TD 实际到达的步骤,不推断私有 CLI 根因。
817
+ 崩溃在输入调用附近时,attempted 不能证明写入发生或未发生,不能据此补键。
818
+ write_returned 不证明原生程序消费、提交、成功执行或最终结果。正文仍按原机制
819
+ 粘贴一次、等待至少 50ms、发送一次 CR;没有新的屏幕识别、启动 sleep 或额外 Enter。
820
+
821
+ 完整报告仅管理员可读;principal 与主动 session 事件只返回
822
+ `launch_diagnostics_available=true`,不返回阶段、其他候选或结构证据。报告不保存
823
+ argv、命令正文、stdout/stderr、环境变量或凭据。报告历史受上述条数及原描述总存储
824
+ 预算约束,不是无限保留的排查日志。
825
+
826
+ 正式冷重试命令:
827
+
828
+ ```sh
829
+ td collab --principal <id> session get <TD-session-id>
830
+ td integration diagnostics <TD-session-id>
831
+ td collab --principal <id> session retry-cold <TD-session-id> \
832
+ --generation <get返回的generation> --idempotency-key <本次操作唯一键>
833
+ ```
834
+
835
+ 权限沿用 **session.create**,并核对记录所属 principal/本机组、原 profile 当前仍被授权、
836
+ 原 cwd 同时符合旧快照和当前目录授权。使用原启动配置快照,不接受新 argv/cwd/profile
837
+ 参数。它保留逻辑 TD ID、消息关联和旧操作证据;实际尝试递增 generation、建立新
838
+ operation_id,状态为 starting,可能随后 binding_pending/ready/failed。返回的操作
839
+ 快照不是实时状态;用 session get 查询最新状态。
840
+
841
+ 只允许 failed、尚未绑定 native UUID、无 TD 消息历史/待投递且没有进行中或未确认操作
842
+ 的记录;还需核实原绑定的唯一承载仍存在、原前台 Agent 已退出、回到合格 shell。
843
+ TD 会在生命周期锁及 worker 承载变更屏障内复核,不终止 Agent,不删除旧记录,不重建
844
+ 消失或身份不明的终端。shell 检查不声称可读取用户未提交的任意草稿,调用方仍须拥有
845
+ 输入操作权限并避免其他手工输入。TD 消息入队前设置持久、单调的历史标记;即使稍后
846
+ 入队失败也保守拒绝冷重试。314 起消息裁剪保留双方历史标记;升级前已裁剪且没有 sender 标记的
847
+ 历史无法证明完整,没有已知消息也返回未确认。旧格式或不可读存储同样拒绝;此缺口
848
+ 持久保留,不因一次正常写入而被误判已修复。
849
+
850
+ 必须有可信的原 launcher/plugin 恢复语义指纹且当前仍匹配;缺少指纹时管理员沿用
851
+ resume-configuration / confirm-resume 明确核对确认,不能把路径相同当内容相同。
852
+ 指纹只覆盖 TD 已记录的 launcher 文件、原配置和插件恢复语义,不声称验证包装器依赖
853
+ 或私有 Agent 二进制全部内容。
854
+
855
+ **cold retry 不是 native restore。** 无已知 UUID 时不能保证延续之前未知的原生历史,
856
+ 也不证明旧程序未创建过原生历史;重试可能创建新 UUID。已有 UUID 必须使用原
857
+ session restore 与原生身份/重复所有者保护。原 session create 同幂等键继续回读已有
858
+ 记录,不会自动冷重试。
859
+
860
+ 同键同参数回读原操作结果,不再次启动;同键不同参数返回 IDEMPOTENCY_CONFLICT。
861
+ 同会话不同操作键不能并发启动。重试意图和新代次在输入前持久保存,重试期间 send/reply
862
+ 拒绝且不入队。服务重启后不会自动再启动:session get 核实原程序与 UUID 后可以转为
863
+ ready;回读精确原 shell 则为 failed/SESSION_COLD_RETRY_INTERRUPTED,明确结束未确认
864
+ 状态,后续需新键显式重试;承载消失或仍不能确认时保留 cold_retry_pending=true 并拒绝
865
+ 发送/重试。旧操作结果未提交且出现后续代次时,同旧键返回 OPERATION_OUTCOME_UNCONFIRMED,
866
+ 不能把当前代次伪装为旧操作结果。
867
+
868
+ | 拒绝码(HTTP 409,另有注明时除外) | 含义 |
869
+ | --- | --- |
870
+ | `INVALID_SESSION_GENERATION / SESSION_GENERATION_MISMATCH` | 未传有效数值代次 / 代次已变 |
871
+ | `SESSION_COLD_RETRY_UNSUPPORTED` | CLI 或运行服务/adapter 不支持 |
872
+ | `SESSION_COLD_RETRY_NATIVE_BOUND` | 已有 UUID,应走精确 restore |
873
+ | `SESSION_COLD_RETRY_NOT_FAILED` | 当前不是 failed 冷启动 |
874
+ | `SESSION_MESSAGE_HISTORY_PRESENT / SESSION_MESSAGE_HISTORY_UNCONFIRMED` | 有消息/入队尝试 / 无法可靠核实历史 |
875
+ | `SESSION_COLD_RETRY_RUNTIME_UNCONFIRMED` | 无法核实原承载和退出 shell |
876
+ | `SESSION_OPERATION_IN_PROGRESS / OPERATION_OUTCOME_UNCONFIRMED` | 操作在进行 / 前次结果须对账 |
877
+ | `RESUME_CONFIGURATION_UNCONFIRMED / RESUME_CONFIGURATION_CHANGED` | 指纹缺失 / launcher 或恢复语义变化 |
878
+ | `SESSION_SCOPE_CONFLICT / SESSION_IDENTITY_MISMATCH` | 跨组承载或逻辑所有权冲突 |
879
+ | `LAUNCH_PROFILE_DENIED / SESSION_CWD_DENIED`(403) | 原 profile 或 cwd 当前不再授权 |
880
+
881
+ 其他启动错误仍沿用前述准确码;fencing 冲突可为
882
+ `TERMINAL_INPUT_TARGET_CHANGED`,观察失败为 `SESSION_OBSERVATION_FAILED`,未知启动异常
883
+ 为 `SESSION_LAUNCH_FAILED`,原 shell 检查失败可为 `SESSION_TARGET_NOT_SHELL`。
884
+ 新能力并未确认 DevBox 私有 TraeX 的间歇启动原因,也不代替业务明确回复验收。
885
+
776
886
  ## 验收边界
777
887
 
778
888
  本版维护机验证:共享释放协议、真实 Unix socket 权限/生命周期事件、零入队拒绝、
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termdock",
3
- "version": "1.4.312",
3
+ "version": "1.4.314",
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.312",
4
+ "version": "1.4.314",
5
5
  "runtimeProtocolVersion": 1,
6
6
  "minimumDesktopVersion": "1.4.46",
7
7
  "nodeMajor": 22,
8
8
  "dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
9
- "serverBundleHash": "sha256-3z8IRTcO44/bc2KIMkaUKGeZbMd7loehrVjqv4I0pGI=",
10
- "clientBundleHash": "sha256-rSq/8EDPH8i6WLa9SUHpZCeR4b5vZUPiTUusapoxjBs=",
9
+ "serverBundleHash": "sha256-8BA4Rs7jbm4c4qf54MOmbAbAWGquvvGNzdCYk1qugCw=",
10
+ "clientBundleHash": "sha256-dQ3PY+dGYy454zmBVdQy9UamsgCO4JNtEHkXzfSF99k=",
11
11
  "entrypoint": "dist/server/cli.js",
12
12
  "clientEntrypoint": "dist/client/index.html"
13
13
  }
@@ -1,2 +0,0 @@
1
- import{bx as r}from"./app-CHxLSuGQ.js";import{b as m}from"./dnd-BCFAPC0L.js";import{b as n}from"./RightSidebar-VMdXpo4h.js";import"./react-XDCjal2T.js";import"./terminal-C7X98Amf.js";import"./App-ChS2-lkz.js";import"./gestureArbiter-DXLmNGli.js";import"./triangle-alert-xPHw25jD.js";import"./referenceLongPress-DFSrssSr.js";import"./DiffReview-DqrOcRfP.js";import"./sparkles-CapLTKAs.js";import"./DiffViewer-F-uQSmhG.js";import"./ChangeWalkthroughPanel-BlQ5-VPp.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};