termdock 1.4.299 → 1.4.301

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 (372) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +2 -1
  3. package/dist/client/assets/App-BziVLy1b.js +179 -0
  4. package/dist/client/assets/App-BziVLy1b.js.br +0 -0
  5. package/dist/client/assets/App-BziVLy1b.js.gz +0 -0
  6. package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js +12 -0
  7. package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js.br +0 -0
  8. package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js.gz +0 -0
  9. package/dist/client/assets/{ChangeWalkthroughPanel-2lXfrgk4.js → ChangeWalkthroughPanel-00oa0z6w.js} +2 -2
  10. package/dist/client/assets/ChangeWalkthroughPanel-00oa0z6w.js.br +0 -0
  11. package/dist/client/assets/ChangeWalkthroughPanel-00oa0z6w.js.gz +0 -0
  12. package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js +1 -0
  13. package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js.br +0 -0
  14. package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js.gz +0 -0
  15. package/dist/client/assets/CollaborationTaskContent-B_mzpNuw.js +2 -0
  16. package/dist/client/assets/ComputerControlView-C9v1Ooc9.js +5 -0
  17. package/dist/client/assets/ComputerControlView-C9v1Ooc9.js.br +0 -0
  18. package/dist/client/assets/ComputerControlView-C9v1Ooc9.js.gz +0 -0
  19. package/dist/client/assets/{DagPlayground-EFUb9S3u.js → DagPlayground-DfUpMALj.js} +1 -1
  20. package/dist/client/assets/DagPlayground-DfUpMALj.js.br +0 -0
  21. package/dist/client/assets/DagPlayground-DfUpMALj.js.gz +0 -0
  22. package/dist/client/assets/{DiffLab-CXWjSE2q.js → DiffLab-Cf_URhQt.js} +1 -1
  23. package/dist/client/assets/DiffLab-Cf_URhQt.js.br +0 -0
  24. package/dist/client/assets/DiffLab-Cf_URhQt.js.gz +0 -0
  25. package/dist/client/assets/{DiffReview-ByMkBaD9.js → DiffReview-DjG9vCpH.js} +1 -1
  26. package/dist/client/assets/DiffReview-DjG9vCpH.js.br +0 -0
  27. package/dist/client/assets/DiffReview-DjG9vCpH.js.gz +0 -0
  28. package/dist/client/assets/{DiffReviewLab-DoWaKm94.js → DiffReviewLab-BKOvHdJY.js} +2 -2
  29. package/dist/client/assets/DiffReviewLab-BKOvHdJY.js.br +0 -0
  30. package/dist/client/assets/DiffReviewLab-BKOvHdJY.js.gz +0 -0
  31. package/dist/client/assets/{DiffViewer-B4hn9z0k.js → DiffViewer-6n3tgsdc.js} +8 -8
  32. package/dist/client/assets/DiffViewer-6n3tgsdc.js.br +0 -0
  33. package/dist/client/assets/DiffViewer-6n3tgsdc.js.gz +0 -0
  34. package/dist/client/assets/{ModelPreview-C-LJZ8so.js → ModelPreview-BNs2sRct.js} +1 -1
  35. package/dist/client/assets/ModelPreview-BNs2sRct.js.br +0 -0
  36. package/dist/client/assets/ModelPreview-BNs2sRct.js.gz +0 -0
  37. package/dist/client/assets/RightSidebar-CcMSU1v8.js +1677 -0
  38. package/dist/client/assets/RightSidebar-CcMSU1v8.js.br +0 -0
  39. package/dist/client/assets/RightSidebar-CcMSU1v8.js.gz +0 -0
  40. package/dist/client/assets/{abnfDiagram-VCTEODGH-BY-pfYKk.js → abnfDiagram-VCTEODGH-DogjvRKp.js} +1 -1
  41. package/dist/client/assets/abnfDiagram-VCTEODGH-DogjvRKp.js.br +0 -0
  42. package/dist/client/assets/abnfDiagram-VCTEODGH-DogjvRKp.js.gz +0 -0
  43. package/dist/client/assets/app-D6vN8PW-.js +35 -0
  44. package/dist/client/assets/app-D6vN8PW-.js.br +0 -0
  45. package/dist/client/assets/app-D6vN8PW-.js.gz +0 -0
  46. package/dist/client/assets/{arc-DIENgCZn.js → arc-Cqel4Ted.js} +1 -1
  47. package/dist/client/assets/arc-Cqel4Ted.js.br +0 -0
  48. package/dist/client/assets/arc-Cqel4Ted.js.gz +0 -0
  49. package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1h4e4az.js → architectureDiagram-5GKGNRK7-DgvPtgNb.js} +1 -1
  50. package/dist/client/assets/architectureDiagram-5GKGNRK7-DgvPtgNb.js.br +0 -0
  51. package/dist/client/assets/architectureDiagram-5GKGNRK7-DgvPtgNb.js.gz +0 -0
  52. package/dist/client/assets/{blockDiagram-I7D4REHJ-B_yOr54K.js → blockDiagram-I7D4REHJ-BxbWO4x4.js} +1 -1
  53. package/dist/client/assets/blockDiagram-I7D4REHJ-BxbWO4x4.js.br +0 -0
  54. package/dist/client/assets/blockDiagram-I7D4REHJ-BxbWO4x4.js.gz +0 -0
  55. package/dist/client/assets/{c4Diagram-7LVT6UL2-DRD4zxIo.js → c4Diagram-7LVT6UL2-gsA37gjL.js} +1 -1
  56. package/dist/client/assets/c4Diagram-7LVT6UL2-gsA37gjL.js.br +0 -0
  57. package/dist/client/assets/c4Diagram-7LVT6UL2-gsA37gjL.js.gz +0 -0
  58. package/dist/client/assets/channel-CBc8-n7y.js +1 -0
  59. package/dist/client/assets/{chunk-2Q5K7J3B-CXytnjmD.js → chunk-2Q5K7J3B-ChC9yYOd.js} +1 -1
  60. package/dist/client/assets/{chunk-5VM5RSS4-Bjmajkf7.js → chunk-5VM5RSS4-Bi4Hc8yL.js} +1 -1
  61. package/dist/client/assets/{chunk-F27PBJKO-CQCL8mJG.js → chunk-F27PBJKO-DvVWvQEk.js} +1 -1
  62. package/dist/client/assets/chunk-F27PBJKO-DvVWvQEk.js.br +0 -0
  63. package/dist/client/assets/chunk-F27PBJKO-DvVWvQEk.js.gz +0 -0
  64. package/dist/client/assets/{chunk-IMKFNOWR-ruHGCADe.js → chunk-IMKFNOWR-BnwQLR5S.js} +1 -1
  65. package/dist/client/assets/chunk-IMKFNOWR-BnwQLR5S.js.br +0 -0
  66. package/dist/client/assets/chunk-IMKFNOWR-BnwQLR5S.js.gz +0 -0
  67. package/dist/client/assets/{chunk-JWPE2WC7-U18S7rxZ.js → chunk-JWPE2WC7-BkNnaDiR.js} +1 -1
  68. package/dist/client/assets/{chunk-POPQ4Y6H-DWnwssfL.js → chunk-POPQ4Y6H-BRzm6Uzi.js} +1 -1
  69. package/dist/client/assets/{chunk-SVP7TREG-DMHj3NSq.js → chunk-SVP7TREG-CDYm-dzk.js} +1 -1
  70. package/dist/client/assets/chunk-SVP7TREG-CDYm-dzk.js.br +0 -0
  71. package/dist/client/assets/chunk-SVP7TREG-CDYm-dzk.js.gz +0 -0
  72. package/dist/client/assets/{chunk-TICWLB2K-Dh_ekvFW.js → chunk-TICWLB2K-BKaW9Z9i.js} +1 -1
  73. package/dist/client/assets/chunk-TICWLB2K-BKaW9Z9i.js.br +0 -0
  74. package/dist/client/assets/chunk-TICWLB2K-BKaW9Z9i.js.gz +0 -0
  75. package/dist/client/assets/{chunk-XXDRQBXY-Bq5wD6iJ.js → chunk-XXDRQBXY-DcHZ_FHb.js} +1 -1
  76. package/dist/client/assets/classDiagram-ZZMXUADV-CNFc2dOc.js +1 -0
  77. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CNFc2dOc.js +1 -0
  78. package/dist/client/assets/{cose-bilkent-JH36ORCC-CsySWhYg.js → cose-bilkent-JH36ORCC-DCbbTNc6.js} +1 -1
  79. package/dist/client/assets/cose-bilkent-JH36ORCC-DCbbTNc6.js.br +0 -0
  80. package/dist/client/assets/cose-bilkent-JH36ORCC-DCbbTNc6.js.gz +0 -0
  81. package/dist/client/assets/{cynefin-OW5HDTMX-9DKE5wV7.js → cynefin-OW5HDTMX-i23hD0Z2.js} +1 -1
  82. package/dist/client/assets/cynefin-OW5HDTMX-i23hD0Z2.js.br +0 -0
  83. package/dist/client/assets/cynefin-OW5HDTMX-i23hD0Z2.js.gz +0 -0
  84. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-B_8fvr9c.js → cynefinDiagram-5FMLGOSQ-CbyLYcqc.js} +1 -1
  85. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbyLYcqc.js.br +0 -0
  86. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbyLYcqc.js.gz +0 -0
  87. package/dist/client/assets/{dagre-GXQ25YYZ-BOdsFNFT.js → dagre-GXQ25YYZ-iJ4VKzZm.js} +1 -1
  88. package/dist/client/assets/dagre-GXQ25YYZ-iJ4VKzZm.js.br +0 -0
  89. package/dist/client/assets/dagre-GXQ25YYZ-iJ4VKzZm.js.gz +0 -0
  90. package/dist/client/assets/{diagram-S7CK7UJ4-6v_qvAvi.js → diagram-S7CK7UJ4-BNVZcdsO.js} +1 -1
  91. package/dist/client/assets/diagram-S7CK7UJ4-BNVZcdsO.js.br +0 -0
  92. package/dist/client/assets/diagram-S7CK7UJ4-BNVZcdsO.js.gz +0 -0
  93. package/dist/client/assets/{diagram-UQ7AKVKN-c03oOGhD.js → diagram-UQ7AKVKN-1ghTvPiu.js} +1 -1
  94. package/dist/client/assets/diagram-UQ7AKVKN-1ghTvPiu.js.br +0 -0
  95. package/dist/client/assets/diagram-UQ7AKVKN-1ghTvPiu.js.gz +0 -0
  96. package/dist/client/assets/{diagram-VSXAHHWV-MMIhRYp_.js → diagram-VSXAHHWV-Ce_0nMd3.js} +1 -1
  97. package/dist/client/assets/diagram-VSXAHHWV-Ce_0nMd3.js.br +0 -0
  98. package/dist/client/assets/diagram-VSXAHHWV-Ce_0nMd3.js.gz +0 -0
  99. package/dist/client/assets/{diagram-VX7I27RA-B_l-uebl.js → diagram-VX7I27RA-CLHEkhUt.js} +1 -1
  100. package/dist/client/assets/diagram-VX7I27RA-CLHEkhUt.js.br +0 -0
  101. package/dist/client/assets/diagram-VX7I27RA-CLHEkhUt.js.gz +0 -0
  102. package/dist/client/assets/{diagram-Z3DM3KII-DKoBC5gn.js → diagram-Z3DM3KII-iyb5DkP6.js} +1 -1
  103. package/dist/client/assets/diagram-Z3DM3KII-iyb5DkP6.js.br +0 -0
  104. package/dist/client/assets/diagram-Z3DM3KII-iyb5DkP6.js.gz +0 -0
  105. package/dist/client/assets/{ebnfDiagram-PWID7BFC-Bs3wu8Az.js → ebnfDiagram-PWID7BFC-Dxh2TzXm.js} +1 -1
  106. package/dist/client/assets/ebnfDiagram-PWID7BFC-Dxh2TzXm.js.br +0 -0
  107. package/dist/client/assets/ebnfDiagram-PWID7BFC-Dxh2TzXm.js.gz +0 -0
  108. package/dist/client/assets/{erDiagram-RLTQ6QDP-mYnHYbKl.js → erDiagram-RLTQ6QDP-Cr8IkdCC.js} +1 -1
  109. package/dist/client/assets/erDiagram-RLTQ6QDP-Cr8IkdCC.js.br +0 -0
  110. package/dist/client/assets/erDiagram-RLTQ6QDP-Cr8IkdCC.js.gz +0 -0
  111. package/dist/client/assets/{flowDiagram-HODETNUW-CwCLWbib.js → flowDiagram-HODETNUW-B8ZF1bwr.js} +1 -1
  112. package/dist/client/assets/flowDiagram-HODETNUW-B8ZF1bwr.js.br +0 -0
  113. package/dist/client/assets/flowDiagram-HODETNUW-B8ZF1bwr.js.gz +0 -0
  114. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-mse8c-ni.js → ganttDiagram-EL5Y4UJY-zhdL10eM.js} +1 -1
  115. package/dist/client/assets/ganttDiagram-EL5Y4UJY-zhdL10eM.js.br +0 -0
  116. package/dist/client/assets/ganttDiagram-EL5Y4UJY-zhdL10eM.js.gz +0 -0
  117. package/dist/client/assets/{gestureArbiter-BviL29ps.js → gestureArbiter-CXYHfU__.js} +1 -1
  118. package/dist/client/assets/gestureArbiter-CXYHfU__.js.br +0 -0
  119. package/dist/client/assets/gestureArbiter-CXYHfU__.js.gz +0 -0
  120. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-BVUfLjAX.js → gitGraphDiagram-WWUBYQGX-BQf2fHBo.js} +1 -1
  121. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BQf2fHBo.js.br +0 -0
  122. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BQf2fHBo.js.gz +0 -0
  123. package/dist/client/assets/{index-C6ftfFlG.css → index-CNY7CTVa.css} +1 -1
  124. package/dist/client/assets/index-CNY7CTVa.css.br +0 -0
  125. package/dist/client/assets/index-CNY7CTVa.css.gz +0 -0
  126. package/dist/client/assets/{infoDiagram-27XIBGKW-XjoFF4BC.js → infoDiagram-27XIBGKW-BT8xey7S.js} +1 -1
  127. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-bH299bWL.js → ishikawaDiagram-5VMMS53U-DunPdwW9.js} +1 -1
  128. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DunPdwW9.js.br +0 -0
  129. package/dist/client/assets/ishikawaDiagram-5VMMS53U-DunPdwW9.js.gz +0 -0
  130. package/dist/client/assets/{journeyDiagram-3NMN7TZE-BG0u_X1A.js → journeyDiagram-3NMN7TZE-B0y75iIg.js} +1 -1
  131. package/dist/client/assets/journeyDiagram-3NMN7TZE-B0y75iIg.js.br +0 -0
  132. package/dist/client/assets/journeyDiagram-3NMN7TZE-B0y75iIg.js.gz +0 -0
  133. package/dist/client/assets/{kanban-definition-UXKFOSKX-DRoc9N-i.js → kanban-definition-UXKFOSKX-BfgA5WLo.js} +1 -1
  134. package/dist/client/assets/kanban-definition-UXKFOSKX-BfgA5WLo.js.br +0 -0
  135. package/dist/client/assets/kanban-definition-UXKFOSKX-BfgA5WLo.js.gz +0 -0
  136. package/dist/client/assets/{layout-mh0t6JpE.js → layout-BvjABLff.js} +1 -1
  137. package/dist/client/assets/layout-BvjABLff.js.br +0 -0
  138. package/dist/client/assets/layout-BvjABLff.js.gz +0 -0
  139. package/dist/client/assets/{linear-B9KTRuUV.js → linear-DgeFRliF.js} +1 -1
  140. package/dist/client/assets/linear-DgeFRliF.js.br +0 -0
  141. package/dist/client/assets/linear-DgeFRliF.js.gz +0 -0
  142. package/dist/client/assets/{mermaid.core-Bu2G9zhK.js → mermaid.core-DM6Rlal9.js} +5 -5
  143. package/dist/client/assets/mermaid.core-DM6Rlal9.js.br +0 -0
  144. package/dist/client/assets/mermaid.core-DM6Rlal9.js.gz +0 -0
  145. package/dist/client/assets/{mindmap-definition-YA3MSWOX-Go6Bg5xm.js → mindmap-definition-YA3MSWOX-DhEiABv6.js} +1 -1
  146. package/dist/client/assets/mindmap-definition-YA3MSWOX-DhEiABv6.js.br +0 -0
  147. package/dist/client/assets/mindmap-definition-YA3MSWOX-DhEiABv6.js.gz +0 -0
  148. package/dist/client/assets/{passwordBootstrap-C7-MUAHQ.js → passwordBootstrap-Dxv0I4wM.js} +1 -1
  149. package/dist/client/assets/passwordBootstrap-Dxv0I4wM.js.br +0 -0
  150. package/dist/client/assets/passwordBootstrap-Dxv0I4wM.js.gz +0 -0
  151. package/dist/client/assets/{pegDiagram-XKGWAZYB-DKUIl_U6.js → pegDiagram-XKGWAZYB-LTlVaJfm.js} +1 -1
  152. package/dist/client/assets/pegDiagram-XKGWAZYB-LTlVaJfm.js.br +0 -0
  153. package/dist/client/assets/pegDiagram-XKGWAZYB-LTlVaJfm.js.gz +0 -0
  154. package/dist/client/assets/{pieDiagram-E7YTZNPT-aoDNlV7J.js → pieDiagram-E7YTZNPT-9bnryna3.js} +1 -1
  155. package/dist/client/assets/pieDiagram-E7YTZNPT-9bnryna3.js.br +0 -0
  156. package/dist/client/assets/pieDiagram-E7YTZNPT-9bnryna3.js.gz +0 -0
  157. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BKuuaF2s.js → quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js} +1 -1
  158. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BKuuaF2s.js.br → quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js.br} +0 -0
  159. package/dist/client/assets/quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js.gz +0 -0
  160. package/dist/client/assets/{railroadDiagram-O6MQD6OU-BwfCW2bp.js → railroadDiagram-O6MQD6OU-DTtXvKOu.js} +1 -1
  161. package/dist/client/assets/railroadDiagram-O6MQD6OU-DTtXvKOu.js.br +0 -0
  162. package/dist/client/assets/railroadDiagram-O6MQD6OU-DTtXvKOu.js.gz +0 -0
  163. package/dist/client/assets/rdpSession-Ggo3N5s5.js +1 -0
  164. package/dist/client/assets/rdpSession-Ggo3N5s5.js.br +0 -0
  165. package/dist/client/assets/rdpSession-Ggo3N5s5.js.gz +0 -0
  166. package/dist/client/assets/referenceLongPress-Df8W2cyP.js +1 -0
  167. package/dist/client/assets/referenceLongPress-Df8W2cyP.js.br +0 -0
  168. package/dist/client/assets/referenceLongPress-Df8W2cyP.js.gz +0 -0
  169. package/dist/client/assets/{requirementDiagram-BXWQKSXE-DbpU9Uig.js → requirementDiagram-BXWQKSXE-BNia9zI0.js} +1 -1
  170. package/dist/client/assets/requirementDiagram-BXWQKSXE-BNia9zI0.js.br +0 -0
  171. package/dist/client/assets/requirementDiagram-BXWQKSXE-BNia9zI0.js.gz +0 -0
  172. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-Bxa22XVM.js → sankeyDiagram-P5KCCOFB-uvg5npfK.js} +1 -1
  173. package/dist/client/assets/sankeyDiagram-P5KCCOFB-uvg5npfK.js.br +0 -0
  174. package/dist/client/assets/sankeyDiagram-P5KCCOFB-uvg5npfK.js.gz +0 -0
  175. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-C4GvzT9z.js → sequenceDiagram-WJ2MYXX4-DpJNf2MD.js} +1 -1
  176. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DpJNf2MD.js.br +0 -0
  177. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DpJNf2MD.js.gz +0 -0
  178. package/dist/client/assets/{sizeCapture-INFHLROL-B9zJJwQw.js → sizeCapture-INFHLROL-CkWB2AnF.js} +1 -1
  179. package/dist/client/assets/sizeCapture-INFHLROL-CkWB2AnF.js.br +0 -0
  180. package/dist/client/assets/sizeCapture-INFHLROL-CkWB2AnF.js.gz +0 -0
  181. package/dist/client/assets/{sparkles-BJbfT-v-.js → sparkles-DOuEtn62.js} +1 -1
  182. package/dist/client/assets/{stateDiagram-D77RDMKH-fqbw6LZa.js → stateDiagram-D77RDMKH-CeMzMQq-.js} +1 -1
  183. package/dist/client/assets/stateDiagram-D77RDMKH-CeMzMQq-.js.br +0 -0
  184. package/dist/client/assets/stateDiagram-D77RDMKH-CeMzMQq-.js.gz +0 -0
  185. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CNYUpLxt.js +1 -0
  186. package/dist/client/assets/{swimlanes-42K2YHIH-Hpc28YZY.js → swimlanes-42K2YHIH-Bo9GejWo.js} +1 -1
  187. package/dist/client/assets/swimlanes-42K2YHIH-Bo9GejWo.js.br +0 -0
  188. package/dist/client/assets/swimlanes-42K2YHIH-Bo9GejWo.js.gz +0 -0
  189. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-EB7zBRFR.js +8 -0
  190. package/dist/client/assets/{timeline-definition-24CTP7MA-qDieK7Re.js → timeline-definition-24CTP7MA-cvWXYEZ4.js} +1 -1
  191. package/dist/client/assets/timeline-definition-24CTP7MA-cvWXYEZ4.js.br +0 -0
  192. package/dist/client/assets/timeline-definition-24CTP7MA-cvWXYEZ4.js.gz +0 -0
  193. package/dist/client/assets/{triangle-alert-YOCAWhtT.js → triangle-alert-DzV0gQXz.js} +1 -1
  194. package/dist/client/assets/{vennDiagram-4TSXK5OY-BJpZlHao.js → vennDiagram-4TSXK5OY-CzleWcmk.js} +1 -1
  195. package/dist/client/assets/{vennDiagram-4TSXK5OY-BJpZlHao.js.br → vennDiagram-4TSXK5OY-CzleWcmk.js.br} +0 -0
  196. package/dist/client/assets/vennDiagram-4TSXK5OY-CzleWcmk.js.gz +0 -0
  197. package/dist/client/assets/{videoCompression-DI9vP0dm.js → videoCompression-DCnzjEfU.js} +1 -1
  198. package/dist/client/assets/videoCompression-DCnzjEfU.js.br +0 -0
  199. package/dist/client/assets/videoCompression-DCnzjEfU.js.gz +0 -0
  200. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-CQJfj6Ns.js → wardleyDiagram-VM6X3IG4-Cir1iutR.js} +1 -1
  201. package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cir1iutR.js.br +0 -0
  202. package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cir1iutR.js.gz +0 -0
  203. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-Cy-lkWBX.js → xychartDiagram-S5SC5T6Z-pNPcVJ1C.js} +1 -1
  204. package/dist/client/assets/xychartDiagram-S5SC5T6Z-pNPcVJ1C.js.br +0 -0
  205. package/dist/client/assets/xychartDiagram-S5SC5T6Z-pNPcVJ1C.js.gz +0 -0
  206. package/dist/client/index.html +2 -2
  207. package/dist/client/index.html.br +0 -0
  208. package/dist/client/index.html.gz +0 -0
  209. package/dist/client/sw.js +1 -1
  210. package/dist/client/sw.js.br +0 -0
  211. package/dist/client/sw.js.gz +0 -0
  212. package/dist/server/agent/collaborationCli.js +56 -10
  213. package/dist/server/agent/collaborationGroupRoutes.js +10 -5
  214. package/dist/server/agent/collaborationLaunchProfiles.js +43 -0
  215. package/dist/server/agent/collaborationRoutes.js +6 -2
  216. package/dist/server/agent/collaborationService.js +8 -2
  217. package/dist/server/agent/collaborationStore.js +32 -1
  218. package/dist/server/agent/collaborationTaskCli.js +11 -3
  219. package/dist/server/agent/collaborationTaskService.js +16 -10
  220. package/dist/server/agent/collaborationTaskStore.js +70 -25
  221. package/dist/server/agent/collaborationTeam.js +3 -3
  222. package/dist/server/agent/integrationCli.js +243 -0
  223. package/dist/server/agent/integrationServer.js +331 -0
  224. package/dist/server/agent/integrationSessions.js +344 -0
  225. package/dist/server/agent/integrationStore.js +222 -0
  226. package/dist/server/cli.js +29 -0
  227. package/dist/server/entry.js +26 -7
  228. package/dist/server/routes/filesystem.js +120 -87
  229. package/dist/server/routes/terminal.js +196 -13
  230. package/dist/server/utils/localAccess.js +27 -7
  231. package/dist/server/utils/sessionDisplayName.js +53 -0
  232. package/docs/integrations.md +304 -0
  233. package/package.json +3 -2
  234. package/runtime-manifest.json +3 -3
  235. package/dist/client/assets/App-DzuUkEI_.js +0 -179
  236. package/dist/client/assets/App-DzuUkEI_.js.br +0 -0
  237. package/dist/client/assets/App-DzuUkEI_.js.gz +0 -0
  238. package/dist/client/assets/ArchitecturePanel-QodxiiCc.js +0 -7
  239. package/dist/client/assets/ArchitecturePanel-QodxiiCc.js.br +0 -0
  240. package/dist/client/assets/ArchitecturePanel-QodxiiCc.js.gz +0 -0
  241. package/dist/client/assets/ChangeWalkthroughPanel-2lXfrgk4.js.br +0 -0
  242. package/dist/client/assets/ChangeWalkthroughPanel-2lXfrgk4.js.gz +0 -0
  243. package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js +0 -1
  244. package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js.br +0 -0
  245. package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js.gz +0 -0
  246. package/dist/client/assets/CollaborationTaskContent-BJe9TUtZ.js +0 -2
  247. package/dist/client/assets/ComputerControlView-B5vigCoW.js +0 -5
  248. package/dist/client/assets/ComputerControlView-B5vigCoW.js.br +0 -0
  249. package/dist/client/assets/ComputerControlView-B5vigCoW.js.gz +0 -0
  250. package/dist/client/assets/DagPlayground-EFUb9S3u.js.br +0 -0
  251. package/dist/client/assets/DagPlayground-EFUb9S3u.js.gz +0 -0
  252. package/dist/client/assets/DiffLab-CXWjSE2q.js.br +0 -0
  253. package/dist/client/assets/DiffLab-CXWjSE2q.js.gz +0 -0
  254. package/dist/client/assets/DiffReview-ByMkBaD9.js.br +0 -0
  255. package/dist/client/assets/DiffReview-ByMkBaD9.js.gz +0 -0
  256. package/dist/client/assets/DiffReviewLab-DoWaKm94.js.br +0 -0
  257. package/dist/client/assets/DiffReviewLab-DoWaKm94.js.gz +0 -0
  258. package/dist/client/assets/DiffViewer-B4hn9z0k.js.br +0 -0
  259. package/dist/client/assets/DiffViewer-B4hn9z0k.js.gz +0 -0
  260. package/dist/client/assets/ModelPreview-C-LJZ8so.js.br +0 -0
  261. package/dist/client/assets/ModelPreview-C-LJZ8so.js.gz +0 -0
  262. package/dist/client/assets/RightSidebar-EaMm4prW.js +0 -1678
  263. package/dist/client/assets/RightSidebar-EaMm4prW.js.br +0 -0
  264. package/dist/client/assets/RightSidebar-EaMm4prW.js.gz +0 -0
  265. package/dist/client/assets/abnfDiagram-VCTEODGH-BY-pfYKk.js.br +0 -0
  266. package/dist/client/assets/abnfDiagram-VCTEODGH-BY-pfYKk.js.gz +0 -0
  267. package/dist/client/assets/app-Ch0UDtJ-.js +0 -35
  268. package/dist/client/assets/app-Ch0UDtJ-.js.br +0 -0
  269. package/dist/client/assets/app-Ch0UDtJ-.js.gz +0 -0
  270. package/dist/client/assets/arc-DIENgCZn.js.br +0 -0
  271. package/dist/client/assets/arc-DIENgCZn.js.gz +0 -0
  272. package/dist/client/assets/architectureDiagram-5GKGNRK7-C1h4e4az.js.br +0 -0
  273. package/dist/client/assets/architectureDiagram-5GKGNRK7-C1h4e4az.js.gz +0 -0
  274. package/dist/client/assets/blockDiagram-I7D4REHJ-B_yOr54K.js.br +0 -0
  275. package/dist/client/assets/blockDiagram-I7D4REHJ-B_yOr54K.js.gz +0 -0
  276. package/dist/client/assets/c4Diagram-7LVT6UL2-DRD4zxIo.js.br +0 -0
  277. package/dist/client/assets/c4Diagram-7LVT6UL2-DRD4zxIo.js.gz +0 -0
  278. package/dist/client/assets/channel-MOXuUKM7.js +0 -1
  279. package/dist/client/assets/chunk-F27PBJKO-CQCL8mJG.js.br +0 -0
  280. package/dist/client/assets/chunk-F27PBJKO-CQCL8mJG.js.gz +0 -0
  281. package/dist/client/assets/chunk-IMKFNOWR-ruHGCADe.js.br +0 -0
  282. package/dist/client/assets/chunk-IMKFNOWR-ruHGCADe.js.gz +0 -0
  283. package/dist/client/assets/chunk-SVP7TREG-DMHj3NSq.js.br +0 -0
  284. package/dist/client/assets/chunk-SVP7TREG-DMHj3NSq.js.gz +0 -0
  285. package/dist/client/assets/chunk-TICWLB2K-Dh_ekvFW.js.br +0 -0
  286. package/dist/client/assets/chunk-TICWLB2K-Dh_ekvFW.js.gz +0 -0
  287. package/dist/client/assets/classDiagram-ZZMXUADV-CEXMdudw.js +0 -1
  288. package/dist/client/assets/classDiagram-v2-VYDZK3BY-CEXMdudw.js +0 -1
  289. package/dist/client/assets/cose-bilkent-JH36ORCC-CsySWhYg.js.br +0 -0
  290. package/dist/client/assets/cose-bilkent-JH36ORCC-CsySWhYg.js.gz +0 -0
  291. package/dist/client/assets/cynefin-OW5HDTMX-9DKE5wV7.js.br +0 -0
  292. package/dist/client/assets/cynefin-OW5HDTMX-9DKE5wV7.js.gz +0 -0
  293. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-B_8fvr9c.js.br +0 -0
  294. package/dist/client/assets/cynefinDiagram-5FMLGOSQ-B_8fvr9c.js.gz +0 -0
  295. package/dist/client/assets/dagre-GXQ25YYZ-BOdsFNFT.js.br +0 -0
  296. package/dist/client/assets/dagre-GXQ25YYZ-BOdsFNFT.js.gz +0 -0
  297. package/dist/client/assets/diagram-S7CK7UJ4-6v_qvAvi.js.br +0 -0
  298. package/dist/client/assets/diagram-S7CK7UJ4-6v_qvAvi.js.gz +0 -0
  299. package/dist/client/assets/diagram-UQ7AKVKN-c03oOGhD.js.br +0 -0
  300. package/dist/client/assets/diagram-UQ7AKVKN-c03oOGhD.js.gz +0 -0
  301. package/dist/client/assets/diagram-VSXAHHWV-MMIhRYp_.js.br +0 -0
  302. package/dist/client/assets/diagram-VSXAHHWV-MMIhRYp_.js.gz +0 -0
  303. package/dist/client/assets/diagram-VX7I27RA-B_l-uebl.js.br +0 -0
  304. package/dist/client/assets/diagram-VX7I27RA-B_l-uebl.js.gz +0 -0
  305. package/dist/client/assets/diagram-Z3DM3KII-DKoBC5gn.js.br +0 -0
  306. package/dist/client/assets/diagram-Z3DM3KII-DKoBC5gn.js.gz +0 -0
  307. package/dist/client/assets/ebnfDiagram-PWID7BFC-Bs3wu8Az.js.br +0 -0
  308. package/dist/client/assets/ebnfDiagram-PWID7BFC-Bs3wu8Az.js.gz +0 -0
  309. package/dist/client/assets/erDiagram-RLTQ6QDP-mYnHYbKl.js.br +0 -0
  310. package/dist/client/assets/erDiagram-RLTQ6QDP-mYnHYbKl.js.gz +0 -0
  311. package/dist/client/assets/flowDiagram-HODETNUW-CwCLWbib.js.br +0 -0
  312. package/dist/client/assets/flowDiagram-HODETNUW-CwCLWbib.js.gz +0 -0
  313. package/dist/client/assets/ganttDiagram-EL5Y4UJY-mse8c-ni.js.br +0 -0
  314. package/dist/client/assets/ganttDiagram-EL5Y4UJY-mse8c-ni.js.gz +0 -0
  315. package/dist/client/assets/gestureArbiter-BviL29ps.js.br +0 -0
  316. package/dist/client/assets/gestureArbiter-BviL29ps.js.gz +0 -0
  317. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BVUfLjAX.js.br +0 -0
  318. package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BVUfLjAX.js.gz +0 -0
  319. package/dist/client/assets/index-C6ftfFlG.css.br +0 -0
  320. package/dist/client/assets/index-C6ftfFlG.css.gz +0 -0
  321. package/dist/client/assets/ishikawaDiagram-5VMMS53U-bH299bWL.js.br +0 -0
  322. package/dist/client/assets/ishikawaDiagram-5VMMS53U-bH299bWL.js.gz +0 -0
  323. package/dist/client/assets/journeyDiagram-3NMN7TZE-BG0u_X1A.js.br +0 -0
  324. package/dist/client/assets/journeyDiagram-3NMN7TZE-BG0u_X1A.js.gz +0 -0
  325. package/dist/client/assets/kanban-definition-UXKFOSKX-DRoc9N-i.js.br +0 -0
  326. package/dist/client/assets/kanban-definition-UXKFOSKX-DRoc9N-i.js.gz +0 -0
  327. package/dist/client/assets/layout-mh0t6JpE.js.br +0 -0
  328. package/dist/client/assets/layout-mh0t6JpE.js.gz +0 -0
  329. package/dist/client/assets/linear-B9KTRuUV.js.br +0 -0
  330. package/dist/client/assets/linear-B9KTRuUV.js.gz +0 -0
  331. package/dist/client/assets/mermaid.core-Bu2G9zhK.js.br +0 -0
  332. package/dist/client/assets/mermaid.core-Bu2G9zhK.js.gz +0 -0
  333. package/dist/client/assets/mindmap-definition-YA3MSWOX-Go6Bg5xm.js.br +0 -0
  334. package/dist/client/assets/mindmap-definition-YA3MSWOX-Go6Bg5xm.js.gz +0 -0
  335. package/dist/client/assets/passwordBootstrap-C7-MUAHQ.js.br +0 -0
  336. package/dist/client/assets/passwordBootstrap-C7-MUAHQ.js.gz +0 -0
  337. package/dist/client/assets/pegDiagram-XKGWAZYB-DKUIl_U6.js.br +0 -0
  338. package/dist/client/assets/pegDiagram-XKGWAZYB-DKUIl_U6.js.gz +0 -0
  339. package/dist/client/assets/pieDiagram-E7YTZNPT-aoDNlV7J.js.br +0 -0
  340. package/dist/client/assets/pieDiagram-E7YTZNPT-aoDNlV7J.js.gz +0 -0
  341. package/dist/client/assets/quadrantDiagram-AXDQQJYC-BKuuaF2s.js.gz +0 -0
  342. package/dist/client/assets/railroadDiagram-O6MQD6OU-BwfCW2bp.js.br +0 -0
  343. package/dist/client/assets/railroadDiagram-O6MQD6OU-BwfCW2bp.js.gz +0 -0
  344. package/dist/client/assets/rdpSession--y6Q98uo.js +0 -1
  345. package/dist/client/assets/rdpSession--y6Q98uo.js.br +0 -0
  346. package/dist/client/assets/rdpSession--y6Q98uo.js.gz +0 -0
  347. package/dist/client/assets/referenceLongPress-BeG1PAdI.js +0 -1
  348. package/dist/client/assets/referenceLongPress-BeG1PAdI.js.br +0 -0
  349. package/dist/client/assets/referenceLongPress-BeG1PAdI.js.gz +0 -0
  350. package/dist/client/assets/requirementDiagram-BXWQKSXE-DbpU9Uig.js.br +0 -0
  351. package/dist/client/assets/requirementDiagram-BXWQKSXE-DbpU9Uig.js.gz +0 -0
  352. package/dist/client/assets/sankeyDiagram-P5KCCOFB-Bxa22XVM.js.br +0 -0
  353. package/dist/client/assets/sankeyDiagram-P5KCCOFB-Bxa22XVM.js.gz +0 -0
  354. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-C4GvzT9z.js.br +0 -0
  355. package/dist/client/assets/sequenceDiagram-WJ2MYXX4-C4GvzT9z.js.gz +0 -0
  356. package/dist/client/assets/sizeCapture-INFHLROL-B9zJJwQw.js.br +0 -0
  357. package/dist/client/assets/sizeCapture-INFHLROL-B9zJJwQw.js.gz +0 -0
  358. package/dist/client/assets/stateDiagram-D77RDMKH-fqbw6LZa.js.br +0 -0
  359. package/dist/client/assets/stateDiagram-D77RDMKH-fqbw6LZa.js.gz +0 -0
  360. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BO23Pbrn.js +0 -1
  361. package/dist/client/assets/swimlanes-42K2YHIH-Hpc28YZY.js.br +0 -0
  362. package/dist/client/assets/swimlanes-42K2YHIH-Hpc28YZY.js.gz +0 -0
  363. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-BLS7y4Di.js +0 -8
  364. package/dist/client/assets/timeline-definition-24CTP7MA-qDieK7Re.js.br +0 -0
  365. package/dist/client/assets/timeline-definition-24CTP7MA-qDieK7Re.js.gz +0 -0
  366. package/dist/client/assets/vennDiagram-4TSXK5OY-BJpZlHao.js.gz +0 -0
  367. package/dist/client/assets/videoCompression-DI9vP0dm.js.br +0 -0
  368. package/dist/client/assets/videoCompression-DI9vP0dm.js.gz +0 -0
  369. package/dist/client/assets/wardleyDiagram-VM6X3IG4-CQJfj6Ns.js.br +0 -0
  370. package/dist/client/assets/wardleyDiagram-VM6X3IG4-CQJfj6Ns.js.gz +0 -0
  371. package/dist/client/assets/xychartDiagram-S5SC5T6Z-Cy-lkWBX.js.br +0 -0
  372. package/dist/client/assets/xychartDiagram-S5SC5T6Z-Cy-lkWBX.js.gz +0 -0
