termdock 1.4.322 → 1.4.325

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 (366) hide show
  1. package/dist/client/assets/App-D8MWr9xp.js +186 -0
  2. package/dist/client/assets/App-D8MWr9xp.js.br +0 -0
  3. package/dist/client/assets/App-D8MWr9xp.js.gz +0 -0
  4. package/dist/client/assets/{ArchitecturePanel-VDM6hrwp.js → ArchitecturePanel-CJXvqmtu.js} +2 -2
  5. package/dist/client/assets/ArchitecturePanel-CJXvqmtu.js.br +0 -0
  6. package/dist/client/assets/ArchitecturePanel-CJXvqmtu.js.gz +0 -0
  7. package/dist/client/assets/{ChangeWalkthroughPanel-B64j3i8o.js → ChangeWalkthroughPanel-ChPZVfRz.js} +1 -1
  8. package/dist/client/assets/ChangeWalkthroughPanel-ChPZVfRz.js.br +0 -0
  9. package/dist/client/assets/ChangeWalkthroughPanel-ChPZVfRz.js.gz +0 -0
  10. package/dist/client/assets/CollaborationMainWorkspace-DkNhqCj4.js +1 -0
  11. package/dist/client/assets/CollaborationMainWorkspace-DkNhqCj4.js.br +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-DkNhqCj4.js.gz +0 -0
  13. package/dist/client/assets/CollaborationTaskContent-BA3bVNJo.js +2 -0
  14. package/dist/client/assets/{ComputerControlView-Co-TTYas.js → ComputerControlView-BTntDI6C.js} +2 -2
  15. package/dist/client/assets/ComputerControlView-BTntDI6C.js.br +0 -0
  16. package/dist/client/assets/ComputerControlView-BTntDI6C.js.gz +0 -0
  17. package/dist/client/assets/{DagPlayground-kJczdJ6J.js → DagPlayground-BIL5vjer.js} +1 -1
  18. package/dist/client/assets/DagPlayground-BIL5vjer.js.br +0 -0
  19. package/dist/client/assets/DagPlayground-BIL5vjer.js.gz +0 -0
  20. package/dist/client/assets/{DiffLab-BaaioC-q.js → DiffLab-CX1AwU2v.js} +1 -1
  21. package/dist/client/assets/DiffLab-CX1AwU2v.js.br +0 -0
  22. package/dist/client/assets/DiffLab-CX1AwU2v.js.gz +0 -0
  23. package/dist/client/assets/{DiffReview-Wfck3RIS.js → DiffReview-CLc1hwO7.js} +1 -1
  24. package/dist/client/assets/DiffReview-CLc1hwO7.js.br +0 -0
  25. package/dist/client/assets/DiffReview-CLc1hwO7.js.gz +0 -0
  26. package/dist/client/assets/{DiffReviewLab-Dblr3wgw.js → DiffReviewLab-DE6m1o4p.js} +1 -1
  27. package/dist/client/assets/DiffReviewLab-DE6m1o4p.js.br +0 -0
  28. package/dist/client/assets/DiffReviewLab-DE6m1o4p.js.gz +0 -0
  29. package/dist/client/assets/{DiffViewer-C-utC5Ga.js → DiffViewer-BDwtwbQM.js} +1 -1
  30. package/dist/client/assets/DiffViewer-BDwtwbQM.js.br +0 -0
  31. package/dist/client/assets/DiffViewer-BDwtwbQM.js.gz +0 -0
  32. package/dist/client/assets/{ModelPreview-BBLnHWVQ.js → ModelPreview-DEwATnxi.js} +1 -1
  33. package/dist/client/assets/ModelPreview-DEwATnxi.js.br +0 -0
  34. package/dist/client/assets/ModelPreview-DEwATnxi.js.gz +0 -0
  35. package/dist/client/assets/{RightSidebar-CUHSFkmZ.js → RightSidebar-jOQJePDV.js} +36 -36
  36. package/dist/client/assets/RightSidebar-jOQJePDV.js.br +0 -0
  37. package/dist/client/assets/RightSidebar-jOQJePDV.js.gz +0 -0
  38. package/dist/client/assets/{abnfDiagram-VCTEODGH-DDd99QpA.js → abnfDiagram-VCTEODGH-GBSf8AEr.js} +1 -1
  39. package/dist/client/assets/abnfDiagram-VCTEODGH-GBSf8AEr.js.br +0 -0
  40. package/dist/client/assets/abnfDiagram-VCTEODGH-GBSf8AEr.js.gz +0 -0
  41. package/dist/client/assets/app-VCmiASzh.js +35 -0
  42. package/dist/client/assets/app-VCmiASzh.js.br +0 -0
  43. package/dist/client/assets/app-VCmiASzh.js.gz +0 -0
  44. package/dist/client/assets/{arc-C3dck_E0.js → arc-BecvFgjf.js} +1 -1
  45. package/dist/client/assets/arc-BecvFgjf.js.br +0 -0
  46. package/dist/client/assets/arc-BecvFgjf.js.gz +0 -0
  47. package/dist/client/assets/{architectureDiagram-5GKGNRK7-C3bCQc2w.js → architectureDiagram-5GKGNRK7-Cfk47zEF.js} +1 -1
  48. package/dist/client/assets/architectureDiagram-5GKGNRK7-Cfk47zEF.js.br +0 -0
  49. package/dist/client/assets/architectureDiagram-5GKGNRK7-Cfk47zEF.js.gz +0 -0
  50. package/dist/client/assets/{blockDiagram-I7D4REHJ-znMn6iCQ.js → blockDiagram-I7D4REHJ-BHYgsLvx.js} +1 -1
  51. package/dist/client/assets/blockDiagram-I7D4REHJ-BHYgsLvx.js.br +0 -0
  52. package/dist/client/assets/blockDiagram-I7D4REHJ-BHYgsLvx.js.gz +0 -0
  53. package/dist/client/assets/{c4Diagram-7LVT6UL2-C0sopIsj.js → c4Diagram-7LVT6UL2-ClWWjTyz.js} +1 -1
  54. package/dist/client/assets/c4Diagram-7LVT6UL2-ClWWjTyz.js.br +0 -0
  55. package/dist/client/assets/c4Diagram-7LVT6UL2-ClWWjTyz.js.gz +0 -0
  56. package/dist/client/assets/channel-8F8qxLSK.js +1 -0
  57. package/dist/client/assets/{chunk-2Q5K7J3B-f7USyccJ.js → chunk-2Q5K7J3B-Cat1Dsqx.js} +1 -1
  58. package/dist/client/assets/{chunk-5VM5RSS4-Ck2xirDs.js → chunk-5VM5RSS4-CT0S2-E8.js} +1 -1
  59. package/dist/client/assets/{chunk-F27PBJKO-DaDCIj30.js → chunk-F27PBJKO-7o5_yA1b.js} +1 -1
  60. package/dist/client/assets/chunk-F27PBJKO-7o5_yA1b.js.br +0 -0
  61. package/dist/client/assets/chunk-F27PBJKO-7o5_yA1b.js.gz +0 -0
  62. package/dist/client/assets/{chunk-IMKFNOWR-DEC_On5x.js → chunk-IMKFNOWR-iAZxGMup.js} +1 -1
  63. package/dist/client/assets/chunk-IMKFNOWR-iAZxGMup.js.br +0 -0
  64. package/dist/client/assets/chunk-IMKFNOWR-iAZxGMup.js.gz +0 -0
  65. package/dist/client/assets/{chunk-JWPE2WC7-BrswC3n2.js → chunk-JWPE2WC7-DLvwOWZm.js} +1 -1
  66. package/dist/client/assets/{chunk-POPQ4Y6H-ClMbDV47.js → chunk-POPQ4Y6H-BpiRuG56.js} +1 -1
  67. package/dist/client/assets/{chunk-SVP7TREG-D7_1VwC5.js → chunk-SVP7TREG-DpB7xpqI.js} +1 -1
  68. package/dist/client/assets/chunk-SVP7TREG-DpB7xpqI.js.br +0 -0
  69. package/dist/client/assets/chunk-SVP7TREG-DpB7xpqI.js.gz +0 -0
  70. package/dist/client/assets/{chunk-TICWLB2K-D5jzVTZ8.js → chunk-TICWLB2K-Z_Sti6yX.js} +1 -1
  71. package/dist/client/assets/chunk-TICWLB2K-Z_Sti6yX.js.br +0 -0
  72. package/dist/client/assets/chunk-TICWLB2K-Z_Sti6yX.js.gz +0 -0
  73. package/dist/client/assets/{chunk-XXDRQBXY-DOhaoLcX.js → chunk-XXDRQBXY-DKngx1rf.js} +1 -1
  74. package/dist/client/assets/classDiagram-ZZMXUADV-C0AmKz7U.js +1 -0
  75. package/dist/client/assets/classDiagram-v2-VYDZK3BY-C0AmKz7U.js +1 -0
  76. package/dist/client/assets/{cose-bilkent-JH36ORCC-DOsaKgiX.js → cose-bilkent-JH36ORCC-CDo8eUXo.js} +1 -1
  77. package/dist/client/assets/cose-bilkent-JH36ORCC-CDo8eUXo.js.br +0 -0
  78. package/dist/client/assets/cose-bilkent-JH36ORCC-CDo8eUXo.js.gz +0 -0
  79. package/dist/client/assets/{cynefin-OW5HDTMX-CMcLh_wh.js → cynefin-OW5HDTMX-R6vltrl4.js} +1 -1
  80. package/dist/client/assets/cynefin-OW5HDTMX-R6vltrl4.js.br +0 -0
  81. package/dist/client/assets/{cynefin-OW5HDTMX-CMcLh_wh.js.gz → cynefin-OW5HDTMX-R6vltrl4.js.gz} +0 -0
  82. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js → cynefinDiagram-5FMLGOSQ-BTGMG-zO.js} +1 -1
  83. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BTGMG-zO.js.br +0 -0
  84. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BTGMG-zO.js.gz +0 -0
  85. package/dist/client/assets/{dagre-GXQ25YYZ-BlW7fAi0.js → dagre-GXQ25YYZ-D67dNSHU.js} +1 -1
  86. package/dist/client/assets/dagre-GXQ25YYZ-D67dNSHU.js.br +0 -0
  87. package/dist/client/assets/dagre-GXQ25YYZ-D67dNSHU.js.gz +0 -0
  88. package/dist/client/assets/{diagram-S7CK7UJ4-B0-tKahG.js → diagram-S7CK7UJ4-CxZmcHs4.js} +1 -1
  89. package/dist/client/assets/diagram-S7CK7UJ4-CxZmcHs4.js.br +0 -0
  90. package/dist/client/assets/diagram-S7CK7UJ4-CxZmcHs4.js.gz +0 -0
  91. package/dist/client/assets/{diagram-UQ7AKVKN-BQumj4Dw.js → diagram-UQ7AKVKN-BErivsDz.js} +1 -1
  92. package/dist/client/assets/diagram-UQ7AKVKN-BErivsDz.js.br +0 -0
  93. package/dist/client/assets/diagram-UQ7AKVKN-BErivsDz.js.gz +0 -0
  94. package/dist/client/assets/{diagram-VSXAHHWV-Zx_FLmPP.js → diagram-VSXAHHWV-BQWEvK9d.js} +1 -1
  95. package/dist/client/assets/diagram-VSXAHHWV-BQWEvK9d.js.br +0 -0
  96. package/dist/client/assets/diagram-VSXAHHWV-BQWEvK9d.js.gz +0 -0
  97. package/dist/client/assets/{diagram-VX7I27RA-CEZvatNH.js → diagram-VX7I27RA-COR5k4JL.js} +1 -1
  98. package/dist/client/assets/diagram-VX7I27RA-COR5k4JL.js.br +0 -0
  99. package/dist/client/assets/diagram-VX7I27RA-COR5k4JL.js.gz +0 -0
  100. package/dist/client/assets/{diagram-Z3DM3KII-CJ9IEQ8j.js → diagram-Z3DM3KII-Cx6oTlVi.js} +1 -1
  101. package/dist/client/assets/diagram-Z3DM3KII-Cx6oTlVi.js.br +0 -0
  102. package/dist/client/assets/diagram-Z3DM3KII-Cx6oTlVi.js.gz +0 -0
  103. package/dist/client/assets/{ebnfDiagram-PWID7BFC-sQQMv3ea.js → ebnfDiagram-PWID7BFC-dKNZki9k.js} +1 -1
  104. package/dist/client/assets/ebnfDiagram-PWID7BFC-dKNZki9k.js.br +0 -0
  105. package/dist/client/assets/ebnfDiagram-PWID7BFC-dKNZki9k.js.gz +0 -0
  106. package/dist/client/assets/{erDiagram-RLTQ6QDP-D3rMpj7M.js → erDiagram-RLTQ6QDP-DD06d9Gl.js} +1 -1
  107. package/dist/client/assets/erDiagram-RLTQ6QDP-DD06d9Gl.js.br +0 -0
  108. package/dist/client/assets/erDiagram-RLTQ6QDP-DD06d9Gl.js.gz +0 -0
  109. package/dist/client/assets/{flowDiagram-HODETNUW-B6QZiE0-.js → flowDiagram-HODETNUW-DXNAvw1d.js} +1 -1
  110. package/dist/client/assets/flowDiagram-HODETNUW-DXNAvw1d.js.br +0 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-DXNAvw1d.js.gz +0 -0
  112. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-Bw9bltcu.js → ganttDiagram-EL5Y4UJY-BSMu3Rsd.js} +1 -1
  113. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BSMu3Rsd.js.br +0 -0
  114. package/dist/client/assets/ganttDiagram-EL5Y4UJY-BSMu3Rsd.js.gz +0 -0
  115. package/dist/client/assets/{gestureArbiter-Cczz34oI.js → gestureArbiter-D1TteC76.js} +1 -1
  116. package/dist/client/assets/gestureArbiter-D1TteC76.js.br +0 -0
  117. package/dist/client/assets/gestureArbiter-D1TteC76.js.gz +0 -0
  118. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-mdnkxjeD.js → gitGraphDiagram-WWUBYQGX-DNDKI803.js} +1 -1
  119. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DNDKI803.js.br +0 -0
  120. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-DNDKI803.js.gz +0 -0
  121. package/dist/client/assets/index-Ctz-IDjR.css +1 -0
  122. package/dist/client/assets/index-Ctz-IDjR.css.br +0 -0
  123. package/dist/client/assets/{index-B4bEMUyn.css.gz → index-Ctz-IDjR.css.gz} +0 -0
  124. package/dist/client/assets/{infoDiagram-27XIBGKW-DyrPP3Yf.js → infoDiagram-27XIBGKW-BRmB1D5B.js} +1 -1
  125. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-CEPH_ePM.js → ishikawaDiagram-5VMMS53U-DXU4nnZ6.js} +1 -1
  126. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DXU4nnZ6.js.br +0 -0
  127. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DXU4nnZ6.js.gz +0 -0
  128. package/dist/client/assets/{journeyDiagram-3NMN7TZE-CQ0PjBy7.js → journeyDiagram-3NMN7TZE-DFx7AfiP.js} +1 -1
  129. package/dist/client/assets/journeyDiagram-3NMN7TZE-DFx7AfiP.js.br +0 -0
  130. package/dist/client/assets/journeyDiagram-3NMN7TZE-DFx7AfiP.js.gz +0 -0
  131. package/dist/client/assets/{kanban-definition-UXKFOSKX-BpQUXA60.js → kanban-definition-UXKFOSKX-B1ikfXJe.js} +1 -1
  132. package/dist/client/assets/kanban-definition-UXKFOSKX-B1ikfXJe.js.br +0 -0
  133. package/dist/client/assets/kanban-definition-UXKFOSKX-B1ikfXJe.js.gz +0 -0
  134. package/dist/client/assets/{layout-BdptC7rq.js → layout-DkyvZr1Y.js} +1 -1
  135. package/dist/client/assets/layout-DkyvZr1Y.js.br +0 -0
  136. package/dist/client/assets/layout-DkyvZr1Y.js.gz +0 -0
  137. package/dist/client/assets/{linear-C2cSRCxu.js → linear-CECAbRuX.js} +1 -1
  138. package/dist/client/assets/linear-CECAbRuX.js.br +0 -0
  139. package/dist/client/assets/linear-CECAbRuX.js.gz +0 -0
  140. package/dist/client/assets/{mermaid.core-ClVMFyAU.js → mermaid.core-CYY7Wb75.js} +5 -5
  141. package/dist/client/assets/mermaid.core-CYY7Wb75.js.br +0 -0
  142. package/dist/client/assets/mermaid.core-CYY7Wb75.js.gz +0 -0
  143. package/dist/client/assets/{mindmap-definition-YA3MSWOX-D0AFCmsY.js → mindmap-definition-YA3MSWOX-CTs-Y3Lq.js} +1 -1
  144. package/dist/client/assets/mindmap-definition-YA3MSWOX-CTs-Y3Lq.js.br +0 -0
  145. package/dist/client/assets/mindmap-definition-YA3MSWOX-CTs-Y3Lq.js.gz +0 -0
  146. package/dist/client/assets/{passwordBootstrap-R2qlU2Pq.js → passwordBootstrap-CPNGDwv6.js} +1 -1
  147. package/dist/client/assets/passwordBootstrap-CPNGDwv6.js.br +0 -0
  148. package/dist/client/assets/passwordBootstrap-CPNGDwv6.js.gz +0 -0
  149. package/dist/client/assets/{pegDiagram-XKGWAZYB-BGAh0bwg.js → pegDiagram-XKGWAZYB-Y1oZrwtK.js} +1 -1
  150. package/dist/client/assets/pegDiagram-XKGWAZYB-Y1oZrwtK.js.br +0 -0
  151. package/dist/client/assets/pegDiagram-XKGWAZYB-Y1oZrwtK.js.gz +0 -0
  152. package/dist/client/assets/{pieDiagram-E7YTZNPT-CDOZUF44.js → pieDiagram-E7YTZNPT-DYSm5OxQ.js} +1 -1
  153. package/dist/client/assets/pieDiagram-E7YTZNPT-DYSm5OxQ.js.br +0 -0
  154. package/dist/client/assets/pieDiagram-E7YTZNPT-DYSm5OxQ.js.gz +0 -0
  155. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-D_Qn6NTU.js → quadrantDiagram-AXDQQJYC-DpibIBz0.js} +1 -1
  156. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DpibIBz0.js.br +0 -0
  157. package/dist/client/assets/quadrantDiagram-AXDQQJYC-DpibIBz0.js.gz +0 -0
  158. package/dist/client/assets/{railroadDiagram-O6MQD6OU-qUVGWhJN.js → railroadDiagram-O6MQD6OU-b7jp7C1K.js} +1 -1
  159. package/dist/client/assets/railroadDiagram-O6MQD6OU-b7jp7C1K.js.br +0 -0
  160. package/dist/client/assets/railroadDiagram-O6MQD6OU-b7jp7C1K.js.gz +0 -0
  161. package/dist/client/assets/{rdpSession-hgCM4i-j.js → rdpSession-DU_OJfX5.js} +1 -1
  162. package/dist/client/assets/rdpSession-DU_OJfX5.js.br +0 -0
  163. package/dist/client/assets/rdpSession-DU_OJfX5.js.gz +0 -0
  164. package/dist/client/assets/{referenceLongPress-BEMsP11a.js → referenceLongPress-BPQ_i68g.js} +1 -1
  165. package/dist/client/assets/referenceLongPress-BPQ_i68g.js.br +0 -0
  166. package/dist/client/assets/referenceLongPress-BPQ_i68g.js.gz +0 -0
  167. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BBQMQuVZ.js → requirementDiagram-BXWQKSXE-BMinO1mf.js} +1 -1
  168. package/dist/client/assets/requirementDiagram-BXWQKSXE-BMinO1mf.js.br +0 -0
  169. package/dist/client/assets/requirementDiagram-BXWQKSXE-BMinO1mf.js.gz +0 -0
  170. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-CeEExsqW.js → sankeyDiagram-P5KCCOFB-CmC977VA.js} +1 -1
  171. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CmC977VA.js.br +0 -0
  172. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CmC977VA.js.gz +0 -0
  173. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js → sequenceDiagram-WJ2MYXX4-D6eGbgK8.js} +1 -1
  174. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D6eGbgK8.js.br +0 -0
  175. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-D6eGbgK8.js.gz +0 -0
  176. package/dist/client/assets/{sizeCapture-INFHLROL-MBjz7Snm.js → sizeCapture-INFHLROL-CnRvyBd8.js} +1 -1
  177. package/dist/client/assets/sizeCapture-INFHLROL-CnRvyBd8.js.br +0 -0
  178. package/dist/client/assets/sizeCapture-INFHLROL-CnRvyBd8.js.gz +0 -0
  179. package/dist/client/assets/{sparkles-C9ShmGPf.js → sparkles-DzadqrlX.js} +1 -1
  180. package/dist/client/assets/{stateDiagram-D77RDMKH-DtLp89uP.js → stateDiagram-D77RDMKH-DRSalH10.js} +1 -1
  181. package/dist/client/assets/stateDiagram-D77RDMKH-DRSalH10.js.br +0 -0
  182. package/dist/client/assets/stateDiagram-D77RDMKH-DRSalH10.js.gz +0 -0
  183. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-DKe8v_ic.js +1 -0
  184. package/dist/client/assets/{swimlanes-42K2YHIH-Bc02S1q-.js → swimlanes-42K2YHIH-u-NnDSzq.js} +1 -1
  185. package/dist/client/assets/swimlanes-42K2YHIH-u-NnDSzq.js.br +0 -0
  186. package/dist/client/assets/swimlanes-42K2YHIH-u-NnDSzq.js.gz +0 -0
  187. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-ei5b8ZYx.js +8 -0
  188. package/dist/client/assets/{timeline-definition-24CTP7MA-BLLwbOm5.js → timeline-definition-24CTP7MA-DkLijg_J.js} +1 -1
  189. package/dist/client/assets/timeline-definition-24CTP7MA-DkLijg_J.js.br +0 -0
  190. package/dist/client/assets/timeline-definition-24CTP7MA-DkLijg_J.js.gz +0 -0
  191. package/dist/client/assets/{triangle-alert-i_L8ws6U.js → triangle-alert-D_6xTTiX.js} +1 -1
  192. package/dist/client/assets/{vennDiagram-4TSXK5OY-8FcrAdbk.js → vennDiagram-4TSXK5OY-AWGJtiv3.js} +1 -1
  193. package/dist/client/assets/{vennDiagram-4TSXK5OY-8FcrAdbk.js.br → vennDiagram-4TSXK5OY-AWGJtiv3.js.br} +0 -0
  194. package/dist/client/assets/vennDiagram-4TSXK5OY-AWGJtiv3.js.gz +0 -0
  195. package/dist/client/assets/{videoCompression-RIaDabW4.js → videoCompression-D3y7Bq8J.js} +1 -1
  196. package/dist/client/assets/videoCompression-D3y7Bq8J.js.br +0 -0
  197. package/dist/client/assets/videoCompression-D3y7Bq8J.js.gz +0 -0
  198. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-paL2wRrJ.js → wardleyDiagram-VM6X3IG4-DI0aZr_y.js} +1 -1
  199. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DI0aZr_y.js.br +0 -0
  200. package/dist/client/assets/wardleyDiagram-VM6X3IG4-DI0aZr_y.js.gz +0 -0
  201. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-BM5qJ4E7.js → xychartDiagram-S5SC5T6Z-CCoIN3uU.js} +1 -1
  202. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CCoIN3uU.js.br +0 -0
  203. package/dist/client/assets/xychartDiagram-S5SC5T6Z-CCoIN3uU.js.gz +0 -0
  204. package/dist/client/index.html +2 -2
  205. package/dist/client/index.html.br +0 -0
  206. package/dist/client/index.html.gz +0 -0
  207. package/dist/client/sw-encrypted-background.js +1 -1
  208. package/dist/client/sw-encrypted-background.js.br +0 -0
  209. package/dist/client/sw-encrypted-background.js.gz +0 -0
  210. package/dist/client/sw.js +1 -1
  211. package/dist/client/sw.js.br +0 -0
  212. package/dist/client/sw.js.gz +0 -0
  213. package/dist/server/agent/collaborationGroupRoutes.js +15 -0
  214. package/dist/server/agent/collaborationStore.js +63 -2
  215. package/dist/server/agent/collaborationTaskRoutes.js +5 -1
  216. package/dist/server/agent/integrationCli.js +38 -20
  217. package/dist/server/agent/integrationServer.js +145 -3
  218. package/dist/server/federation/packets.js +179 -28
  219. package/dist/server/federation/requestContext.js +6 -1
  220. package/dist/server/federation/runtime.js +19 -8
  221. package/dist/server/routes/terminal.js +285 -85
  222. package/dist/server/utils/autoUpdate.js +55 -8
  223. package/dist/server/utils/hostResources.js +128 -0
  224. package/dist/server/utils/npmUpdate.js +84 -8
  225. package/dist/server/utils/terminalPasteBuffer.js +66 -0
  226. package/dist/server/utils/tmuxClientCapabilities.js +4 -0
  227. package/dist/server/utils/tmuxCopySelection.js +94 -0
  228. package/dist/server/utils/tmuxEmptyServerProbe.js +15 -0
  229. package/dist/server/utils/tmuxRecoveryOperations.js +348 -0
  230. package/docs/integrations.md +36 -0
  231. package/package.json +5 -2
  232. package/runtime-manifest.json +3 -3
  233. package/.desktop-dist/main.js +0 -1989
  234. package/dist/client/assets/App-DEKo4SNL.js +0 -186
  235. package/dist/client/assets/App-DEKo4SNL.js.br +0 -0
  236. package/dist/client/assets/App-DEKo4SNL.js.gz +0 -0
  237. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.br +0 -0
  238. package/dist/client/assets/ArchitecturePanel-VDM6hrwp.js.gz +0 -0
  239. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.br +0 -0
  240. package/dist/client/assets/ChangeWalkthroughPanel-B64j3i8o.js.gz +0 -0
  241. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js +0 -1
  242. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.br +0 -0
  243. package/dist/client/assets/CollaborationMainWorkspace-DG8TQNqo.js.gz +0 -0
  244. package/dist/client/assets/CollaborationTaskContent-msQsgVaI.js +0 -2
  245. package/dist/client/assets/ComputerControlView-Co-TTYas.js.br +0 -0
  246. package/dist/client/assets/ComputerControlView-Co-TTYas.js.gz +0 -0
  247. package/dist/client/assets/DagPlayground-kJczdJ6J.js.br +0 -0
  248. package/dist/client/assets/DagPlayground-kJczdJ6J.js.gz +0 -0
  249. package/dist/client/assets/DiffLab-BaaioC-q.js.br +0 -0
  250. package/dist/client/assets/DiffLab-BaaioC-q.js.gz +0 -0
  251. package/dist/client/assets/DiffReview-Wfck3RIS.js.br +0 -0
  252. package/dist/client/assets/DiffReview-Wfck3RIS.js.gz +0 -0
  253. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.br +0 -0
  254. package/dist/client/assets/DiffReviewLab-Dblr3wgw.js.gz +0 -0
  255. package/dist/client/assets/DiffViewer-C-utC5Ga.js.br +0 -0
  256. package/dist/client/assets/DiffViewer-C-utC5Ga.js.gz +0 -0
  257. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.br +0 -0
  258. package/dist/client/assets/ModelPreview-BBLnHWVQ.js.gz +0 -0
  259. package/dist/client/assets/RightSidebar-CUHSFkmZ.js.br +0 -0
  260. package/dist/client/assets/RightSidebar-CUHSFkmZ.js.gz +0 -0
  261. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.br +0 -0
  262. package/dist/client/assets/abnfDiagram-VCTEODGH-DDd99QpA.js.gz +0 -0
  263. package/dist/client/assets/app-CfqF7_nh.js +0 -35
  264. package/dist/client/assets/app-CfqF7_nh.js.br +0 -0
  265. package/dist/client/assets/app-CfqF7_nh.js.gz +0 -0
  266. package/dist/client/assets/arc-C3dck_E0.js.br +0 -0
  267. package/dist/client/assets/arc-C3dck_E0.js.gz +0 -0
  268. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.br +0 -0
  269. package/dist/client/assets/architectureDiagram-5GKGNRK7-C3bCQc2w.js.gz +0 -0
  270. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.br +0 -0
  271. package/dist/client/assets/blockDiagram-I7D4REHJ-znMn6iCQ.js.gz +0 -0
  272. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.br +0 -0
  273. package/dist/client/assets/c4Diagram-7LVT6UL2-C0sopIsj.js.gz +0 -0
  274. package/dist/client/assets/channel-CMC8t83j.js +0 -1
  275. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.br +0 -0
  276. package/dist/client/assets/chunk-F27PBJKO-DaDCIj30.js.gz +0 -0
  277. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.br +0 -0
  278. package/dist/client/assets/chunk-IMKFNOWR-DEC_On5x.js.gz +0 -0
  279. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.br +0 -0
  280. package/dist/client/assets/chunk-SVP7TREG-D7_1VwC5.js.gz +0 -0
  281. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.br +0 -0
  282. package/dist/client/assets/chunk-TICWLB2K-D5jzVTZ8.js.gz +0 -0
  283. package/dist/client/assets/classDiagram-ZZMXUADV-ElMHzA-E.js +0 -1
  284. package/dist/client/assets/classDiagram-v2-VYDZK3BY-ElMHzA-E.js +0 -1
  285. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.br +0 -0
  286. package/dist/client/assets/cose-bilkent-JH36ORCC-DOsaKgiX.js.gz +0 -0
  287. package/dist/client/assets/cynefin-OW5HDTMX-CMcLh_wh.js.br +0 -0
  288. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.br +0 -0
  289. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-Dd8bfq9V.js.gz +0 -0
  290. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.br +0 -0
  291. package/dist/client/assets/dagre-GXQ25YYZ-BlW7fAi0.js.gz +0 -0
  292. package/dist/client/assets/diagram-S7CK7UJ4-B0-tKahG.js.br +0 -0
  293. package/dist/client/assets/diagram-S7CK7UJ4-B0-tKahG.js.gz +0 -0
  294. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.br +0 -0
  295. package/dist/client/assets/diagram-UQ7AKVKN-BQumj4Dw.js.gz +0 -0
  296. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.br +0 -0
  297. package/dist/client/assets/diagram-VSXAHHWV-Zx_FLmPP.js.gz +0 -0
  298. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.br +0 -0
  299. package/dist/client/assets/diagram-VX7I27RA-CEZvatNH.js.gz +0 -0
  300. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.br +0 -0
  301. package/dist/client/assets/diagram-Z3DM3KII-CJ9IEQ8j.js.gz +0 -0
  302. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.br +0 -0
  303. package/dist/client/assets/ebnfDiagram-PWID7BFC-sQQMv3ea.js.gz +0 -0
  304. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.br +0 -0
  305. package/dist/client/assets/erDiagram-RLTQ6QDP-D3rMpj7M.js.gz +0 -0
  306. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.br +0 -0
  307. package/dist/client/assets/flowDiagram-HODETNUW-B6QZiE0-.js.gz +0 -0
  308. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.br +0 -0
  309. package/dist/client/assets/ganttDiagram-EL5Y4UJY-Bw9bltcu.js.gz +0 -0
  310. package/dist/client/assets/gestureArbiter-Cczz34oI.js.br +0 -0
  311. package/dist/client/assets/gestureArbiter-Cczz34oI.js.gz +0 -0
  312. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.br +0 -0
  313. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-mdnkxjeD.js.gz +0 -0
  314. package/dist/client/assets/index-B4bEMUyn.css +0 -1
  315. package/dist/client/assets/index-B4bEMUyn.css.br +0 -0
  316. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.br +0 -0
  317. package/dist/client/assets/ishikawaDiagram-5VMMS53U-CEPH_ePM.js.gz +0 -0
  318. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.br +0 -0
  319. package/dist/client/assets/journeyDiagram-3NMN7TZE-CQ0PjBy7.js.gz +0 -0
  320. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.br +0 -0
  321. package/dist/client/assets/kanban-definition-UXKFOSKX-BpQUXA60.js.gz +0 -0
  322. package/dist/client/assets/layout-BdptC7rq.js.br +0 -0
  323. package/dist/client/assets/layout-BdptC7rq.js.gz +0 -0
  324. package/dist/client/assets/linear-C2cSRCxu.js.br +0 -0
  325. package/dist/client/assets/linear-C2cSRCxu.js.gz +0 -0
  326. package/dist/client/assets/mermaid.core-ClVMFyAU.js.br +0 -0
  327. package/dist/client/assets/mermaid.core-ClVMFyAU.js.gz +0 -0
  328. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.br +0 -0
  329. package/dist/client/assets/mindmap-definition-YA3MSWOX-D0AFCmsY.js.gz +0 -0
  330. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.br +0 -0
  331. package/dist/client/assets/passwordBootstrap-R2qlU2Pq.js.gz +0 -0
  332. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.br +0 -0
  333. package/dist/client/assets/pegDiagram-XKGWAZYB-BGAh0bwg.js.gz +0 -0
  334. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.br +0 -0
  335. package/dist/client/assets/pieDiagram-E7YTZNPT-CDOZUF44.js.gz +0 -0
  336. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.br +0 -0
  337. package/dist/client/assets/quadrantDiagram-AXDQQJYC-D_Qn6NTU.js.gz +0 -0
  338. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.br +0 -0
  339. package/dist/client/assets/railroadDiagram-O6MQD6OU-qUVGWhJN.js.gz +0 -0
  340. package/dist/client/assets/rdpSession-hgCM4i-j.js.br +0 -0
  341. package/dist/client/assets/rdpSession-hgCM4i-j.js.gz +0 -0
  342. package/dist/client/assets/referenceLongPress-BEMsP11a.js.br +0 -0
  343. package/dist/client/assets/referenceLongPress-BEMsP11a.js.gz +0 -0
  344. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.br +0 -0
  345. package/dist/client/assets/requirementDiagram-BXWQKSXE-BBQMQuVZ.js.gz +0 -0
  346. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CeEExsqW.js.br +0 -0
  347. package/dist/client/assets/sankeyDiagram-P5KCCOFB-CeEExsqW.js.gz +0 -0
  348. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.br +0 -0
  349. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-7ZPO-X0a.js.gz +0 -0
  350. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.br +0 -0
  351. package/dist/client/assets/sizeCapture-INFHLROL-MBjz7Snm.js.gz +0 -0
  352. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.br +0 -0
  353. package/dist/client/assets/stateDiagram-D77RDMKH-DtLp89uP.js.gz +0 -0
  354. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CIQb4Dp7.js +0 -1
  355. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.br +0 -0
  356. package/dist/client/assets/swimlanes-42K2YHIH-Bc02S1q-.js.gz +0 -0
  357. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-RiKL7eXI.js +0 -8
  358. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.br +0 -0
  359. package/dist/client/assets/timeline-definition-24CTP7MA-BLLwbOm5.js.gz +0 -0
  360. package/dist/client/assets/vennDiagram-4TSXK5OY-8FcrAdbk.js.gz +0 -0
  361. package/dist/client/assets/videoCompression-RIaDabW4.js.br +0 -0
  362. package/dist/client/assets/videoCompression-RIaDabW4.js.gz +0 -0
  363. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.br +0 -0
  364. package/dist/client/assets/wardleyDiagram-VM6X3IG4-paL2wRrJ.js.gz +0 -0
  365. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.br +0 -0
  366. package/dist/client/assets/xychartDiagram-S5SC5T6Z-BM5qJ4E7.js.gz +0 -0
