termdock 1.4.320 → 1.4.322

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 (354) hide show
  1. package/dist/client/assets/{App-BF6YvbKL.js → App-DEKo4SNL.js} +67 -67
  2. package/dist/client/assets/App-DEKo4SNL.js.br +0 -0
  3. package/dist/client/assets/App-DEKo4SNL.js.gz +0 -0
  4. package/dist/client/assets/{ArchitecturePanel-D1Jca05w.js → ArchitecturePanel-VDM6hrwp.js} +2 -2
  5. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.br +0 -0
  6. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.gz +0 -0
  7. package/dist/client/assets/{ChangeWalkthroughPanel-B59JwhzK.js → ChangeWalkthroughPanel-B64j3i8o.js} +1 -1
  8. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.br +0 -0
  9. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.gz +0 -0
  10. package/dist/client/assets/{CollaborationMainWorkspace-CS_o2iYt.js → CollaborationMainWorkspace-DG8TQNqo.js} +1 -1
  11. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.br +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.gz +0 -0
  13. package/dist/client/assets/CollaborationTaskContent-msQsgVaI.js +2 -0
  14. package/dist/client/assets/{ComputerControlView-CRquP12U.js → ComputerControlView-Co-TTYas.js} +2 -2
  15. package/dist/client/assets/ComputerControlView-Co-TTYas.js.br +0 -0
  16. package/dist/client/assets/ComputerControlView-Co-TTYas.js.gz +0 -0
  17. package/dist/client/assets/{DagPlayground-CAfziHw_.js → DagPlayground-kJczdJ6J.js} +1 -1
  18. package/dist/client/assets/DagPlayground-kJczdJ6J.js.br +0 -0
  19. package/dist/client/assets/DagPlayground-kJczdJ6J.js.gz +0 -0
  20. package/dist/client/assets/{DiffLab-CPlA_7PJ.js → DiffLab-BaaioC-q.js} +1 -1
  21. package/dist/client/assets/DiffLab-BaaioC-q.js.br +0 -0
  22. package/dist/client/assets/DiffLab-BaaioC-q.js.gz +0 -0
  23. package/dist/client/assets/{DiffReview-CjEi6PCy.js → DiffReview-Wfck3RIS.js} +1 -1
  24. package/dist/client/assets/DiffReview-Wfck3RIS.js.br +0 -0
  25. package/dist/client/assets/DiffReview-Wfck3RIS.js.gz +0 -0
  26. package/dist/client/assets/{DiffReviewLab-BFRqRotl.js → DiffReviewLab-Dblr3wgw.js} +1 -1
  27. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.br +0 -0
  28. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.gz +0 -0
  29. package/dist/client/assets/{DiffViewer-Bh6lvUYN.js → DiffViewer-C-utC5Ga.js} +1 -1
  30. package/dist/client/assets/DiffViewer-C-utC5Ga.js.br +0 -0
  31. package/dist/client/assets/DiffViewer-C-utC5Ga.js.gz +0 -0
  32. package/dist/client/assets/{ModelPreview-D_WFk4yX.js → ModelPreview-BBLnHWVQ.js} +1 -1
  33. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.br +0 -0
  34. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.gz +0 -0
  35. package/dist/client/assets/{RightSidebar-7C9-PfhA.js → RightSidebar-CUHSFkmZ.js} +3 -3
  36. package/dist/client/assets/RightSidebar-CUHSFkmZ.js.br +0 -0
  37. package/dist/client/assets/{RightSidebar-7C9-PfhA.js.gz → RightSidebar-CUHSFkmZ.js.gz} +0 -0
  38. package/dist/client/assets/{abnfDiagram-VCTEODGH-DDAdRY3H.js → abnfDiagram-VCTEODGH-DDd99QpA.js} +1 -1
  39. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.br +0 -0
  40. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.gz +0 -0
  41. package/dist/client/assets/{app-BRESmgxW.js → app-CfqF7_nh.js} +3 -3
  42. package/dist/client/assets/app-CfqF7_nh.js.br +0 -0
  43. package/dist/client/assets/app-CfqF7_nh.js.gz +0 -0
  44. package/dist/client/assets/{arc-CV9RqbOa.js → arc-C3dck_E0.js} +1 -1
  45. package/dist/client/assets/arc-C3dck_E0.js.br +0 -0
  46. package/dist/client/assets/arc-C3dck_E0.js.gz +0 -0
  47. package/dist/client/assets/{architectureDiagram-5GKGNRK7-Ct8CtmBh.js → architectureDiagram-5GKGNRK7-C3bCQc2w.js} +1 -1
  48. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.br +0 -0
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.gz +0 -0
  50. package/dist/client/assets/{blockDiagram-I7D4REHJ-CVjuOZ0h.js → blockDiagram-I7D4REHJ-znMn6iCQ.js} +1 -1
  51. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.br +0 -0
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.gz +0 -0
  53. package/dist/client/assets/{c4Diagram-7LVT6UL2-CSKcN0J-.js → c4Diagram-7LVT6UL2-C0sopIsj.js} +1 -1
  54. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.br +0 -0
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.gz +0 -0
  56. package/dist/client/assets/channel-CMC8t83j.js +1 -0
  57. package/dist/client/assets/{chunk-2Q5K7J3B-CF6SP9Cv.js → chunk-2Q5K7J3B-f7USyccJ.js} +1 -1
  58. package/dist/client/assets/{chunk-5VM5RSS4-DZhLGwG4.js → chunk-5VM5RSS4-Ck2xirDs.js} +1 -1
  59. package/dist/client/assets/{chunk-F27PBJKO-CwqjUNpz.js → chunk-F27PBJKO-DaDCIj30.js} +1 -1
  60. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.br +0 -0
  61. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.gz +0 -0
  62. package/dist/client/assets/{chunk-IMKFNOWR-C9WCfeN9.js → chunk-IMKFNOWR-DEC_On5x.js} +1 -1
  63. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.br +0 -0
  64. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.gz +0 -0
  65. package/dist/client/assets/{chunk-JWPE2WC7-DUIVW6rN.js → chunk-JWPE2WC7-BrswC3n2.js} +1 -1
  66. package/dist/client/assets/{chunk-POPQ4Y6H-YgwJ3iH4.js → chunk-POPQ4Y6H-ClMbDV47.js} +1 -1
  67. package/dist/client/assets/{chunk-SVP7TREG-A-vVSOuv.js → chunk-SVP7TREG-D7_1VwC5.js} +1 -1
  68. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.br +0 -0
  69. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.gz +0 -0
  70. package/dist/client/assets/{chunk-TICWLB2K-akdXuwgx.js → chunk-TICWLB2K-D5jzVTZ8.js} +1 -1
  71. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.br +0 -0
  72. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.gz +0 -0
  73. package/dist/client/assets/{chunk-XXDRQBXY-Da273BkJ.js → chunk-XXDRQBXY-DOhaoLcX.js} +1 -1
  74. package/dist/client/assets/classDiagram-ZZMXUADV-ElMHzA-E.js +1 -0
  75. package/dist/client/assets/classDiagram-v2-VYDZK3BY-ElMHzA-E.js +1 -0
  76. package/dist/client/assets/{cose-bilkent-JH36ORCC-CGfQhg7T.js → cose-bilkent-JH36ORCC-DOsaKgiX.js} +1 -1
  77. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.br +0 -0
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.gz +0 -0
  79. package/dist/client/assets/{cynefin-OW5HDTMX-C9RaJCMn.js → cynefin-OW5HDTMX-CMcLh_wh.js} +1 -1
  80. package/dist/client/assets/cynefin-OW5HDTMX-CMcLh_wh.js.br +0 -0
  81. package/dist/client/assets/cynefin-OW5HDTMX-CMcLh_wh.js.gz +0 -0
  82. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-C6SWqaZK.js → cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js} +1 -1
  83. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.br +0 -0
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.gz +0 -0
  85. package/dist/client/assets/{dagre-GXQ25YYZ-DTMtzPmS.js → dagre-GXQ25YYZ-BlW7fAi0.js} +1 -1
  86. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.br +0 -0
  87. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.gz +0 -0
  88. package/dist/client/assets/{diagram-S7CK7UJ4-CRalzYBW.js → diagram-S7CK7UJ4-B0-tKahG.js} +1 -1
  89. package/dist/client/assets/diagram-S7CK7UJ4-B0-tKahG.js.br +0 -0
  90. package/dist/client/assets/diagram-S7CK7UJ4-B0-tKahG.js.gz +0 -0
  91. package/dist/client/assets/{diagram-UQ7AKVKN-B5qxEH5p.js → diagram-UQ7AKVKN-BQumj4Dw.js} +1 -1
  92. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.br +0 -0
  93. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.gz +0 -0
  94. package/dist/client/assets/{diagram-VSXAHHWV-CPSmBWU-.js → diagram-VSXAHHWV-Zx_FLmPP.js} +1 -1
  95. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.br +0 -0
  96. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.gz +0 -0
  97. package/dist/client/assets/{diagram-VX7I27RA-CU8A_voC.js → diagram-VX7I27RA-CEZvatNH.js} +1 -1
  98. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.br +0 -0
  99. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.gz +0 -0
  100. package/dist/client/assets/{diagram-Z3DM3KII-CtT4QOY-.js → diagram-Z3DM3KII-CJ9IEQ8j.js} +1 -1
  101. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.br +0 -0
  102. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.gz +0 -0
  103. package/dist/client/assets/{ebnfDiagram-PWID7BFC-Cvk6Y8JV.js → ebnfDiagram-PWID7BFC-sQQMv3ea.js} +1 -1
  104. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.br +0 -0
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.gz +0 -0
  106. package/dist/client/assets/{erDiagram-RLTQ6QDP-_9Ct2AHs.js → erDiagram-RLTQ6QDP-D3rMpj7M.js} +1 -1
  107. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.br +0 -0
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.gz +0 -0
  109. package/dist/client/assets/{flowDiagram-HODETNUW-BR29aDF_.js → flowDiagram-HODETNUW-B6QZiE0-.js} +1 -1
  110. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.br +0 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.gz +0 -0
  112. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-BvVG7ism.js → ganttDiagram-EL5Y4UJY-Bw9bltcu.js} +1 -1
  113. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.br +0 -0
  114. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.gz +0 -0
  115. package/dist/client/assets/{gestureArbiter-DalDKZKj.js → gestureArbiter-Cczz34oI.js} +1 -1
  116. package/dist/client/assets/gestureArbiter-Cczz34oI.js.br +0 -0
  117. package/dist/client/assets/gestureArbiter-Cczz34oI.js.gz +0 -0
  118. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-BHOjoasY.js → gitGraphDiagram-WWUBYQGX-mdnkxjeD.js} +1 -1
  119. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.br +0 -0
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.gz +0 -0
  121. package/dist/client/assets/{infoDiagram-27XIBGKW-DgmnLtPV.js → infoDiagram-27XIBGKW-DyrPP3Yf.js} +1 -1
  122. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-DoiUx_u1.js → ishikawaDiagram-5VMMS53U-CEPH_ePM.js} +1 -1
  123. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.br +0 -0
  124. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.gz +0 -0
  125. package/dist/client/assets/{journeyDiagram-3NMN7TZE-sz2KwGQ4.js → journeyDiagram-3NMN7TZE-CQ0PjBy7.js} +1 -1
  126. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.br +0 -0
  127. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.gz +0 -0
  128. package/dist/client/assets/{kanban-definition-UXKFOSKX-CdAnN6NF.js → kanban-definition-UXKFOSKX-BpQUXA60.js} +1 -1
  129. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.br +0 -0
  130. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.gz +0 -0
  131. package/dist/client/assets/{layout-7mCqPnQ2.js → layout-BdptC7rq.js} +1 -1
  132. package/dist/client/assets/layout-BdptC7rq.js.br +0 -0
  133. package/dist/client/assets/layout-BdptC7rq.js.gz +0 -0
  134. package/dist/client/assets/{linear-CtGxEwoA.js → linear-C2cSRCxu.js} +1 -1
  135. package/dist/client/assets/linear-C2cSRCxu.js.br +0 -0
  136. package/dist/client/assets/linear-C2cSRCxu.js.gz +0 -0
  137. package/dist/client/assets/{mermaid.core-BxJ2mx92.js → mermaid.core-ClVMFyAU.js} +5 -5
  138. package/dist/client/assets/mermaid.core-ClVMFyAU.js.br +0 -0
  139. package/dist/client/assets/mermaid.core-ClVMFyAU.js.gz +0 -0
  140. package/dist/client/assets/{mindmap-definition-YA3MSWOX-Ck2pdDVb.js → mindmap-definition-YA3MSWOX-D0AFCmsY.js} +1 -1
  141. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.br +0 -0
  142. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.gz +0 -0
  143. package/dist/client/assets/{passwordBootstrap-gTJ9KuKa.js → passwordBootstrap-R2qlU2Pq.js} +1 -1
  144. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.br +0 -0
  145. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.gz +0 -0
  146. package/dist/client/assets/{pegDiagram-XKGWAZYB-CYBdOhd0.js → pegDiagram-XKGWAZYB-BGAh0bwg.js} +1 -1
  147. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.br +0 -0
  148. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.gz +0 -0
  149. package/dist/client/assets/{pieDiagram-E7YTZNPT-IxFUaefz.js → pieDiagram-E7YTZNPT-CDOZUF44.js} +1 -1
  150. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.br +0 -0
  151. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.gz +0 -0
  152. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-CSirkHeE.js → quadrantDiagram-AXDQQJYC-D_Qn6NTU.js} +1 -1
  153. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.br +0 -0
  154. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.gz +0 -0
  155. package/dist/client/assets/{railroadDiagram-O6MQD6OU-CYoi1Ctl.js → railroadDiagram-O6MQD6OU-qUVGWhJN.js} +1 -1
  156. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.br +0 -0
  157. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.gz +0 -0
  158. package/dist/client/assets/{rdpSession-BQ_xI5BI.js → rdpSession-hgCM4i-j.js} +1 -1
  159. package/dist/client/assets/rdpSession-hgCM4i-j.js.br +0 -0
  160. package/dist/client/assets/rdpSession-hgCM4i-j.js.gz +0 -0
  161. package/dist/client/assets/{referenceLongPress-DfQ5jnsk.js → referenceLongPress-BEMsP11a.js} +1 -1
  162. package/dist/client/assets/referenceLongPress-BEMsP11a.js.br +0 -0
  163. package/dist/client/assets/referenceLongPress-BEMsP11a.js.gz +0 -0
  164. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BCoG9aBY.js → requirementDiagram-BXWQKSXE-BBQMQuVZ.js} +1 -1
  165. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.br +0 -0
  166. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.gz +0 -0
  167. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-BM0bKWHQ.js → sankeyDiagram-P5KCCOFB-CeEExsqW.js} +1 -1
  168. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CeEExsqW.js.br +0 -0
  169. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CeEExsqW.js.gz +0 -0
  170. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CVc-3QVK.js → sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js} +1 -1
  171. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.br +0 -0
  172. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.gz +0 -0
  173. package/dist/client/assets/{sizeCapture-INFHLROL-70GusSOh.js → sizeCapture-INFHLROL-MBjz7Snm.js} +1 -1
  174. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.br +0 -0
  175. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.gz +0 -0
  176. package/dist/client/assets/{sparkles-DbcgKKVd.js → sparkles-C9ShmGPf.js} +1 -1
  177. package/dist/client/assets/{stateDiagram-D77RDMKH-BCw-OQPL.js → stateDiagram-D77RDMKH-DtLp89uP.js} +1 -1
  178. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.br +0 -0
  179. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.gz +0 -0
  180. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CIQb4Dp7.js +1 -0
  181. package/dist/client/assets/{swimlanes-42K2YHIH--yebjz0I.js → swimlanes-42K2YHIH-Bc02S1q-.js} +1 -1
  182. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.br +0 -0
  183. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.gz +0 -0
  184. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-RiKL7eXI.js +8 -0
  185. package/dist/client/assets/{timeline-definition-24CTP7MA-B9_XXo4h.js → timeline-definition-24CTP7MA-BLLwbOm5.js} +1 -1
  186. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.br +0 -0
  187. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.gz +0 -0
  188. package/dist/client/assets/{triangle-alert-DG_BJhJY.js → triangle-alert-i_L8ws6U.js} +1 -1
  189. package/dist/client/assets/{vennDiagram-4TSXK5OY-BjYW4tQw.js → vennDiagram-4TSXK5OY-8FcrAdbk.js} +1 -1
  190. package/dist/client/assets/vennDiagram-4TSXK5OY-8FcrAdbk.js.br +0 -0
  191. package/dist/client/assets/{vennDiagram-4TSXK5OY-BjYW4tQw.js.gz → vennDiagram-4TSXK5OY-8FcrAdbk.js.gz} +0 -0
  192. package/dist/client/assets/{videoCompression-DrYmE1Ed.js → videoCompression-RIaDabW4.js} +1 -1
  193. package/dist/client/assets/videoCompression-RIaDabW4.js.br +0 -0
  194. package/dist/client/assets/videoCompression-RIaDabW4.js.gz +0 -0
  195. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-DNVW8Yot.js → wardleyDiagram-VM6X3IG4-paL2wRrJ.js} +1 -1
  196. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.br +0 -0
  197. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.gz +0 -0
  198. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-l7gJBKpK.js → xychartDiagram-S5SC5T6Z-BM5qJ4E7.js} +1 -1
  199. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.br +0 -0
  200. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.gz +0 -0
  201. package/dist/client/index.html +1 -1
  202. package/dist/client/index.html.br +0 -0
  203. package/dist/client/index.html.gz +0 -0
  204. package/dist/client/sw.js +1 -1
  205. package/dist/client/sw.js.br +0 -0
  206. package/dist/client/sw.js.gz +0 -0
  207. package/dist/server/agent/collaborationCli.js +30 -3
  208. package/dist/server/agent/collaborationDeliveryWorker.js +27 -8
  209. package/dist/server/agent/collaborationPeerTransport.js +3 -2
  210. package/dist/server/agent/collaborationRoutes.js +14 -1
  211. package/dist/server/agent/collaborationRouting.js +32 -0
  212. package/dist/server/agent/collaborationStore.js +27 -1
  213. package/dist/server/agent/collaborationTaskCli.js +1 -1
  214. package/dist/server/agent/collaborationTaskGuidance.js +2 -0
  215. package/dist/server/agent/collaborationTaskStore.js +18 -11
  216. package/dist/server/agent/collaborationTmuxDelivery.js +3 -2
  217. package/dist/server/agent/integrationCli.js +6 -0
  218. package/dist/server/agent/integrationServer.js +2 -0
  219. package/dist/server/agent/promptDelivery.js +2 -2
  220. package/dist/server/agent/sessionBindingRecovery.js +1 -1
  221. package/dist/server/agent/sessionLaunchState.js +20 -0
  222. package/dist/server/agent/terminalInput.js +17 -0
  223. package/dist/server/routes/terminal.js +125 -47
  224. package/docs/integrations.md +122 -0
  225. package/package.json +1 -1
  226. package/runtime-manifest.json +3 -3
  227. package/dist/client/assets/App-BF6YvbKL.js.br +0 -0
  228. package/dist/client/assets/App-BF6YvbKL.js.gz +0 -0
  229. package/dist/client/assets/ArchitecturePanel-D1Jca05w.js.br +0 -0
  230. package/dist/client/assets/ArchitecturePanel-D1Jca05w.js.gz +0 -0
  231. package/dist/client/assets/ChangeWalkthroughPanel-B59JwhzK.js.br +0 -0
  232. package/dist/client/assets/ChangeWalkthroughPanel-B59JwhzK.js.gz +0 -0
  233. package/dist/client/assets/CollaborationMainWorkspace-CS_o2iYt.js.br +0 -0
  234. package/dist/client/assets/CollaborationMainWorkspace-CS_o2iYt.js.gz +0 -0
  235. package/dist/client/assets/CollaborationTaskContent-WQ5CC-0d.js +0 -2
  236. package/dist/client/assets/ComputerControlView-CRquP12U.js.br +0 -0
  237. package/dist/client/assets/ComputerControlView-CRquP12U.js.gz +0 -0
  238. package/dist/client/assets/DagPlayground-CAfziHw_.js.br +0 -0
  239. package/dist/client/assets/DagPlayground-CAfziHw_.js.gz +0 -0
  240. package/dist/client/assets/DiffLab-CPlA_7PJ.js.br +0 -0
  241. package/dist/client/assets/DiffLab-CPlA_7PJ.js.gz +0 -0
  242. package/dist/client/assets/DiffReview-CjEi6PCy.js.br +0 -0
  243. package/dist/client/assets/DiffReview-CjEi6PCy.js.gz +0 -0
  244. package/dist/client/assets/DiffReviewLab-BFRqRotl.js.br +0 -0
  245. package/dist/client/assets/DiffReviewLab-BFRqRotl.js.gz +0 -0
  246. package/dist/client/assets/DiffViewer-Bh6lvUYN.js.br +0 -0
  247. package/dist/client/assets/DiffViewer-Bh6lvUYN.js.gz +0 -0
  248. package/dist/client/assets/ModelPreview-D_WFk4yX.js.br +0 -0
  249. package/dist/client/assets/ModelPreview-D_WFk4yX.js.gz +0 -0
  250. package/dist/client/assets/RightSidebar-7C9-PfhA.js.br +0 -0
  251. package/dist/client/assets/abnfDiagram-VCTEODGH-DDAdRY3H.js.br +0 -0
  252. package/dist/client/assets/abnfDiagram-VCTEODGH-DDAdRY3H.js.gz +0 -0
  253. package/dist/client/assets/app-BRESmgxW.js.br +0 -0
  254. package/dist/client/assets/app-BRESmgxW.js.gz +0 -0
  255. package/dist/client/assets/arc-CV9RqbOa.js.br +0 -0
  256. package/dist/client/assets/arc-CV9RqbOa.js.gz +0 -0
  257. package/dist/client/assets/architectureDiagram-5GKGNRK7-Ct8CtmBh.js.br +0 -0
  258. package/dist/client/assets/architectureDiagram-5GKGNRK7-Ct8CtmBh.js.gz +0 -0
  259. package/dist/client/assets/blockDiagram-I7D4REHJ-CVjuOZ0h.js.br +0 -0
  260. package/dist/client/assets/blockDiagram-I7D4REHJ-CVjuOZ0h.js.gz +0 -0
  261. package/dist/client/assets/c4Diagram-7LVT6UL2-CSKcN0J-.js.br +0 -0
  262. package/dist/client/assets/c4Diagram-7LVT6UL2-CSKcN0J-.js.gz +0 -0
  263. package/dist/client/assets/channel-BDjp8qZS.js +0 -1
  264. package/dist/client/assets/chunk-F27PBJKO-CwqjUNpz.js.br +0 -0
  265. package/dist/client/assets/chunk-F27PBJKO-CwqjUNpz.js.gz +0 -0
  266. package/dist/client/assets/chunk-IMKFNOWR-C9WCfeN9.js.br +0 -0
  267. package/dist/client/assets/chunk-IMKFNOWR-C9WCfeN9.js.gz +0 -0
  268. package/dist/client/assets/chunk-SVP7TREG-A-vVSOuv.js.br +0 -0
  269. package/dist/client/assets/chunk-SVP7TREG-A-vVSOuv.js.gz +0 -0
  270. package/dist/client/assets/chunk-TICWLB2K-akdXuwgx.js.br +0 -0
  271. package/dist/client/assets/chunk-TICWLB2K-akdXuwgx.js.gz +0 -0
  272. package/dist/client/assets/classDiagram-ZZMXUADV-CkFBQKLs.js +0 -1
  273. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CkFBQKLs.js +0 -1
  274. package/dist/client/assets/cose-bilkent-JH36ORCC-CGfQhg7T.js.br +0 -0
  275. package/dist/client/assets/cose-bilkent-JH36ORCC-CGfQhg7T.js.gz +0 -0
  276. package/dist/client/assets/cynefin-OW5HDTMX-C9RaJCMn.js.br +0 -0
  277. package/dist/client/assets/cynefin-OW5HDTMX-C9RaJCMn.js.gz +0 -0
  278. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-C6SWqaZK.js.br +0 -0
  279. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-C6SWqaZK.js.gz +0 -0
  280. package/dist/client/assets/dagre-GXQ25YYZ-DTMtzPmS.js.br +0 -0
  281. package/dist/client/assets/dagre-GXQ25YYZ-DTMtzPmS.js.gz +0 -0
  282. package/dist/client/assets/diagram-S7CK7UJ4-CRalzYBW.js.br +0 -0
  283. package/dist/client/assets/diagram-S7CK7UJ4-CRalzYBW.js.gz +0 -0
  284. package/dist/client/assets/diagram-UQ7AKVKN-B5qxEH5p.js.br +0 -0
  285. package/dist/client/assets/diagram-UQ7AKVKN-B5qxEH5p.js.gz +0 -0
  286. package/dist/client/assets/diagram-VSXAHHWV-CPSmBWU-.js.br +0 -0
  287. package/dist/client/assets/diagram-VSXAHHWV-CPSmBWU-.js.gz +0 -0
  288. package/dist/client/assets/diagram-VX7I27RA-CU8A_voC.js.br +0 -0
  289. package/dist/client/assets/diagram-VX7I27RA-CU8A_voC.js.gz +0 -0
  290. package/dist/client/assets/diagram-Z3DM3KII-CtT4QOY-.js.br +0 -0
  291. package/dist/client/assets/diagram-Z3DM3KII-CtT4QOY-.js.gz +0 -0
  292. package/dist/client/assets/ebnfDiagram-PWID7BFC-Cvk6Y8JV.js.br +0 -0
  293. package/dist/client/assets/ebnfDiagram-PWID7BFC-Cvk6Y8JV.js.gz +0 -0
  294. package/dist/client/assets/erDiagram-RLTQ6QDP-_9Ct2AHs.js.br +0 -0
  295. package/dist/client/assets/erDiagram-RLTQ6QDP-_9Ct2AHs.js.gz +0 -0
  296. package/dist/client/assets/flowDiagram-HODETNUW-BR29aDF_.js.br +0 -0
  297. package/dist/client/assets/flowDiagram-HODETNUW-BR29aDF_.js.gz +0 -0
  298. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BvVG7ism.js.br +0 -0
  299. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BvVG7ism.js.gz +0 -0
  300. package/dist/client/assets/gestureArbiter-DalDKZKj.js.br +0 -0
  301. package/dist/client/assets/gestureArbiter-DalDKZKj.js.gz +0 -0
  302. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BHOjoasY.js.br +0 -0
  303. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BHOjoasY.js.gz +0 -0
  304. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DoiUx_u1.js.br +0 -0
  305. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DoiUx_u1.js.gz +0 -0
  306. package/dist/client/assets/journeyDiagram-3NMN7TZE-sz2KwGQ4.js.br +0 -0
  307. package/dist/client/assets/journeyDiagram-3NMN7TZE-sz2KwGQ4.js.gz +0 -0
  308. package/dist/client/assets/kanban-definition-UXKFOSKX-CdAnN6NF.js.br +0 -0
  309. package/dist/client/assets/kanban-definition-UXKFOSKX-CdAnN6NF.js.gz +0 -0
  310. package/dist/client/assets/layout-7mCqPnQ2.js.br +0 -0
  311. package/dist/client/assets/layout-7mCqPnQ2.js.gz +0 -0
  312. package/dist/client/assets/linear-CtGxEwoA.js.br +0 -0
  313. package/dist/client/assets/linear-CtGxEwoA.js.gz +0 -0
  314. package/dist/client/assets/mermaid.core-BxJ2mx92.js.br +0 -0
  315. package/dist/client/assets/mermaid.core-BxJ2mx92.js.gz +0 -0
  316. package/dist/client/assets/mindmap-definition-YA3MSWOX-Ck2pdDVb.js.br +0 -0
  317. package/dist/client/assets/mindmap-definition-YA3MSWOX-Ck2pdDVb.js.gz +0 -0
  318. package/dist/client/assets/passwordBootstrap-gTJ9KuKa.js.br +0 -0
  319. package/dist/client/assets/passwordBootstrap-gTJ9KuKa.js.gz +0 -0
  320. package/dist/client/assets/pegDiagram-XKGWAZYB-CYBdOhd0.js.br +0 -0
  321. package/dist/client/assets/pegDiagram-XKGWAZYB-CYBdOhd0.js.gz +0 -0
  322. package/dist/client/assets/pieDiagram-E7YTZNPT-IxFUaefz.js.br +0 -0
  323. package/dist/client/assets/pieDiagram-E7YTZNPT-IxFUaefz.js.gz +0 -0
  324. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CSirkHeE.js.br +0 -0
  325. package/dist/client/assets/quadrantDiagram-AXDQQJYC-CSirkHeE.js.gz +0 -0
  326. package/dist/client/assets/railroadDiagram-O6MQD6OU-CYoi1Ctl.js.br +0 -0
  327. package/dist/client/assets/railroadDiagram-O6MQD6OU-CYoi1Ctl.js.gz +0 -0
  328. package/dist/client/assets/rdpSession-BQ_xI5BI.js.br +0 -0
  329. package/dist/client/assets/rdpSession-BQ_xI5BI.js.gz +0 -0
  330. package/dist/client/assets/referenceLongPress-DfQ5jnsk.js.br +0 -0
  331. package/dist/client/assets/referenceLongPress-DfQ5jnsk.js.gz +0 -0
  332. package/dist/client/assets/requirementDiagram-BXWQKSXE-BCoG9aBY.js.br +0 -0
  333. package/dist/client/assets/requirementDiagram-BXWQKSXE-BCoG9aBY.js.gz +0 -0
  334. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BM0bKWHQ.js.br +0 -0
  335. package/dist/client/assets/sankeyDiagram-P5KCCOFB-BM0bKWHQ.js.gz +0 -0
  336. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CVc-3QVK.js.br +0 -0
  337. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-CVc-3QVK.js.gz +0 -0
  338. package/dist/client/assets/sizeCapture-INFHLROL-70GusSOh.js.br +0 -0
  339. package/dist/client/assets/sizeCapture-INFHLROL-70GusSOh.js.gz +0 -0
  340. package/dist/client/assets/stateDiagram-D77RDMKH-BCw-OQPL.js.br +0 -0
  341. package/dist/client/assets/stateDiagram-D77RDMKH-BCw-OQPL.js.gz +0 -0
  342. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-C2WqSO6X.js +0 -1
  343. package/dist/client/assets/swimlanes-42K2YHIH--yebjz0I.js.br +0 -0
  344. package/dist/client/assets/swimlanes-42K2YHIH--yebjz0I.js.gz +0 -0
  345. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-Cyxi7gqq.js +0 -8
  346. package/dist/client/assets/timeline-definition-24CTP7MA-B9_XXo4h.js.br +0 -0
  347. package/dist/client/assets/timeline-definition-24CTP7MA-B9_XXo4h.js.gz +0 -0
  348. package/dist/client/assets/vennDiagram-4TSXK5OY-BjYW4tQw.js.br +0 -0
  349. package/dist/client/assets/videoCompression-DrYmE1Ed.js.br +0 -0
  350. package/dist/client/assets/videoCompression-DrYmE1Ed.js.gz +0 -0
  351. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DNVW8Yot.js.br +0 -0
  352. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DNVW8Yot.js.gz +0 -0
  353. package/dist/client/assets/xychartDiagram-S5SC5T6Z-l7gJBKpK.js.br +0 -0
  354. package/dist/client/assets/xychartDiagram-S5SC5T6Z-l7gJBKpK.js.gz +0 -0