@@ -1,6 +1,7 @@
1
1
  import { Router } from 'express';
2
2
  import { CollaborationError } from './collaborationProtocol.js';
3
3
  import { COLLAB_NAME_FORBIDDEN } from './collaborationPrompt.js';
4
+ import { validateLaunchProfiles } from './collaborationLaunchProfiles.js';
4
5
  /** The current service owns group membership, including retained offline members. */
5
6
  export function collaborationGroupRoutes(options) {
6
7
  const router = Router();
@@ -11,15 +12,15 @@ export function collaborationGroupRoutes(options) {
11
12
  router.post('/collaboration-groups', async (req, res) => {
12
13
  try {
13
14
  const body = req.body ?? {};
14
- const { id, name, sessionIds, expectedUpdatedAt } = body;
15
+ const { id, name, sessionIds, expectedUpdatedAt, launchProfiles, defaultLaunchProfileId } = body;
15
16
  // Unknown fields used to be dropped silently while the save still
16
17
  // returned ok — a caller submitting `members` to rename someone got a
17
18
  // success and no rename. Reject them and route the common case (member
18
19
  // renames) to the command that actually does it.
19
- const unknownKeys = Object.keys(body).filter((key) => !['id', 'name', 'sessionIds', 'expectedUpdatedAt'].includes(key));
20
+ const unknownKeys = Object.keys(body).filter((key) => !['id', 'name', 'sessionIds', 'expectedUpdatedAt', 'launchProfiles', 'defaultLaunchProfileId'].includes(key));
20
21
  if (unknownKeys.length) {
21
22
  const hint = unknownKeys.includes('members') ? ';要改成员显示名请用 td collab rename <session-id> <新名字>' : '';
22
- throw new CollaborationError('INVALID_GROUP', `含未知字段 ${unknownKeys.join('、')}(合法字段:name, sessionIds, id, expectedUpdatedAt)${hint}`, 400);
23
+ throw new CollaborationError('INVALID_GROUP', `含未知字段 ${unknownKeys.join('、')}(合法字段:name, sessionIds, id, expectedUpdatedAt, launchProfiles, defaultLaunchProfileId)${hint}`, 400);
23
24
  }
24
25
  if ((id !== undefined && (typeof id !== 'string' || !id))
25
26
  || typeof name !== 'string' || !name.trim() || !Array.isArray(sessionIds)
@@ -36,15 +37,19 @@ export function collaborationGroupRoutes(options) {
36
37
  throw new CollaborationError('GROUP_CHANGED', `协作组已被修改(当前 updatedAt=${existing?.updatedAt})。请先确认最新成员列表,再以 expectedUpdatedAt=${existing?.updatedAt} 重新提交`, 409, { currentUpdatedAt: existing?.updatedAt });
37
38
  }
38
39
  const ids = [...new Set(sessionIds)];
40
+ const launch = launchProfiles !== undefined || defaultLaunchProfileId !== undefined ? {
41
+ launchProfiles: validateLaunchProfiles(launchProfiles ?? existing?.launchProfiles ?? [], defaultLaunchProfileId ?? null),
42
+ defaultLaunchProfileId: defaultLaunchProfileId ?? null,
43
+ } : {};
39
44
  if (options.save) {
40
- res.json(await options.save(req, { id, name, sessionIds: ids, expectedUpdatedAt }));
45
+ res.json(await options.save(req, { id, name, sessionIds: ids, expectedUpdatedAt, ...launch }));
41
46
  return;
42
47
  }
43
48
  const known = new Set([...options.sessions().map((session) => session.sessionId), ...(existing?.sessionIds ?? [])]);
44
49
  if (ids.some((value) => !known.has(value))) {
45
50
  throw new CollaborationError('MEMBERS_CHANGED', '所选会话已变化,请刷新后重新选择;尚未保存任何修改', 409);
46
51
  }
47
- res.json({ group: options.store.save({ id, name, sessionIds: ids }) });
52
+ res.json({ group: options.store.save({ id, name, sessionIds: ids, ...launch }) });
48
53
  }
49
54
  catch (error) {
50
55
  res.status(error instanceof CollaborationError ? error.httpStatus : 500)
@@ -0,0 +1,43 @@
1
+ import { CollaborationError } from './collaborationProtocol.js';
2
+ /** User-authored shell commands; never interpolate coordinator-provided parameters. */
3
+ export function validateLaunchProfiles(profiles, defaultId) {
4
+ const invalid = () => { throw new CollaborationError('INVALID_LAUNCH_PROFILE', '启动方案无效:请填写唯一标识、名称、Agent 和单行启动命令,并选择存在的默认方案', 400); };
5
+ if (!Array.isArray(profiles) || profiles.length > 20)
6
+ return invalid();
7
+ const ids = new Set();
8
+ for (const profile of profiles) {
9
+ if (!profile || typeof profile !== 'object' || Array.isArray(profile)
10
+ || Object.keys(profile).some(key => !['id', 'name', 'agentSlug', 'command', 'notes'].includes(key))
11
+ || typeof profile.id !== 'string' || !/^[a-zA-Z0-9_-]{1,64}$/.test(profile.id) || ids.has(profile.id)
12
+ || typeof profile.name !== 'string' || !profile.name.trim() || profile.name.length > 100
13
+ || typeof profile.agentSlug !== 'string' || !/^[a-zA-Z0-9_-]{1,64}$/.test(profile.agentSlug)
14
+ || typeof profile.command !== 'string' || !profile.command.trim() || profile.command.length > 4096
15
+ || typeof profile.notes !== 'string' || profile.notes.length > 2000
16
+ || /[\x00-\x1f\x7f]/.test(profile.command + profile.name)
17
+ || /[\x00-\x08\x0b-\x1f\x7f]/.test(profile.notes))
18
+ return invalid();
19
+ ids.add(profile.id);
20
+ }
21
+ if (defaultId !== undefined && defaultId !== null && (typeof defaultId !== 'string' || !ids.has(defaultId)))
22
+ return invalid();
23
+ return profiles.map(p => ({ id: p.id, name: p.name.trim(), agentSlug: p.agentSlug, command: p.command.trim(), notes: p.notes.trim() }));
24
+ }
25
+ export function resolveCollaborationLaunch(group, input) {
26
+ if (input.launchProfileId !== undefined && typeof input.launchProfileId !== 'string')
27
+ throw new CollaborationError('INVALID_LAUNCH_PROFILE', '启动方案标识必须是文本', 400);
28
+ const slug = typeof input.agentSlug === 'string' ? input.agentSlug.trim().toLowerCase() : '';
29
+ const explicit = typeof input.launchProfileId === 'string' && !!input.launchProfileId;
30
+ const profileId = explicit ? input.launchProfileId : input.launchProfileId === '' ? null : group.defaultLaunchProfileId;
31
+ const candidate = group.launchProfiles?.find(p => p.id === profileId);
32
+ if (explicit && !candidate)
33
+ throw new CollaborationError('LAUNCH_PROFILE_NOT_FOUND', '启动方案已被删除,请读取最新协作组配置', 409);
34
+ if (explicit && slug && candidate.agentSlug !== slug)
35
+ throw new CollaborationError('LAUNCH_PROFILE_AGENT_MISMATCH', '启动方案与所选 Agent 类型不一致', 400);
36
+ const profile = candidate && (!slug || candidate.agentSlug === slug) ? candidate : undefined;
37
+ if (profile)
38
+ validateLaunchProfiles([profile], profile.id);
39
+ return { agentSlug: profile?.agentSlug ?? slug, profile };
40
+ }
41
+ export function launchProfileKey(profile) {
42
+ return profile ? JSON.stringify([profile.id, profile.agentSlug, profile.command]) : '';
43
+ }
@@ -1,4 +1,5 @@
1
1
  import { terminalMessage } from './collaborationStore.js';
2
+ import { getTermdockVersion } from '../utils/version.js';
2
3
  import { assertPeerRegistrationAuthority } from './collaborationPeerTransport.js';
3
4
  import { Router } from 'express';
4
5
  import { COLLAB_LIMITS, CollaborationError, MIN_ID_PREFIX_LENGTH, ambiguousIdMessage, extrasFromBody } from './collaborationProtocol.js';
@@ -150,10 +151,11 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
150
151
  }
151
152
  };
152
153
  router.get('/capabilities', run((_req, res) => {
153
- res.json({ protocol_version: 2, limits: COLLAB_LIMITS,
154
+ res.json({ protocol_version: 2, server_version: getTermdockVersion(), limits: COLLAB_LIMITS,
154
155
  task_workflow: { version: 2, command: 'td collab task', single_authority: true, explicit_reports: true,
155
156
  managed_goals: true, automatic_review: true, dependency_dispatch: true, isolated_worktrees: true, encrypted_commit_transfer: true,
156
157
  durable_questions: true, user_acceptance: true, versioned_artifacts: true, independent_reviews: true,
158
+ correlated_responses: true, accepted_comments: true,
157
159
  task_reply: 'Replies to task-linked user messages are stored in the task; status=stored is not a terminal delivery receipt' },
158
160
  routing: { background_recovery: true, explicit_rebind: Boolean(rebind), fixed_tmux_pane: true },
159
161
  statuses: ['pending', 'delivered', 'failed', 'expired'], queued_status: 'pending',
@@ -211,7 +213,7 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
211
213
  const extras = extrasFromBody(req.body);
212
214
  const status = extras.task?.status ?? (extras.responseKind === 'ack' ? 'ack' : extras.responseKind === 'result' ? 'complete' : extras.responseKind === 'progress' ? 'working' : null);
213
215
  const task = await req.app.locals.collaborationTasks.apply(link.taskId, {
214
- kind: status ? 'report' : 'comment', status: status ?? undefined, attemptId: link.attemptId,
216
+ kind: status ? 'report' : link.replyToEventId ? 'respond' : 'comment', replyToEventId: link.replyToEventId, status: status ?? undefined, attemptId: link.attemptId,
215
217
  content: req.body.content, evidence: extras.task?.evidence, idempotencyKey: extras.idempotencyKey,
216
218
  }, req.app.locals.collaborationService.taskMember(sessionId));
217
219
  res.json({ ok: true, status: 'stored', task_recorded: true, task_id: task.id, task_revision: task.revision });
@@ -323,6 +325,8 @@ export function collaborationRoutes({ store, resolveSession, deliver, rebind, re
323
325
  id: group.id, name: group.name, sessionIds: group.sessionIds,
324
326
  members: group.sessionIds.map((sessionId) => ({ sessionId, name: names[sessionId] ?? null })),
325
327
  roles: group.roles ?? {},
328
+ launchProfiles: group.launchProfiles ?? [], defaultLaunchProfileId: group.defaultLaunchProfileId ?? null,
329
+ memberLaunchProfiles: group.memberLaunchProfiles ?? {},
326
330
  };
327
331
  };
328
332
  router.get('/rules', run((req, res, sessionId) => {
@@ -3,6 +3,7 @@ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
3
  import { dirname } from 'node:path';
4
4
  import { CollaborationError } from './collaborationProtocol.js';
5
5
  import { COLLAB_NAME_FORBIDDEN } from './collaborationPrompt.js';
6
+ import { validateLaunchProfiles } from './collaborationLaunchProfiles.js';
6
7
  import { remoteSession, validateCollaborationNode } from './collaborationPeerTransport.js';
7
8
  const hash = (value) => createHash('sha256').update(value).digest('hex');
8
9
  const address = (id) => { if (!id.startsWith('remote:'))
@@ -12,6 +13,7 @@ const local = (origin, id) => { const a = address(id); return a?.origin === orig
12
13
  const mapRoles = (value, map) => value && Object.fromEntries(Object.entries(value).map(([id, item]) => [map(id), item]));
13
14
  function mapGroup(group, map) {
14
15
  return { ...group, sessionIds: group.sessionIds.map(map), roles: mapRoles(group.roles, map), roleVersions: mapRoles(group.roleVersions, map),
16
+ memberLaunchProfiles: mapRoles(group.memberLaunchProfiles, map),
15
17
  instructions: group.instructions && { ...group.instructions, updatedBy: map(group.instructions.updatedBy) } };
16
18
  }
17
19
  /** Sole owner of peer discovery and group replication. UI and CLI call the same
@@ -460,10 +462,14 @@ export class CollaborationService {
460
462
  throw new CollaborationError('GROUP_CHANGED', `协作组已变化(当前 updatedAt=${existing.updatedAt}),请刷新后重试`, 409, { currentUpdatedAt: existing.updatedAt });
461
463
  if (typeof input.name !== 'string' || !input.name.trim() || COLLAB_NAME_FORBIDDEN.test(input.name) || !Array.isArray(input.sessionIds) || input.sessionIds.some(id => typeof id !== 'string'))
462
464
  throw new Error('INVALID_GROUP');
465
+ const launch = input.launchProfiles !== undefined || input.defaultLaunchProfileId !== undefined ? {
466
+ launchProfiles: validateLaunchProfiles(input.launchProfiles ?? existing?.launchProfiles ?? [], input.defaultLaunchProfileId ?? null),
467
+ defaultLaunchProfileId: input.defaultLaunchProfileId ?? null,
468
+ } : {};
463
469
  if (!input.sessionIds.some(id => address(id)) && !existing?.federated) {
464
470
  if (input.sessionIds.some(id => !this.options.sessions().some(s => s.sessionId === id) && !existing?.sessionIds.includes(id)))
465
471
  throw new Error('GROUP_MEMBER_UNAVAILABLE');
466
- return { group: this.options.store.save(input) };
472
+ return { group: this.options.store.save({ ...input, ...launch }) };
467
473
  }
468
474
  if (input.sessionIds.length < 2)
469
475
  throw new CollaborationError('INVALID_GROUP', '跨服务组仍需两个成员;修改未保存', 400);
@@ -477,7 +483,7 @@ export class CollaborationService {
477
483
  const available = new Set([...this.options.sessions(), ...this.directory().sessions.filter(s => s.serviceConnected)].map(s => s.sessionId));
478
484
  if (!Array.isArray(input.sessionIds) || input.sessionIds.some(id => !available.has(id) && !existing?.sessionIds.includes(id)))
479
485
  throw new Error('GROUP_MEMBER_UNAVAILABLE');
480
- const group = { ...existing, id: existing?.federated ? existing.id : `cross-${randomBytes(16).toString('hex')}`, name: input.name,
486
+ const group = { ...existing, ...launch, id: existing?.federated ? existing.id : `cross-${randomBytes(16).toString('hex')}`, name: input.name,
481
487
  sessionIds: [...new Set(input.sessionIds)], createdAt: existing?.createdAt ?? Date.now(), updatedAt: Math.max(Date.now(), (existing?.updatedAt ?? 0) + 1), federated: true };
482
488
  const canonical = mapGroup(group, id => address(id) ? id : remoteSession(this.node().origin, id));
483
489
  if (canonical.sessionIds.some(id => !this.nodes().some(node => node.origin === address(id)?.origin)))
@@ -1,4 +1,5 @@
1
1
  import { plainCollaborationSnapshot } from './collaborationText.js';
2
+ import { validateLaunchProfiles } from './collaborationLaunchProfiles.js';
2
3
  import fs from 'node:fs';
3
4
  import path from 'node:path';
4
5
  import crypto from 'node:crypto';
@@ -43,6 +44,9 @@ export class CollaborationStore {
43
44
  filePath;
44
45
  drawId;
45
46
  onMessageQueued;
47
+ changeListeners = new Set();
48
+ subscribe(listener) { this.changeListeners.add(listener); return () => { this.changeListeners.delete(listener); }; }
49
+ snapshotMessages() { return structuredClone(this.document.messages); }
46
50
  peerActivity = new Map();
47
51
  recordPeerActivity(sessionId, outputAt, observedAt) {
48
52
  if (this.peerActivity.size >= 2000 && !this.peerActivity.has(sessionId))
@@ -122,9 +126,14 @@ export class CollaborationStore {
122
126
  const existing = input.id ? this.document.groups.find((group) => group.id === input.id) : null;
123
127
  if (input.id && (!existing || existing.deleted))
124
128
  throw new CollaborationError('GROUP_NOT_FOUND', '协作组已删除,请刷新列表', 404);
129
+ const launchProfiles = input.launchProfiles === undefined ? existing?.launchProfiles : validateLaunchProfiles(input.launchProfiles, input.defaultLaunchProfileId ?? null);
130
+ const defaultLaunchProfileId = input.defaultLaunchProfileId !== undefined ? input.defaultLaunchProfileId : input.launchProfiles !== undefined ? null : existing?.defaultLaunchProfileId;
131
+ if (launchProfiles || defaultLaunchProfileId)
132
+ validateLaunchProfiles(launchProfiles ?? [], defaultLaunchProfileId);
125
133
  const sessionIds = Array.from(new Set(input.sessionIds.map((id) => id.trim()).filter(Boolean)));
126
134
  const group = pruneRoles({
127
135
  ...existing,
136
+ launchProfiles, defaultLaunchProfileId,
128
137
  ...(existing?.remoteSessions ? { remoteSessions: existing.remoteSessions.filter((session) => sessionIds.includes(session.sessionId)) } : {}),
129
138
  id: existing?.id ?? newCollaborationId(this.takenIds(), this.drawId),
130
139
  name: input.name.trim(),
@@ -138,6 +147,15 @@ export class CollaborationStore {
138
147
  this.persist();
139
148
  return group;
140
149
  }
150
+ setMemberLaunchProfile(groupId, sessionId, profile) {
151
+ const group = this.getGroup(groupId);
152
+ if (!group || group.deleted || !group.sessionIds.includes(sessionId))
153
+ throw new CollaborationError('NOT_A_MEMBER', '会话不在协作组内', 409);
154
+ const [snapshot] = validateLaunchProfiles([profile], profile.id);
155
+ this.document.groups = this.document.groups.map(g => g.id === groupId ? { ...g,
156
+ memberLaunchProfiles: { ...g.memberLaunchProfiles, [sessionId]: snapshot }, updatedAt: Math.max(Date.now(), g.updatedAt + 1) } : g);
157
+ this.persist();
158
+ }
141
159
  /** Set or clear a member's role (定位). The target may be any group member —
142
160
  * oneself, a peer, or a federated remote session; peers can set each other's
143
161
  * roles. Roles ride the group document into federation and are dropped
@@ -199,7 +217,9 @@ export class CollaborationStore {
199
217
  ...(group.remoteSessions ? { remoteSessions: group.remoteSessions.filter((session) => sourceIds.includes(session.sessionId)) } : {}),
200
218
  updatedAt: Math.max(now, group.updatedAt + 1) }, sourceIds)];
201
219
  }
202
- return group.id === target.id ? [{ ...group, sessionIds: [...new Set([...group.sessionIds, input.sessionId])], updatedAt: Math.max(now, group.updatedAt + 1) }] : [group];
220
+ return group.id === target.id ? [{ ...group, sessionIds: [...new Set([...group.sessionIds, input.sessionId])],
221
+ ...(source.memberLaunchProfiles?.[input.sessionId] ? { memberLaunchProfiles: { ...group.memberLaunchProfiles, [input.sessionId]: source.memberLaunchProfiles[input.sessionId] } } : {}),
222
+ updatedAt: Math.max(now, group.updatedAt + 1) }] : [group];
203
223
  }),
204
224
  messages: this.document.messages,
205
225
  };
@@ -727,6 +747,12 @@ export class CollaborationStore {
727
747
  fs.writeFileSync(temporaryPath, serialized, { mode: 0o600 });
728
748
  fs.renameSync(temporaryPath, this.filePath);
729
749
  this.persistedDocument = serialized;
750
+ for (const listener of this.changeListeners) {
751
+ try {
752
+ listener();
753
+ }
754
+ catch { /* Journal retries from durable source records. */ }
755
+ }
730
756
  }
731
757
  catch (error) {
732
758
  this.document = JSON.parse(this.persistedDocument);
@@ -739,6 +765,11 @@ function stableJson(value) {
739
765
  ? Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b))) : entry);
740
766
  }
741
767
  function validateFederatedGroup(group) {
768
+ if (group.launchProfiles !== undefined || group.defaultLaunchProfileId !== undefined)
769
+ validateLaunchProfiles(group.launchProfiles ?? [], group.defaultLaunchProfileId);
770
+ if (group.memberLaunchProfiles)
771
+ for (const profile of Object.values(group.memberLaunchProfiles))
772
+ validateLaunchProfiles([profile], profile.id);
742
773
  if (!group.federated || typeof group.id !== 'string' || !group.id.startsWith('cross-') || typeof group.name !== 'string' || !group.name.trim()
743
774
  || !Number.isFinite(group.updatedAt) || !Number.isFinite(group.createdAt)
744
775
  || !Array.isArray(group.sessionIds) || group.sessionIds.some((id) => typeof id !== 'string')
@@ -3,8 +3,12 @@ import { randomUUID } from 'node:crypto';
3
3
  export async function executeTaskCommand(command, request, io) {
4
4
  const o = command.options, operation = command.operation;
5
5
  const bodyOptions = ['content', 'file', 'stdin', 'idempotency-key'];
6
+ const originOptions = ['source', 'external-actor', 'external-message-id', 'metadata'];
7
+ if (originOptions.some(key => o[key]) && !o.principal)
8
+ throw new Error('External source metadata requires --principal');
6
9
  const allowed = {
7
10
  list: ['group'], get: [], create: [...bodyOptions, 'group', 'title', 'constraints', 'acceptance', 'assignee', 'coordinator', 'parent', 'depends-on', 'managed', 'reviewers', 'shared-directory', 'integration', 'work-type'],
11
+ answer: [...bodyOptions, 'decision'], respond: [...bodyOptions, 'attempt', 'to-event', 'evidence'],
8
12
  assign: [...bodyOptions, 'assignee', 'revision'], report: [...bodyOptions, 'attempt', 'status', 'evidence', 'summary'], ask: [...bodyOptions, 'attempt', 'options'],
9
13
  plan: [...bodyOptions, 'attempt', 'evidence'], review: [...bodyOptions, 'artifact', 'evidence', 'verdict'], comment: bodyOptions,
10
14
  'request-review': [...bodyOptions, 'artifact', 'assignee', 'revision'],
@@ -12,7 +16,7 @@ export async function executeTaskCommand(command, request, io) {
12
16
  coordinate: [...bodyOptions, 'revision'], pause: [...bodyOptions, 'revision'], resume: [...bodyOptions, 'revision'], retry: [...bodyOptions, 'revision'],
13
17
  };
14
18
  for (const flag of Object.keys(o))
15
- if (![...allowed[operation], 'session', 'json', 'jsonl', 'text', 'help'].includes(flag))
19
+ if (![...allowed[operation], ...(o.principal ? originOptions : []), 'principal', 'session', 'json', 'jsonl', 'text', 'help'].includes(flag))
16
20
  throw new Error(`--${flag} is not supported by task ${operation}`);
17
21
  if (operation === 'list')
18
22
  return request('GET', `/tasks${o.group ? `?group=${encodeURIComponent(String(o.group))}` : ''}`);
@@ -32,8 +36,12 @@ export async function executeTaskCommand(command, request, io) {
32
36
  throw new Error('Read task get first, then supply --revision to avoid overwriting another decision');
33
37
  if (['assign', 'request-review'].includes(operation) && !o.assignee)
34
38
  throw new Error('This task operation requires --assignee');
35
- if (['report', 'ask', 'plan'].includes(operation) && !o.attempt)
39
+ if (['report', 'respond', 'ask', 'plan'].includes(operation) && !o.attempt)
36
40
  throw new Error('Use --attempt from the dispatch message; never guess the current attempt');
41
+ if (operation === 'respond' && !o['to-event'])
42
+ throw new Error('respond requires --to-event <comment-event-id>');
43
+ if (operation === 'answer' && !o.decision)
44
+ throw new Error('answer requires --decision <question-id>');
37
45
  if (operation === 'create') {
38
46
  if (!o.title || !o.group)
39
47
  throw new Error('task create requires --title and --group');
@@ -47,7 +55,7 @@ export async function executeTaskCommand(command, request, io) {
47
55
  if (options !== undefined && (!Array.isArray(options) || options.some(v => typeof v !== 'string')))
48
56
  throw new Error('--options must be a JSON array of strings');
49
57
  return request('POST', `/tasks/${encodeURIComponent(command.target)}`, { input: {
50
- kind: operation === 'plan' ? 'submit-plan' : operation, idempotencyKey, expectedRevision, content,
58
+ replyToEventId: o['to-event'], decisionId: o.decision, kind: operation === 'plan' ? 'submit-plan' : operation, idempotencyKey, expectedRevision, content,
51
59
  assigneeSessionId: o.assignee, attemptId: o.attempt, status: o.status, artifactId: o.artifact, options, verdict: o.verdict,
52
60
  evidence: o.evidence ? JSON.parse(String(o.evidence)) : undefined, summary: o.summary,
53
61
  } });
@@ -54,9 +54,9 @@ export class CollaborationTaskService {
54
54
  const roster = summary ? undefined : group?.sessionIds.map(sessionId => {
55
55
  const member = this.peers.taskMember(sessionId);
56
56
  const template = task.workflow?.reviewers.some(m => taskMemberKey(m) === taskMemberKey(member));
57
- return { member, sessionId, role: `${template ? '此目标的执行成员模板;' : ''}${group.roles?.[sessionId] ?? ''}` };
57
+ return { member, sessionId, launchProfile: group.memberLaunchProfiles?.[sessionId], role: `${template ? '此目标的执行成员模板;' : ''}${group.roles?.[sessionId] ?? ''}` };
58
58
  });
59
- return { ...task, children, roster, memberSessions, replica: task.ownerServiceId !== this.self, summaryOnly: summary, outbox: (summary ? [] : this.tasks.pending(task.id))
59
+ return { ...task, children, roster, launchProfiles: summary ? undefined : group?.launchProfiles, defaultLaunchProfileId: summary ? undefined : group?.defaultLaunchProfileId, memberSessions, replica: task.ownerServiceId !== this.self, summaryOnly: summary, outbox: (summary ? [] : this.tasks.pending(task.id))
60
60
  .map(({ id, attemptId, messageId, lastError }) => ({ id, attemptId, messageId, lastError })) };
61
61
  }
62
62
  list(groupId, actor) {
@@ -70,7 +70,7 @@ export class CollaborationTaskService {
70
70
  this.group(task.groupId, actor);
71
71
  return this.view(task);
72
72
  }
73
- async create(input, actor) {
73
+ async create(input, actor, origin) {
74
74
  this.group(input.groupId, actor);
75
75
  this.validateMembers(input.groupId, input);
76
76
  const dependencies = [...(input.dependsOn ?? []), ...(input.parentTaskId ? [input.parentTaskId] : [])];
@@ -81,22 +81,26 @@ export class CollaborationTaskService {
81
81
  if (this.tasks.get(dependency)?.ownerServiceId !== authority)
82
82
  throw new CollaborationError('DEPENDENCY_AUTHORITY_REQUIRED', '依赖与父任务需在同一来源服务创建', 409);
83
83
  }
84
+ if (origin && authority !== this.self)
85
+ throw new CollaborationError('INTEGRATION_LOCAL_ONLY', '首版集成任务须由本机服务保存', 409);
84
86
  if (authority !== this.self) {
85
87
  const result = await this.peers.requestTasks(authority, { op: 'create', input, actorSessionId: actor?.sessionId ?? null });
86
88
  const task = result.task;
87
89
  this.tasks.merge(task, authority);
88
90
  return this.view(task);
89
91
  }
90
- const task = this.tasks.create(this.self, input, actor);
92
+ const task = this.tasks.create(this.self, input, actor, origin);
91
93
  void this.flush();
92
94
  return this.view(task);
93
95
  }
94
- async apply(taskId, input, actor) {
96
+ async apply(taskId, input, actor, origin) {
95
97
  const task = this.tasks.get(taskId);
96
98
  if (!task)
97
99
  throw new CollaborationError('TASK_NOT_FOUND', '任务不存在', 404);
98
100
  this.group(task.groupId, actor);
99
101
  this.validateMembers(task.groupId, input);
102
+ if (origin && task.ownerServiceId !== this.self)
103
+ throw new CollaborationError('INTEGRATION_LOCAL_ONLY', '首版集成任务须由本机服务保存', 409);
100
104
  if (task.ownerServiceId !== this.self) {
101
105
  const result = await this.peers.requestTasks(task.ownerServiceId, { op: 'apply', taskId, input, actorSessionId: actor?.sessionId ?? null });
102
106
  this.tasks.merge(result.task, task.ownerServiceId);
@@ -126,7 +130,7 @@ export class CollaborationTaskService {
126
130
  artifactId: child.acceptedArtifactId, integration: child.workflow?.integration === true,
127
131
  commit: child.artifacts.find(a => a.id === child.acceptedArtifactId)?.evidence?.commit })) } };
128
132
  }
129
- const updated = this.tasks.apply(taskId, input, actor);
133
+ const updated = this.tasks.apply(taskId, input, actor, origin);
130
134
  void this.flush();
131
135
  return this.view(updated);
132
136
  }
@@ -196,7 +200,7 @@ export class CollaborationTaskService {
196
200
  const queued = this.messages.send({ groupId: group.id, fromSessionId: null, toSessionIds: [recipient.sessionId],
197
201
  kind: packet.kind === 'task' ? 'task' : 'message', content: String(packet.content ?? ''), threadId: attempt?.threadId ?? task.id,
198
202
  idempotencyKey: `task:${peer.serviceId}:${String(packet.outboxId)}`,
199
- metadata: { taskOutboxId: packet.outboxId, termdockTask: { taskId: task.id, attemptId: attempt?.id ?? null, ownerServiceId: peer.serviceId } } });
203
+ metadata: { taskOutboxId: packet.outboxId, termdockTask: { taskId: task.id, attemptId: attempt?.id ?? null, ownerServiceId: peer.serviceId, replyToEventId: task.events.find(e => e.deliveryId === packet.outboxId && e.attemptId === attempt?.id && e.kind === 'comment')?.id } } });
200
204
  this.deliver(recipient.sessionId);
201
205
  return { receipt: this.receipt(queued[0].id) };
202
206
  }
@@ -313,14 +317,16 @@ export class CollaborationTaskService {
313
317
  if (!task?.workflow)
314
318
  return true;
315
319
  const root = task.workflow.rootTaskId ? this.tasks.get(task.workflow.rootTaskId) : task;
316
- return !task.workflow.paused && !root?.workflow?.paused && root?.status === 'open';
320
+ const consultation = outbox.replyToEventId && task.events.some(e => e.id === outbox.replyToEventId && e.kind === 'comment');
321
+ return consultation || !task.workflow.paused && !root?.workflow?.paused && root?.status === 'open';
317
322
  }).slice(0, 16);
318
323
  for (const outbox of ready) {
319
324
  try {
320
325
  const task = this.tasks.get(outbox.taskId);
321
326
  this.group(task.groupId, outbox.target);
322
327
  const root = task.workflow?.rootTaskId ? this.tasks.get(task.workflow.rootTaskId) : task;
323
- if (task.workflow && (task.workflow.paused || root?.workflow?.paused || root?.status !== 'open'))
328
+ const consultation = outbox.replyToEventId && task.events.some(e => e.id === outbox.replyToEventId && e.kind === 'comment');
329
+ if (task.workflow && !consultation && (task.workflow.paused || root?.workflow?.paused || root?.status !== 'open'))
324
330
  continue;
325
331
  if (outbox.target.serviceId === this.self) {
326
332
  if (outbox.messageId && this.messages.getMessage(outbox.messageId)) {
@@ -330,7 +336,7 @@ export class CollaborationTaskService {
330
336
  }
331
337
  const queued = this.messages.send({ groupId: task.groupId, fromSessionId: null, toSessionIds: [outbox.target.sessionId],
332
338
  kind: outbox.kind, content: outbox.content, threadId: outbox.threadId, idempotencyKey: `task:${this.self}:${outbox.id}`,
333
- metadata: { termdockTask: { taskId: task.id, attemptId: outbox.attemptId, ownerServiceId: this.self } } });
339
+ metadata: { termdockTask: { taskId: task.id, attemptId: outbox.attemptId, ownerServiceId: this.self, replyToEventId: outbox.replyToEventId } } });
334
340
  this.deliver(outbox.target.sessionId);
335
341
  this.tasks.delivered(outbox.id, this.receipt(queued[0].id));
336
342
  }