package/dist/client/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let r={};const c=e=>n(e,o),d={module:{uri:o},exports:r,require:c};s[o]=Promise.all(i.map(e=>d[e]||c(e))).then(e=>(a(...e),r))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"033016787a43249e62a30135b9e6aa98"},{url:"assets/app-CfqF7_nh.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/index-B4bEMUyn.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
1
+ if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,a)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let c={};const r=e=>n(e,o),d={module:{uri:o},exports:c,require:r};s[o]=Promise.all(i.map(e=>d[e]||r(e))).then(e=>(a(...e),c))}}define(["./workbox-9845bf53"],function(e){"use strict";importScripts("sw-encrypted-background.js","sw-notifications.js","sw-secure-api.js","sw-downloads.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"index.html",revision:"140615ef2cf415473ada0b3ab2bce1ae"},{url:"assets/app-VCmiASzh.js",revision:null},{url:"assets/react-XDCjal2T.js",revision:null},{url:"assets/dnd-BCFAPC0L.js",revision:null},{url:"assets/terminal-C7X98Amf.js",revision:null},{url:"assets/index-Ctz-IDjR.css",revision:null},{url:"icons/agents/opencode.svg",revision:"851c2931d95821ba2b39b68587b48976"},{url:"icons/agents/kimi.svg",revision:"5366c710f4f763022fe159a69cf17409"},{url:"icons/agents/grok.svg",revision:"cd745b0b964545bc7a6b4f36021c3298"},{url:"icons/agents/goose.svg",revision:"c79b927278983c19098d77b4b0c11ab3"},{url:"icons/agents/gemini.svg",revision:"7a64f6d6f80a908255e9c0256903882e"},{url:"icons/agents/droid.svg",revision:"f28723b8c5c115e0908ba3c72613e256"},{url:"icons/agents/cursor.svg",revision:"a1528f3d3cda497f75a5db28defb19de"},{url:"icons/agents/copilot.svg",revision:"dd52e96c1eac0b6ec4bedcd0ddd3b52d"},{url:"icons/agents/codex.svg",revision:"608e55babb0b217e1f2da287342b46d3"},{url:"icons/agents/claude.svg",revision:"08af0225b7acdd8e8f573f3247e5e1c3"},{url:"icons/agents/amp.svg",revision:"af12f8b33faa81e4d46ea7b93c7e43f3"},{url:"apple-touch-icon-180x180.png",revision:"628c2e2f28a9b545aa57be1352025643"},{url:"boot-logo.png",revision:"2e3a25efd9b0b8ca1eab53b5f2284556"},{url:"favicon.ico",revision:"2994debfa6f59a0898e24eb0c54d64b5"},{url:"ipad-status-bar.js",revision:"3a8080edb8a5cc658a7908f6ad69537f"},{url:"maskable-icon-512x512.png",revision:"4d489331fd81f0713c400b26426442b9"},{url:"pwa-192x192.png",revision:"4d6f899888cfb8ccd7a1fd3c9e583ad2"},{url:"pwa-512x512.png",revision:"0885dd7ec8932e7f878b013d51a380a4"},{url:"robots.txt",revision:"d9339907142917dee4aac78494ac9cfe"},{url:"sw-downloads.js",revision:"48dab2e78bd93b4eee27fca487eccfde"},{url:"sw-notifications.js",revision:"fde578590ea8b0540d488ef448b48f45"},{url:"sw-secure-api.js",revision:"cf2bdbd03d41d66d60344c0b5a1075de"},{url:"manifest.webmanifest",revision:"83f9a43b74c236012adafb077fb6d774"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//,/^\/__termdock-download\//,/^\/health$/]})),e.registerRoute(/\/assets\/.*\.(?:js|css)$/,new e.CacheFirst({cacheName:"termdock-lazy-assets-v1",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:96,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/terminal\/[^/]+-[a-f0-9]{12}\.woff2$/,new e.CacheFirst({cacheName:"termdock-fonts-v2",plugins:[new e.CacheableResponsePlugin({statuses:[0,200]}),new e.ExpirationPlugin({maxEntries:384,maxAgeSeconds:2592e3})]}),"GET"),e.registerRoute(/\/fonts\/.*\.(?:woff2|ttf)$/,new e.StaleWhileRevalidate({cacheName:"termdock-fonts-v1",plugins:[new e.ExpirationPlugin({maxEntries:24,maxAgeSeconds:2592e3})]}),"GET")});
Binary file
Binary file
@@ -9,6 +9,21 @@ export function collaborationGroupRoutes(options) {
9
9
  res.json({ federationVersion: 1, capabilities: { groupRevision: 1, groupPromotion: 1, groupMove: 1, serverCollaboration: options.save ? 1 : undefined },
10
10
  groups: options.store.list(), sessions: options.sessions() });
11
11
  });
12
+ for (const [verb, archived] of [['archive', true], ['unarchive', false]]) {
13
+ router.post(`/collaboration-groups/:groupId/${verb}`, (req, res) => {
14
+ try {
15
+ const body = req.body ?? {};
16
+ if (Object.keys(body).some(key => !['expectedUpdatedAt', 'idempotencyKey'].includes(key)))
17
+ throw new CollaborationError('INVALID_GROUP_ARCHIVE_REQUEST', 'Only expectedUpdatedAt and idempotencyKey are accepted', 400);
18
+ const result = options.store.setLocalGroupArchived(req.params.groupId, archived, body.expectedUpdatedAt, body.idempotencyKey);
19
+ res.json(result);
20
+ }
21
+ catch (error) {
22
+ res.status(error instanceof CollaborationError ? error.httpStatus : 500).json({ code: error instanceof CollaborationError ? error.code : 'GROUP_ARCHIVE_FAILED',
23
+ ...(error instanceof CollaborationError && error.details ? error.details : {}), error: error instanceof Error ? error.message : 'Group archive operation failed' });
24
+ }
25
+ });
26
+ }
12
27
  router.post('/collaboration-groups', async (req, res) => {
13
28
  try {
14
29
  const body = req.body ?? {};
@@ -82,6 +82,7 @@ export class CollaborationStore {
82
82
  historyAvailable = true;
83
83
  groupCreationAvailable = true;
84
84
  groupRenamesAvailable = true;
85
+ groupArchivesAvailable = true;
85
86
  /** `drawId` is the random source behind newCollaborationId. It is a
86
87
  * constructor seam so tests can force a collision and prove the guard
87
88
  * below actually skips it; production always uses the CSPRNG default. */
@@ -126,6 +127,16 @@ export class CollaborationStore {
126
127
  && typeof value.applied.name === 'string' && !!value.applied.name.trim() && value.applied.name.length <= 256
127
128
  && !COLLAB_NAME_FORBIDDEN.test(value.applied.name) && Number.isSafeInteger(value.applied.updatedAt) && value.applied.updatedAt >= 0));
128
129
  this.document.localGroupRenames = this.groupRenamesAvailable ? renames ?? {} : {};
130
+ const archives = parsed.localGroupArchives;
131
+ this.groupArchivesAvailable = [1, 2].includes(parsed.version ?? 0) && Array.isArray(parsed.groups)
132
+ && (parsed.localGroupArchivesComplete === undefined || parsed.localGroupArchivesComplete === true)
133
+ && (archives === undefined || archives !== null && typeof archives === 'object' && !Array.isArray(archives)
134
+ && Object.entries(archives).every(([key, value]) => /^[a-f0-9]{64}$/.test(key) && value && typeof value.hash === 'string' && /^[a-f0-9]{64}$/.test(value.hash)
135
+ && value.applied && typeof value.applied.id === 'string' && /^[a-zA-Z0-9._-]{1,80}$/.test(value.applied.id)
136
+ && typeof value.applied.name === 'string' && !!value.applied.name.trim() && value.applied.name.length <= 256
137
+ && !COLLAB_NAME_FORBIDDEN.test(value.applied.name) && Number.isSafeInteger(value.applied.updatedAt) && value.applied.updatedAt >= 0
138
+ && (value.applied.archivedAt === undefined || Number.isSafeInteger(value.applied.archivedAt) && value.applied.archivedAt >= 0)));
139
+ this.document.localGroupArchives = this.groupArchivesAvailable ? archives ?? {} : {};
129
140
  this.document.sequence = Math.max(parsed.sequence ?? 0, this.document.sequence ?? 0);
130
141
  this.document.idempotency = parsed.idempotency ?? {};
131
142
  this.document.consumers = parsed.consumers ?? {};
@@ -138,10 +149,12 @@ export class CollaborationStore {
138
149
  this.historyAvailable = error.code === 'ENOENT';
139
150
  this.groupCreationAvailable = this.historyAvailable;
140
151
  this.groupRenamesAvailable = this.historyAvailable;
152
+ this.groupArchivesAvailable = this.historyAvailable;
141
153
  }
142
154
  this.document.terminalHistoryComplete = this.historyAvailable;
143
155
  this.document.localGroupRequestsComplete = this.groupCreationAvailable;
144
156
  this.document.localGroupRenamesComplete = this.groupRenamesAvailable;
157
+ this.document.localGroupArchivesComplete = this.groupArchivesAvailable;
145
158
  this.persistedDocument = JSON.stringify(this.document);
146
159
  }
147
160
  list() {
@@ -248,7 +261,54 @@ export class CollaborationStore {
248
261
  throw new CollaborationError('GROUP_NOT_LOCAL', 'Administrator metadata operations require a local group', 409);
249
262
  if (!Number.isSafeInteger(group.updatedAt) || group.updatedAt < 0)
250
263
  throw new CollaborationError('GROUP_STATE_UNCONFIRMED', 'Group revision is unavailable', 409);
251
- return { id: group.id, name: group.name, updatedAt: group.updatedAt };
264
+ return { id: group.id, name: group.name, updatedAt: group.updatedAt, ...(group.archivedAt !== undefined ? { archivedAt: group.archivedAt } : {}) };
265
+ }
266
+ listLocalGroupMetadata(includeArchived = false) {
267
+ return this.list().filter(group => !group.federated && (includeArchived || group.archivedAt === undefined))
268
+ .map(group => ({ id: group.id, name: group.name, updatedAt: group.updatedAt,
269
+ ...(group.archivedAt !== undefined ? { archivedAt: group.archivedAt } : {}) }));
270
+ }
271
+ /** Archive is a reversible discovery flag; it never changes membership or message routing. */
272
+ setLocalGroupArchived(id, archived, expectedUpdatedAt, key) {
273
+ if (typeof id !== 'string' || !/^[a-zA-Z0-9._-]{1,80}$/.test(id))
274
+ throw new CollaborationError('INVALID_GROUP_ID', 'An exact group ID is required', 400);
275
+ if (typeof archived !== 'boolean')
276
+ throw new CollaborationError('INVALID_GROUP_ARCHIVE_REQUEST', 'Archive state must be explicit', 400);
277
+ if (!Number.isSafeInteger(expectedUpdatedAt) || expectedUpdatedAt < 0)
278
+ throw new CollaborationError('INVALID_GROUP_VERSION', 'expected_updated_at must be a non-negative safe integer', 400);
279
+ const requestKey = localGroupRequestKey(key);
280
+ if (!this.groupArchivesAvailable)
281
+ throw new CollaborationError('GROUP_ARCHIVE_STATE_UNCONFIRMED', 'Archive journal is unavailable; reconcile persisted state before changing group visibility', 409);
282
+ const hash = crypto.createHash('sha256').update(JSON.stringify(['archive-local-group', id, archived, expectedUpdatedAt])).digest('hex');
283
+ const previous = this.document.localGroupArchives?.[requestKey];
284
+ if (previous) {
285
+ if (previous.hash !== hash)
286
+ throw new CollaborationError('IDEMPOTENCY_CONFLICT', 'This administrator archive key was used with different parameters', 409);
287
+ const target = this.getGroup(id);
288
+ if (!target || target.deleted || target.federated)
289
+ throw new CollaborationError('GROUP_ARCHIVE_TARGET_UNAVAILABLE', 'Original local archive target is unavailable; no replacement is created', 409);
290
+ const group = this.getLocalGroupMetadata(id);
291
+ this.persist(true);
292
+ return { group, applied: { ...previous.applied }, replayed: true };
293
+ }
294
+ const current = this.getLocalGroupMetadata(id);
295
+ if (current.updatedAt !== expectedUpdatedAt)
296
+ throw new CollaborationError('GROUP_CHANGED', 'Group changed; read its current revision before deciding again', 409, { currentUpdatedAt: current.updatedAt });
297
+ if (Object.keys(this.document.localGroupArchives ?? {}).length >= 2000)
298
+ throw new CollaborationError('GROUP_ARCHIVE_LIMIT', 'Administrator archive journal has reached its 2000-record limit', 409);
299
+ const target = this.getGroup(id);
300
+ const currentlyArchived = target.archivedAt !== undefined;
301
+ const changed = currentlyArchived !== archived;
302
+ const updatedAt = changed ? Math.max(Date.now(), current.updatedAt + 1) : current.updatedAt;
303
+ if (!Number.isSafeInteger(updatedAt))
304
+ throw new CollaborationError('GROUP_STATE_UNCONFIRMED', 'Group revision cannot advance safely', 409);
305
+ const archivedAt = archived ? currentlyArchived ? target.archivedAt : Date.now() : undefined;
306
+ const applied = { id, name: target.name, updatedAt, ...(archivedAt !== undefined ? { archivedAt } : {}) };
307
+ this.document = { ...this.document, groups: this.document.groups.map(group => group.id === id
308
+ ? { ...group, updatedAt, ...(archivedAt !== undefined ? { archivedAt } : { archivedAt: undefined }) } : group),
309
+ localGroupArchives: { ...this.document.localGroupArchives, [requestKey]: { hash, applied } } };
310
+ this.persist(true);
311
+ return { group: { ...applied }, applied: { ...applied }, replayed: false };
252
312
  }
253
313
  /** Display metadata and its original receipt share a durable commit. */
254
314
  renameLocalGroup(id, value, expectedUpdatedAt, key) {
@@ -282,7 +342,8 @@ export class CollaborationStore {
282
342
  const updatedAt = name === current.name ? current.updatedAt : Math.max(Date.now(), current.updatedAt + 1);
283
343
  if (!Number.isSafeInteger(updatedAt))
284
344
  throw new CollaborationError('GROUP_STATE_UNCONFIRMED', 'Group revision cannot advance safely', 409);
285
- const applied = { id, name, updatedAt };
345
+ const target = this.getGroup(id);
346
+ const applied = { id, name, updatedAt, ...(target.archivedAt !== undefined ? { archivedAt: target.archivedAt } : {}) };
286
347
  this.document = { ...this.document, groups: this.document.groups.map(group => group.id === id ? { ...group, name, updatedAt } : group),
287
348
  localGroupRenames: { ...this.document.localGroupRenames, [requestKey]: { hash, applied } } };
288
349
  this.persist(true);
@@ -1,6 +1,7 @@
1
1
  import { Router } from 'express';
2
2
  import { CollaborationError } from './collaborationProtocol.js';
3
3
  import { assertPeerRegistrationAuthority } from './collaborationPeerTransport.js';
4
+ import { hasEncryptedServiceAccess } from '../federation/requestContext.js';
4
5
  export function collaborationTaskRoutes(options) {
5
6
  const router = Router();
6
7
  const groupId = (value) => {
@@ -15,8 +16,11 @@ export function collaborationTaskRoutes(options) {
15
16
  if (!tasks || !peers)
16
17
  throw new CollaborationError('TASK_SERVICE_STARTING', '任务服务正在启动,请稍后重试', 503);
17
18
  if (!options.agent) {
19
+ // Reading the inbox does not register peers or create durable authority.
20
+ // Open-mode full-service viewers may read; mutations still require admin.
18
21
  try {
19
- assertPeerRegistrationAuthority(req);
22
+ if (!(['GET', 'HEAD'].includes(req.method) && hasEncryptedServiceAccess(req)))
23
+ assertPeerRegistrationAuthority(req);
20
24
  }
21
25
  catch {
22
26
  throw new CollaborationError('TASK_PERMISSION_DENIED', '当前连接无权处理协作任务', 403);
@@ -26,6 +26,14 @@ export const INTEGRATION_HELP = `td integration — local scoped integration adm
26
26
  GROUP_CHANGED, GROUP_NOT_FOUND, GROUP_NOT_LOCAL, GROUP_STATE_UNCONFIRMED,
27
27
  GROUP_RENAME_TARGET_UNAVAILABLE, GROUP_RENAME_STATE_UNCONFIRMED,
28
28
  GROUP_RENAME_LIMIT, ADMIN_LOCAL_GROUP_RENAME_UNSUPPORTED.
29
+ group archive|unarchive <exact-group-id> --expected-updated-at <N> --idempotency-key <key>
30
+ Administrator only; minimum CLI/running service 1.4.323; admin_local_group_archive=true.
31
+ Reversible discovery metadata only. Default groups list hides archived groups;
32
+ groups --include-archived lists them. group get always includes archivedAt when set.
33
+ Membership, principals, sessions, runtime, messages and history are unchanged.
34
+ Retry uncertain results with the same operation, revision and key; GROUP_CHANGED
35
+ requires rereading current metadata and choosing a new key. Archive receipts are
36
+ retained separately from the immutable group-create snapshot.
29
37
  group create --name <name> --idempotency-key <key>
30
38
  Administrator only; create an empty local group without a terminal source.
31
39
  Minimum CLI/running service 1.4.318; admin_local_group_create=true.
@@ -125,29 +133,33 @@ export async function runIntegrationAdmin(argv, port, adminToken, write) {
125
133
  return 0;
126
134
  }
127
135
  const socketPath = integrationSocketPath(port);
128
- if (action === 'group' && ['get', 'rename'].includes(argv[1])) {
136
+ if (action === 'group' && ['get', 'rename', 'archive', 'unarchive'].includes(argv[1])) {
129
137
  const operation = argv[1], id = argv[2], args = {};
130
- const usage = 'Usage: td integration group get <exact-id> | group rename <exact-id> --name <name> --expected-updated-at <N> --idempotency-key <key>';
138
+ const usage = 'Usage: td integration group get <exact-id> | group rename <exact-id> --name <name> --expected-updated-at <N> --idempotency-key <key> | group archive|unarchive <exact-id> --expected-updated-at <N> --idempotency-key <key>';
131
139
  if (!id || !/^[a-zA-Z0-9._-]{1,80}$/.test(id))
132
140
  throw new CollaborationError('INVALID_GROUP_ID', usage, 400);
133
141
  if (operation === 'get' && argv.length !== 3)
134
142
  throw new CollaborationError('INVALID_GROUP_RENAME_REQUEST', usage, 400);
135
- if (operation === 'rename') {
143
+ if (operation !== 'get') {
136
144
  for (let i = 3; i < argv.length; i += 2) {
137
- if (!['--name', '--expected-updated-at', '--idempotency-key'].includes(argv[i]) || !argv[i + 1] || Object.hasOwn(args, argv[i]))
138
- throw new CollaborationError('INVALID_GROUP_RENAME_REQUEST', usage, 400);
145
+ const allowed = operation === 'rename' ? ['--name', '--expected-updated-at', '--idempotency-key'] : ['--expected-updated-at', '--idempotency-key'];
146
+ if (!allowed.includes(argv[i]) || !argv[i + 1] || Object.hasOwn(args, argv[i]))
147
+ throw new CollaborationError(operation === 'rename' ? 'INVALID_GROUP_RENAME_REQUEST' : 'INVALID_GROUP_ARCHIVE_REQUEST', usage, 400);
139
148
  args[argv[i]] = argv[i + 1];
140
149
  }
141
- if (Object.keys(args).length !== 3 || !args['--name']?.trim() || !args['--idempotency-key']?.trim())
142
- throw new CollaborationError('INVALID_GROUP_RENAME_REQUEST', usage, 400);
150
+ if (operation === 'rename' ? Object.keys(args).length !== 3 || !args['--name']?.trim() || !args['--idempotency-key']?.trim()
151
+ : Object.keys(args).length !== 2 || !args['--idempotency-key']?.trim())
152
+ throw new CollaborationError(operation === 'rename' ? 'INVALID_GROUP_RENAME_REQUEST' : 'INVALID_GROUP_ARCHIVE_REQUEST', usage, 400);
143
153
  if (!/^(0|[1-9][0-9]*)$/.test(args['--expected-updated-at']) || !Number.isSafeInteger(Number(args['--expected-updated-at'])))
144
154
  throw new CollaborationError('INVALID_GROUP_VERSION', usage, 400);
145
155
  }
146
156
  const capabilities = parsed(await request(socketPath, 'GET', '/admin/capabilities', undefined, headers(undefined, adminToken)));
147
- if (capabilities.admin_local_group_rename !== true)
148
- throw new CollaborationError('ADMIN_LOCAL_GROUP_RENAME_UNSUPPORTED', 'CLI and running service must support administrator group metadata operations (minimum 1.4.319)', 409);
149
- const body = operation === 'rename' ? { name: args['--name'], expected_updated_at: Number(args['--expected-updated-at']), idempotency_key: args['--idempotency-key'] } : undefined;
150
- write(JSON.stringify(parsed(await request(socketPath, body ? 'POST' : 'GET', `/admin/groups/${encodeURIComponent(id)}${body ? '/rename' : ''}`, body, headers(undefined, adminToken)))));
157
+ const isArchive = operation === 'archive' || operation === 'unarchive';
158
+ if (capabilities[isArchive ? 'admin_local_group_archive' : 'admin_local_group_rename'] !== true)
159
+ throw new CollaborationError(isArchive ? 'ADMIN_LOCAL_GROUP_ARCHIVE_UNSUPPORTED' : 'ADMIN_LOCAL_GROUP_RENAME_UNSUPPORTED', `CLI and running service must support this operation (minimum 1.4.${isArchive ? '323' : '319'})`, 409);
160
+ const body = operation === 'get' ? undefined : { ...(operation === 'rename' ? { name: args['--name'] } : {}), expected_updated_at: Number(args['--expected-updated-at']), idempotency_key: args['--idempotency-key'] };
161
+ const suffix = operation === 'get' ? '' : `/${operation}`;
162
+ write(JSON.stringify(parsed(await request(socketPath, body ? 'POST' : 'GET', `/admin/groups/${encodeURIComponent(id)}${suffix}`, body, headers(undefined, adminToken)))));
151
163
  return 0;
152
164
  }
153
165
  if (action === 'group') {
@@ -213,16 +225,22 @@ export async function runIntegrationAdmin(argv, port, adminToken, write) {
213
225
  write(JSON.stringify(parsed(await request(socketPath, 'GET', `/admin/sessions/${encodeURIComponent(argv[1])}/restore-diagnostics`, undefined, headers(undefined, adminToken)))));
214
226
  return 0;
215
227
  }
216
- for (let index = 1; index < argv.length; index += 2) {
217
- const flag = argv[index];
218
- if (!['--file', '--credential-file'].includes(flag) || !argv[index + 1] || options[flag])
219
- throw new Error('Invalid integration arguments');
220
- options[flag] = argv[index + 1];
221
- }
228
+ if (action !== 'groups' && action !== 'list')
229
+ for (let index = 1; index < argv.length; index += 2) {
230
+ const flag = argv[index];
231
+ if (!['--file', '--credential-file'].includes(flag) || !argv[index + 1] || options[flag])
232
+ throw new Error('Invalid integration arguments');
233
+ options[flag] = argv[index + 1];
234
+ }
222
235
  if (action === 'groups' || action === 'list') {
223
- if (argv.length !== 1)
224
- throw new Error('Unexpected arguments');
225
- write(JSON.stringify(parsed(await request(socketPath, 'GET', action === 'groups' ? '/admin/groups' : '/admin/principals', undefined, headers(undefined, adminToken)))));
236
+ if (action === 'list' && argv.length !== 1 || action === 'groups' && argv.length > 2 || action === 'groups' && argv.length === 2 && argv[1] !== '--include-archived')
237
+ throw new Error('Usage: td integration groups [--include-archived] | list');
238
+ if (action === 'groups' && argv[1] === '--include-archived') {
239
+ const capabilities = parsed(await request(socketPath, 'GET', '/admin/capabilities', undefined, headers(undefined, adminToken)));
240
+ if (capabilities.admin_local_group_archive !== true)
241
+ throw new CollaborationError('ADMIN_LOCAL_GROUP_ARCHIVE_UNSUPPORTED', 'CLI and running service must support archived group discovery (minimum 1.4.323)', 409);
242
+ }
243
+ write(JSON.stringify(parsed(await request(socketPath, 'GET', action === 'groups' ? `/admin/groups${argv[1] ? '?include_archived=true' : ''}` : '/admin/principals', undefined, headers(undefined, adminToken)))));
226
244
  return 0;
227
245
  }
228
246
  if (action === 'update') {
@@ -3,10 +3,10 @@ import { createServer } from 'node:http';
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import { homedir } from 'node:os';
6
- import { timingSafeEqual } from 'node:crypto';
6
+ import { createHash, randomUUID, timingSafeEqual } from 'node:crypto';
7
7
  import { CollaborationError, resolveIdPrefix } from './collaborationProtocol.js';
8
8
  import { terminalMessage } from './collaborationStore.js';
9
- import { IntegrationStore, INTEGRATION_PROTOCOL, INTEGRATION_OPERATIONS, integrationError } from './integrationStore.js';
9
+ import { IntegrationStore, INTEGRATION_PROTOCOL, INTEGRATION_OPERATIONS, atomicJson, integrationError } from './integrationStore.js';
10
10
  import { IntegrationSessions, publicIntegrationSession } from './integrationSessions.js';
11
11
  import { getTermdockVersion } from '../utils/version.js';
12
12
  export function integrationSocketPath(port) { return path.join(homedir(), '.termdock', `integration-${port}.sock`); }
@@ -30,10 +30,32 @@ export class IntegrationRuntime {
30
30
  sent = new Map();
31
31
  syncing = false;
32
32
  retry;
33
+ releaseBatchFile;
34
+ releaseBatchOperations = [];
35
+ releaseBatchRunning = false;
33
36
  constructor(options) {
34
37
  this.options = options;
35
38
  this.store = new IntegrationStore(path.join(options.directory, 'integrations.json'));
36
39
  this.sessions = new IntegrationSessions(path.join(options.directory, 'integration-sessions.json'), options.sessions);
40
+ this.releaseBatchFile = path.join(options.directory, 'session-release-batches.json');
41
+ try {
42
+ const saved = JSON.parse(fs.readFileSync(this.releaseBatchFile, 'utf8'));
43
+ if (!Array.isArray(saved))
44
+ throw new Error('Invalid batch release journal');
45
+ this.releaseBatchOperations = saved;
46
+ for (const operation of this.releaseBatchOperations) {
47
+ if (operation.state === 'running')
48
+ operation.state = 'queued';
49
+ for (const item of operation.items)
50
+ if (item.state === 'running')
51
+ item.state = 'queued';
52
+ }
53
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
54
+ }
55
+ catch (error) {
56
+ if (error.code !== 'ENOENT')
57
+ throw error;
58
+ }
37
59
  this.stops.push(options.messages.registerRuntimeGuard(id => this.sessions.assertRuntimeMessage(id)));
38
60
  const changed = () => { try {
39
61
  this.sync();
@@ -68,7 +90,7 @@ export class IntegrationRuntime {
68
90
  if (!expected.length || given.length !== expected.length || !timingSafeEqual(given, expected))
69
91
  integrationError('INTEGRATION_ADMIN_REQUIRED', 'Local administration credential is required', 401);
70
92
  };
71
- app.get('/admin/groups', run(req => { admin(req); return { groups: options.messages.list().filter(g => !g.federated).map(g => ({ id: g.id, name: g.name, updatedAt: g.updatedAt })) }; }));
93
+ app.get('/admin/groups', run(req => { admin(req); return { groups: options.messages.listLocalGroupMetadata(req.query.include_archived === 'true') }; }));
72
94
  app.get('/admin/groups/:id', run(req => { admin(req); return { group: options.messages.getLocalGroupMetadata(req.params.id) }; }));
73
95
  app.post('/admin/groups/:id/rename', run(req => {
74
96
  admin(req);
@@ -78,6 +100,22 @@ export class IntegrationRuntime {
78
100
  }
79
101
  return options.messages.renameLocalGroup(req.params.id, body.name, body.expected_updated_at, body.idempotency_key);
80
102
  }));
103
+ app.post('/admin/groups/:id/archive', run(req => {
104
+ admin(req);
105
+ const body = req.body;
106
+ if (!body || typeof body !== 'object' || Array.isArray(body) || Object.keys(body).some(key => !['expected_updated_at', 'idempotency_key'].includes(key))) {
107
+ integrationError('INVALID_GROUP_ARCHIVE_REQUEST', 'Specify only expected_updated_at and idempotency_key');
108
+ }
109
+ return options.messages.setLocalGroupArchived(req.params.id, true, body.expected_updated_at, body.idempotency_key);
110
+ }));
111
+ app.post('/admin/groups/:id/unarchive', run(req => {
112
+ admin(req);
113
+ const body = req.body;
114
+ if (!body || typeof body !== 'object' || Array.isArray(body) || Object.keys(body).some(key => !['expected_updated_at', 'idempotency_key'].includes(key))) {
115
+ integrationError('INVALID_GROUP_ARCHIVE_REQUEST', 'Specify only expected_updated_at and idempotency_key');
116
+ }
117
+ return options.messages.setLocalGroupArchived(req.params.id, false, body.expected_updated_at, body.idempotency_key);
118
+ }));
81
119
  app.post('/admin/groups', run(req => {
82
120
  admin(req);
83
121
  const body = req.body;
@@ -216,6 +254,19 @@ export class IntegrationRuntime {
216
254
  app.post('/sessions/:id/restore', run(async (req) => { const p = principal(req); this.authorize(p, 'session.restore'); const session = await this.sessions.restore(p, req.params.id, req.body?.idempotency_key); this.sync(); return { session: publicIntegrationSession(session) }; }));
217
255
  app.post('/sessions/:id/retry-cold', run(async (req) => { const p = principal(req); this.authorize(p, 'session.create'); const session = await this.sessions.retryCold(p, req.params.id, req.body?.generation, req.body?.idempotency_key); this.sync(); return { session: publicIntegrationSession(session) }; }));
218
256
  app.post('/sessions/:id/release', run(async (req) => { const p = principal(req); this.authorize(p, 'session.release'); const session = await this.sessions.release(p, req.params.id, req.body?.generation, req.body?.idempotency_key); this.sync(); return { session: publicIntegrationSession(session) }; }));
257
+ app.post('/sessions/release-batch', run(async (req) => {
258
+ const p = principal(req);
259
+ this.authorize(p, 'session.release');
260
+ return this.createReleaseBatch(p, req.body?.session_ids, req.body?.idempotency_key);
261
+ }));
262
+ app.get('/sessions/release-batches/:id', run(req => {
263
+ const p = principal(req);
264
+ this.authorize(p, 'session.release');
265
+ const operation = this.releaseBatchOperations.find(item => item.id === req.params.id && item.principal_id === p.id && item.group_id === p.groupId);
266
+ if (!operation)
267
+ integrationError('RELEASE_BATCH_NOT_FOUND', 'Batch release operation was not found', 404);
268
+ return { operation: structuredClone(operation) };
269
+ }));
219
270
  app.post('/sessions/:id/rename', run(async (req) => { const p = principal(req); this.authorize(p, 'session.rename'); const session = await this.sessions.rename(p, req.params.id, req.body?.generation, req.body?.name, req.body?.idempotency_key); this.sync(); return { session: publicIntegrationSession(session) }; }));
220
271
  app.post('/sessions/:id/close', run(async (req) => { const p = principal(req); this.authorize(p, 'session.close'); const session = await this.sessions.closeSession(p, req.params.id, req.body?.generation, req.body?.idempotency_key); this.sync(); return { session: publicIntegrationSession(session) }; }));
221
272
  app.get('/events', run((req, res) => {
@@ -254,13 +305,103 @@ export class IntegrationRuntime {
254
305
  session_close: true, session_close_min_version: '1.4.315',
255
306
  admin_local_group_create: true, admin_local_group_create_min_version: '1.4.318',
256
307
  admin_local_group_rename: true, admin_local_group_rename_min_version: '1.4.319',
308
+ admin_local_group_archive: true, admin_local_group_archive_min_version: '1.4.323',
257
309
  integration_policy_update: true,
258
310
  session_restore_diagnostics: true,
259
311
  native_identity_linux_flock_owner: process.platform === 'linux',
260
312
  background_task_records: true, task_purpose_configuration: true, explicit_execution_state: true,
261
313
  integration_message_send: true, integration_message_reply: true, integration_message_history: true,
314
+ session_release_batch: true, session_release_batch_min_version: getTermdockVersion(),
262
315
  permissions: INTEGRATION_OPERATIONS };
263
316
  }
317
+ async createReleaseBatch(principal, rawSessionIds, rawKey) {
318
+ if (!Array.isArray(rawSessionIds) || rawSessionIds.length < 1 || rawSessionIds.length > 100
319
+ || rawSessionIds.some(id => typeof id !== 'string' || !/^[a-zA-Z0-9._-]{1,80}$/.test(id))) {
320
+ integrationError('INVALID_RELEASE_BATCH', 'session_ids must contain 1–100 exact session IDs');
321
+ }
322
+ if (typeof rawKey !== 'string' || !rawKey.trim() || rawKey.length > 160)
323
+ integrationError('INVALID_IDEMPOTENCY_KEY', 'A 1–160 character idempotency_key is required');
324
+ const sessionIds = [...new Set(rawSessionIds)].sort();
325
+ const keyHash = createHash('sha256').update(`${principal.id}:${rawKey}`).digest('hex');
326
+ const requestHash = createHash('sha256').update(JSON.stringify([principal.groupId, sessionIds])).digest('hex');
327
+ const existing = this.releaseBatchOperations.find(operation => operation.idempotency_key === keyHash);
328
+ if (existing) {
329
+ if (existing.request_hash !== requestHash)
330
+ integrationError('IDEMPOTENCY_CONFLICT', 'This batch release key was used with different sessions', 409);
331
+ return { accepted: true, operation: structuredClone(existing), replayed: true };
332
+ }
333
+ if (this.releaseBatchOperations.length >= 1000)
334
+ integrationError('RELEASE_BATCH_HISTORY_FULL', 'Batch release history is full; reconcile retained operations before creating another', 503);
335
+ const items = [];
336
+ for (const sessionId of sessionIds) {
337
+ const session = await this.sessions.get(principal, sessionId);
338
+ items.push({ session_id: sessionId, generation: session.generation ?? 1, state: 'queued' });
339
+ }
340
+ const now = Date.now();
341
+ const operation = { id: randomUUID(), principal_id: principal.id, group_id: principal.groupId,
342
+ idempotency_key: keyHash, request_hash: requestHash, state: 'queued', created_at: now, updated_at: now, items };
343
+ this.releaseBatchOperations.push(operation);
344
+ try {
345
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
346
+ }
347
+ catch (error) {
348
+ this.releaseBatchOperations = this.releaseBatchOperations.filter(item => item.id !== operation.id);
349
+ throw error;
350
+ }
351
+ void this.pumpReleaseBatches();
352
+ return { accepted: true, operation: structuredClone(operation), replayed: false };
353
+ }
354
+ async pumpReleaseBatches() {
355
+ if (this.releaseBatchRunning)
356
+ return;
357
+ this.releaseBatchRunning = true;
358
+ try {
359
+ for (;;) {
360
+ const operation = this.releaseBatchOperations.find(item => item.state === 'queued' || item.state === 'running');
361
+ if (!operation)
362
+ break;
363
+ operation.state = 'running';
364
+ operation.updated_at = Date.now();
365
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
366
+ for (const item of operation.items) {
367
+ if (item.state !== 'queued')
368
+ continue;
369
+ item.state = 'running';
370
+ operation.updated_at = Date.now();
371
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
372
+ try {
373
+ const policy = this.store.policies().find(candidate => candidate.id === operation.principal_id && candidate.groupId === operation.group_id && !candidate.revoked);
374
+ if (!policy)
375
+ throw Object.assign(new Error('Integration principal was revoked before release'), { code: 'INTEGRATION_REVOKED' });
376
+ const activePrincipal = policy;
377
+ this.store.authorize(activePrincipal, 'session.release');
378
+ const session = await this.sessions.release(activePrincipal, item.session_id, item.generation, `${operation.idempotency_key}:${item.session_id}`);
379
+ if (session.state !== 'released')
380
+ throw Object.assign(new Error(session.error_code ?? 'Session release did not reach released state'), { code: session.error_code ?? 'SESSION_RELEASE_FAILED' });
381
+ item.state = 'released';
382
+ }
383
+ catch (error) {
384
+ const value = error;
385
+ item.state = 'failed';
386
+ item.error_code = typeof value?.code === 'string' ? value.code : 'SESSION_RELEASE_FAILED';
387
+ item.error = (error instanceof Error ? error.message : String(error)).slice(0, 500);
388
+ }
389
+ operation.updated_at = Date.now();
390
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
391
+ }
392
+ operation.state = operation.items.some(item => item.state === 'failed') ? 'partial_failure' : 'succeeded';
393
+ operation.updated_at = Date.now();
394
+ atomicJson(this.releaseBatchFile, this.releaseBatchOperations);
395
+ this.sync();
396
+ }
397
+ }
398
+ catch (error) {
399
+ console.error('[integration-release-batch] worker stopped; persisted operation will reconcile on restart:', error);
400
+ }
401
+ finally {
402
+ this.releaseBatchRunning = false;
403
+ }
404
+ }
264
405
  error(error) {
265
406
  return { type: 'error', ok: false, code: error instanceof CollaborationError ? error.code : 'INTEGRATION_INTERNAL_ERROR',
266
407
  ...(error instanceof CollaborationError && error.code === 'GROUP_CHANGED' && Number.isSafeInteger(error.details?.currentUpdatedAt)
@@ -458,6 +599,7 @@ export class IntegrationRuntime {
458
599
  await new Promise((resolve, reject) => { this.server.once('error', reject); this.server.listen(this.options.socketPath, () => { this.server.removeListener('error', reject); fs.chmodSync(this.options.socketPath, 0o600); resolve(); }); });
459
600
  this.sync();
460
601
  await this.sessions.refreshAll();
602
+ void this.pumpReleaseBatches();
461
603
  }
462
604
  async close() {
463
605
  for (const stop of this.stops)