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,3 +1,6 @@
1
+ import { collaborationSessionDisplayName } from '../utils/sessionDisplayName.js';
2
+ import { integrationError } from '../agent/integrationStore.js';
3
+ import { integrationLaunchCommand } from '../agent/integrationSessions.js';
1
4
  import { ensureTeam } from '../agent/collaborationTeam.js';
2
5
  import { androidRecordings } from '../android/recording.js';
3
6
  import { assertPeerRegistrationAuthority } from '../agent/collaborationPeerTransport.js';
@@ -26,7 +29,7 @@ import { gitStatusCache } from '../utils/gitStatus.js';
26
29
  import { getPtyHostManager } from '../ptyhost/manager.js';
27
30
  import { pathValidator } from '../utils/pathValidator.js';
28
31
  import { TERMINAL, TMUX } from '../config.js';
29
- import { localAccessManager } from '../utils/localAccess.js';
32
+ import { localAccessManager, localAccessInterfaceUrl } from '../utils/localAccess.js';
30
33
  import { normalizeLocalAccessName, getLocaleSetting, setLocaleSetting, getContextDraftHeightSetting, setContextDraftHeightSetting, getAutoRenameAgentsSetting, setAutoRenameAgentsSetting, getAutoRenameNamerSetting, setAutoRenameNamerSetting, getAutoRenameModelsSetting, setAutoRenameModelsSetting, getAutoRenameIntervalMinutesSetting, setAutoRenameIntervalMinutesSetting, getAutoRenamePromptPreferenceSetting, setAutoRenamePromptPreferenceSetting, getAutoRenamePromptPayloadCharsSetting, setAutoRenamePromptPayloadCharsSetting, getNewSessionAgentSlugSetting, setNewSessionAgentSlugSetting, getRunningSessionButtonEnabledSetting, getAttentionButtonEnabledSetting, getCollaborationPanelsSetting, setCollaborationPanelSetting, getAndroidPanelSetting, setAndroidPanelSetting, normalizeAndroidPanel, getCollaborationFloatingGroupIdSetting, setCollaborationFloatingGroupIdSetting, getServiceSwitcherExpandedSetting, setServiceSwitcherExpandedSetting, setRunningSessionButtonEnabledSetting, setAttentionButtonEnabledSetting, getFileSortModesSetting, getHideGitIgnoredRootsSetting, getGitIgnoreExceptionsSetting, setGitIgnoreExceptionsSetting, setHideGitIgnoredRootSetting, setFileSortModesSetting, setFileSortModeSetting, getNestedGitScanRootsSetting, setNestedGitScanRootSetting, getPinnedExplorerRootsSetting, setPinnedExplorerRootsSetting, setPinnedExplorerRootSetting, watchPinnedExplorerRootsSetting, getActiveGitReposSetting, setActiveGitRepoSetting, } from '../utils/settings.js';
31
34
  import { loadContextDraft, saveContextDraft } from '../utils/contextDraft.js';
32
35
  import { getOnboardingServerUrl } from '../onboardingServer.js';
@@ -51,6 +54,7 @@ import { CollaborationStore } from '../agent/collaborationStore.js';
51
54
  import { COLLAB_NAME_FORBIDDEN, formatCollaborationDelivery } from '../agent/collaborationPrompt.js';
52
55
  import { ambiguousIdMessage } from '../agent/collaborationProtocol.js';
53
56
  import { buildCollaborationSpawnCommand, resolveCollaborationSpawnMode } from '../agent/collaborationSpawn.js';
57
+ import { resolveCollaborationLaunch, launchProfileKey } from '../agent/collaborationLaunchProfiles.js';
54
58
  import { SessionSearchStore } from '../agent/sessionSearchStore.js';
55
59
  import { NativeSessionSearch } from '../agent/nativeSessionSearch.js';
56
60
  import { CollaborationError } from '../agent/collaborationProtocol.js';
@@ -435,7 +439,16 @@ async function flushClientStateBroadcast() {
435
439
  }
436
440
  }
437
441
  }