@@ -51,7 +51,8 @@ import { archiveTaskWorkspace, restoreTaskWorkspace, snapshotTaskWorkspace } fro
51
51
  import { isTmuxRecoveryCandidate } from '../utils/tmuxRecoveryCandidate.js';
52
52
  import { AutomationStore, normalizeAutomationSchedule } from '../agent/automationStore.js';
53
53
  import { writeBracketedPrompt, canDeliverPromptToAgent } from '../agent/promptDelivery.js';
54
- import { captureTerminalInputGuard, waitAndWriteTerminalInput, TerminalInputTargetChangedError } from '../agent/terminalInput.js';
54
+ import { captureTerminalInputGuard, captureRuntimeInputGuard, waitAndWriteTerminalInput } from '../agent/terminalInput.js';
55
+ import { mergeSessionLaunchState } from '../agent/sessionLaunchState.js';
55
56
  import { agentLaunchBlockReason, normalizeAgentLaunchCheck } from '../agent/agentLaunchCheck.js';
56
57
  import { prepareSupervisionEnable } from '../utils/enableSupervision.js';
57
58
  import { buildServerHealthState, dismissServerHealth } from '../utils/serverHealth.js';
@@ -66,7 +67,7 @@ import { SessionSearchStore } from '../agent/sessionSearchStore.js';
66
67
  import { NativeSessionSearch } from '../agent/nativeSessionSearch.js';