442
+ const integrationSessionObservers = new Set();
443
+ let integrationDeliveryGuard;
444
+ function notifyIntegrationSessions() { for (const listener of integrationSessionObservers) {
445
+ try {
446
+ listener();
447
+ }
448
+ catch { /* Observation failure does not affect terminal clients. */ }
449
+ } }
438
450
  function broadcastClientState() {
451
+ notifyIntegrationSessions();
439
452
  if (broadcastClientStateTimer) {
440
453
  return;
441
454
  }
@@ -1401,7 +1414,12 @@ function orchestrationSessionSnapshot(record) {
1401
1414
  sessionId: record.sessionId,
1402
1415
  agentNativeSessionId: binding?.pane ? binding.pane.nativeSessionId : binding?.nativeSessionId ?? backend?.agentSession?.sessionId ?? record.agentResume?.sessionId ?? null,
1403
1416
  backendSessionId: backendId ?? null,
1404
- name: record.name,
1417
+ name: collaborationSessionDisplayName({ ...record,
1418
+ activeProgram: backend?.activeProgram?.command ?? record.activeProgram,
1419
+ shellTitle: backend?.lastOscTitle ?? record.shellTitle,
1420
+ cwd: backend?.cwd ?? record.cwd,
1421
+ agent: agent ? { displayName: agent.displayName } : null,
1422
+ }),
1405
1423
  cwd: backend?.cwd ?? record.cwd ?? '',
1406
1424
  agent: agent ? { slug: agent.slug, displayName: agent.displayName } : null,
1407
1425
  status: route.state === 'unchecked' && terminalConnected ? 'terminal-connected' : route.state,
@@ -1642,6 +1660,11 @@ async function resolveCollaborationRoute(frontendSessionId) {
1642
1660
  let record = globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId);
1643
1661
  if (!record)
1644
1662
  return { state: 'offline', reason: 'SESSION_REMOVED' };
1663
+ if (record.tmuxSessionName?.startsWith('wt-integration-') && !integrationDeliveryGuard)
1664
+ return { state: 'unavailable', reason: 'INTEGRATION_RUNTIME_UNAVAILABLE' };
1665
+ const startup = await integrationDeliveryGuard?.(frontendSessionId);
1666
+ if (startup && !startup.allowed)
1667
+ return { state: 'recovering', reason: startup.reason ?? 'SESSION_STARTUP_INPUT_PENDING' };
1645
1668
  let backend = resolveOrchestrationBackend(record);
1646
1669
  let binding = collaborationRouting.get(frontendSessionId) ?? {
1647
1670
  sessionId: record.sessionId, backendSessionId: null, mode: record.mode, tmuxSessionName: record.tmuxSessionName,
@@ -1729,7 +1752,7 @@ function deliverCollaborationInboxWhenAgentReady(frontendSessionId) {
1729
1752
  collaborationDeliveryWorker.wake(frontendSessionId);
1730
1753
  }
1731
1754
  async function spawnCollaborationAgentSession(req, group, sourceSessionId, input, bootstrapRole) {
1732
- const agentSlug = typeof input.agentSlug === 'string' ? input.agentSlug.trim().toLowerCase() : '';
1755
+ const { agentSlug, profile } = resolveCollaborationLaunch(group, input);
1733
1756
  const launchers = await listDetectedAgentLaunchers();
1734
1757
  const launcher = launchers.find((candidate) => candidate.slug === agentSlug);
1735
1758
  if (!launcher)
@@ -1751,7 +1774,7 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1751
1774
  }
1752
1775
  const requestedCwd = typeof input.cwd === 'string' ? input.cwd.trim() : '';
1753
1776
  const opened = await openInventorySession(req, {
1754
- name: requestedName || `${launcher.displayName} · ${group.name}`,
1777
+ name: requestedName || `${profile?.name ?? launcher.displayName} · ${group.name}`,
1755
1778
  customName: true,
1756
1779
  mode,
1757
1780
  cwd: requestedCwd || fallbackRecord?.cwd || undefined,
@@ -1780,7 +1803,9 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1780
1803
  });
1781
1804
  if (bootstrapRole)
1782
1805
  collaborationStore.setRole({ groupId: group.id, sessionId: frontendSessionId, role: bootstrapRole });
1783
- writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: launcher.command })}\r`);
1806
+ if (profile)
1807
+ collaborationStore.setMemberLaunchProfile(group.id, frontendSessionId, profile);
1808
+ writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: profile?.command ?? launcher.command })}\r`);
1784
1809
  const requestedTask = typeof input.task === 'string' ? input.task.trim().slice(0, 20_000) : '';