67
68
  import { CollaborationError } from '../agent/collaborationProtocol.js';
68
69
  import { resolveCollaborationBackend, resolveCollaborationSessionId } from '../agent/sessionBindingRecovery.js';
69
- import { CollaborationRoutingStore, selectCollaborationPane, selectDrivePane } from '../agent/collaborationRouting.js';
70
+ import { CollaborationRoutingStore, selectCollaborationPane, selectDrivePane, assessCollaborationRouteIdentity } from '../agent/collaborationRouting.js';
70
71
  import { CollaborationDeliveryWorker } from '../agent/collaborationDeliveryWorker.js';
71
72
  import { approveCollaborationDialog, captureTmuxPaneHistory, captureTmuxPaneText, sendTmuxPaneKey, writeCollaborationTmuxPane } from '../agent/collaborationTmuxDelivery.js';
72
73
  import { listAllHookAgents, refreshStaleHooksAtLaunch, installHooksForSlug, uninstallHooksForSlug, } from '../agent/installers.js';
@@ -678,6 +679,9 @@ process.on('SIGINT', () => { void shutdownWithRecordings(); });
678
679
  // 服务启动时从磁盘加载(带去重,防止历史累积的重复条目复活)
679
680
  void (async () => {
680
681
  await Promise.all([loadGlobalSessionStateFromDisk(), loadTmuxRecoveryStateFromDisk()]);
682
+ // Delivery needs the loaded inventory, not optional PTY adoption/metadata backfill.
683
+ // Those steps must not leave durable messages without a background scheduler.
684
+ collaborationDeliveryWorker.start();
681
685
  await watchGlobalSessionStateFile();
682
686
  // pty-host adoption runs after the state load (its record upserts must not
683
687
  // be clobbered) and before pruning (surviving shell records' backends are
@@ -687,7 +691,6 @@ void (async () => {
687
691
  });
688
692
  pruneOrphanSessions();
689
693
  await backfillPersistedTmuxMetadata();
690
- collaborationDeliveryWorker.start();
691
694
  })();
692
695
  caffeinateManager.startNetworkMonitor();
693
696
  // 清理磁盘恢复后后端已不存在的 session 引用。
@@ -1080,8 +1083,9 @@ async function withInventoryOpenLock(key, task) {
1080
1083
  inventoryOpenLocks.set(key, pending);
1081
1084
  return pending;
1082
1085
  }
1083
- function upsertGlobalSessionRecord(record) {
1084
- const normalized = normalizePersistedClientSession(record);
1086
+ function upsertGlobalSessionRecord(record, launchChange) {
1087
+ const current = globalSessionState.sessions.find(candidate => candidate.sessionId === record.sessionId);
1088
+ const normalized = normalizePersistedClientSession(mergeSessionLaunchState(record, current, launchChange));
1085
1089
  if (!normalized) {
1086
1090
  throw new Error('invalid session record');
1087
1091
  }
@@ -1460,8 +1464,16 @@ async function beginAgentLaunchCheck(frontendSessionId, agentSlug, nativeSession
1460
1464
  if (!record)
1461
1465
  throw new Error('SESSION_REMOVED');
1462
1466
  const id = randomUUID();
1463
- upsertGlobalSessionRecord({ ...record, agentLaunchGeneration: id, agentLaunchCheck: { id, agentSlug, nativeSessionId, deadline: Date.now() + 120_000 } });
1464
- await persistGlobalStateNow();
1467
+ const updated = upsertGlobalSessionRecord(record, { expectedGeneration: record.agentLaunchGeneration ?? null,
1468
+ expectedCheckId: record.agentLaunchCheck?.id ?? null, generation: id,
1469
+ check: { id, agentSlug, nativeSessionId, deadline: Date.now() + 120_000 } });
1470
+ // Capture the guard before persistence yields. The launch command must use
1471
+ // this exact generation, even if another launch occurs during an await.
1472
+ const assertCurrent = terminalInputGuard(updated);
1473
+ assertCurrent('guard_capture');
1474
+ await persistGlobalStateNow(true);
1475
+ assertCurrent('launch_persisted');
1476
+ return assertCurrent;
1465
1477
  }
1466
1478
  async function observeAgentLaunchCheck(record, observed) {
1467
1479
  const check = record.agentLaunchCheck;
@@ -1475,51 +1487,56 @@ async function observeAgentLaunchCheck(record, observed) {
1475
1487
  return { state: 'offline', reason: 'SESSION_REMOVED' };
1476
1488
  if (latest.agentLaunchCheck?.id !== check.id)
1477
1489
  return { state: 'recovering', reason: 'AGENT_LAUNCH_CHANGED' };
1478
- upsertGlobalSessionRecord({ ...latest, agentLaunchCheck: null });
1490
+ upsertGlobalSessionRecord(latest, { expectedGeneration: latest.agentLaunchGeneration ?? null,
1491
+ expectedCheckId: check.id, generation: latest.agentLaunchGeneration ?? null, check: null });
1479
1492
  await persistGlobalStateNow();
1480
1493
  return null;
1481
1494
  }
1482
1495
  function terminalInputGuard(record) {
1483
1496
  const frontendSessionId = record.sessionId;
1484
1497
  const backendSessionId = record.backendSessionId;
1485
- const launchId = record.agentLaunchGeneration ?? null;
1486
- const backend = backendSessionId ? terminalSessions.get(backendSessionId) : undefined;
1487
- return () => {
1498
+ const expected = { backendSessionId, launchId: record.agentLaunchGeneration ?? null,
1499
+ routeRevision: collaborationRouting.get(frontendSessionId)?.routeRevision ?? null,
1500
+ backendInstance: backendSessionId ? terminalSessions.get(backendSessionId) : undefined };
1501
+ return captureRuntimeInputGuard(() => {
1488
1502
  const latest = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1489
1503
  if (!latest)
1490
1504
  throw new Error('SESSION_REMOVED');
1491
- const instanceMatches = !backendSessionId || terminalSessions.get(backendSessionId) === backend;
1492
- if ((latest.agentLaunchGeneration ?? null) !== launchId || latest.backendSessionId !== backendSessionId || !instanceMatches) {
1493
- throw new TerminalInputTargetChangedError({ expected_backend_session_id: backendSessionId, current_backend_session_id: latest.backendSessionId,
1494
- expected_launch_id: launchId, current_launch_id: latest.agentLaunchGeneration ?? null, backend_instance_matches: instanceMatches });
1495
- }
1496
- };
1505
+ return { backendSessionId: latest.backendSessionId, launchId: latest.agentLaunchGeneration ?? null,
1506
+ routeRevision: collaborationRouting.get(frontendSessionId)?.routeRevision ?? null,
1507
+ backendInstance: latest.backendSessionId ? terminalSessions.get(latest.backendSessionId) : undefined };
1508
+ }, expected);
1497
1509
  }
1498
1510
  /** tmux input always uses the pane queue, including automation and launch commands. */
1499
1511
  async function automaticTerminalInput(record, assertCurrent = terminalInputGuard(record), progress) {
1500
- assertCurrent();
1512
+ progress?.('guard_captured');
1513
+ assertCurrent('runtime_resolve');
1514
+ progress?.('runtime_resolving');
1501
1515
  if (record.mode === 'tmux') {
1502
1516
  const binding = collaborationRouting.get(record.sessionId) ?? {
1503
1517
  sessionId: record.sessionId, backendSessionId: record.backendSessionId, mode: record.mode,
1504
1518
  tmuxSessionName: record.tmuxSessionName, agentSlug: null, nativeSessionId: null, pane: null,
1505
1519
  };
1506
1520
  const inspected = await inspectCollaborationTmux(binding, null, true);
1507
- assertCurrent();
1521
+ assertCurrent('runtime_resolved');
1508
1522
  if (inspected.state !== 'ready' || !inspected.pane)
1509
1523
  throw new Error(inspected.reason ?? 'TMUX_PANE_UNAVAILABLE');
1510
1524
  const pane = inspected.pane;
1525
+ progress?.('runtime_resolved');
1511
1526
  return (prompt) => writeCollaborationTmuxPane(runTmux, pane, prompt, runTmuxStdin, assertCurrent, progress);
1512
1527
  }
1513
1528
  const backend = record.backendSessionId ? terminalSessions.get(record.backendSessionId) : null;
1514
1529
  if (!backend)
1515
1530
  throw new Error('SHELL_BACKEND_NOT_RUNNING');
1531
+ assertCurrent('runtime_resolved');
1532
+ progress?.('runtime_resolved');
1516
1533
  return (prompt) => writeBracketedPrompt(backend.ptyProcess, prompt, assertCurrent, progress);
1517
1534
  }
1518
- async function writeAutomaticTerminalPrompt(frontendSessionId, prompt, progress) {
1535
+ async function writeAutomaticTerminalPrompt(frontendSessionId, prompt, progress, launchGuard) {
1519
1536
  const record = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1520
1537
  if (!record)
1521
1538
  throw new Error('SESSION_REMOVED');
1522
- const write = await automaticTerminalInput(record, terminalInputGuard(record), progress);
1539
+ const write = await automaticTerminalInput(record, launchGuard ?? terminalInputGuard(record), progress);
1523
1540
  await write(prompt);
1524
1541
  }
1525
1542
  async function deliverAutomationPromptWhenReady(backendSessionId, prompt) {
@@ -1576,9 +1593,8 @@ async function runAgentAutomation(automation, req) {
1576
1593
  throw new Error('自动任务会话创建失败');
1577
1594
  if (automation.command) {
1578
1595
  const agent = detectAgentFromCommand(automation.command, agentCustomCommands());
1579
- if (agent)
1580
- await beginAgentLaunchCheck(frontendSessionId, agent.slug);
1581
- await writeAutomaticTerminalPrompt(frontendSessionId, automation.command);
1596
+ const launchGuard = agent ? await beginAgentLaunchCheck(frontendSessionId, agent.slug) : undefined;
1597
+ await writeAutomaticTerminalPrompt(frontendSessionId, automation.command, undefined, launchGuard);
1582
1598
  }
1583
1599
  if (automation.prompt) {
1584
1600
  if (automation.command)
@@ -1612,6 +1628,7 @@ export function resolveStableFederationSessionId(id) {
1612
1628
  }
1613
1629
  function collaborationRemoteSessions() {
1614
1630
  return Array.from(new Map(collaborationStore.list().flatMap((group) => group.remoteSessions ?? [])
1631
+ .filter(session => session.sessionId.startsWith('remote:'))
1615
1632
  .map((session) => {
1616
1633
  const facts = collaborationStore.sessionFacts(session.sessionId, false);
1617
1634
  const { currentTask: _currentTask, ...terminalSession } = session;
@@ -1622,8 +1639,7 @@ function collaborationRemoteSessions() {
1622
1639
  })).values());
1623
1640
  }
1624
1641
  function tryDeliverCollaborationInbox(frontendSessionId) {
1625
- const remote = collaborationRemoteSessions().find((session) => session.sessionId === frontendSessionId);
1626
- if (remote) {
1642
+ if (frontendSessionId.startsWith('remote:')) {
1627
1643
  return { delivered: [], pending: collaborationStore.pendingCount(frontendSessionId), waitable: true,
1628
1644
  reason: '跨服务消息已入队,服务后台正在投递;使用 message get 查看送达回执或注册、重试原因。' };
1629
1645
  }
@@ -1669,7 +1685,7 @@ function formatLocalCollaborationMessages(frontendSessionId, messages) {
1669
1685
  * agent-keyed selector can never reach it. Delivery still needs an agent (the
1670
1686
  * confirm gate and prompt formatting assume a TUI); driving a terminal —
1671
1687
  * run/capture — is a shell operation and works on any pane. */
1672
- async function inspectCollaborationTmux(binding, requestedPane, allowPlainPane = false, nativeProcessIdentity = false, freshProcess = false) {
1688
+ async function inspectCollaborationTmux(binding, requestedPane, allowPlainPane = false, nativeProcessIdentity = false, freshProcess = false, describeNativeFailure = false) {
1673
1689
  if (!binding.tmuxSessionName)
1674
1690
  return { state: 'offline', reason: 'TMUX_BINDING_MISSING' };
1675
1691
  const name = `=${binding.tmuxSessionName}`;
@@ -1696,14 +1712,16 @@ async function inspectCollaborationTmux(binding, requestedPane, allowPlainPane =
1696
1712
  const program = await resolveTmuxPaneProgram(pane, true, nativeProcessIdentity || freshProcess);
1697
1713
  const agent = detectAgentFromCommand(program?.rawArgs ?? program?.command ?? '', agentCustomCommands());
1698
1714
  const identity = nativeProcessIdentity ? await observeProgramNativeIdentity(agent, program)
1699
- : { nativeId: agent && program?.rawArgs ? inferResumeSessionId(agent, splitCommandToArgv(program.rawArgs)) : null, failure: null };
1700
- if (identity.failure)
1715
+ : { nativeId: agent && program?.rawArgs ? inferResumeSessionId(agent, splitCommandToArgv(program.rawArgs)) : null, failure: null, source: null };
1716
+ if (identity.failure && !describeNativeFailure)
1701
1717
  integrationError(identity.failure === 'NATIVE_SESSION_IDENTITY_CONFLICT'
1702
1718
  ? 'NATIVE_SESSION_ID_MISMATCH' : 'NATIVE_SESSION_OWNER_UNCONFIRMED', 'Current process native identity evidence conflicts or cannot be uniquely verified', 409);
1703
1719
  const nativeSessionId = identity.nativeId;
1704
1720
  return { serverPid, sessionId: layout.sessionId, paneId: pane.id, panePid: pane.pid,
1705
1721
  agentSlug: agent?.slug ?? '', nativeSessionId, cwd: pane.currentPath,
1706
- isShell: shellNamesBackend.has(normalizeProgramName(program?.command ?? '')?.toLowerCase() ?? '') };
1722
+ isShell: shellNamesBackend.has(normalizeProgramName(program?.command ?? '')?.toLowerCase() ?? ''),
1723
+ ...(nativeProcessIdentity ? { nativeIdentitySource: identity.source, nativeIdentityFailure: identity.failure,
1724
+ nativeIdentityVerified: identity.source === 'linux-flock-owner' && !identity.failure } : {}) };
1707
1725
  }));
1708
1726
  const candidates = requestedPane ? panes.filter((pane) => pane.paneId === requestedPane) : panes;
1709
1727
  if (allowPlainPane && !binding.pane) {
@@ -1711,24 +1729,56 @@ async function inspectCollaborationTmux(binding, requestedPane, allowPlainPane =
1711
1729
  // pane so a plain shell member is drivable (run/capture are shell ops).
1712
1730
  return selectDrivePane(binding, candidates, layout.activePaneId);
1713
1731
  }
1714
- return selectCollaborationPane(binding, candidates);
1732
+ return { ...selectCollaborationPane(binding, candidates), candidates };
1733
+ }
1734
+ function routeOwnershipConfirmed(frontendSessionId, binding, panes) {
1735
+ const record = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1736
+ return !!record && record.mode === 'tmux' && record.tmuxSessionName === binding.tmuxSessionName
1737
+ && !globalSessionState.sessions.some(other => other.sessionId !== frontendSessionId && (other.tmuxSessionName === binding.tmuxSessionName
1738
+ || !!binding.backendSessionId && other.backendSessionId === binding.backendSessionId))
1739
+ && (!binding.backendSessionId || [null, frontendSessionId].includes(collaborationRouting.ownerOfBackend(binding.backendSessionId)))
1740
+ && panes.every(pane => !collaborationRouting.hasOtherPaneOwner(frontendSessionId, pane));
1741
+ }
1742
+ function routeHasUnconfirmedWrite(frontendSessionId) {
1743
+ return collaborationStore.hasUnconfirmedDelivery(frontendSessionId);
1744
+ }
1745
+ async function describeCollaborationRoute(frontendSessionId) {
1746
+ const record = globalSessionState.sessions.find(candidate => candidate.sessionId === frontendSessionId);
1747
+ if (!record)
1748
+ throw new Error('SESSION_REMOVED');
1749
+ const binding = collaborationRouting.get(frontendSessionId);
1750
+ if (!binding || binding.mode !== 'tmux')
1751
+ return { session_id: frontendSessionId, binding,
1752
+ worker: collaborationDeliveryWorker.diagnostics(frontendSessionId), identity: null };
1753
+ const inspected = await inspectCollaborationTmux(binding, null, false, true, true, true);
1754
+ const assessment = assessCollaborationRouteIdentity(binding, inspected.candidates ?? [], routeOwnershipConfirmed(frontendSessionId, binding, inspected.candidates ?? []), routeHasUnconfirmedWrite(frontendSessionId));
1755
+ return { session_id: frontendSessionId, binding, worker: collaborationDeliveryWorker.diagnostics(frontendSessionId),
1756
+ observed_at: Date.now(), state: inspected.state, error: inspected.reason ?? null, identity: assessment.diagnostics,
1757
+ integration_managed: record.tmuxSessionName?.startsWith('wt-integration-') ?? false };
1715
1758
  }
1716
1759
  async function rebindCollaborationRoute(frontendSessionId, paneId) {
1717
1760
  await collaborationDeliveryWorker.reconfigure(frontendSessionId, async () => {
1718
1761
  const record = globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId);
1719
1762
  if (!record)
1720
1763
  throw new Error('SESSION_REMOVED');
1764
+ if (record.tmuxSessionName?.startsWith('wt-integration-'))
1765
+ throw new Error('INTEGRATION_SESSION_RESTORE_REQUIRED: use the owning principal session restore lifecycle');
1721
1766
  const previous = collaborationRouting.get(frontendSessionId);
1767
+ if (routeHasUnconfirmedWrite(frontendSessionId))
1768
+ throw new Error('ROUTE_DELIVERY_OUTCOME_UNCONFIRMED: inspect prior write outcome before rebinding; the body is not replayed');
1722
1769
  const binding = {
1723
1770
  sessionId: frontendSessionId, backendSessionId: previous?.backendSessionId ?? record.backendSessionId,
1724
1771
  mode: record.mode, tmuxSessionName: record.tmuxSessionName ?? previous?.tmuxSessionName ?? null,
1725
1772
  agentSlug: null, nativeSessionId: null, pane: null,
1773
+ routeRevision: crypto.randomUUID(), lastRecovery: { kind: 'owner-confirmed', at: Date.now(), previousPane: previous?.pane ?? null },
1726
1774
  };
1727
1775
  if (binding.mode === 'tmux') {
1728
1776
  const inspected = await inspectCollaborationTmux(binding, paneId);
1729
1777
  if (inspected.state !== 'ready' || !inspected.pane)
1730
1778
  throw new Error(inspected.reason ?? 'AGENT_NOT_RUNNING');
1731
1779
  const pane = inspected.pane;
1780
+ if (!routeOwnershipConfirmed(frontendSessionId, binding, [pane]))
1781
+ throw new Error('ROUTE_OWNERSHIP_UNCONFIRMED');
1732
1782
  binding.pane = { serverPid: pane.serverPid, sessionId: pane.sessionId, paneId: pane.paneId, panePid: pane.panePid,
1733
1783
  agentSlug: pane.agentSlug, nativeSessionId: pane.nativeSessionId };
1734
1784
  binding.agentSlug = pane.agentSlug;
@@ -1759,6 +1809,7 @@ async function rebindCollaborationRoute(frontendSessionId, paneId) {
1759
1809
  * snapshot of the recipient after the write, and the sender judges from that.
1760
1810
  */
1761
1811
  async function resolveCollaborationRoute(frontendSessionId) {
1812
+ let recoveredNativeIdentity = false;
1762
1813
  let record = globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId);
1763
1814
  if (!record)
1764
1815
  return { state: 'offline', reason: 'SESSION_REMOVED' };
@@ -1774,7 +1825,26 @@ async function resolveCollaborationRoute(frontendSessionId) {
1774
1825
  agentSlug: record.agentResume?.slug ?? null, nativeSessionId: record.agentResume?.sessionId ?? null, pane: null,
1775
1826
  };
1776
1827
  if (binding.mode === 'tmux') {
1777
- const inspected = await inspectCollaborationTmux(binding, undefined, false, Boolean(record.agentLaunchCheck?.nativeSessionId), Boolean(record.agentLaunchCheck));
1828
+ let inspected = await inspectCollaborationTmux(binding, undefined, false, Boolean(record.agentLaunchCheck?.nativeSessionId), Boolean(record.agentLaunchCheck));
1829
+ if (inspected.state === 'identity-mismatch' && !record.tmuxSessionName?.startsWith('wt-integration-')) {
1830
+ const observed = await inspectCollaborationTmux(binding, null, false, true, true, true);
1831
+ const assessment = assessCollaborationRouteIdentity(binding, observed.candidates ?? [], routeOwnershipConfirmed(frontendSessionId, binding, observed.candidates ?? []), routeHasUnconfirmedWrite(frontendSessionId));
1832
+ if (assessment.diagnostics.recovery !== 'automatic' || !assessment.pane)
1833
+ return { state: 'identity-mismatch', reason: 'TMUX_PANE_CHANGED', diagnostics: assessment.diagnostics };
1834
+ const previous = collaborationRouting.get(frontendSessionId);
1835
+ if (JSON.stringify(previous) !== JSON.stringify(binding))
1836
+ return { state: 'recovering', reason: 'ROUTE_CHANGED_DURING_RECOVERY' };
1837
+ const verify = await inspectCollaborationTmux(binding, null, false, true, true, true);
1838
+ const confirmed = assessCollaborationRouteIdentity(binding, verify.candidates ?? [], routeOwnershipConfirmed(frontendSessionId, binding, verify.candidates ?? []), routeHasUnconfirmedWrite(frontendSessionId));
1839
+ if (confirmed.diagnostics.recovery !== 'automatic' || !confirmed.pane || JSON.stringify(confirmed.pane) !== JSON.stringify(assessment.pane)) {
1840
+ return { state: 'identity-mismatch', reason: 'ROUTE_CHANGED_DURING_RECOVERY', diagnostics: confirmed.diagnostics };
1841
+ }
1842
+ binding = { ...binding, pane: confirmed.pane, routeRevision: crypto.randomUUID(),
1843
+ lastRecovery: { kind: 'native-identity', at: Date.now(), previousPane: binding.pane } };
1844
+ collaborationRouting.bind(binding);
1845
+ inspected = { state: 'ready', pane: confirmed.pane };
1846
+ recoveredNativeIdentity = true;
1847
+ }
1778
1848
  assertGeneration();
1779
1849
  if (inspected.state !== 'ready' || !inspected.pane)
1780
1850
  return inspected;
@@ -1816,6 +1886,14 @@ async function resolveCollaborationRoute(frontendSessionId) {
1816
1886
  return { state: 'ready', isShell: pane.isShell, capture: async () => captureTmuxPaneText(runTmux, pinned), write: async (messages) => {
1817
1887
  if (!globalSessionState.sessions.some((candidate) => candidate.sessionId === frontendSessionId))
1818
1888
  throw new Error('SESSION_REMOVED');
1889
+ if (recoveredNativeIdentity) {
1890
+ const current = await inspectCollaborationTmux(binding, null, false, true, true, true);
1891
+ const proof = current.candidates?.find(candidate => candidate.serverPid === pinned.serverPid && candidate.sessionId === pinned.sessionId
1892
+ && candidate.paneId === pinned.paneId && candidate.panePid === pinned.panePid);
1893
+ if (!proof?.nativeIdentityVerified || proof.nativeIdentityFailure || proof.nativeSessionId !== pinned.nativeSessionId
1894
+ || proof.agentSlug !== pinned.agentSlug || !routeOwnershipConfirmed(frontendSessionId, binding, [proof]))
1895
+ throw new Error('ROUTE_NATIVE_IDENTITY_CHANGED_BEFORE_WRITE');
1896
+ }
1819
1897
  await writeCollaborationTmuxPane(runTmux, pinned, formatLocalCollaborationMessages(frontendSessionId, messages), runTmuxStdin, () => { assertGeneration(); assertCurrent(); });
1820
1898
  backend.lastActivity = Date.now();
1821
1899
  } };
@@ -1904,7 +1982,7 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1904
1982
  const backend = terminalSessions.get(opened.terminalSession.sessionId);
1905
1983
  if (!backend)
1906
1984
  throw new HttpStatusError(500, 'Agent Session 创建失败', 'COLLAB_AGENT_SESSION_FAILED');
1907
- await beginAgentLaunchCheck(frontendSessionId, launcher.slug);
1985
+ const launchGuard = await beginAgentLaunchCheck(frontendSessionId, launcher.slug);
1908
1986
  const latestGroup = collaborationStore.getGroup(group.id);
1909
1987
  if (!latestGroup || latestGroup.deleted) {
1910
1988
  const created = globalSessionState.sessions.find(record => record.sessionId === frontendSessionId);
@@ -1927,7 +2005,7 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1927
2005
  collaborationStore.setRole({ groupId: group.id, sessionId: frontendSessionId, role: bootstrapRole, creationKey });
1928
2006
  if (profile)
1929
2007
  collaborationStore.setMemberLaunchProfile(group.id, frontendSessionId, profile);
1930
- await writeAutomaticTerminalPrompt(frontendSessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: profile?.command ?? launcher.command }));
2008
+ await writeAutomaticTerminalPrompt(frontendSessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: profile?.command ?? launcher.command }), undefined, launchGuard);
1931
2009
  const requestedTask = typeof input.task === 'string' ? input.task.trim().slice(0, 20_000) : '';
1932
2010
  collaborationStore.send({
1933
2011
  groupId: updatedGroup.id,
@@ -2357,8 +2435,8 @@ async function launchIntegrationTerminal(record, restoring, prepared, progress,
2357
2435
  backend.agent = null;
2358
2436
  backend.agentResumeRecovered = false;
2359
2437
  progress?.('launch_intent');
2360
- await beginAgentLaunchCheck(record.session_id, record.agent_slug, restoring ? record.agent_native_session_id : null);
2361
- await writeAutomaticTerminalPrompt(record.session_id, integrationLaunchCommand(record, restoring), progress);
2438
+ const launchGuard = await beginAgentLaunchCheck(record.session_id, record.agent_slug, restoring ? record.agent_native_session_id : null);
2439
+ await writeAutomaticTerminalPrompt(record.session_id, integrationLaunchCommand(record, restoring), progress, launchGuard);
2362
2440
  broadcastClientState();
2363
2441
  });
2364
2442
  }
@@ -2405,12 +2483,12 @@ export function prepareCollaborationTaskWorker(task, template, dependencies, ser
2405
2483
  throw error;
2406
2484
  }
2407
2485
  if (!currentAgent && (!launch || launch.backendId !== opened.terminalSession.sessionId)) {
2408
- await beginAgentLaunchCheck(record.sessionId, launcher.slug);
2486
+ const launchGuard = await beginAgentLaunchCheck(record.sessionId, launcher.slug);
2409
2487
  // Persist before typing: a retry must never type the launcher into a newly booted Agent's prompt.
2410
2488
  const temporary = `${launchFile}.${process.pid}.tmp`;
2411
2489
  await fs.promises.writeFile(temporary, JSON.stringify({ sessionId: record.sessionId, backendId: opened.terminalSession.sessionId }), { mode: 0o600 });
2412
2490
  await fs.promises.rename(temporary, launchFile);
2413
- await writeAutomaticTerminalPrompt(opened.session.sessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: inheritedProfile?.command ?? launcher.command }));
2491
+ await writeAutomaticTerminalPrompt(opened.session.sessionId, buildCollaborationSpawnCommand({ slug: launcher.slug, command: inheritedProfile?.command ?? launcher.command }), undefined, launchGuard);
2414
2492
  }
2415
2493
  const group = collaborationStore.getGroup(task.groupId);
2416
2494
  if (!group || group.deleted)
@@ -6078,8 +6156,8 @@ router.post('/tmux/recovery/restore-all', async (_req, res) => {
6078
6156
  const previous = collaborationRouting.get(frontendSessionId);
6079
6157
  if (previous)
6080
6158
  collaborationRouting.bind({ ...previous, pane: null });
6081
- await beginAgentLaunchCheck(frontendSessionId, agent.slug, target.nativeSessionId);
6082
- await writeAutomaticTerminalPrompt(frontendSessionId, command);
6159
+ const launchGuard = await beginAgentLaunchCheck(frontendSessionId, agent.slug, target.nativeSessionId);
6160
+ await writeAutomaticTerminalPrompt(frontendSessionId, command, undefined, launchGuard);
6083
6161
  }));
6084
6162
  outcomes.push({ sessionId: frontendSessionId, restored: true });
6085
6163
  }
@@ -6474,7 +6552,8 @@ router.get('/operations/collaboration-groups/:groupId/messages', (req, res) => {
6474
6552
  return ambiguousGroupResponse(res, ambiguous);
6475
6553
  if (!group)
6476
6554
  return res.status(404).json({ error: '协作组不存在' });
6477
- res.json({ messages: collaborationStore.listMessages(group.id, Number(req.query.limit) || 200) });
6555
+ res.json({ messages: collaborationStore.listMessages(group.id, Number(req.query.limit) || 200)
6556
+ .map(message => ({ ...message, delivery: collaborationStore.receipt(message.id).delivery })) });
6478
6557
  });
6479
6558
  router.post('/operations/collaboration-groups/:groupId/messages', (req, res) => {
6480
6559
  try {
@@ -6789,7 +6868,7 @@ router.post('/operations/orchestration/drive', async (req, res) => {
6789
6868
  }
6790
6869
  });
6791
6870
  router.use('/operations/orchestration', collaborationRoutes({ store: collaborationStore, resolveSession: resolveFrontendSessionId,
6792
- deliver: tryDeliverCollaborationInbox, rebind: rebindCollaborationRoute,
6871
+ deliver: tryDeliverCollaborationInbox, rebind: rebindCollaborationRoute, diagnoseRoute: describeCollaborationRoute,
6793
6872
  resolveNames: (ids) => {
6794
6873
  const names = new Map([...collaborationRemoteSessions(),
6795
6874
  ...globalSessionState.sessions.map(orchestrationSessionSnapshot)].map((session) => [session.sessionId, session.name]));
@@ -7031,8 +7110,8 @@ router.post('/operations/execution-archives/:sessionId/restore', executionArchiv
7031
7110
  broadcastClientState();
7032
7111
  throw error;
7033
7112
  }
7034
- await beginAgentLaunchCheck(record.sessionId, target.slug, target.nativeSessionId);
7035
- await writeAutomaticTerminalPrompt(opened.session.sessionId, command);
7113
+ const launchGuard = await beginAgentLaunchCheck(record.sessionId, target.slug, target.nativeSessionId);
7114
+ await writeAutomaticTerminalPrompt(opened.session.sessionId, command, undefined, launchGuard);
7036
7115
  restoreArchivedMembership(entry, record.sessionId);
7037
7116
  await persistGlobalStateNow();
7038
7117
  broadcastClientState();
@@ -8276,10 +8355,9 @@ router.post('/:sessionId/agent-resume', async (req, res) => {
8276
8355
  try {
8277
8356
  const frontend = globalSessionState.sessions.find(candidate => candidate.backendSessionId === sessionId);
8278
8357
  const launch = async () => {
8358
+ const launchGuard = frontend ? await beginAgentLaunchCheck(frontend.sessionId, target.slug, target.nativeSessionId) : undefined;
8279
8359
  if (frontend)
8280
- await beginAgentLaunchCheck(frontend.sessionId, target.slug, target.nativeSessionId);
8281
- if (frontend)
8282
- await writeAutomaticTerminalPrompt(frontend.sessionId, target.command);
8360
+ await writeAutomaticTerminalPrompt(frontend.sessionId, target.command, undefined, launchGuard);
8283
8361
  else
8284
8362
  await writeBracketedPrompt(session.ptyProcess, target.command, captureTerminalInputGuard(() => terminalSessions.get(sessionId), session));
8285
8363
  };
@@ -1169,3 +1169,125 @@ TD/native session ID、消息/reply、事件/consumer 历史。没有 Agent 启
1169
1169
  并发不同键竞争/同键重放、删除/跨服务、管理员 Unix 路由/CLI 权限及 JSON、网页列表
1170
1170
  回读和旧网页表单版本冲突。DevBox 业务组及真实 macOS/iOS 显示尚待接入方实机验收,
1171
1171
  不以源码/模拟回归代替其运行现场。
1172
+
1173
+ ## 1.4.321:普通协作会话的承载变化、阻断诊断与恢复
1174
+
1175
+ 最低 CLI/实际服务均为 **1.4.321**;普通协作协议仍为 2,integration protocol 仍为 1。
1176
+ 当前 CLI 版本不能替代实际服务版本;普通成员使用
1177
+ `td collab --session <自身ID> capabilities --json` 回读 `server_version`、
1178
+ `route_diagnostics=true`、`route_identity_recovery=true`、
1179
+ `route_identity_recovery_min_version=1.4.321`。
1180
+
1181
+ ```sh
1182
+ td collab --session <自身ID> route get <精确本地目标ID> --json
1183
+ td collab --session <自身ID> message get <原消息ID> --receipt-only --json
1184
+ # 只有目标拥有者在自己的真实终端确认“当前承载就是目标”后执行:
1185
+ td collab --session <目标自身ID> rebind --pane <当前pane-ID> --json
1186
+ ```
1187
+
1188
+ `route get` 为只读 `GET /operations/orchestration/route/:id`,只允许自身或共享组的本地
1189
+ 成员;不解析前缀/名称,不替远端拥有者查询其当前进程。旧服务缺能力时 CLI 明确拒绝。
1190
+ 返回 `route.session_id/binding/worker/observed_at/state/error/identity`:worker 包括
1191
+ `started/tick_in_progress/recipient_in_progress/last_tick_at/route/pending_count`;identity
1192
+ 包括原 `expected`、当前 `observed`(最多 20 项、`truncated`)、`recovery/reason` 和
1193
+ 拥有者正式 `rebind_command`。只导出承载标识、Agent 类型及原生身份证据元数据,
1194
+ 没有终端正文、argv、环境或凭据。证据未知即未知,不使用旧缓存 UUID 替代当前身份。
1195
+ 只读查询不启动/恢复 Agent、改绑或补键,不把进程/身份正确称为输入已就绪。
1196
+
1197
+ 已绑定的 tmux server/session/pane/PID 变化时,原物理身份保护仍拒绝直接写入。
1198
+ 消息维持 `status=pending`,诊断会给 `delivery.stage=blocked`、`error=TMUX_PANE_CHANGED`、
1199
+ `route_state`、`requires_confirmation` 及 `route` 差异/建议;`attempt_count=0` 表示尚未
1200
+ 尝试写入,不等于失败后可重发。现有 `message.delivery` 主动事件携带该 receipt;
1201
+ 网页协作记录也展示绑定变化和投递暂停,保留原正文。跨服务交换在状态不变但错误变化
1202
+ 时仍同步错误,不因 pending 状态相同而隐去新的阻断。运行服务未采集过的历史差异
1203
+ 不能由新版本凭空补出;`worker.started` 等字段用于确认当前调度事实。
1204
+
1205
+ 本地/远端目标依据稳定 `remote:` 地址区分,组是否 federated 不影响组内本地消息进入
1206
+ 本地 worker。后台 worker 在会话登记加载完成后启动,不等待额外 PTY adoption 或
1207
+ tmux 元数据 backfill;订阅消息存储变化并保留定时重试。缺绑定/进程/权限时仍保留原
1208
+ 消息,诊断拒绝原因,不依赖网页维持投递。此加固不能替代旧现场的运行证据,也不能
1209
+ 从过去缺少 transport 条目推断唯一内部根因。
1210
+
1211
+ 承载变化后的**自动**更新仅用于普通 tmux 会话,并同时要求:原生 ID/Agent 类型已知,
1212
+ 当前可信 provider 独立核验同一原生 ID、同一 Agent,唯一匹配且原逻辑记录/后端/pane
1213
+ 归属无冲突,没有原待投递消息的未确认写入尝试。对账前再次核验当前候选和登记,
1214
+ 首次继续写入前再次核验当前原生身份。只改绑定,不启动/恢复/切换原生 Agent。
1215
+ 当前独立证据 provider 是已配置的 Linux flock-owner 核验;核心不按 Agent 名称或
1216
+ TUI 展示字符串分支。argv 的 resume ID 只能作为启动意图元数据,单独不满足自动更新。
1217
+ 因此没有可靠 provider 的 Mac 冷启动 Codex 等场景需要明确拥有者确认,不能宣称跨
1218
+ 平台自动身份恢复已通过。独立证据的能力/适用平台由 provider 决定。
1219
+
1220
+ 原生身份缺失/不同、多匹配、归属不明或此前写入结果不明时,保留原消息并显示
1221
+ `confirmation-required` 及对应原因(`NATIVE_IDENTITY_UNCONFIRMED`、
1222
+ `MULTIPLE_NATIVE_IDENTITY_MATCHES`、`ROUTE_OWNERSHIP_UNCONFIRMED`、
1223
+ `DELIVERY_OUTCOME_UNCONFIRMED`)。拥有者确认当前承载后可用现有 rebind 明确接受当前
1224
+ Agent/原生身份;这不是承诺精确恢复旧原生历史,也不要求猜 UUID 或编辑私有记录。
1225
+ 无运行 tmux 的情况须先通过原会话恢复入口恢复承载,不能靠 rebind 新建。
1226
+
1227
+ 重新绑定与投递按该逻辑成员的 worker 屏障串行,持久保存 `routeRevision` 和
1228
+ `lastRecovery={kind,at,previousPane}`,后者只记录最近一次自动/显式绑定恢复。
1229
+ 绑定以 routing 文件原子替换提交;失败不采用新绑定。输入队列同时核验 routeRevision,
1230
+ 旧队列不能在新绑定上继续粘贴/提交。待处理消息已经记录尝试(`attempt_count>0`)而结果
1231
+ 未确认时,显式 rebind 返回 `ROUTE_DELIVERY_OUTCOME_UNCONFIRMED`,先对账,不能借修复
1232
+ 重发正文。记录不承诺永久审计或跨掉电的恰好一次输入;原终端传输的写入语义/保留
1233
+ 边界不变。
1234
+
1235
+ `IntegrationSession` 不通过普通 rebind 绕过其代次/精确 UUID/配置与所有者保护,须继续
1236
+ 用受限 principal 的 `session get/restore`;普通 rebind 对此返回
1237
+ `INTEGRATION_SESSION_RESTORE_REQUIRED`。当前修复不改变业务任务、principal、组、
1238
+ message/thread/幂等键或历史,不自动补 Enter、不用屏幕文字识别消费;delivered 仍只
1239
+ 表示终端写入,完成须明确回复。
1240
+
1241
+ 回归覆盖同组本地消息处于 federated 组、存储变化唤醒/后台阻断、修复后原消息单次
1242
+ 投递、不同/缺失/弱原生证据、多匹配/归属/未知旧写入拒绝、绑定持久化和失败、
1243
+ 只读路由权限/CLI、网页暂停提示及加密传输边界。Mac 实际现场的当前原生身份尚未独立确认,原消息尚待拥有者确认及接入方实际服务
1244
+ 升级/回读后继续投递;不以维护机回归冒充该现场已恢复。
1245
+
1246
+
1247
+ ## 1.4.322:启动代次一致性与输入检查诊断
1248
+
1249
+ 最低实际服务 **1.4.322**,配套 CLI 也升级至 1.4.322。`capabilities` 回读:
1250
+ `agent_launch_generation_consistency=true`、
1251
+ `agent_launch_generation_consistency_min_version=1.4.322`、
1252
+ `terminal_input_check_diagnostics=true`。普通协作协议仍为 2,integration protocol 仍为 1;
1253
+ 不新增权限。只更新 CLI 不会改变正在运行的旧服务。
1254
+
1255
+ 启动代次是 TD 服务生成的 `agentLaunchGeneration`,与原生 Agent UUID、
1256
+ IntegrationSession 的数值 `generation` 分别记录。同一 backend 在启动准备时从 null
1257
+ 变为新的启动 UUID 是正常动作。名称、cwd、原生身份元数据等整记录更新过去可能
1258
+ 携带 await 之前的旧启动字段写回;本版将启动字段交由专门的比较后更新路径管理,
1259
+ 普通元数据更新继承当前启动代次与一次性检查,不能覆盖或复活旧值。
1260
+
1261
+ 启动操作在写入本次代次后、持久化之前捕获自己的输入检查令牌,并在持久化返回、
1262
+ 承载解析、获取输入队列及粘贴/提交前持续使用它。冷启动、精确恢复、显式 cold retry
1263
+ 和普通启动共用这条保护;不会为了继续输入而采纳后来出现的启动代次。启动状态
1264
+ 落盘失败时不输入。真实 backend 对象/ID、绑定版本、tmux pane 或启动代次变化仍拒绝,
1265
+ 保留 `TERMINAL_INPUT_TARGET_CHANGED` / `TMUX_PANE_CHANGED` 等错误。
1266
+
1267
+ 管理员沿现有入口读取已保存的诊断:
1268
+
1269
+ ```sh
1270
+ td integration diagnostics <TD-session-id>
1271
+ ```
1272
+
1273
+ `launch_diagnostics.steps` 追加可选阶段 `guard_captured / runtime_resolving / runtime_resolved`;
1274
+ 既有 `queue_wait / queue_acquired / paste_* / submit_*` 保留。拒绝时
1275
+ `target_change` 可含 `check_phase / guard_captured_at / checked_at`,以及
1276
+ `expected_launch_id / current_launch_id`、backend ID/实例比较、绑定版本比较。
1277
+ `check_phase` 包含 `launch_state_commit / guard_capture / launch_persisted / runtime_resolve /
1278
+ runtime_resolved / queue_acquired / before_paste / before_submit`。时间是 TD 检查时间,
1279
+ 不是内核首字节写入时间;不包含正文、argv、环境或凭据。旧记录不补造缺失的证据。
1280
+
1281
+ 这次修复不增加自动重试:原 create 同键只回读原操作。失败现场保留,先用
1282
+ `session get` 核对当前事实;明确授权后才按现有 `session retry-cold` 契约显式操作,
1283
+ 必须满足无原生 UUID、无 TD 消息历史或待投递、精确原 shell、配置指纹与代次等条件。
1284
+ 已有原生 UUID 的会话继续精确 restore,不能以 cold retry 替代。消息正文不因升级重发。
1285
+
1286
+ 升级由现场唯一维护者协调:保留现有 HTTPS/鉴权参数,仅替换并重启 TD 服务;
1287
+ 核对在跑 tmux/Agent 完整身份没有变化,再回读实际服务版本和以上能力。
1288
+ 本版不要求重启、重建或重试业务 Agent,不更改 launch profile、sandbox 或业务调度。
1289
+ 终端动作仍是粘贴一次、50ms 后发送一次回车;TD 仍不保证应用提交、消费或执行完成。
1290
+
1291
+ 确定性交错回归覆盖延迟改名/元数据回写、清除检查、持久化等待、输入队列等待、
1292
+ 真实第二次启动、backend 替换及重新绑定;发生真实换代时,旧输入及旧的延迟回车
1293
+ 仍被拒绝。测试证明 TD 一致性与终端写入边界,不代替私有 Agent 的实机消费验收。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termdock",
3
- "version": "1.4.320",
3
+ "version": "1.4.322",
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.320",
4
+ "version": "1.4.322",
5
5
  "runtimeProtocolVersion": 1,
6
6
  "minimumDesktopVersion": "1.4.46",
7
7
  "nodeMajor": 22,
8
8
  "dependencyHash": "sha256-oaGYi/P5ob8sd6VnNBOwshKozjhdV+hYiCmLAsn5x00=",
9
- "serverBundleHash": "sha256-gDDXXi77xb12IjXMDyoQfphY068s3YYypX7eonkYaBI=",
10
- "clientBundleHash": "sha256-/khgWBy20WS07NVRjRse/qqfC/0Z7Oq5E30fwmuL3Ww=",
9
+ "serverBundleHash": "sha256-T9JZp3X9tfMUYciSrnZbiUIXuc+IHqHJuGp6Wf5bHs8=",
10
+ "clientBundleHash": "sha256-4wVT4/UzD+TMRQjVw307g0c0x0cJm6NknoDeybiIQfA=",
11
11
  "entrypoint": "dist/server/cli.js",
12
12
  "clientEntrypoint": "dist/client/index.html"
13
13
  }
@@ -1,2 +0,0 @@
1
- import{by as r}from"./app-BRESmgxW.js";import{b as m}from"./dnd-BCFAPC0L.js";import{b as n}from"./RightSidebar-7C9-PfhA.js";import"./react-XDCjal2T.js";import"./terminal-C7X98Amf.js";import"./App-BF6YvbKL.js";import"./gestureArbiter-DalDKZKj.js";import"./triangle-alert-DG_BJhJY.js";import"./referenceLongPress-DfQ5jnsk.js";import"./DiffReview-CjEi6PCy.js";import"./sparkles-DbcgKKVd.js";import"./DiffViewer-Bh6lvUYN.js";import"./ChangeWalkthroughPanel-B59JwhzK.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};