1785
1810
  collaborationStore.send({
1786
1811
  groupId: updatedGroup.id,
@@ -1792,7 +1817,154 @@ async function spawnCollaborationAgentSession(req, group, sourceSessionId, input
1792
1817
  setTimeout(() => {
1793
1818
  deliverCollaborationInboxWhenAgentReady(frontendSessionId);
1794
1819
  }, 300).unref?.();
1795
- return { group: updatedGroup, session: orchestrationSessionSnapshot(globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId)) };
1820
+ return { group: collaborationStore.getGroup(group.id), session: orchestrationSessionSnapshot(globalSessionState.sessions.find((candidate) => candidate.sessionId === frontendSessionId)) };
1821
+ }
1822
+ /** Restricted session adapter: only preconfigured argv and the exact owned
1823
+ * terminal can be launched; no remote drive or arbitrary shell commands. */
1824
+ async function integrationPaneIsIdleShell(pane) {
1825
+ if (!pane.isShell)
1826
+ return false;
1827
+ try {
1828
+ const { stdout } = await execFileAsync('ps', ['-p', String(pane.panePid), '-o', 'pgid=,tpgid=,args='], { timeout: 3000, maxBuffer: 16384 });
1829
+ const row = stdout.trim().match(/^(\d+)\s+(\d+)\s+(.+)$/);
1830
+ if (!row || row[1] !== row[2])
1831
+ return false;
1832
+ const argv = splitCommandToArgv(row[3]);
1833
+ const command = normalizeProgramName(argv[0]?.replace(/^-/, ''))?.toLowerCase();
1834
+ return !!command && shellNamesBackend.has(command) && argv.slice(1).every(arg => ['-l', '-i', '-il', '-li', '--login', '--interactive'].includes(arg));
1835
+ }
1836
+ catch {
1837
+ return false;
1838
+ }
1839
+ }
1840
+ function integrationTerminalRecord(record) {
1841
+ const terminal = globalSessionState.sessions.find(s => s.sessionId === record.session_id);
1842
+ if (terminal && (terminal.mode !== 'tmux' || terminal.tmuxSessionName !== `wt-integration-${record.session_id}`))
1843
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Owned TD terminal binding changed', 409);
1844
+ return terminal;
1845
+ }
1846
+ export const integrationSessionAdapter = {
1847
+ subscribe(listener) { integrationSessionObservers.add(listener); return () => { integrationSessionObservers.delete(listener); }; },
1848
+ registerDeliveryGuard(guard) { integrationDeliveryGuard = guard; return () => { if (integrationDeliveryGuard === guard)
1849
+ integrationDeliveryGuard = undefined; }; },
1850
+ async capture(record) {
1851
+ const observed = await integrationSessionAdapter.inspect(record);
1852
+ if (!observed.exists || !observed.running || observed.agentSlug !== record.agent_slug || !record.terminal_binding
1853
+ || record.agent_native_session_id && observed.nativeId && record.agent_native_session_id !== observed.nativeId) {
1854
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Startup input observation requires the original Agent pane', 409);
1855
+ }
1856
+ return captureTmuxPaneText(runTmux, record.terminal_binding);
1857
+ },
1858
+ async inspect(record) {
1859
+ const terminal = integrationTerminalRecord(record);
1860
+ if (!terminal)
1861
+ return { exists: false, running: false, shell: false, agentSlug: null, nativeId: null };
1862
+ const binding = { sessionId: record.session_id, backendSessionId: terminal.backendSessionId,
1863
+ mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: record.agent_slug,
1864
+ nativeSessionId: record.agent_native_session_id, pane: record.terminal_binding ?? null };
1865
+ const inspected = await inspectCollaborationTmux(binding);
1866
+ if (inspected.state === 'offline')
1867
+ return { exists: false, running: false, shell: false, agentSlug: null, nativeId: null };
1868
+ if (inspected.state !== 'ready' || !inspected.pane)
1869
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Owned tmux pane cannot be uniquely verified', 409);
1870
+ const pane = inspected.pane;
1871
+ const layout = await getTmuxLayout(terminal.tmuxSessionName);
1872
+ if (layout.windows.flatMap(window => window.panes).length !== 1 || layout.activePaneId !== pane.paneId)
1873
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Integration native binding requires the single owned pane', 409);
1874
+ const backend = terminal.backendSessionId ? terminalSessions.get(terminal.backendSessionId) : null;
1875
+ // Hook evidence is fresh process evidence only on the single owned pane.
1876
+ // A recovered last-known UUID must not prove a new launch succeeded.
1877
+ const nativeId = pane.agentSlug ? pane.nativeSessionId ?? (backend?.agent?.slug === pane.agentSlug && backend.agentSession?.rich && !backend.agentResumeRecovered ? backend.agentSession.sessionId : null) ?? null : null;
1878
+ if (nativeId && (nativeId.length > 256 || /[\x00-\x1f\x7f]/.test(nativeId)))
1879
+ integrationError('NATIVE_SESSION_ID_INVALID', 'Observed native session id is invalid', 409);
1880
+ const route = collaborationRouting.get(record.session_id);
1881
+ if (nativeId && (!record.agent_native_session_id || record.agent_native_session_id === nativeId) && route?.pane
1882
+ && route.pane.paneId === pane.paneId && route.pane.panePid === pane.panePid && route.pane.serverPid === pane.serverPid && route.pane.sessionId === pane.sessionId
1883
+ && route.pane.nativeSessionId !== nativeId)
1884
+ collaborationRouting.bind({ ...route, nativeSessionId: nativeId, pane: { ...route.pane, nativeSessionId: nativeId } });
1885
+ return { exists: true, running: Boolean(pane.agentSlug), shell: await integrationPaneIsIdleShell(pane), agentSlug: pane.agentSlug || null, nativeId };
1886
+ },
1887
+ async create(record, prepared) {
1888
+ await listDetectedAgentLaunchers();
1889
+ if (!agentBySlug(record.agent_slug))
1890
+ integrationError('COLLAB_AGENT_UNAVAILABLE', 'Configured agent plugin is not installed');
1891
+ if (integrationTerminalRecord(record))
1892
+ integrationError('SESSION_CREATE_OUTCOME_UNKNOWN', 'Creation intent already has a terminal; inspect it instead of relaunching', 409);
1893
+ await launchIntegrationTerminal(record, false, prepared);
1894
+ },
1895
+ async restore(record, prepared) {
1896
+ await listDetectedAgentLaunchers();
1897
+ const agent = agentBySlug(record.agent_slug);
1898
+ if (!record.agent_native_session_id || !agent || !buildResumeCommand(agent, record.agent_native_session_id, null))
1899
+ integrationError('EXACT_RESUME_UNSUPPORTED', 'Agent plugin must support exact native resume');
1900
+ if (findActiveAgentResumeOwner('', { slug: record.agent_slug, nativeSessionId: record.agent_native_session_id, command: '' }))
1901
+ integrationError('NATIVE_SESSION_ALREADY_RUNNING', 'Native Agent conversation is already running', 409);
1902
+ await launchIntegrationTerminal(record, true, prepared);
1903
+ },
1904
+ };
1905
+ async function launchIntegrationTerminal(record, restoring, prepared) {
1906
+ await collaborationDeliveryWorker.reconfigure(record.session_id, async () => {
1907
+ const group = collaborationStore.getGroup(record.group_id);
1908
+ if (!group || group.deleted)
1909
+ integrationError('TASK_GROUP_NOT_FOUND', 'Integration group no longer exists', 404);
1910
+ const original = await integrationSessionAdapter.inspect(record);
1911
+ if (!original.exists) {
1912
+ let tmuxExists = false;
1913
+ try {
1914
+ await runTmux(['has-session', '-t', `=wt-integration-${record.session_id}`]);
1915
+ tmuxExists = true;
1916
+ }
1917
+ catch (error) {
1918
+ if (!/can't find session|no server running|no sessions|error connecting.*No such file/i.test(getErrorMessage(error)))
1919
+ throw error;
1920
+ }
1921
+ if (tmuxExists)
1922
+ integrationError('SESSION_IDENTITY_MISMATCH', 'A terminal with this name exists without the owned binding', 409);
1923
+ }
1924
+ const opened = await openInventorySession({}, { preferredFrontendSessionId: record.session_id,
1925
+ mode: 'tmux', tmuxSessionName: `wt-integration-${record.session_id}`, cwd: record.cwd,
1926
+ name: `${record.agent_slug} · ${group.name}`, customName: true });
1927
+ if (opened.session.sessionId !== record.session_id)
1928
+ integrationError('SESSION_IDENTITY_MISMATCH', 'Terminal id changed', 409);
1929
+ const terminal = integrationTerminalRecord(record);
1930
+ const backend = terminalSessions.get(opened.terminalSession.sessionId);
1931
+ if (!backend)
1932
+ integrationError('SESSION_BACKEND_UNAVAILABLE', 'Owned terminal backend is unavailable', 503);
1933
+ const inspected = await inspectCollaborationTmux({ sessionId: record.session_id, backendSessionId: opened.terminalSession.sessionId,
1934
+ mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: null, nativeSessionId: null,
1935
+ // A recreated tmux may get a new pane only during explicit exact resume.
1936
+ pane: original.exists ? record.terminal_binding ?? null : null }, null, true);
1937
+ if (inspected.state !== 'ready' || !inspected.pane || !await integrationPaneIsIdleShell(inspected.pane))
1938
+ integrationError('SESSION_TARGET_NOT_SHELL', 'Refusing to launch into an unverified shell', 409);
1939
+ const pane = inspected.pane;
1940
+ const pinned = { serverPid: pane.serverPid, sessionId: pane.sessionId,
1941
+ paneId: pane.paneId, panePid: pane.panePid, agentSlug: record.agent_slug, nativeSessionId: record.agent_native_session_id };
1942
+ prepared(pinned); // Must persist before the command enters the terminal.
1943
+ collaborationRouting.bind({ sessionId: record.session_id, backendSessionId: opened.terminalSession.sessionId,
1944
+ mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: record.agent_slug, nativeSessionId: record.agent_native_session_id, pane: pinned });
1945
+ const latest = collaborationStore.getGroup(group.id);
1946
+ if (!latest || latest.deleted)
1947
+ integrationError('TASK_GROUP_NOT_FOUND', 'Integration group changed', 409);
1948
+ collaborationStore.save({ id: latest.id, name: latest.name, sessionIds: [...new Set([...latest.sessionIds, record.session_id])] });
1949
+ if (restoring)
1950
+ upsertGlobalSessionRecord({ ...terminal, agentResume: { slug: record.agent_slug, sessionId: record.agent_native_session_id,
1951
+ launchArgv: [record.profile.executable, ...record.profile.argv], updatedAt: Date.now() } });
1952
+ await persistGlobalStateNow();
1953
+ // Recheck the actual pinned shell immediately before writing. This cannot
1954
+ // use an active-pane target which might have changed during preparation.
1955
+ const shell = await inspectCollaborationTmux({ sessionId: record.session_id, backendSessionId: opened.terminalSession.sessionId,
1956
+ mode: 'tmux', tmuxSessionName: terminal.tmuxSessionName, agentSlug: null, nativeSessionId: null, pane: pinned });
1957
+ if (shell.state !== 'ready' || !shell.pane || !await integrationPaneIsIdleShell(shell.pane))
1958
+ integrationError('SESSION_TARGET_NOT_SHELL', 'Owned shell changed before launch', 409);
1959
+ // This owned pane is a verified shell; clear stale rich state before a new
1960
+ // process starts, so its new SessionStart must supply the native binding.
1961
+ backend.agentSession = null;
1962
+ backend.agent = null;
1963
+ backend.agentResumeRecovered = false;
1964
+ await runTmux(['send-keys', '-t', pinned.paneId, '-l', integrationLaunchCommand(record, restoring)]);
1965
+ await runTmux(['send-keys', '-t', pinned.paneId, 'Enter']);
1966
+ broadcastClientState();
1967
+ });
1796
1968
  }
1797
1969
  const preparingTaskWorkers = new Map();
1798
1970
  /** Dedicated persistent terminals leave existing member sessions and the user's checkout untouched. */
@@ -1806,10 +1978,16 @@ export function prepareCollaborationTaskWorker(task, template, dependencies, ser
1806
1978
  if (!source || template.serviceId !== service.descriptor().serviceId)
1807
1979
  throw new Error('执行成员当前不可用,请协调者重新分派');
1808
1980
  const snapshot = orchestrationSessionSnapshot(source);
1981
+ const inheritedProfile = collaborationStore.getGroup(task.groupId)?.memberLaunchProfiles?.[template.sessionId];
1809
1982
  const slug = snapshot.agent?.slug ?? source.agentResume?.slug;
1810
1983
  const launcher = (await listDetectedAgentLaunchers()).find(a => a.slug === slug);
1811
1984
  if (!launcher || !source.cwd)
1812
1985
  throw new Error('独立代码任务需要有项目目录的 Agent 成员,请选择可用成员');
1986
+ if (inheritedProfile) {
1987
+ if (inheritedProfile.agentSlug !== launcher.slug)
1988
+ throw new Error('执行成员的启动方案与当前 Agent 不一致,请重新分派');
1989
+ resolveCollaborationLaunch({ launchProfiles: [inheritedProfile] }, { launchProfileId: inheritedProfile.id, agentSlug: launcher.slug });
1990
+ }
1813
1991
  const workspace = await prepareTaskWorkspace(task, source.cwd, dependencies, (dependency, repository) => importTaskDependency(task, dependency, repository, service, readDependency));
1814
1992
  await pathValidator.allowSessionCwd(workspace.cwd);
1815
1993
  const existing = globalSessionState.sessions.find(s => s.cwd === workspace.cwd);
@@ -1835,7 +2013,7 @@ export function prepareCollaborationTaskWorker(task, template, dependencies, ser
1835
2013
  const temporary = `${launchFile}.${process.pid}.tmp`;
1836
2014
  await fs.promises.writeFile(temporary, JSON.stringify({ sessionId: record.sessionId, backendId: opened.terminalSession.sessionId }), { mode: 0o600 });
1837
2015
  await fs.promises.rename(temporary, launchFile);
1838
- writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: launcher.command })}\r`);
2016
+ writeTerminalInput(backend, `${buildCollaborationSpawnCommand({ slug: launcher.slug, command: inheritedProfile?.command ?? launcher.command })}\r`);
1839
2017
  }
1840
2018
  const group = collaborationStore.getGroup(task.groupId);
1841
2019
  if (!group || group.deleted)
@@ -1843,6 +2021,8 @@ export function prepareCollaborationTaskWorker(task, template, dependencies, ser
1843
2021
  if (!group.sessionIds.includes(record.sessionId))
1844
2022
  await service.save({ id: group.id, name: group.name,
1845
2023
  sessionIds: [...group.sessionIds, record.sessionId], expectedUpdatedAt: group.updatedAt });
2024
+ if (inheritedProfile)
2025
+ collaborationStore.setMemberLaunchProfile(group.id, record.sessionId, inheritedProfile);
1846
2026
  return { sessionId: record.sessionId, workspace };
1847
2027
  })().finally(() => preparingTaskWorkers.delete(key));
1848
2028
  preparingTaskWorkers.set(key, operation);
@@ -3192,6 +3372,7 @@ function broadcastAgentStatus(sessionId, session, force = false) {
3192
3372
  if (!force && previousSnapshot === snapshot)
3193
3373
  return;
3194
3374
  lastAgentStatusSnapshots.set(sessionId, snapshot);
3375
+ notifyIntegrationSessions();
3195
3376
  broadcastEvent(sessionId, payload);
3196
3377
  const previous = previousSnapshot
3197
3378
  ? JSON.parse(previousSnapshot)
@@ -5802,26 +5983,28 @@ router.post('/operations/collaboration-groups/:groupId/team', async (req, res) =
5802
5983
  return res.status(404).json({ error: '协作组不存在' });
5803
5984
  if (group.federated)
5804
5985
  throw new Error('跨服务组请先从成员设置添加 Agent');
5805
- const agentSlug = typeof req.body?.agentSlug === 'string' ? req.body.agentSlug : '';
5986
+ const { agentSlug, profile } = resolveCollaborationLaunch(group, req.body ?? {});
5806
5987
  if (!(await listDetectedAgentLaunchers()).some(agent => agent.slug === agentSlug))
5807
5988
  throw new Error('所选 Agent 当前不可用');
5808
5989
  if (typeof req.body?.cwd !== 'string' || !req.body.cwd.trim())
5809
5990
  throw new Error('请选择工作目录');
5810
5991
  const cwd = await resolveWorkingDirectory(req, req.body.cwd);
5811
5992
  const previous = preparingTeams.get(group.id) ?? Promise.resolve();
5812
- const operation = previous.catch(() => { }).then(() => ensureTeam({ agentSlug, cwd,
5993
+ const operation = previous.catch(() => { }).then(() => ensureTeam({ agentSlug, cwd, launchProfileKey: launchProfileKey(profile),
5813
5994
  members: () => {
5814
5995
  const current = collaborationStore.getGroup(group.id);
5815
5996
  if (!current || current.deleted)
5816
5997
  throw new Error('协作组已删除');
5998
+ if (profile && launchProfileKey(current.launchProfiles?.find(p => p.id === profile.id)) !== launchProfileKey(profile))
5999
+ throw new Error('启动方案已变更,请重新开始协作');
5817
6000
  return globalSessionState.sessions.filter(record => current.sessionIds.includes(record.sessionId))
5818
- .map(record => ({ id: record.sessionId, cwd: record.cwd, role: current.roles?.[record.sessionId], agentSlug: orchestrationSessionSnapshot(record).agent?.slug }));
6001
+ .map(record => ({ id: record.sessionId, cwd: record.cwd, role: current.roles?.[record.sessionId], agentSlug: orchestrationSessionSnapshot(record).agent?.slug, launchProfileKey: launchProfileKey(current.memberLaunchProfiles?.[record.sessionId]) }));
5819
6002
  },
5820
6003
  spawn: async (role) => {
5821
6004
  const current = collaborationStore.getGroup(group.id);
5822
6005
  if (!current || current.deleted)
5823
6006
  throw new Error('协作组已删除');
5824
- const result = await spawnCollaborationAgentSession(req, current, null, { agentSlug, cwd, mode: 'tmux', name: role.startsWith('自动协调者') ? `协调 ${group.name}` : `执行与评审 ${group.name}` }, role);
6007
+ const result = await spawnCollaborationAgentSession(req, current, null, { agentSlug, launchProfileId: profile?.id ?? '', cwd, mode: 'tmux', name: role.startsWith('自动协调者') ? `协调 ${group.name}` : `执行与评审 ${group.name}` }, role);
5825
6008
  return result.session.sessionId;
5826
6009
  },
5827
6010
  }));
@@ -6633,7 +6816,7 @@ router.put('/toolbar-presets', (req, res) => {
6633
6816
  async function getSettingsPayload() {
6634
6817
  const localAccess = localAccessManager.getState();
6635
6818
  const interfaces = await Promise.all(localAccess.interfaces.map(async (entry) => {
6636
- const url = `${localAccess.httpsEnabled ? 'https' : 'http'}://${entry.address}:9834`;
6819
+ const url = localAccessInterfaceUrl(localAccess.url, entry.address);
6637
6820
  const qrDataUrl = await QRCode.toDataURL(url, {
6638
6821
  margin: 1,
6639
6822
  width: 132,
@@ -6669,7 +6852,7 @@ async function getSettingsPayload() {
6669
6852
  localAccess: {
6670
6853
  ...localAccess,
6671
6854
  interfaces,
6672
- onboardingUrl: getOnboardingServerUrl() ?? null,
6855
+ onboardingUrl: localAccess.status === 'loopback-only' ? null : getOnboardingServerUrl() ?? null,
6673
6856
  },
6674
6857
  };
6675
6858
  }
@@ -11,7 +11,26 @@ function normalizeQuestionName(name) {
11
11
  return name.endsWith('.') ? name.slice(0, -1).toLowerCase() : name.toLowerCase();
12
12
  }
13
13
  export function isLoopbackHost(host) {
14
- return LOCALHOST_NAMES.has(host) || host.startsWith('127.');
14
+ const normalized = host.replace(/^\[|\]$/g, '').toLowerCase();
15
+ return LOCALHOST_NAMES.has(normalized) || normalized.startsWith('127.') || normalized.startsWith('::ffff:127.');
16
+ }
17
+ export function localAccessOrigin(host, port, scheme) {
18
+ const hostname = host.includes(':') && !host.startsWith('[') ? `[${host}]` : host;
19
+ return new URL(`${scheme}://${hostname}:${port}`).origin;
20
+ }
21
+ export function localAccessInterfaceUrl(serviceUrl, address) {
22
+ const origin = new URL(serviceUrl);
23
+ origin.hostname = address.includes(':') && !address.startsWith('[') ? `[${address}]` : address;
24
+ return origin.origin;
25
+ }
26
+ function getBoundLanIPv4Interfaces(host) {
27
+ if (isLoopbackHost(host))
28
+ return [];
29
+ const interfaces = getLanIPv4Interfaces();
30
+ if (host === '0.0.0.0' || host === '::' || host === '[::]')
31
+ return interfaces;
32
+ const address = host.replace(/^::ffff:/, '');
33
+ return interfaces.filter((entry) => entry.address === address);
15
34
  }
16
35
  function interfaceLabel(name) {
17
36
  if (name === 'en0')
@@ -47,18 +66,19 @@ export function getLanIPv4Addresses() {
47
66
  }
48
67
  function buildState(setting, options, status, reason) {
49
68
  const hostname = hostnameForName(setting.name);
50
- const interfaces = getLanIPv4Interfaces();
69
+ const interfaces = getBoundLanIPv4Interfaces(options.host);
51
70
  const lanAddresses = interfaces.map((entry) => entry.address);
52
71
  const onboardingHost = lanAddresses[0] ?? null;
53
- const fallbackHostname = onboardingHost ?? hostname;
72
+ const wildcardHost = options.host === '0.0.0.0' || options.host === '::' || options.host === '[::]';
73
+ const fallbackHostname = onboardingHost ?? (wildcardHost ? hostname : options.host);
54
74
  return {
55
75
  name: setting.name,
56
76
  source: setting.source,
57
77
  hostname,
58
78
  fallbackHostname,
59
- url: `${options.scheme}://${hostname}:${options.port}`,
60
- fallbackUrl: `${options.scheme}://${fallbackHostname}:${options.port}`,
61
- onboardingUrl: onboardingHost ? `http://${onboardingHost}:${options.onboardingPort ?? options.port}/ca` : null,
79
+ url: localAccessOrigin(hostname, options.port, options.scheme),
80
+ fallbackUrl: localAccessOrigin(fallbackHostname, options.port, options.scheme),
81
+ onboardingUrl: onboardingHost ? `${localAccessOrigin(onboardingHost, options.onboardingPort ?? options.port, 'http')}/ca` : null,
62
82
  status,
63
83
  reason,
64
84
  httpsEnabled: options.scheme === 'https',
@@ -84,7 +104,7 @@ export class LocalAccessManager {
84
104
  this.options = options;
85
105
  await this.stop();
86
106
  let setting = await getLocalAccessSettingAsync();
87
- const lanAddresses = getLanIPv4Addresses();
107
+ const lanAddresses = getBoundLanIPv4Interfaces(options.host).map((entry) => entry.address);
88
108
  if (isLoopbackHost(options.host)) {
89
109
  this.state = buildState(setting, options, 'loopback-only', 'Server is bound to loopback only.');
90
110
  return this.state;
@@ -0,0 +1,53 @@
1
+ export const DEFAULT_SESSION_DISPLAY_SHELL_NAMES = new Set([
2
+ 'bash',
3
+ 'zsh',
4
+ 'fish',
5
+ 'sh',
6
+ 'dash',
7
+ 'ksh',
8
+ 'tcsh',
9
+ 'csh',
10
+ 'nu',
11
+ ]);
12
+ export function getCwdLeafName(cwd) {
13
+ if (!cwd)
14
+ return null;
15
+ if (cwd === '/')
16
+ return '/';
17
+ const segments = cwd.replace(/\/+$/, '').split('/');
18
+ return segments[segments.length - 1] || cwd;
19
+ }
20
+ export function getSessionDisplayLines(session, activeProgram, cwd, shellNames = DEFAULT_SESSION_DISPLAY_SHELL_NAMES, shellTitle = null, promptState = null) {
21
+ if (session.customName)
22
+ return { primary: session.name, secondary: getCwdLeafName(cwd) };
23
+ // Shell integration (OSC 2) provides real-time title: command name when running,
24
+ // cwd when idle. This is faster and more accurate than server-side process polling.
25
+ if (shellTitle) {
26
+ const cwdLeaf = getCwdLeafName(cwd);
27
+ const titleLooksLikeCwd = shellTitle === cwd || shellTitle === cwdLeaf;
28
+ // If the shell reports a running state, the title is the command name.
29
+ if (promptState !== 'idle' && !shellNames.has(shellTitle) && !titleLooksLikeCwd) {
30
+ return { primary: shellTitle, secondary: cwdLeaf };
31
+ }
32
+ // If idle, the title is typically the cwd — fall through to show cwd leaf.
33
+ }
34
+ if (activeProgram && !shellNames.has(activeProgram)) {
35
+ return { primary: activeProgram, secondary: getCwdLeafName(cwd) };
36
+ }
37
+ const dir = getCwdLeafName(cwd);
38
+ if (dir)
39
+ return { primary: dir, secondary: null };
40
+ return { primary: session.name, secondary: null };
41
+ }
42
+ export function getSessionDisplayName(session, activeProgram, cwd, shellNames = DEFAULT_SESSION_DISPLAY_SHELL_NAMES, shellTitle = null, promptState = null) {
43
+ return getSessionDisplayLines(session, activeProgram, cwd, shellNames, shellTitle, promptState).primary;
44
+ }
45
+ /** Resolve the same title hints the session sidebar uses, without exposing route IDs. */
46
+ export function collaborationSessionDisplayName(session) {
47
+ const cwdLeaf = getCwdLeafName(session.cwd ?? null);
48
+ const title = session.shellTitle === session.cwd || session.shellTitle === cwdLeaf ? null : session.shellTitle ?? null;
49
+ const name = getSessionDisplayName(session, session.activeProgram ?? null, null, DEFAULT_SESSION_DISPLAY_SHELL_NAMES, title);
50
+ return !name.trim() || /^(?:tmux:|remote:|wt-)/i.test(name) || name === session.sessionId
51
+ ? session.agent?.displayName || cwdLeaf || '终端会话'
52
+ : name;
53
+ }