@band-app/server 0.20.1 → 0.21.0

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 (162) hide show
  1. package/dist/client/assets/DockviewBrowserContainer-_omnSiyJ.js +5 -0
  2. package/dist/client/assets/DockviewTerminalContainer-DAn_WCfx.js +2 -0
  3. package/dist/client/assets/TerminalPanel-CNPsPif8.js +5 -0
  4. package/dist/client/assets/{_basePickBy-Dcf1Y8Iq.js → _basePickBy-DtyMrmhl.js} +1 -1
  5. package/dist/client/assets/{_baseUniq-Cy98IGsx.js → _baseUniq-BJUkdL_v.js} +1 -1
  6. package/dist/client/assets/{arc-rOBphWj1.js → arc-yAV3EAnY.js} +1 -1
  7. package/dist/client/assets/{architectureDiagram-VXUJARFQ-C54lj_mp.js → architectureDiagram-VXUJARFQ-B3FpBxQF.js} +1 -1
  8. package/dist/client/assets/{blockDiagram-VD42YOAC-IXpkKl99.js → blockDiagram-VD42YOAC-3LlBLqQC.js} +1 -1
  9. package/dist/client/assets/{c4Diagram-YG6GDRKO-eHkAJFz1.js → c4Diagram-YG6GDRKO-Be5RpvjZ.js} +1 -1
  10. package/dist/client/assets/channel-DbN6Vg7w.js +1 -0
  11. package/dist/client/assets/{chunk-4BX2VUAB-BVtvPQLw.js → chunk-4BX2VUAB-CISDQxrq.js} +1 -1
  12. package/dist/client/assets/{chunk-55IACEB6-DWUF7TBt.js → chunk-55IACEB6-BfU__3ET.js} +1 -1
  13. package/dist/client/assets/{chunk-B4BG7PRW-BT2NV-OP.js → chunk-B4BG7PRW-D4iHXw8l.js} +1 -1
  14. package/dist/client/assets/{chunk-DI55MBZ5-Cg5CF9C8.js → chunk-DI55MBZ5-BAdhjTka.js} +1 -1
  15. package/dist/client/assets/{chunk-FMBD7UC4-B0SYeHBH.js → chunk-FMBD7UC4-Zwu4-L0P.js} +1 -1
  16. package/dist/client/assets/{chunk-QN33PNHL-C5tEKH2s.js → chunk-QN33PNHL-DxMovsgL.js} +1 -1
  17. package/dist/client/assets/{chunk-QZHKN3VN-B3eOtTKT.js → chunk-QZHKN3VN-vrDNXKJS.js} +1 -1
  18. package/dist/client/assets/{chunk-TZMSLE5B-C2LU8iG2.js → chunk-TZMSLE5B-CX92zDel.js} +1 -1
  19. package/dist/client/assets/classDiagram-2ON5EDUG-BegLJbQe.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-WZHVMYZB-BegLJbQe.js +1 -0
  21. package/dist/client/assets/clone-Cl7gVEL3.js +1 -0
  22. package/dist/client/assets/{cose-bilkent-S5V4N54A-DMEstRG3.js → cose-bilkent-S5V4N54A-GNlGGpMz.js} +1 -1
  23. package/dist/client/assets/{dagre-6UL2VRFP-Dnk33exg.js → dagre-6UL2VRFP-p1fgRXjW.js} +1 -1
  24. package/dist/client/assets/{diagram-PSM6KHXK-mrXKTY_T.js → diagram-PSM6KHXK-CYtWPBH-.js} +1 -1
  25. package/dist/client/assets/{diagram-QEK2KX5R-BzHK-hsq.js → diagram-QEK2KX5R-Cgd-_Ub3.js} +1 -1
  26. package/dist/client/assets/{diagram-S2PKOQOG-CQCxQKV-.js → diagram-S2PKOQOG-DAs62NY3.js} +1 -1
  27. package/dist/client/assets/{erDiagram-Q2GNP2WA-BPDJfava.js → erDiagram-Q2GNP2WA-DBI_1PZQ.js} +1 -1
  28. package/dist/client/assets/{flowDiagram-NV44I4VS-C6Mmdoua.js → flowDiagram-NV44I4VS-C8JqBNNX.js} +1 -1
  29. package/dist/client/assets/{ganttDiagram-JELNMOA3-DLbgXlJh.js → ganttDiagram-JELNMOA3-B_NTSbsU.js} +1 -1
  30. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-DVLRTDa6.js → gitGraphDiagram-V2S2FVAM-CSgrclqJ.js} +1 -1
  31. package/dist/client/assets/{graph-Cwyvupsz.js → graph-CnuI3kx8.js} +1 -1
  32. package/dist/client/assets/{highlighted-body-B3W2YXNL-C0bhSLak.js → highlighted-body-B3W2YXNL-B0miGNm_.js} +1 -1
  33. package/dist/client/assets/{index-DsTs1gei.js → index-7yDQgH1f.js} +1 -1
  34. package/dist/client/assets/{index-CbBtBBYr.js → index-B6S69IUm.js} +1 -1
  35. package/dist/client/assets/{index-FSq9CQql.js → index-BArE6nAN.js} +1 -1
  36. package/dist/client/assets/{index-8fmEfQXt.js → index-BOAi4k9G.js} +1 -1
  37. package/dist/client/assets/{index-CCvDsqEy.js → index-BWouWVU0.js} +1 -1
  38. package/dist/client/assets/{index-ERt8cxUV.js → index-BmMzlQLK.js} +1 -1
  39. package/dist/client/assets/{index-CqhJvfhF.js → index-Bz2VMYkX.js} +1 -1
  40. package/dist/client/assets/{index-CA4qMsBj.js → index-C4-1pvZ7.js} +1 -1
  41. package/dist/client/assets/{index-Bx_OaRaP.js → index-CmyTYJul.js} +1 -1
  42. package/dist/client/assets/{index-BzF5H3v-.js → index-CtkaVda1.js} +1 -1
  43. package/dist/client/assets/{index-UCQ1zVBi.js → index-D88tU2rQ.js} +1 -1
  44. package/dist/client/assets/{index-8qew1yXR.js → index-DSgvPpOw.js} +1 -1
  45. package/dist/client/assets/{index-fifqJXyx.js → index-DXAzUetQ.js} +1 -1
  46. package/dist/client/assets/{index-DWLuzOpi.js → index-DYeExVW-.js} +1 -1
  47. package/dist/client/assets/{index-BjRdyIjf.js → index-DtIW2F6f.js} +1 -1
  48. package/dist/client/assets/{index-BwEcNyXc.js → index-UiJjSfLA.js} +1 -1
  49. package/dist/client/assets/{index-CXNMB7pL.js → index-W_8A45Ak.js} +1 -1
  50. package/dist/client/assets/{index-BEfdqN9O.js → index-nNmyPk2g.js} +1 -1
  51. package/dist/client/assets/{infoDiagram-HS3SLOUP-7Hhl73vO.js → infoDiagram-HS3SLOUP-CsK1yEhl.js} +1 -1
  52. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-CJcXgH51.js → journeyDiagram-XKPGCS4Q-7ztemwUy.js} +1 -1
  53. package/dist/client/assets/{kanban-definition-3W4ZIXB7-CBsuk1vp.js → kanban-definition-3W4ZIXB7-Cre8PAMX.js} +1 -1
  54. package/dist/client/assets/{layout-ZjLAsNj-.js → layout-BM0hAxpp.js} +1 -1
  55. package/dist/client/assets/main-BgcIGjy5.css +1 -0
  56. package/dist/client/assets/{main-QmYiKgqv.js → main-p2Lo-pWV.js} +230 -230
  57. package/dist/client/assets/{mindmap-definition-VGOIOE7T-doqFtLjy.js → mindmap-definition-VGOIOE7T-BjEgocYT.js} +1 -1
  58. package/dist/client/assets/{pieDiagram-ADFJNKIX-Bzaqqvl9.js → pieDiagram-ADFJNKIX-C4RjN3hy.js} +1 -1
  59. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-DxzHu9fl.js → quadrantDiagram-AYHSOK5B-NEf3JRFz.js} +1 -1
  60. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-Cp3foAel.js → requirementDiagram-UZGBJVZJ-BeRnY69a.js} +1 -1
  61. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-BQx6TKI3.js → sankeyDiagram-TZEHDZUN-DVODsg78.js} +1 -1
  62. package/dist/client/assets/{sequenceDiagram-WL72ISMW-Cd_242bL.js → sequenceDiagram-WL72ISMW-D6joy57s.js} +1 -1
  63. package/dist/client/assets/{square-terminal-bliRzpRN.js → square-terminal-DHH8tUx5.js} +1 -1
  64. package/dist/client/assets/{stateDiagram-FKZM4ZOC-GZM9iqTD.js → stateDiagram-FKZM4ZOC-DsFp4qia.js} +1 -1
  65. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-Dgk5Hjv7.js +1 -0
  66. package/dist/client/assets/{timeline-definition-IT6M3QCI-D5mcm-Qu.js → timeline-definition-IT6M3QCI-0xcgjNhV.js} +1 -1
  67. package/dist/client/assets/{treemap-GDKQZRPO-CkKCE0F7.js → treemap-GDKQZRPO-BWb88BcP.js} +1 -1
  68. package/dist/client/assets/{workspace._workspaceId-CQVHqxcU.js → workspace._workspaceId-BGYd2hI-.js} +1 -1
  69. package/dist/client/assets/{workspace._workspaceId-DFvkHRHC.js → workspace._workspaceId-jOqDoJcM.js} +2 -2
  70. package/dist/client/assets/{xychartDiagram-PRI3JC2R-Djg2lfgU.js → xychartDiagram-PRI3JC2R--tkhYHwZ.js} +1 -1
  71. package/dist/openapi.json +85 -25
  72. package/dist/server/assets/{DockviewBrowserContainer-Btjtd2O1.js → DockviewBrowserContainer-bdNwZbjc.js} +62 -44
  73. package/dist/server/assets/{DockviewTerminalContainer-bMEUzx6R.js → DockviewTerminalContainer-B1Nw8LXB.js} +65 -46
  74. package/dist/server/assets/{TerminalPanel-DDazs1HR.js → TerminalPanel-Badqj0m0.js} +67 -11
  75. package/dist/server/assets/{_basePickBy-BR2ebl6H.js → _basePickBy-D8ok8_jI.js} +2 -2
  76. package/dist/server/assets/{_baseUniq-C7-_tYXk.js → _baseUniq--LQjrjoo.js} +1 -1
  77. package/dist/server/assets/_tanstack-start-manifest_v-CIcSNV55.js +4 -0
  78. package/dist/server/assets/{arc-CWFSWY_u.js → arc-UlCdTTPZ.js} +1 -1
  79. package/dist/server/assets/{architecture-7HQA4BMR-DDMO671Z.js → architecture-7HQA4BMR-g585WmZs.js} +6 -6
  80. package/dist/server/assets/{architectureDiagram-VXUJARFQ-vPxmruSN.js → architectureDiagram-VXUJARFQ-kdf4spX4.js} +6 -6
  81. package/dist/server/assets/{blockDiagram-VD42YOAC-DGV6m5iW.js → blockDiagram-VD42YOAC-XJWMoZPI.js} +6 -6
  82. package/dist/server/assets/{c4Diagram-YG6GDRKO-9PjJESuA.js → c4Diagram-YG6GDRKO-BULLTo2O.js} +2 -2
  83. package/dist/server/assets/{channel-DzyKDZfe.js → channel-N781S9-q.js} +1 -1
  84. package/dist/server/assets/{chunk-4BX2VUAB-MyrUiBmB.js → chunk-4BX2VUAB-D4MPtIqQ.js} +1 -1
  85. package/dist/server/assets/{chunk-55IACEB6-CJ4fKFif.js → chunk-55IACEB6-BsRaN4wq.js} +1 -1
  86. package/dist/server/assets/{chunk-B4BG7PRW-CKzqfTU-.js → chunk-B4BG7PRW-kuOFZXeP.js} +4 -4
  87. package/dist/server/assets/{chunk-DI55MBZ5-DrXLxcKs.js → chunk-DI55MBZ5-ccubr48T.js} +3 -3
  88. package/dist/server/assets/{chunk-FMBD7UC4-yeB6m7NE.js → chunk-FMBD7UC4-BNEgTZts.js} +1 -1
  89. package/dist/server/assets/{chunk-QN33PNHL-qCq8pCkn.js → chunk-QN33PNHL-gAa-_mPg.js} +1 -1
  90. package/dist/server/assets/{chunk-QZHKN3VN-CHvK5Ic5.js → chunk-QZHKN3VN-qid0EAJk.js} +1 -1
  91. package/dist/server/assets/{chunk-TZMSLE5B-wF9ZPcJp.js → chunk-TZMSLE5B-BAwrhrCM.js} +1 -1
  92. package/dist/server/assets/{classDiagram-v2-WZHVMYZB-D1OcdIXp.js → classDiagram-2ON5EDUG-D48G1fOA.js} +5 -5
  93. package/dist/server/assets/{classDiagram-2ON5EDUG-D1OcdIXp.js → classDiagram-v2-WZHVMYZB-D48G1fOA.js} +5 -5
  94. package/dist/server/assets/{clone-BH4YtRmr.js → clone-g6aLZKbC.js} +1 -1
  95. package/dist/server/assets/{cose-bilkent-S5V4N54A-BiP6P-09.js → cose-bilkent-S5V4N54A-GH832JBk.js} +1 -1
  96. package/dist/server/assets/{dagre-6UL2VRFP-BKfzYlJQ.js → dagre-6UL2VRFP-DCM_EeeJ.js} +6 -6
  97. package/dist/server/assets/{diagram-PSM6KHXK-BF6r9xQS.js → diagram-PSM6KHXK-Wsb4GT24.js} +7 -7
  98. package/dist/server/assets/{diagram-QEK2KX5R-CxL6qeVX.js → diagram-QEK2KX5R--ln7zI47.js} +6 -6
  99. package/dist/server/assets/{diagram-S2PKOQOG-CUKugrbt.js → diagram-S2PKOQOG-nDhXR9ui.js} +6 -6
  100. package/dist/server/assets/{erDiagram-Q2GNP2WA-CRPjeaHB.js → erDiagram-Q2GNP2WA-CMa2Pz-v.js} +4 -4
  101. package/dist/server/assets/{flowDiagram-NV44I4VS-CXnLZPl0.js → flowDiagram-NV44I4VS-4gEGHH9W.js} +5 -5
  102. package/dist/server/assets/{ganttDiagram-JELNMOA3-CP5EwGxj.js → ganttDiagram-JELNMOA3-BOS7aF_7.js} +1 -1
  103. package/dist/server/assets/{gitGraph-G5XIXVHT-UYMoyufq.js → gitGraph-G5XIXVHT-DPzSD5yq.js} +6 -6
  104. package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-CZNtwgUE.js → gitGraphDiagram-V2S2FVAM-CKZ8qTSA.js} +7 -7
  105. package/dist/server/assets/{graph-BB1_2Q0x.js → graph-CdCcTp1P.js} +2 -2
  106. package/dist/server/assets/{highlighted-body-B3W2YXNL-C6BqMnvu.js → highlighted-body-B3W2YXNL-Dmr6rOWq.js} +1 -1
  107. package/dist/server/assets/{index-lmhecPWc.js → index-3AJisjJ-.js} +2 -2
  108. package/dist/server/assets/{index-DH3a6-do.js → index-BQy_SzGG.js} +2 -2
  109. package/dist/server/assets/{index-Ct5-lZTn.js → index-BXNtERIJ.js} +2 -2
  110. package/dist/server/assets/{index-Bme4JhwA.js → index-Bvxb7XFW.js} +1 -1
  111. package/dist/server/assets/{index-Dqk2jQZ7.js → index-C4WwCpyx.js} +2 -2
  112. package/dist/server/assets/{index-DLEtsdeb.js → index-CZpP5Q96.js} +2 -2
  113. package/dist/server/assets/{index-BUm0x4GN.js → index-D7vNc-qo.js} +2 -2
  114. package/dist/server/assets/{index-BbUtF3L1.js → index-DAc69z6c.js} +2 -2
  115. package/dist/server/assets/{index-DrWaYPW7.js → index-DBfcn5gX.js} +2 -2
  116. package/dist/server/assets/{index-DsrV0B5O.js → index-DTBi6jO_.js} +5 -5
  117. package/dist/server/assets/{index-D5hMY11m.js → index-Ddp0lHMA.js} +4 -4
  118. package/dist/server/assets/{index-D49PP401.js → index-DinEbWse.js} +3 -3
  119. package/dist/server/assets/{index-CMxtCPk9.js → index-Dm8dBBAU.js} +2 -2
  120. package/dist/server/assets/{index-Bay77lf3.js → index-DtlVc4yR.js} +2 -2
  121. package/dist/server/assets/{index-DLV7EX0H.js → index-DzVgMYHM.js} +1 -1
  122. package/dist/server/assets/{index-BHQ8bMg_.js → index-VEnlzI7K.js} +3 -3
  123. package/dist/server/assets/{index-B5V3PU-n.js → index-gQzM4HJi.js} +2 -2
  124. package/dist/server/assets/{index-DC1gaho7.js → index-joSkjgFP.js} +5 -5
  125. package/dist/server/assets/{info-VBDWY6EO-X8DJfp6J.js → info-VBDWY6EO-BZp8zZQH.js} +6 -6
  126. package/dist/server/assets/{infoDiagram-HS3SLOUP-BqzWimk3.js → infoDiagram-HS3SLOUP-CLZPZZt4.js} +5 -5
  127. package/dist/server/assets/{journeyDiagram-XKPGCS4Q-TTA7OGV5.js → journeyDiagram-XKPGCS4Q-DqIllasj.js} +4 -4
  128. package/dist/server/assets/{kanban-definition-3W4ZIXB7-DxNhleha.js → kanban-definition-3W4ZIXB7-B3yTD6nz.js} +2 -2
  129. package/dist/server/assets/{layout-CdOkK52n.js → layout-DbYj2Jh8.js} +4 -4
  130. package/dist/server/assets/{mermaid-3ZIDBTTL-Cof8t4J_.js → mermaid-3ZIDBTTL-Bf-b4R3F.js} +1 -1
  131. package/dist/server/assets/{mermaid-parser.core-Cqz_DwKC.js → mermaid-parser.core-BPo5KaJR.js} +11 -11
  132. package/dist/server/assets/{mindmap-definition-VGOIOE7T-DeGYTIld.js → mindmap-definition-VGOIOE7T-BsUTGWbP.js} +3 -3
  133. package/dist/server/assets/{packet-DYOGHKS2-TuIP3-Qx.js → packet-DYOGHKS2-BNRq6Npr.js} +6 -6
  134. package/dist/server/assets/{pie-VRWISCQL-DH44dC73.js → pie-VRWISCQL-Dbo7CqNc.js} +6 -6
  135. package/dist/server/assets/{pieDiagram-ADFJNKIX-BPUa7SIP.js → pieDiagram-ADFJNKIX-BSiV1fdc.js} +7 -7
  136. package/dist/server/assets/{quadrantDiagram-AYHSOK5B-CkonmhO6.js → quadrantDiagram-AYHSOK5B-DzkaSCma.js} +1 -1
  137. package/dist/server/assets/{radar-ZZBFDIW7-oedT_dlV.js → radar-ZZBFDIW7-C5pSAtKi.js} +6 -6
  138. package/dist/server/assets/{requirementDiagram-UZGBJVZJ-B39ng8tF.js → requirementDiagram-UZGBJVZJ--OE8EeQy.js} +3 -3
  139. package/dist/server/assets/{router-Dz7oMBKX.js → router-D6HwaUre.js} +851 -445
  140. package/dist/server/assets/{sankeyDiagram-TZEHDZUN-61A7I6h9.js → sankeyDiagram-TZEHDZUN--_Lp6TNE.js} +1 -1
  141. package/dist/server/assets/{sequenceDiagram-WL72ISMW-CXIpjJu4.js → sequenceDiagram-WL72ISMW-Cnkewzyp.js} +3 -3
  142. package/dist/server/assets/{square-terminal-D86hckth.js → square-terminal-D02AASv1.js} +1 -1
  143. package/dist/server/assets/{stateDiagram-FKZM4ZOC-DSp5PEkn.js → stateDiagram-FKZM4ZOC-Rrf6wgHM.js} +8 -8
  144. package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-B5TiwK_8.js → stateDiagram-v2-4FDKWEC3-CLZxE5q1.js} +4 -4
  145. package/dist/server/assets/{timeline-definition-IT6M3QCI-DvosEzgh.js → timeline-definition-IT6M3QCI-CXfT4jgF.js} +2 -2
  146. package/dist/server/assets/{treemap-GDKQZRPO-BOdkONyj.js → treemap-GDKQZRPO-CLL_lvY2.js} +6 -6
  147. package/dist/server/assets/{workspace._workspaceId-Dcw9dnbJ.js → workspace._workspaceId-CwFiKcq0.js} +1 -1
  148. package/dist/server/assets/{workspace._workspaceId-CvbciLVC.js → workspace._workspaceId-DXxXFkGR.js} +3 -3
  149. package/dist/server/assets/{xychartDiagram-PRI3JC2R-C22gtuGl.js → xychartDiagram-PRI3JC2R-DPZMWcNA.js} +1 -1
  150. package/dist/server/server.js +2 -2
  151. package/dist/start-server.mjs +477 -220
  152. package/package.json +4 -4
  153. package/dist/client/assets/DockviewBrowserContainer-DqC_h-bo.js +0 -5
  154. package/dist/client/assets/DockviewTerminalContainer-DyBQtb3U.js +0 -2
  155. package/dist/client/assets/TerminalPanel-CFDxHN4Q.js +0 -5
  156. package/dist/client/assets/channel-DDj6wNE3.js +0 -1
  157. package/dist/client/assets/classDiagram-2ON5EDUG-DEMr_v7L.js +0 -1
  158. package/dist/client/assets/classDiagram-v2-WZHVMYZB-DEMr_v7L.js +0 -1
  159. package/dist/client/assets/clone-BsghsKY1.js +0 -1
  160. package/dist/client/assets/main-BzKe6bG7.css +0 -1
  161. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-yLFyTsJU.js +0 -1
  162. package/dist/server/assets/_tanstack-start-manifest_v-TcfwNbuH.js +0 -4
@@ -1226,7 +1226,7 @@ const createLucideIcon = (iconName, iconNode) => {
1226
1226
  Component.displayName = toPascalCase(iconName);
1227
1227
  return Component;
1228
1228
  };
1229
- const __iconNode$1r = [
1229
+ const __iconNode$1s = [
1230
1230
  [
1231
1231
  "path",
1232
1232
  {
@@ -1235,45 +1235,45 @@ const __iconNode$1r = [
1235
1235
  }
1236
1236
  ]
1237
1237
  ];
1238
- const Activity = createLucideIcon("activity", __iconNode$1r);
1239
- const __iconNode$1q = [
1238
+ const Activity = createLucideIcon("activity", __iconNode$1s);
1239
+ const __iconNode$1r = [
1240
1240
  ["path", { d: "M12 17V3", key: "1cwfxf" }],
1241
1241
  ["path", { d: "m6 11 6 6 6-6", key: "12ii2o" }],
1242
1242
  ["path", { d: "M19 21H5", key: "150jfl" }]
1243
1243
  ];
1244
- const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$1q);
1245
- const __iconNode$1p = [
1244
+ const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$1r);
1245
+ const __iconNode$1q = [
1246
1246
  ["path", { d: "M12 5v14", key: "s699le" }],
1247
1247
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
1248
1248
  ];
1249
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$1p);
1250
- const __iconNode$1o = [
1249
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$1q);
1250
+ const __iconNode$1p = [
1251
1251
  ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
1252
1252
  ["path", { d: "M19 12H5", key: "x3x0zl" }]
1253
1253
  ];
1254
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$1o);
1255
- const __iconNode$1n = [
1254
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$1p);
1255
+ const __iconNode$1o = [
1256
1256
  ["path", { d: "M5 12h14", key: "1ays0h" }],
1257
1257
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
1258
1258
  ];
1259
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$1n);
1260
- const __iconNode$1m = [
1259
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$1o);
1260
+ const __iconNode$1n = [
1261
1261
  ["path", { d: "m18 9-6-6-6 6", key: "kcunyi" }],
1262
1262
  ["path", { d: "M12 3v14", key: "7cf3v8" }],
1263
1263
  ["path", { d: "M5 21h14", key: "11awu3" }]
1264
1264
  ];
1265
- const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$1m);
1266
- const __iconNode$1l = [
1265
+ const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$1n);
1266
+ const __iconNode$1m = [
1267
1267
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
1268
1268
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
1269
1269
  ];
1270
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$1l);
1271
- const __iconNode$1k = [
1270
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$1m);
1271
+ const __iconNode$1l = [
1272
1272
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1273
1273
  ["path", { d: "M4.929 4.929 19.07 19.071", key: "196cmz" }]
1274
1274
  ];
1275
- const Ban = createLucideIcon("ban", __iconNode$1k);
1276
- const __iconNode$1j = [
1275
+ const Ban = createLucideIcon("ban", __iconNode$1l);
1276
+ const __iconNode$1k = [
1277
1277
  ["path", { d: "M12 8V4H8", key: "hb8ula" }],
1278
1278
  ["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
1279
1279
  ["path", { d: "M2 14h2", key: "vft8re" }],
@@ -1281,60 +1281,68 @@ const __iconNode$1j = [
1281
1281
  ["path", { d: "M15 13v2", key: "1xurst" }],
1282
1282
  ["path", { d: "M9 13v2", key: "rq6x2g" }]
1283
1283
  ];
1284
- const Bot = createLucideIcon("bot", __iconNode$1j);
1285
- const __iconNode$1i = [
1284
+ const Bot = createLucideIcon("bot", __iconNode$1k);
1285
+ const __iconNode$1j = [
1286
1286
  ["path", { d: "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", key: "d5nyq2" }],
1287
1287
  ["path", { d: "M22 9v7", key: "pvm9v3" }],
1288
1288
  ["path", { d: "M3.304 13h6.392", key: "1q3zxz" }],
1289
1289
  ["circle", { cx: "18.5", cy: "12.5", r: "3.5", key: "z97x68" }]
1290
1290
  ];
1291
- const CaseSensitive = createLucideIcon("case-sensitive", __iconNode$1i);
1292
- const __iconNode$1h = [
1291
+ const CaseSensitive = createLucideIcon("case-sensitive", __iconNode$1j);
1292
+ const __iconNode$1i = [
1293
1293
  ["path", { d: "M3 3v16a2 2 0 0 0 2 2h16", key: "c24i48" }],
1294
1294
  ["path", { d: "M18 17V9", key: "2bz60n" }],
1295
1295
  ["path", { d: "M13 17V5", key: "1frdt8" }],
1296
1296
  ["path", { d: "M8 17v-3", key: "17ska0" }]
1297
1297
  ];
1298
- const ChartColumn = createLucideIcon("chart-column", __iconNode$1h);
1299
- const __iconNode$1g = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
1300
- const Check = createLucideIcon("check", __iconNode$1g);
1301
- const __iconNode$1f = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
1302
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$1f);
1303
- const __iconNode$1e = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
1304
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1e);
1305
- const __iconNode$1d = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
1306
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$1d);
1307
- const __iconNode$1c = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
1308
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$1c);
1309
- const __iconNode$1b = [
1298
+ const ChartColumn = createLucideIcon("chart-column", __iconNode$1i);
1299
+ const __iconNode$1h = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
1300
+ const Check = createLucideIcon("check", __iconNode$1h);
1301
+ const __iconNode$1g = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
1302
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$1g);
1303
+ const __iconNode$1f = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
1304
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1f);
1305
+ const __iconNode$1e = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
1306
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$1e);
1307
+ const __iconNode$1d = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
1308
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$1d);
1309
+ const __iconNode$1c = [
1310
1310
  ["path", { d: "m7 20 5-5 5 5", key: "13a0gw" }],
1311
1311
  ["path", { d: "m7 4 5 5 5-5", key: "1kwcof" }]
1312
1312
  ];
1313
- const ChevronsDownUp = createLucideIcon("chevrons-down-up", __iconNode$1b);
1314
- const __iconNode$1a = [
1313
+ const ChevronsDownUp = createLucideIcon("chevrons-down-up", __iconNode$1c);
1314
+ const __iconNode$1b = [
1315
1315
  ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
1316
1316
  ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
1317
1317
  ];
1318
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1a);
1319
- const __iconNode$19 = [
1318
+ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1b);
1319
+ const __iconNode$1a = [
1320
1320
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1321
1321
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
1322
1322
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
1323
1323
  ];
1324
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$19);
1325
- const __iconNode$18 = [
1324
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$1a);
1325
+ const __iconNode$19 = [
1326
1326
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1327
1327
  ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
1328
1328
  ];
1329
- const CircleCheck = createLucideIcon("circle-check", __iconNode$18);
1330
- const __iconNode$17 = [
1329
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$19);
1330
+ const __iconNode$18 = [
1331
1331
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1332
1332
  ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
1333
1333
  ["path", { d: "m9 9 6 6", key: "z0biqf" }]
1334
1334
  ];
1335
- const CircleX = createLucideIcon("circle-x", __iconNode$17);
1336
- const __iconNode$16 = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
1337
- const Circle = createLucideIcon("circle", __iconNode$16);
1335
+ const CircleX = createLucideIcon("circle-x", __iconNode$18);
1336
+ const __iconNode$17 = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
1337
+ const Circle = createLucideIcon("circle", __iconNode$17);
1338
+ const __iconNode$16 = [
1339
+ ["rect", { width: "8", height: "4", x: "8", y: "2", rx: "1", ry: "1", key: "tgr4d6" }],
1340
+ ["path", { d: "M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2", key: "4jdomd" }],
1341
+ ["path", { d: "M16 4h2a2 2 0 0 1 2 2v4", key: "3hqy98" }],
1342
+ ["path", { d: "M21 14H11", key: "1bme5i" }],
1343
+ ["path", { d: "m15 10-4 4 4 4", key: "5dvupr" }]
1344
+ ];
1345
+ const ClipboardCopy = createLucideIcon("clipboard-copy", __iconNode$16);
1338
1346
  const __iconNode$15 = [
1339
1347
  ["path", { d: "M11 14h10", key: "1w8e9d" }],
1340
1348
  ["path", { d: "M16 4h2a2 2 0 0 1 2 2v1.344", key: "1e62lh" }],
@@ -40668,53 +40676,53 @@ async function loadLanguage(lang) {
40668
40676
  try {
40669
40677
  switch (lang) {
40670
40678
  case "javascript":
40671
- return import("./index-Ct5-lZTn.js").then((m2) => m2.javascript());
40679
+ return import("./index-BXNtERIJ.js").then((m2) => m2.javascript());
40672
40680
  case "jsx":
40673
- return import("./index-Ct5-lZTn.js").then((m2) => m2.javascript({ jsx: true }));
40681
+ return import("./index-BXNtERIJ.js").then((m2) => m2.javascript({ jsx: true }));
40674
40682
  case "typescript":
40675
- return import("./index-Ct5-lZTn.js").then(
40683
+ return import("./index-BXNtERIJ.js").then(
40676
40684
  (m2) => m2.javascript({ typescript: true })
40677
40685
  );
40678
40686
  case "tsx":
40679
- return import("./index-Ct5-lZTn.js").then(
40687
+ return import("./index-BXNtERIJ.js").then(
40680
40688
  (m2) => m2.javascript({ jsx: true, typescript: true })
40681
40689
  );
40682
40690
  case "python":
40683
- return import("./index-DLEtsdeb.js").then((m2) => m2.python());
40691
+ return import("./index-CZpP5Q96.js").then((m2) => m2.python());
40684
40692
  case "html":
40685
- return import("./index-D5hMY11m.js").then((m2) => m2.html());
40693
+ return import("./index-Ddp0lHMA.js").then((m2) => m2.html());
40686
40694
  case "css":
40687
- return import("./index-Dqk2jQZ7.js").then((m2) => m2.css());
40695
+ return import("./index-C4WwCpyx.js").then((m2) => m2.css());
40688
40696
  case "scss":
40689
40697
  case "sass":
40690
- return import("./index-D49PP401.js").then((m2) => m2.sass());
40698
+ return import("./index-DinEbWse.js").then((m2) => m2.sass());
40691
40699
  case "less":
40692
- return import("./index-BHQ8bMg_.js").then((m2) => m2.less());
40700
+ return import("./index-VEnlzI7K.js").then((m2) => m2.less());
40693
40701
  case "json":
40694
40702
  case "jsonc":
40695
- return import("./index-Bay77lf3.js").then((m2) => m2.json());
40703
+ return import("./index-DtlVc4yR.js").then((m2) => m2.json());
40696
40704
  case "markdown":
40697
40705
  case "mdx":
40698
- return import("./index-DC1gaho7.js").then((m2) => m2.markdown());
40706
+ return import("./index-joSkjgFP.js").then((m2) => m2.markdown());
40699
40707
  case "xml":
40700
- return import("./index-BUm0x4GN.js").then((m2) => m2.xml());
40708
+ return import("./index-D7vNc-qo.js").then((m2) => m2.xml());
40701
40709
  case "yaml":
40702
- return import("./index-lmhecPWc.js").then((m2) => m2.yaml());
40710
+ return import("./index-3AJisjJ-.js").then((m2) => m2.yaml());
40703
40711
  case "sql":
40704
- return import("./index-BbUtF3L1.js").then((m2) => m2.sql());
40712
+ return import("./index-DAc69z6c.js").then((m2) => m2.sql());
40705
40713
  case "rust":
40706
- return import("./index-DH3a6-do.js").then((m2) => m2.rust());
40714
+ return import("./index-BQy_SzGG.js").then((m2) => m2.rust());
40707
40715
  case "go":
40708
- return import("./index-DrWaYPW7.js").then((m2) => m2.go());
40716
+ return import("./index-DBfcn5gX.js").then((m2) => m2.go());
40709
40717
  case "java":
40710
- return import("./index-CMxtCPk9.js").then((m2) => m2.java());
40718
+ return import("./index-Dm8dBBAU.js").then((m2) => m2.java());
40711
40719
  case "kotlin":
40712
- return import("./index-CMxtCPk9.js").then((m2) => m2.java());
40720
+ return import("./index-Dm8dBBAU.js").then((m2) => m2.java());
40713
40721
  case "c":
40714
40722
  case "cpp":
40715
- return import("./index-B5V3PU-n.js").then((m2) => m2.cpp());
40723
+ return import("./index-gQzM4HJi.js").then((m2) => m2.cpp());
40716
40724
  case "php":
40717
- return import("./index-DsrV0B5O.js").then((m2) => m2.php());
40725
+ return import("./index-DTBi6jO_.js").then((m2) => m2.php());
40718
40726
  // Legacy modes via StreamLanguage
40719
40727
  case "bash":
40720
40728
  case "fish":
@@ -41127,9 +41135,102 @@ function serializeEditorState(view) {
41127
41135
  scrollTop: view.scrollDOM.scrollTop
41128
41136
  };
41129
41137
  }
41138
+ async function writeClipboardText(text2) {
41139
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
41140
+ try {
41141
+ await navigator.clipboard.writeText(text2);
41142
+ return true;
41143
+ } catch {
41144
+ }
41145
+ }
41146
+ return legacyCopy(text2);
41147
+ }
41148
+ function legacyCopy(text2) {
41149
+ if (typeof document === "undefined") return false;
41150
+ const textarea = document.createElement("textarea");
41151
+ textarea.value = text2;
41152
+ textarea.setAttribute("readonly", "");
41153
+ textarea.style.position = "fixed";
41154
+ textarea.style.top = "0";
41155
+ textarea.style.left = "0";
41156
+ textarea.style.width = "1px";
41157
+ textarea.style.height = "1px";
41158
+ textarea.style.padding = "0";
41159
+ textarea.style.border = "0";
41160
+ textarea.style.opacity = "0";
41161
+ textarea.style.pointerEvents = "none";
41162
+ document.body.appendChild(textarea);
41163
+ const previouslyFocused = document.activeElement;
41164
+ try {
41165
+ textarea.focus();
41166
+ textarea.select();
41167
+ textarea.setSelectionRange(0, text2.length);
41168
+ return document.execCommand("copy");
41169
+ } catch {
41170
+ return false;
41171
+ } finally {
41172
+ document.body.removeChild(textarea);
41173
+ previouslyFocused?.focus?.();
41174
+ }
41175
+ }
41176
+ async function readClipboardText() {
41177
+ if (typeof navigator === "undefined" || !navigator.clipboard?.readText) {
41178
+ return "";
41179
+ }
41180
+ try {
41181
+ return await navigator.clipboard.readText();
41182
+ } catch {
41183
+ return "";
41184
+ }
41185
+ }
41186
+ function buildLineReference(filePath, startLine, endLine) {
41187
+ return startLine === endLine ? `${filePath}:${startLine}` : `${filePath}:${startLine}-${endLine}`;
41188
+ }
41130
41189
  const MIN_SELECTION_LENGTH = 1;
41131
41190
  const SHOW_DELAY_MS = 500;
41132
41191
  const setSelectionTooltip = StateEffect.define();
41192
+ const SVG_NS = "http://www.w3.org/2000/svg";
41193
+ function makeIcon(children2) {
41194
+ const svg2 = document.createElementNS(SVG_NS, "svg");
41195
+ svg2.setAttribute("width", "14");
41196
+ svg2.setAttribute("height", "14");
41197
+ svg2.setAttribute("viewBox", "0 0 24 24");
41198
+ svg2.setAttribute("fill", "none");
41199
+ svg2.setAttribute("stroke", "currentColor");
41200
+ svg2.setAttribute("stroke-width", "2");
41201
+ svg2.setAttribute("stroke-linecap", "round");
41202
+ svg2.setAttribute("stroke-linejoin", "round");
41203
+ for (const child of children2) {
41204
+ const el = document.createElementNS(SVG_NS, child.tag);
41205
+ if (child.tag === "path") el.setAttribute("d", child.d);
41206
+ else if (child.tag === "polyline") el.setAttribute("points", child.points);
41207
+ else if (child.tag === "line") {
41208
+ el.setAttribute("x1", child.x1);
41209
+ el.setAttribute("y1", child.y1);
41210
+ el.setAttribute("x2", child.x2);
41211
+ el.setAttribute("y2", child.y2);
41212
+ } else {
41213
+ el.setAttribute("x", child.x);
41214
+ el.setAttribute("y", child.y);
41215
+ el.setAttribute("width", child.width);
41216
+ el.setAttribute("height", child.height);
41217
+ el.setAttribute("rx", child.rx);
41218
+ }
41219
+ svg2.appendChild(el);
41220
+ }
41221
+ return svg2;
41222
+ }
41223
+ const ICON_CHAT = [
41224
+ { tag: "path", d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }
41225
+ ];
41226
+ const ICON_TERMINAL = [
41227
+ { tag: "polyline", points: "4 17 10 11 4 5" },
41228
+ { tag: "line", x1: "12", y1: "19", x2: "20", y2: "19" }
41229
+ ];
41230
+ const ICON_COPY = [
41231
+ { tag: "rect", x: "8", y: "8", width: "14", height: "14", rx: "2" },
41232
+ { tag: "path", d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" }
41233
+ ];
41133
41234
  function selectionToChatExtension(filePath, lineNumberMap) {
41134
41235
  const tooltipField = StateField.define({
41135
41236
  create() {
@@ -41151,59 +41252,88 @@ function selectionToChatExtension(filePath, lineNumberMap) {
41151
41252
  timer2 = null;
41152
41253
  }
41153
41254
  }
41255
+ function readSelection() {
41256
+ const { from: from2, to: to2 } = view.state.selection.main;
41257
+ if (from2 === to2) return null;
41258
+ const selectedText = view.state.sliceDoc(from2, to2);
41259
+ const docStartLine = view.state.doc.lineAt(from2).number;
41260
+ const docEndLine = view.state.doc.lineAt(to2).number;
41261
+ const startLine = lineNumberMap && docStartLine >= 1 && docStartLine <= lineNumberMap.length ? lineNumberMap[docStartLine - 1] : docStartLine;
41262
+ const endLine = lineNumberMap && docEndLine >= 1 && docEndLine <= lineNumberMap.length ? lineNumberMap[docEndLine - 1] : docEndLine;
41263
+ return { filePath, selectedText, startLine, endLine };
41264
+ }
41154
41265
  function buildTooltip() {
41155
41266
  const sel = view.state.selection.main;
41156
41267
  if (sel.empty || sel.to - sel.from < MIN_SELECTION_LENGTH) return null;
41157
41268
  return {
41158
41269
  pos: sel.head,
41159
- above: true,
41160
- strictSide: true,
41270
+ // Prefer rendering below the selection so the buttons don't cover the
41271
+ // selected text. `strictSide: false` lets CodeMirror flip back above
41272
+ // when there isn't enough room below (e.g. a selection near the bottom
41273
+ // edge of the editor) instead of clipping the tooltip.
41274
+ above: false,
41275
+ strictSide: false,
41161
41276
  arrow: false,
41162
- create(view2) {
41277
+ // Named `tooltipView` to avoid shadowing the outer `view` that
41278
+ // `readSelection` closes over (same instance, but the distinct name
41279
+ // keeps the data flow clear).
41280
+ create(tooltipView) {
41163
41281
  const dom = document.createElement("div");
41164
41282
  dom.className = "cm-add-to-chat-tooltip";
41165
- const btn = document.createElement("button");
41166
- btn.className = "cm-add-to-chat-btn";
41167
- btn.setAttribute("type", "button");
41168
- const svg2 = document.createElementNS("http://www.w3.org/2000/svg", "svg");
41169
- svg2.setAttribute("width", "14");
41170
- svg2.setAttribute("height", "14");
41171
- svg2.setAttribute("viewBox", "0 0 24 24");
41172
- svg2.setAttribute("fill", "none");
41173
- svg2.setAttribute("stroke", "currentColor");
41174
- svg2.setAttribute("stroke-width", "2");
41175
- svg2.setAttribute("stroke-linecap", "round");
41176
- svg2.setAttribute("stroke-linejoin", "round");
41177
- const path2 = document.createElementNS("http://www.w3.org/2000/svg", "path");
41178
- path2.setAttribute("d", "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z");
41179
- svg2.appendChild(path2);
41180
- btn.appendChild(svg2);
41181
- const label = document.createElement("span");
41182
- label.textContent = "Add to Chat";
41183
- btn.appendChild(label);
41184
- btn.addEventListener("mousedown", (e3) => {
41185
- e3.preventDefault();
41186
- e3.stopPropagation();
41187
- const { from: from2, to: to2 } = view2.state.selection.main;
41188
- if (from2 === to2) return;
41189
- const selectedText = view2.state.sliceDoc(from2, to2);
41190
- const docStartLine = view2.state.doc.lineAt(from2).number;
41191
- const docEndLine = view2.state.doc.lineAt(to2).number;
41192
- const startLine = lineNumberMap && docStartLine >= 1 && docStartLine <= lineNumberMap.length ? lineNumberMap[docStartLine - 1] : docStartLine;
41193
- const endLine = lineNumberMap && docEndLine >= 1 && docEndLine <= lineNumberMap.length ? lineNumberMap[docEndLine - 1] : docEndLine;
41194
- const detail = {
41195
- filePath,
41196
- selectedText,
41197
- startLine,
41198
- endLine
41199
- };
41200
- window.dispatchEvent(new CustomEvent("band:add-to-chat", { detail }));
41201
- view2.dispatch({
41202
- selection: { anchor: from2 },
41203
- effects: setSelectionTooltip.of(null)
41283
+ function makeButton(label, icon2, testId, onActivate) {
41284
+ const btn = document.createElement("button");
41285
+ btn.className = "cm-add-to-chat-btn";
41286
+ btn.setAttribute("type", "button");
41287
+ btn.setAttribute("data-testid", testId);
41288
+ btn.appendChild(makeIcon(icon2));
41289
+ const span = document.createElement("span");
41290
+ span.textContent = label;
41291
+ btn.appendChild(span);
41292
+ btn.addEventListener("mousedown", (e3) => {
41293
+ e3.preventDefault();
41294
+ e3.stopPropagation();
41295
+ const detail = readSelection();
41296
+ if (!detail) return;
41297
+ onActivate(detail);
41298
+ tooltipView.dispatch({
41299
+ selection: { anchor: tooltipView.state.selection.main.from },
41300
+ effects: setSelectionTooltip.of(null)
41301
+ });
41204
41302
  });
41205
- });
41206
- dom.appendChild(btn);
41303
+ return btn;
41304
+ }
41305
+ dom.appendChild(
41306
+ makeButton("Add to Chat", ICON_CHAT, "selection-tooltip__add-to-chat", (detail) => {
41307
+ window.dispatchEvent(new CustomEvent("band:add-to-chat", { detail }));
41308
+ })
41309
+ );
41310
+ dom.appendChild(
41311
+ makeButton(
41312
+ "Add to Terminal",
41313
+ ICON_TERMINAL,
41314
+ "selection-tooltip__add-to-terminal",
41315
+ (detail) => {
41316
+ const reference = `${buildLineReference(detail.filePath, detail.startLine, detail.endLine)} `;
41317
+ window.dispatchEvent(
41318
+ new CustomEvent("band:add-to-terminal", {
41319
+ detail: { reference }
41320
+ })
41321
+ );
41322
+ }
41323
+ )
41324
+ );
41325
+ dom.appendChild(
41326
+ makeButton(
41327
+ "Copy reference",
41328
+ ICON_COPY,
41329
+ "selection-tooltip__copy-reference",
41330
+ (detail) => {
41331
+ void writeClipboardText(
41332
+ buildLineReference(detail.filePath, detail.startLine, detail.endLine)
41333
+ );
41334
+ }
41335
+ )
41336
+ );
41207
41337
  return { dom };
41208
41338
  }
41209
41339
  };
@@ -41234,7 +41364,9 @@ function selectionToChatExtension(filePath, lineNumberMap) {
41234
41364
  ".cm-tooltip.cm-add-to-chat-tooltip": {
41235
41365
  backgroundColor: "transparent",
41236
41366
  border: "none",
41237
- zIndex: "100"
41367
+ zIndex: "100",
41368
+ display: "flex",
41369
+ gap: "4px"
41238
41370
  },
41239
41371
  ".cm-add-to-chat-btn": {
41240
41372
  display: "inline-flex",
@@ -50863,6 +50995,19 @@ function useSearch({
50863
50995
  dispatchToViews
50864
50996
  };
50865
50997
  }
50998
+ function useWorkspacePath(workspaceId) {
50999
+ const { projects } = useProjects();
51000
+ return reactExports.useMemo(() => {
51001
+ for (const proj of projects) {
51002
+ for (const wt2 of proj.worktrees) {
51003
+ if (toWorkspaceId(proj.name, wt2.branch) === workspaceId) {
51004
+ return wt2.path;
51005
+ }
51006
+ }
51007
+ }
51008
+ return void 0;
51009
+ }, [projects, workspaceId]);
51010
+ }
50866
51011
  function buildFileTree(fileStatuses) {
50867
51012
  const root2 = { children: /* @__PURE__ */ new Map() };
50868
51013
  for (const [filePath, status] of Object.entries(fileStatuses)) {
@@ -53849,6 +53994,11 @@ function getFileIcon(filename) {
53849
53994
  function getFolderIcon(name2, expanded = false) {
53850
53995
  return getOrCreate(resolveFolderIconName(name2, expanded), "FolderIcon");
53851
53996
  }
53997
+ function joinWorkspacePath(workspaceRoot, relativePath) {
53998
+ const root2 = workspaceRoot.replace(/\/+$/, "");
53999
+ const rel2 = relativePath.replace(/^\/+/, "");
54000
+ return rel2 ? `${root2}/${rel2}` : root2;
54001
+ }
53852
54002
  const statusColors = {
53853
54003
  A: "text-green-600 dark:text-green-400",
53854
54004
  M: "text-blue-600 dark:text-blue-400",
@@ -53886,6 +54036,7 @@ function ChangesTreeNode({
53886
54036
  onSelectFile,
53887
54037
  onRequestReset,
53888
54038
  canReset,
54039
+ workspacePath,
53889
54040
  activeFile
53890
54041
  }) {
53891
54042
  const isDir = node2.children !== void 0;
@@ -53911,6 +54062,7 @@ function ChangesTreeNode({
53911
54062
  ref: isActive ? btnRef : void 0,
53912
54063
  type: "button",
53913
54064
  "data-band-active": isActive ? "true" : void 0,
54065
+ "data-testid": `changes-tree__row--${node2.path}`,
53914
54066
  onClick: handleClick,
53915
54067
  className: `flex h-[28px] w-full select-none items-center gap-1 pr-3 text-left text-[13px] hover:bg-accent/50 [-webkit-touch-callout:none] ${isActive ? "bg-blue-500/30 text-foreground outline outline-1 -outline-offset-1 outline-blue-400/60 hover:bg-blue-500/30 dark:bg-blue-500/40 dark:outline-blue-400/70 dark:hover:bg-blue-500/40" : ""}`,
53916
54068
  style: { paddingLeft: `${depth * 12 + 4}px` },
@@ -53931,20 +54083,49 @@ function ChangesTreeNode({
53931
54083
  }
53932
54084
  );
53933
54085
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
53934
- canReset ? /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenu, { children: [
54086
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenu, { children: [
53935
54087
  /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTrigger, { asChild: true, children: button }),
53936
- /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuContent, { onCloseAutoFocus: menu.flush, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
53937
- ContextMenuItem,
53938
- {
53939
- variant: "destructive",
53940
- onSelect: () => menu.queue(() => onRequestReset(node2)),
53941
- children: [
53942
- /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" }),
53943
- "Reset changes"
53944
- ]
53945
- }
53946
- ) })
53947
- ] }) : button,
54088
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { onCloseAutoFocus: menu.flush, children: [
54089
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
54090
+ ContextMenuItem,
54091
+ {
54092
+ "data-testid": "changes-tree__copy-relative-path",
54093
+ onSelect: () => menu.queue(() => void writeClipboardText(node2.path)),
54094
+ children: [
54095
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardCopy, { className: "size-4" }),
54096
+ "Copy relative path"
54097
+ ]
54098
+ }
54099
+ ),
54100
+ workspacePath && /* @__PURE__ */ jsxRuntimeExports.jsxs(
54101
+ ContextMenuItem,
54102
+ {
54103
+ "data-testid": "changes-tree__copy-absolute-path",
54104
+ onSelect: () => menu.queue(
54105
+ () => void writeClipboardText(joinWorkspacePath(workspacePath, node2.path))
54106
+ ),
54107
+ children: [
54108
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardCopy, { className: "size-4" }),
54109
+ "Copy absolute path"
54110
+ ]
54111
+ }
54112
+ ),
54113
+ canReset && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
54114
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
54115
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
54116
+ ContextMenuItem,
54117
+ {
54118
+ variant: "destructive",
54119
+ onSelect: () => menu.queue(() => onRequestReset(node2)),
54120
+ children: [
54121
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" }),
54122
+ "Reset changes"
54123
+ ]
54124
+ }
54125
+ )
54126
+ ] })
54127
+ ] })
54128
+ ] }),
53948
54129
  isExpanded && node2.children?.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
53949
54130
  ChangesTreeNode,
53950
54131
  {
@@ -53955,6 +54136,7 @@ function ChangesTreeNode({
53955
54136
  onSelectFile,
53956
54137
  onRequestReset,
53957
54138
  canReset,
54139
+ workspacePath,
53958
54140
  activeFile
53959
54141
  },
53960
54142
  child.path
@@ -53975,7 +54157,8 @@ function ChangesFileTree({
53975
54157
  fileStatuses,
53976
54158
  onSelectFile,
53977
54159
  activeFile,
53978
- onRevertPaths
54160
+ onRevertPaths,
54161
+ workspacePath
53979
54162
  }) {
53980
54163
  const tree = reactExports.useMemo(() => buildFileTree(fileStatuses), [fileStatuses]);
53981
54164
  const seenDirPathsRef = reactExports.useRef(new Set(collectDirPaths(tree)));
@@ -54050,6 +54233,7 @@ function ChangesFileTree({
54050
54233
  onSelectFile,
54051
54234
  onRequestReset: handleRequestReset,
54052
54235
  canReset,
54236
+ workspacePath,
54053
54237
  activeFile
54054
54238
  },
54055
54239
  node2.path
@@ -54991,6 +55175,7 @@ function DiffView({
54991
55175
  const adapter2 = useAdapter();
54992
55176
  const projectKind = useProjectKindForWorkspace(workspaceId);
54993
55177
  const isPlain = projectKind === "plain";
55178
+ const workspacePath = useWorkspacePath(workspaceId);
54994
55179
  const [summary, setSummary] = reactExports.useState(null);
54995
55180
  const summaryRef = reactExports.useRef(null);
54996
55181
  const [error, setError] = reactExports.useState(null);
@@ -55780,7 +55965,8 @@ function DiffView({
55780
55965
  fileStatuses,
55781
55966
  onSelectFile: handleScrollToFile,
55782
55967
  activeFile,
55783
- onRevertPaths: adapter2.revertFile ? handleRevertPaths : void 0
55968
+ onRevertPaths: adapter2.revertFile ? handleRevertPaths : void 0,
55969
+ workspacePath
55784
55970
  },
55785
55971
  workspaceId
55786
55972
  ) })
@@ -56261,6 +56447,7 @@ function TreeNode2({
56261
56447
  canCut,
56262
56448
  canCopy,
56263
56449
  canPaste,
56450
+ workspacePath,
56264
56451
  compact,
56265
56452
  treeSelection,
56266
56453
  clipboard,
@@ -56302,6 +56489,7 @@ function TreeNode2({
56302
56489
  ref: isSelected ? selectedRef : void 0,
56303
56490
  type: "button",
56304
56491
  "data-band-active": isSelected ? "true" : void 0,
56492
+ "data-testid": `file-tree__row--${entryPath}`,
56305
56493
  onClick: handleClick,
56306
56494
  onDoubleClick: handleDoubleClick,
56307
56495
  onContextMenu: (e3) => e3.stopPropagation(),
@@ -56409,7 +56597,30 @@ function TreeNode2({
56409
56597
  /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardPaste, { className: "size-4" }),
56410
56598
  "Paste"
56411
56599
  ] }),
56412
- (canCut || canCopy || isDir && canPaste) && (canRename || canDelete) && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
56600
+ (canCut || canCopy || isDir && canPaste) && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
56601
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
56602
+ ContextMenuItem,
56603
+ {
56604
+ "data-testid": "file-tree__copy-relative-path",
56605
+ onSelect: () => menu.queue(() => void writeClipboardText(entryPath)),
56606
+ children: [
56607
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardCopy, { className: "size-4" }),
56608
+ "Copy relative path"
56609
+ ]
56610
+ }
56611
+ ),
56612
+ workspacePath && /* @__PURE__ */ jsxRuntimeExports.jsxs(
56613
+ ContextMenuItem,
56614
+ {
56615
+ "data-testid": "file-tree__copy-absolute-path",
56616
+ onSelect: () => menu.queue(() => void writeClipboardText(joinWorkspacePath(workspacePath, entryPath))),
56617
+ children: [
56618
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardCopy, { className: "size-4" }),
56619
+ "Copy absolute path"
56620
+ ]
56621
+ }
56622
+ ),
56623
+ (canRename || canDelete) && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
56413
56624
  canRename && /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => menu.queue(() => onRequestRename(entryPath)), children: [
56414
56625
  /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-4" }),
56415
56626
  "Rename"
@@ -56460,6 +56671,7 @@ function TreeNode2({
56460
56671
  canCut,
56461
56672
  canCopy,
56462
56673
  canPaste,
56674
+ workspacePath,
56463
56675
  compact,
56464
56676
  treeSelection,
56465
56677
  clipboard,
@@ -56518,6 +56730,7 @@ function TreeNode2({
56518
56730
  }
56519
56731
  const FileBrowser = reactExports.forwardRef(function FileBrowser2({
56520
56732
  workspaceId,
56733
+ workspacePath,
56521
56734
  onOpenFile,
56522
56735
  onOpenFilePinned,
56523
56736
  compact,
@@ -57017,6 +57230,7 @@ const FileBrowser = reactExports.forwardRef(function FileBrowser2({
57017
57230
  canCut: canCutCopy,
57018
57231
  canCopy: canCopyOp,
57019
57232
  canPaste,
57233
+ workspacePath,
57020
57234
  compact,
57021
57235
  treeSelection,
57022
57236
  clipboard,
@@ -108983,7 +109197,7 @@ var tn = f$5("block", "before:content-[counter(line)]", "before:inline-block", "
108983
109197
  var et$1 = ({ className: e3, language: t2, style: o3, isIncomplete: n2, ...s2 }) => jsxRuntimeExports.jsx("div", { className: f$5("my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2", e3), "data-incomplete": n2 || void 0, "data-language": t2, "data-streamdown": "code-block", style: { contentVisibility: "auto", containIntrinsicSize: "auto 200px", ...o3 }, ...s2 });
108984
109198
  var Se$1 = reactExports.createContext({ code: "" }), de$2 = () => reactExports.useContext(Se$1);
108985
109199
  var ot$1 = ({ language: e3 }) => jsxRuntimeExports.jsx("div", { className: "flex h-8 items-center text-muted-foreground text-xs", "data-language": e3, "data-streamdown": "code-block-header", children: jsxRuntimeExports.jsx("span", { className: "ml-1 font-mono lowercase", children: e3 }) });
108986
- var cn = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-C6BqMnvu.js").then((e3) => ({ default: e3.HighlightedCodeBlockBody }))), rt = ({ code: e3, language: t2, className: o3, children: n2, isIncomplete: s2 = false, ...r2 }) => {
109200
+ var cn = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-Dmr6rOWq.js").then((e3) => ({ default: e3.HighlightedCodeBlockBody }))), rt = ({ code: e3, language: t2, className: o3, children: n2, isIncomplete: s2 = false, ...r2 }) => {
108987
109201
  let i2 = reactExports.useMemo(() => e3.replace(cn, ""), [e3]), c2 = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i2.split(`
108988
109202
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i2]);
108989
109203
  return jsxRuntimeExports.jsx(Se$1.Provider, { value: { code: e3 }, children: jsxRuntimeExports.jsxs(et$1, { isIncomplete: s2, language: t2, children: [jsxRuntimeExports.jsx(ot$1, { language: t2 }), n2 ? jsxRuntimeExports.jsx("div", { className: "pointer-events-none sticky top-2 z-10 -mt-10 flex h-8 items-center justify-end", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto flex shrink-0 items-center gap-2 rounded-md border border-sidebar bg-sidebar/80 px-1.5 py-1 supports-[backdrop-filter]:bg-sidebar/70 supports-[backdrop-filter]:backdrop-blur", "data-streamdown": "code-block-actions", children: n2 }) }) : null, jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: jsxRuntimeExports.jsx(Qe$1, { className: o3, language: t2, result: c2, ...r2 }), children: jsxRuntimeExports.jsx(dn, { className: o3, code: i2, language: t2, raw: c2, ...r2 }) })] }) });
@@ -109305,7 +109519,7 @@ var Dt = ({ children: e3, className: t2, onDownload: o3, onError: n2 }) => {
109305
109519
  }, []), jsxRuntimeExports.jsxs("div", { className: "relative", ref: i2, children: [jsxRuntimeExports.jsx("button", { className: f$5("cursor-pointer p-1 text-muted-foreground transition-all hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50", t2), disabled: c2, onClick: () => r2(!s2), title: "Download table", type: "button", children: e3 != null ? e3 : jsxRuntimeExports.jsx(Z$2, { size: 14 }) }), s2 ? jsxRuntimeExports.jsxs("div", { className: "absolute top-full right-0 z-10 mt-1 min-w-[120px] overflow-hidden rounded-md border border-border bg-background shadow-lg", children: [jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("csv"), title: "Download table as CSV", type: "button", children: "CSV" }), jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("markdown"), title: "Download table as Markdown", type: "button", children: "Markdown" })] }) : null] });
109306
109520
  };
109307
109521
  var Vt = ({ children: e3, className: t2, showControls: o3, ...n2 }) => jsxRuntimeExports.jsxs("div", { className: "my-4 flex flex-col gap-2 rounded-lg border border-border bg-sidebar p-2", "data-streamdown": "table-wrapper", children: [o3 ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [jsxRuntimeExports.jsx(Ht, {}), jsxRuntimeExports.jsx(Dt, {})] }) : null, jsxRuntimeExports.jsx("div", { className: "border-collapse overflow-x-auto overscroll-y-auto rounded-md border border-border bg-background", children: jsxRuntimeExports.jsx("table", { className: f$5("w-full divide-y divide-border", t2), "data-streamdown": "table", ...n2, children: e3 }) })] });
109308
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-Cof8t4J_.js").then((e3) => ({ default: e3.Mermaid }))), Kn = /language-([^\s]+)/;
109522
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-Bf-b4R3F.js").then((e3) => ({ default: e3.Mermaid }))), Kn = /language-([^\s]+)/;
109309
109523
  function ke$1(e3, t2) {
109310
109524
  if (!(e3 != null && e3.position || t2 != null && t2.position)) return true;
109311
109525
  if (!(e3 != null && e3.position && (t2 != null && t2.position))) return false;
@@ -161476,12 +161690,12 @@ var registerDefaultLayoutLoaders = /* @__PURE__ */ __name(() => {
161476
161690
  registerLayoutLoaders([
161477
161691
  {
161478
161692
  name: "dagre",
161479
- loader: /* @__PURE__ */ __name(async () => await import("./dagre-6UL2VRFP-BKfzYlJQ.js"), "loader")
161693
+ loader: /* @__PURE__ */ __name(async () => await import("./dagre-6UL2VRFP-DCM_EeeJ.js"), "loader")
161480
161694
  },
161481
161695
  ...[
161482
161696
  {
161483
161697
  name: "cose-bilkent",
161484
- loader: /* @__PURE__ */ __name(async () => await import("./cose-bilkent-S5V4N54A-BiP6P-09.js"), "loader")
161698
+ loader: /* @__PURE__ */ __name(async () => await import("./cose-bilkent-S5V4N54A-GH832JBk.js"), "loader")
161485
161699
  }
161486
161700
  ]
161487
161701
  ]);
@@ -161920,7 +162134,7 @@ var detector = /* @__PURE__ */ __name((txt) => {
161920
162134
  return /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(txt);
161921
162135
  }, "detector");
161922
162136
  var loader = /* @__PURE__ */ __name(async () => {
161923
- const { diagram: diagram2 } = await import("./c4Diagram-YG6GDRKO-9PjJESuA.js");
162137
+ const { diagram: diagram2 } = await import("./c4Diagram-YG6GDRKO-BULLTo2O.js");
161924
162138
  return { id, diagram: diagram2 };
161925
162139
  }, "loader");
161926
162140
  var plugin = {
@@ -161937,7 +162151,7 @@ var detector2 = /* @__PURE__ */ __name((txt, config2) => {
161937
162151
  return /^\s*graph/.test(txt);
161938
162152
  }, "detector");
161939
162153
  var loader2 = /* @__PURE__ */ __name(async () => {
161940
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-CXnLZPl0.js");
162154
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-4gEGHH9W.js");
161941
162155
  return { id: id2, diagram: diagram2 };
161942
162156
  }, "loader");
161943
162157
  var plugin2 = {
@@ -161960,7 +162174,7 @@ var detector3 = /* @__PURE__ */ __name((txt, config2) => {
161960
162174
  return /^\s*flowchart/.test(txt);
161961
162175
  }, "detector");
161962
162176
  var loader3 = /* @__PURE__ */ __name(async () => {
161963
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-CXnLZPl0.js");
162177
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-4gEGHH9W.js");
161964
162178
  return { id: id3, diagram: diagram2 };
161965
162179
  }, "loader");
161966
162180
  var plugin3 = {
@@ -161974,7 +162188,7 @@ var detector4 = /* @__PURE__ */ __name((txt) => {
161974
162188
  return /^\s*erDiagram/.test(txt);
161975
162189
  }, "detector");
161976
162190
  var loader4 = /* @__PURE__ */ __name(async () => {
161977
- const { diagram: diagram2 } = await import("./erDiagram-Q2GNP2WA-CRPjeaHB.js");
162191
+ const { diagram: diagram2 } = await import("./erDiagram-Q2GNP2WA-CMa2Pz-v.js");
161978
162192
  return { id: id4, diagram: diagram2 };
161979
162193
  }, "loader");
161980
162194
  var plugin4 = {
@@ -161988,7 +162202,7 @@ var detector5 = /* @__PURE__ */ __name((txt) => {
161988
162202
  return /^\s*gitGraph/.test(txt);
161989
162203
  }, "detector");
161990
162204
  var loader5 = /* @__PURE__ */ __name(async () => {
161991
- const { diagram: diagram2 } = await import("./gitGraphDiagram-V2S2FVAM-CZNtwgUE.js");
162205
+ const { diagram: diagram2 } = await import("./gitGraphDiagram-V2S2FVAM-CKZ8qTSA.js");
161992
162206
  return { id: id5, diagram: diagram2 };
161993
162207
  }, "loader");
161994
162208
  var plugin5 = {
@@ -162002,7 +162216,7 @@ var detector6 = /* @__PURE__ */ __name((txt) => {
162002
162216
  return /^\s*gantt/.test(txt);
162003
162217
  }, "detector");
162004
162218
  var loader6 = /* @__PURE__ */ __name(async () => {
162005
- const { diagram: diagram2 } = await import("./ganttDiagram-JELNMOA3-CP5EwGxj.js");
162219
+ const { diagram: diagram2 } = await import("./ganttDiagram-JELNMOA3-BOS7aF_7.js");
162006
162220
  return { id: id6, diagram: diagram2 };
162007
162221
  }, "loader");
162008
162222
  var plugin6 = {
@@ -162016,7 +162230,7 @@ var detector7 = /* @__PURE__ */ __name((txt) => {
162016
162230
  return /^\s*info/.test(txt);
162017
162231
  }, "detector");
162018
162232
  var loader7 = /* @__PURE__ */ __name(async () => {
162019
- const { diagram: diagram2 } = await import("./infoDiagram-HS3SLOUP-BqzWimk3.js");
162233
+ const { diagram: diagram2 } = await import("./infoDiagram-HS3SLOUP-CLZPZZt4.js");
162020
162234
  return { id: id7, diagram: diagram2 };
162021
162235
  }, "loader");
162022
162236
  var info = {
@@ -162029,7 +162243,7 @@ var detector8 = /* @__PURE__ */ __name((txt) => {
162029
162243
  return /^\s*pie/.test(txt);
162030
162244
  }, "detector");
162031
162245
  var loader8 = /* @__PURE__ */ __name(async () => {
162032
- const { diagram: diagram2 } = await import("./pieDiagram-ADFJNKIX-BPUa7SIP.js");
162246
+ const { diagram: diagram2 } = await import("./pieDiagram-ADFJNKIX-BSiV1fdc.js");
162033
162247
  return { id: id8, diagram: diagram2 };
162034
162248
  }, "loader");
162035
162249
  var pie = {
@@ -162042,7 +162256,7 @@ var detector9 = /* @__PURE__ */ __name((txt) => {
162042
162256
  return /^\s*quadrantChart/.test(txt);
162043
162257
  }, "detector");
162044
162258
  var loader9 = /* @__PURE__ */ __name(async () => {
162045
- const { diagram: diagram2 } = await import("./quadrantDiagram-AYHSOK5B-CkonmhO6.js");
162259
+ const { diagram: diagram2 } = await import("./quadrantDiagram-AYHSOK5B-DzkaSCma.js");
162046
162260
  return { id: id9, diagram: diagram2 };
162047
162261
  }, "loader");
162048
162262
  var plugin7 = {
@@ -162056,7 +162270,7 @@ var detector10 = /* @__PURE__ */ __name((txt) => {
162056
162270
  return /^\s*xychart(-beta)?/.test(txt);
162057
162271
  }, "detector");
162058
162272
  var loader10 = /* @__PURE__ */ __name(async () => {
162059
- const { diagram: diagram2 } = await import("./xychartDiagram-PRI3JC2R-C22gtuGl.js");
162273
+ const { diagram: diagram2 } = await import("./xychartDiagram-PRI3JC2R-DPZMWcNA.js");
162060
162274
  return { id: id10, diagram: diagram2 };
162061
162275
  }, "loader");
162062
162276
  var plugin8 = {
@@ -162070,7 +162284,7 @@ var detector11 = /* @__PURE__ */ __name((txt) => {
162070
162284
  return /^\s*requirement(Diagram)?/.test(txt);
162071
162285
  }, "detector");
162072
162286
  var loader11 = /* @__PURE__ */ __name(async () => {
162073
- const { diagram: diagram2 } = await import("./requirementDiagram-UZGBJVZJ-B39ng8tF.js");
162287
+ const { diagram: diagram2 } = await import("./requirementDiagram-UZGBJVZJ--OE8EeQy.js");
162074
162288
  return { id: id11, diagram: diagram2 };
162075
162289
  }, "loader");
162076
162290
  var plugin9 = {
@@ -162084,7 +162298,7 @@ var detector12 = /* @__PURE__ */ __name((txt) => {
162084
162298
  return /^\s*sequenceDiagram/.test(txt);
162085
162299
  }, "detector");
162086
162300
  var loader12 = /* @__PURE__ */ __name(async () => {
162087
- const { diagram: diagram2 } = await import("./sequenceDiagram-WL72ISMW-CXIpjJu4.js");
162301
+ const { diagram: diagram2 } = await import("./sequenceDiagram-WL72ISMW-Cnkewzyp.js");
162088
162302
  return { id: id12, diagram: diagram2 };
162089
162303
  }, "loader");
162090
162304
  var plugin10 = {
@@ -162101,7 +162315,7 @@ var detector13 = /* @__PURE__ */ __name((txt, config2) => {
162101
162315
  return /^\s*classDiagram/.test(txt);
162102
162316
  }, "detector");
162103
162317
  var loader13 = /* @__PURE__ */ __name(async () => {
162104
- const { diagram: diagram2 } = await import("./classDiagram-2ON5EDUG-D1OcdIXp.js");
162318
+ const { diagram: diagram2 } = await import("./classDiagram-2ON5EDUG-D48G1fOA.js");
162105
162319
  return { id: id13, diagram: diagram2 };
162106
162320
  }, "loader");
162107
162321
  var plugin11 = {
@@ -162118,7 +162332,7 @@ var detector14 = /* @__PURE__ */ __name((txt, config2) => {
162118
162332
  return /^\s*classDiagram-v2/.test(txt);
162119
162333
  }, "detector");
162120
162334
  var loader14 = /* @__PURE__ */ __name(async () => {
162121
- const { diagram: diagram2 } = await import("./classDiagram-v2-WZHVMYZB-D1OcdIXp.js");
162335
+ const { diagram: diagram2 } = await import("./classDiagram-v2-WZHVMYZB-D48G1fOA.js");
162122
162336
  return { id: id14, diagram: diagram2 };
162123
162337
  }, "loader");
162124
162338
  var plugin12 = {
@@ -162135,7 +162349,7 @@ var detector15 = /* @__PURE__ */ __name((txt, config2) => {
162135
162349
  return /^\s*stateDiagram/.test(txt);
162136
162350
  }, "detector");
162137
162351
  var loader15 = /* @__PURE__ */ __name(async () => {
162138
- const { diagram: diagram2 } = await import("./stateDiagram-FKZM4ZOC-DSp5PEkn.js");
162352
+ const { diagram: diagram2 } = await import("./stateDiagram-FKZM4ZOC-Rrf6wgHM.js");
162139
162353
  return { id: id15, diagram: diagram2 };
162140
162354
  }, "loader");
162141
162355
  var plugin13 = {
@@ -162155,7 +162369,7 @@ var detector16 = /* @__PURE__ */ __name((txt, config2) => {
162155
162369
  return false;
162156
162370
  }, "detector");
162157
162371
  var loader16 = /* @__PURE__ */ __name(async () => {
162158
- const { diagram: diagram2 } = await import("./stateDiagram-v2-4FDKWEC3-B5TiwK_8.js");
162372
+ const { diagram: diagram2 } = await import("./stateDiagram-v2-4FDKWEC3-CLZxE5q1.js");
162159
162373
  return { id: id16, diagram: diagram2 };
162160
162374
  }, "loader");
162161
162375
  var plugin14 = {
@@ -162169,7 +162383,7 @@ var detector17 = /* @__PURE__ */ __name((txt) => {
162169
162383
  return /^\s*journey/.test(txt);
162170
162384
  }, "detector");
162171
162385
  var loader17 = /* @__PURE__ */ __name(async () => {
162172
- const { diagram: diagram2 } = await import("./journeyDiagram-XKPGCS4Q-TTA7OGV5.js");
162386
+ const { diagram: diagram2 } = await import("./journeyDiagram-XKPGCS4Q-DqIllasj.js");
162173
162387
  return { id: id17, diagram: diagram2 };
162174
162388
  }, "loader");
162175
162389
  var plugin15 = {
@@ -162236,7 +162450,7 @@ var detector18 = /* @__PURE__ */ __name((txt, config2 = {}) => {
162236
162450
  return false;
162237
162451
  }, "detector");
162238
162452
  var loader18 = /* @__PURE__ */ __name(async () => {
162239
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-CXnLZPl0.js");
162453
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-4gEGHH9W.js");
162240
162454
  return { id: id18, diagram: diagram2 };
162241
162455
  }, "loader");
162242
162456
  var plugin16 = {
@@ -162250,7 +162464,7 @@ var detector19 = /* @__PURE__ */ __name((txt) => {
162250
162464
  return /^\s*timeline/.test(txt);
162251
162465
  }, "detector");
162252
162466
  var loader19 = /* @__PURE__ */ __name(async () => {
162253
- const { diagram: diagram2 } = await import("./timeline-definition-IT6M3QCI-DvosEzgh.js");
162467
+ const { diagram: diagram2 } = await import("./timeline-definition-IT6M3QCI-CXfT4jgF.js");
162254
162468
  return { id: id19, diagram: diagram2 };
162255
162469
  }, "loader");
162256
162470
  var plugin17 = {
@@ -162264,7 +162478,7 @@ var detector20 = /* @__PURE__ */ __name((txt) => {
162264
162478
  return /^\s*mindmap/.test(txt);
162265
162479
  }, "detector");
162266
162480
  var loader20 = /* @__PURE__ */ __name(async () => {
162267
- const { diagram: diagram2 } = await import("./mindmap-definition-VGOIOE7T-DeGYTIld.js");
162481
+ const { diagram: diagram2 } = await import("./mindmap-definition-VGOIOE7T-BsUTGWbP.js");
162268
162482
  return { id: id20, diagram: diagram2 };
162269
162483
  }, "loader");
162270
162484
  var plugin18 = {
@@ -162278,7 +162492,7 @@ var detector21 = /* @__PURE__ */ __name((txt) => {
162278
162492
  return /^\s*kanban/.test(txt);
162279
162493
  }, "detector");
162280
162494
  var loader21 = /* @__PURE__ */ __name(async () => {
162281
- const { diagram: diagram2 } = await import("./kanban-definition-3W4ZIXB7-DxNhleha.js");
162495
+ const { diagram: diagram2 } = await import("./kanban-definition-3W4ZIXB7-B3yTD6nz.js");
162282
162496
  return { id: id21, diagram: diagram2 };
162283
162497
  }, "loader");
162284
162498
  var plugin19 = {
@@ -162292,7 +162506,7 @@ var detector22 = /* @__PURE__ */ __name((txt) => {
162292
162506
  return /^\s*sankey(-beta)?/.test(txt);
162293
162507
  }, "detector");
162294
162508
  var loader22 = /* @__PURE__ */ __name(async () => {
162295
- const { diagram: diagram2 } = await import("./sankeyDiagram-TZEHDZUN-61A7I6h9.js");
162509
+ const { diagram: diagram2 } = await import("./sankeyDiagram-TZEHDZUN--_Lp6TNE.js");
162296
162510
  return { id: id22, diagram: diagram2 };
162297
162511
  }, "loader");
162298
162512
  var plugin20 = {
@@ -162306,7 +162520,7 @@ var detector23 = /* @__PURE__ */ __name((txt) => {
162306
162520
  return /^\s*packet(-beta)?/.test(txt);
162307
162521
  }, "detector");
162308
162522
  var loader23 = /* @__PURE__ */ __name(async () => {
162309
- const { diagram: diagram2 } = await import("./diagram-S2PKOQOG-CUKugrbt.js");
162523
+ const { diagram: diagram2 } = await import("./diagram-S2PKOQOG-nDhXR9ui.js");
162310
162524
  return { id: id23, diagram: diagram2 };
162311
162525
  }, "loader");
162312
162526
  var packet = {
@@ -162319,7 +162533,7 @@ var detector24 = /* @__PURE__ */ __name((txt) => {
162319
162533
  return /^\s*radar-beta/.test(txt);
162320
162534
  }, "detector");
162321
162535
  var loader24 = /* @__PURE__ */ __name(async () => {
162322
- const { diagram: diagram2 } = await import("./diagram-QEK2KX5R-CxL6qeVX.js");
162536
+ const { diagram: diagram2 } = await import("./diagram-QEK2KX5R--ln7zI47.js");
162323
162537
  return { id: id24, diagram: diagram2 };
162324
162538
  }, "loader");
162325
162539
  var radar = {
@@ -162332,7 +162546,7 @@ var detector25 = /* @__PURE__ */ __name((txt) => {
162332
162546
  return /^\s*block(-beta)?/.test(txt);
162333
162547
  }, "detector");
162334
162548
  var loader25 = /* @__PURE__ */ __name(async () => {
162335
- const { diagram: diagram2 } = await import("./blockDiagram-VD42YOAC-DGV6m5iW.js");
162549
+ const { diagram: diagram2 } = await import("./blockDiagram-VD42YOAC-XJWMoZPI.js");
162336
162550
  return { id: id25, diagram: diagram2 };
162337
162551
  }, "loader");
162338
162552
  var plugin21 = {
@@ -162346,7 +162560,7 @@ var detector26 = /* @__PURE__ */ __name((txt) => {
162346
162560
  return /^\s*architecture/.test(txt);
162347
162561
  }, "detector");
162348
162562
  var loader26 = /* @__PURE__ */ __name(async () => {
162349
- const { diagram: diagram2 } = await import("./architectureDiagram-VXUJARFQ-vPxmruSN.js");
162563
+ const { diagram: diagram2 } = await import("./architectureDiagram-VXUJARFQ-kdf4spX4.js");
162350
162564
  return { id: id26, diagram: diagram2 };
162351
162565
  }, "loader");
162352
162566
  var architecture = {
@@ -162360,7 +162574,7 @@ var detector27 = /* @__PURE__ */ __name((txt) => {
162360
162574
  return /^\s*treemap/.test(txt);
162361
162575
  }, "detector");
162362
162576
  var loader27 = /* @__PURE__ */ __name(async () => {
162363
- const { diagram: diagram2 } = await import("./diagram-PSM6KHXK-BF6r9xQS.js");
162577
+ const { diagram: diagram2 } = await import("./diagram-PSM6KHXK-Wsb4GT24.js");
162364
162578
  return { id: id27, diagram: diagram2 };
162365
162579
  }, "loader");
162366
162580
  var treemap = {
@@ -163599,17 +163813,7 @@ function CodeBrowserView({
163599
163813
  const removeFileRef = reactExports.useRef(tabState.removeFile);
163600
163814
  removeFileRef.current = tabState.removeFile;
163601
163815
  const { settings } = useSettingsQuery();
163602
- const { projects } = useProjects();
163603
- const workspacePath = (() => {
163604
- for (const proj of projects) {
163605
- for (const wt2 of proj.worktrees) {
163606
- if (toWorkspaceId(proj.name, wt2.branch) === workspaceId) {
163607
- return wt2.path;
163608
- }
163609
- }
163610
- }
163611
- return void 0;
163612
- })();
163816
+ const workspacePath = useWorkspacePath(workspaceId);
163613
163817
  const [viewFilePath, setViewFilePath] = reactExports.useState(() => {
163614
163818
  if (file2) return parseFileLocation(file2).filePath;
163615
163819
  return fileTabs.activeTabPath ?? "";
@@ -164507,6 +164711,7 @@ function CodeBrowserView({
164507
164711
  {
164508
164712
  ref: fileBrowserRef,
164509
164713
  workspaceId,
164714
+ workspacePath,
164510
164715
  onOpenFile: handleSelectFile,
164511
164716
  onOpenFilePinned: handleSelectFilePinned,
164512
164717
  selectedFile: viewFilePath,
@@ -164555,6 +164760,7 @@ function CodeBrowserView({
164555
164760
  {
164556
164761
  ref: fileBrowserRef,
164557
164762
  workspaceId,
164763
+ workspacePath,
164558
164764
  onOpenFile: handleSelectFile,
164559
164765
  onOpenFilePinned: handleSelectFilePinned,
164560
164766
  compact: true,
@@ -164675,54 +164881,6 @@ function CodeBrowserView({
164675
164881
  ) })
164676
164882
  );
164677
164883
  }
164678
- async function writeClipboardText(text2) {
164679
- if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
164680
- try {
164681
- await navigator.clipboard.writeText(text2);
164682
- return true;
164683
- } catch {
164684
- }
164685
- }
164686
- return legacyCopy(text2);
164687
- }
164688
- function legacyCopy(text2) {
164689
- if (typeof document === "undefined") return false;
164690
- const textarea = document.createElement("textarea");
164691
- textarea.value = text2;
164692
- textarea.setAttribute("readonly", "");
164693
- textarea.style.position = "fixed";
164694
- textarea.style.top = "0";
164695
- textarea.style.left = "0";
164696
- textarea.style.width = "1px";
164697
- textarea.style.height = "1px";
164698
- textarea.style.padding = "0";
164699
- textarea.style.border = "0";
164700
- textarea.style.opacity = "0";
164701
- textarea.style.pointerEvents = "none";
164702
- document.body.appendChild(textarea);
164703
- const previouslyFocused = document.activeElement;
164704
- try {
164705
- textarea.focus();
164706
- textarea.select();
164707
- textarea.setSelectionRange(0, text2.length);
164708
- return document.execCommand("copy");
164709
- } catch {
164710
- return false;
164711
- } finally {
164712
- document.body.removeChild(textarea);
164713
- previouslyFocused?.focus?.();
164714
- }
164715
- }
164716
- async function readClipboardText() {
164717
- if (typeof navigator === "undefined" || !navigator.clipboard?.readText) {
164718
- return "";
164719
- }
164720
- try {
164721
- return await navigator.clipboard.readText();
164722
- } catch {
164723
- return "";
164724
- }
164725
- }
164726
164884
  function cycleTabsInActiveGroup(api, direction, refocus) {
164727
164885
  const group = api?.activeGroup;
164728
164886
  if (!api || !group) return;
@@ -172324,8 +172482,7 @@ const PromptInput = ({
172324
172482
  const handler = (e3) => {
172325
172483
  if (wsActiveRef.current === false) return;
172326
172484
  const { filePath, startLine, endLine } = e3.detail;
172327
- const lineRef = startLine === endLine ? `${filePath}:${startLine}` : `${filePath}:${startLine}-${endLine}`;
172328
- const reference = `\`${lineRef}\` `;
172485
+ const reference = `\`${buildLineReference(filePath, startLine, endLine)}\` `;
172329
172486
  const textarea = textareaRef.current;
172330
172487
  const current2 = textarea?.value ?? "";
172331
172488
  const combined = current2 + reference;
@@ -173549,6 +173706,7 @@ function ToolCall({ item }) {
173549
173706
  markdown && /* @__PURE__ */ jsxRuntimeExports.jsx(MessageResponse, { children: markdown })
173550
173707
  ] });
173551
173708
  }
173709
+ const HISTORY_PAGE_SIZE = 50;
173552
173710
  const CHAT_EVENT_TYPES = [
173553
173711
  "user-message",
173554
173712
  "task-started",
@@ -173565,7 +173723,8 @@ const CHAT_EVENT_TYPES = [
173565
173723
  "error",
173566
173724
  "file",
173567
173725
  "queue-updated",
173568
- "subscription-opened"
173726
+ "subscription-opened",
173727
+ "history-meta"
173569
173728
  ];
173570
173729
  const INITIAL_STATE = {
173571
173730
  messages: [],
@@ -173577,7 +173736,11 @@ const INITIAL_STATE = {
173577
173736
  taskRunning: false,
173578
173737
  taskErrorMessage: void 0,
173579
173738
  currentAssistantId: void 0,
173580
- messageIdCounter: 0
173739
+ messageIdCounter: 0,
173740
+ hasOlder: false,
173741
+ oldestOffset: void 0,
173742
+ pendingToolOutputs: {},
173743
+ pendingOptimisticTask: false
173581
173744
  };
173582
173745
  function appendPart(messages, assistantId, part) {
173583
173746
  const idx = messages.findIndex((m2) => m2.id === assistantId);
@@ -173665,17 +173828,79 @@ function makeToolOutputPart(prev2, evt) {
173665
173828
  approval: prev2?.approval
173666
173829
  };
173667
173830
  }
173668
- function chatEventReducer(state2, event) {
173831
+ function drainPendingToolOutputs(messages, pending2) {
173832
+ const ids2 = Object.keys(pending2);
173833
+ if (ids2.length === 0) return { messages, pending: pending2 };
173834
+ let nextMessages = messages;
173835
+ let nextPending;
173836
+ for (const toolCallId of ids2) {
173837
+ let ownerId;
173838
+ let prevPart;
173839
+ for (let i2 = nextMessages.length - 1; i2 >= 0; i2--) {
173840
+ const msg = nextMessages[i2];
173841
+ if (msg.role !== "assistant") continue;
173842
+ const part = msg.parts.find((p2) => {
173843
+ const pp = p2;
173844
+ return pp.toolCallId === toolCallId;
173845
+ });
173846
+ if (part) {
173847
+ ownerId = msg.id;
173848
+ prevPart = part;
173849
+ break;
173850
+ }
173851
+ }
173852
+ if (!ownerId) continue;
173853
+ nextMessages = replaceToolPart(
173854
+ nextMessages,
173855
+ ownerId,
173856
+ toolCallId,
173857
+ makeToolOutputPart(prevPart, pending2[toolCallId])
173858
+ );
173859
+ if (!nextPending) nextPending = { ...pending2 };
173860
+ delete nextPending[toolCallId];
173861
+ }
173862
+ return { messages: nextMessages, pending: nextPending ?? pending2 };
173863
+ }
173864
+ function chatEventReducer(state2, action) {
173865
+ if (action.type === "prepend-messages") {
173866
+ const merged = [...action.messages, ...state2.messages];
173867
+ const mergedPending = action.pendingToolOutputs ? { ...state2.pendingToolOutputs, ...action.pendingToolOutputs } : state2.pendingToolOutputs;
173868
+ const drained = drainPendingToolOutputs(merged, mergedPending);
173869
+ return {
173870
+ ...state2,
173871
+ messages: drained.messages,
173872
+ pendingToolOutputs: drained.pending,
173873
+ hasOlder: action.hasOlder,
173874
+ oldestOffset: action.oldestOffset
173875
+ };
173876
+ }
173877
+ const event = action;
173669
173878
  const lastEventId = Math.max(state2.lastEventId ?? 0, event.eventId);
173670
173879
  switch (event.type) {
173671
173880
  case "subscription-opened": {
173672
- const taskRunning = state2.taskRunning || event.taskRunning;
173881
+ if (state2.pendingOptimisticTask) {
173882
+ const taskRunning2 = state2.taskRunning || event.taskRunning;
173883
+ return {
173884
+ ...state2,
173885
+ lastEventId,
173886
+ sessionId: event.sessionId ?? state2.sessionId,
173887
+ taskRunning: taskRunning2,
173888
+ status: taskRunning2 ? "streaming" : state2.status
173889
+ };
173890
+ }
173891
+ const taskRunning = event.taskRunning;
173892
+ let status = state2.status;
173893
+ if (taskRunning) {
173894
+ status = "streaming";
173895
+ } else if (state2.taskRunning) {
173896
+ status = state2.messages.some((m2) => m2.role === "assistant") ? "completed" : "idle";
173897
+ }
173673
173898
  return {
173674
173899
  ...state2,
173675
173900
  lastEventId,
173676
173901
  sessionId: event.sessionId ?? state2.sessionId,
173677
173902
  taskRunning,
173678
- status: taskRunning ? "streaming" : state2.status
173903
+ status
173679
173904
  };
173680
173905
  }
173681
173906
  case "session-resolved":
@@ -173728,7 +173953,11 @@ function chatEventReducer(state2, event) {
173728
173953
  taskRunning: true,
173729
173954
  status: "submitting",
173730
173955
  taskErrorMessage: void 0,
173731
- currentAssistantId: void 0
173956
+ currentAssistantId: void 0,
173957
+ // Negative eventId ⇒ this is `send()`'s synthetic pre-ack task-started.
173958
+ // A real server task-started (positive eventId) acknowledges it and
173959
+ // clears the pending flag, re-enabling authoritative downgrades.
173960
+ pendingOptimisticTask: event.eventId < 0
173732
173961
  };
173733
173962
  case "task-completed":
173734
173963
  return {
@@ -173736,7 +173965,8 @@ function chatEventReducer(state2, event) {
173736
173965
  lastEventId,
173737
173966
  taskRunning: false,
173738
173967
  status: "completed",
173739
- currentAssistantId: void 0
173968
+ currentAssistantId: void 0,
173969
+ pendingOptimisticTask: false
173740
173970
  };
173741
173971
  case "task-error":
173742
173972
  return {
@@ -173745,7 +173975,8 @@ function chatEventReducer(state2, event) {
173745
173975
  taskRunning: false,
173746
173976
  status: "error",
173747
173977
  taskErrorMessage: event.message,
173748
- currentAssistantId: void 0
173978
+ currentAssistantId: void 0,
173979
+ pendingOptimisticTask: false
173749
173980
  };
173750
173981
  case "text-start": {
173751
173982
  const created = state2.currentAssistantId === void 0;
@@ -173799,6 +174030,7 @@ function chatEventReducer(state2, event) {
173799
174030
  messages = [...messages, { id: assistantId, role: "assistant", parts: [] }];
173800
174031
  }
173801
174032
  messages = appendPart(messages, assistantId, makeToolInputPart(event));
174033
+ const drained = drainPendingToolOutputs(messages, state2.pendingToolOutputs);
173802
174034
  return {
173803
174035
  ...state2,
173804
174036
  lastEventId,
@@ -173808,7 +174040,8 @@ function chatEventReducer(state2, event) {
173808
174040
  status: state2.taskRunning ? "streaming" : state2.status,
173809
174041
  currentAssistantId: assistantId,
173810
174042
  messageIdCounter: nextCounter,
173811
- messages
174043
+ messages: drained.messages,
174044
+ pendingToolOutputs: drained.pending
173812
174045
  };
173813
174046
  }
173814
174047
  case "tool-output-available": {
@@ -173828,11 +174061,11 @@ function chatEventReducer(state2, event) {
173828
174061
  }
173829
174062
  }
173830
174063
  if (!ownerId) {
173831
- console.warn(
173832
- "[chat] tool-output-available for unknown toolCallId — dropping",
173833
- event.toolCallId
173834
- );
173835
- return { ...state2, lastEventId };
174064
+ return {
174065
+ ...state2,
174066
+ lastEventId,
174067
+ pendingToolOutputs: { ...state2.pendingToolOutputs, [event.toolCallId]: event }
174068
+ };
173836
174069
  }
173837
174070
  const messages = replaceToolPart(
173838
174071
  state2.messages,
@@ -173902,11 +174135,24 @@ _Error: ${event.message}_`
173902
174135
  }
173903
174136
  case "queue-updated":
173904
174137
  return { ...state2, lastEventId, queuedMessages: event.messages };
174138
+ case "history-meta":
174139
+ return {
174140
+ ...state2,
174141
+ lastEventId,
174142
+ hasOlder: event.hasOlder,
174143
+ oldestOffset: event.oldestOffset
174144
+ };
173905
174145
  default: {
173906
174146
  return { ...state2, lastEventId };
173907
174147
  }
173908
174148
  }
173909
174149
  }
174150
+ function applyEvents(state2, events2) {
174151
+ let next2 = state2;
174152
+ for (const evt of events2) next2 = chatEventReducer(next2, evt);
174153
+ return next2;
174154
+ }
174155
+ const OLDER_PAGE_LIMIT = HISTORY_PAGE_SIZE;
173910
174156
  const MAX_BACKOFF_MS = 1e4;
173911
174157
  const INITIAL_BACKOFF_MS = 500;
173912
174158
  async function fileToWirePart(file2) {
@@ -174090,6 +174336,51 @@ function useChatSubscription(opts) {
174090
174336
  } catch {
174091
174337
  }
174092
174338
  }, [workspaceId, chatId]);
174339
+ const [loadingOlder, setLoadingOlder] = reactExports.useState(false);
174340
+ const loadingOlderRef = reactExports.useRef(false);
174341
+ const paginationRef = reactExports.useRef({
174342
+ hasOlder: state2.hasOlder,
174343
+ oldestOffset: state2.oldestOffset,
174344
+ sessionId: state2.sessionId
174345
+ });
174346
+ paginationRef.current.hasOlder = state2.hasOlder;
174347
+ paginationRef.current.oldestOffset = state2.oldestOffset;
174348
+ paginationRef.current.sessionId = state2.sessionId;
174349
+ const loadOlder = reactExports.useCallback(async () => {
174350
+ if (loadingOlderRef.current) return;
174351
+ const { hasOlder, oldestOffset, sessionId } = paginationRef.current;
174352
+ const before = oldestOffset;
174353
+ if (!hasOlder || before == null || before <= 0 || !sessionId) return;
174354
+ loadingOlderRef.current = true;
174355
+ setLoadingOlder(true);
174356
+ try {
174357
+ const params = new URLSearchParams();
174358
+ params.set("before", String(before));
174359
+ params.set("limit", String(OLDER_PAGE_LIMIT));
174360
+ const res = await fetch(
174361
+ `/api/chats/${encodeURIComponent(chatId)}/history?${params.toString()}`,
174362
+ { credentials: "include" }
174363
+ );
174364
+ if (!res.ok) throw new Error(`history fetch failed: HTTP ${res.status}`);
174365
+ const data = await res.json();
174366
+ const folded = applyEvents(INITIAL_STATE, data.events);
174367
+ const namespaced = folded.messages.map((m2) => ({ ...m2, id: `o${before}-${m2.id}` }));
174368
+ dispatch2({
174369
+ type: "prepend-messages",
174370
+ messages: namespaced,
174371
+ hasOlder: data.hasOlder,
174372
+ oldestOffset: data.oldestOffset,
174373
+ // Carry forward any outputs the page couldn't resolve internally (their
174374
+ // tool_use is in an even-older page) so a later load resolves them.
174375
+ pendingToolOutputs: folded.pendingToolOutputs
174376
+ });
174377
+ } catch (err) {
174378
+ console.error("[chat-sub] loadOlder failed", err);
174379
+ } finally {
174380
+ loadingOlderRef.current = false;
174381
+ setLoadingOlder(false);
174382
+ }
174383
+ }, [chatId]);
174093
174384
  return {
174094
174385
  messages: state2.messages,
174095
174386
  status: state2.status,
@@ -174098,9 +174389,12 @@ function useChatSubscription(opts) {
174098
174389
  usage: state2.usage,
174099
174390
  taskRunning: state2.taskRunning,
174100
174391
  taskErrorMessage: state2.taskErrorMessage,
174392
+ hasOlder: state2.hasOlder,
174101
174393
  isConnected,
174102
174394
  send,
174103
- cancel
174395
+ cancel,
174396
+ loadOlder,
174397
+ loadingOlder
174104
174398
  };
174105
174399
  }
174106
174400
  function createLazyMeasurementsView(count2, flat, getItemKey) {
@@ -175483,7 +175777,39 @@ function VirtualizedMessageList({
175483
175777
  estimateSize = 220,
175484
175778
  overscan = 5
175485
175779
  }) {
175486
- const { scrollRef } = useStickToBottomContext();
175780
+ const { scrollRef, scrollToBottom } = useStickToBottomContext();
175781
+ const [revealed, setRevealed] = reactExports.useState(false);
175782
+ reactExports.useEffect(() => {
175783
+ let raf = 0;
175784
+ let frames = 0;
175785
+ let stableFrames = 0;
175786
+ let lastHeight = -1;
175787
+ const MAX_FRAMES = 24;
175788
+ const STABLE_FRAMES = 2;
175789
+ const reveal = () => {
175790
+ scrollToBottom("instant");
175791
+ setRevealed(true);
175792
+ };
175793
+ const tick = () => {
175794
+ frames += 1;
175795
+ const el = scrollRef.current;
175796
+ if (el) el.scrollTop = el.scrollHeight;
175797
+ const height = el ? el.scrollHeight : 0;
175798
+ if (height === lastHeight) {
175799
+ stableFrames += 1;
175800
+ } else {
175801
+ stableFrames = 0;
175802
+ }
175803
+ lastHeight = height;
175804
+ if (stableFrames >= STABLE_FRAMES && frames >= 2 || frames >= MAX_FRAMES) {
175805
+ reveal();
175806
+ return;
175807
+ }
175808
+ raf = requestAnimationFrame(tick);
175809
+ };
175810
+ raf = requestAnimationFrame(tick);
175811
+ return () => cancelAnimationFrame(raf);
175812
+ }, []);
175487
175813
  const estimateSizeFn = reactExports.useCallback(() => estimateSize, [estimateSize]);
175488
175814
  const itemsRef = reactExports.useRef(items);
175489
175815
  itemsRef.current = items;
@@ -175501,6 +175827,17 @@ function VirtualizedMessageList({
175501
175827
  // when items shift (e.g. a new message pushes earlier ones up).
175502
175828
  getItemKey: getItemKeyFn
175503
175829
  });
175830
+ const prevFirstKeyRef = reactExports.useRef(null);
175831
+ reactExports.useLayoutEffect(() => {
175832
+ const firstKey = items.length > 0 ? getKey(items[0], 0) : null;
175833
+ const prevFirstKey = prevFirstKeyRef.current;
175834
+ prevFirstKeyRef.current = firstKey;
175835
+ if (prevFirstKey == null || firstKey === prevFirstKey) return;
175836
+ const newIndex = items.findIndex((item, i2) => getKey(item, i2) === prevFirstKey);
175837
+ if (newIndex > 0) {
175838
+ virtualizer.scrollToIndex(newIndex, { align: "start" });
175839
+ }
175840
+ }, [items]);
175504
175841
  const virtualItems = virtualizer.getVirtualItems();
175505
175842
  const totalSize = virtualizer.getTotalSize();
175506
175843
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -175513,7 +175850,11 @@ function VirtualizedMessageList({
175513
175850
  // scrollbar shows the correct extent.
175514
175851
  height: `${totalSize}px`,
175515
175852
  width: "100%",
175516
- position: "relative"
175853
+ position: "relative",
175854
+ // First-paint reveal gate (see the effect above). Hidden rows
175855
+ // still occupy layout — their ResizeObservers keep firing — so
175856
+ // the height/offset convergence completes off-screen.
175857
+ visibility: revealed ? void 0 : "hidden"
175517
175858
  },
175518
175859
  children: virtualItems.map((virtualRow) => {
175519
175860
  const item = items[virtualRow.index];
@@ -175656,9 +175997,10 @@ function ChatView({
175656
175997
  }) {
175657
175998
  const [initialSessionCleared, setInitialSessionCleared] = reactExports.useState(false);
175658
175999
  const [contextMeterEnabled] = useExperimentalContextMeter();
175659
- reactExports.useRef(null);
176000
+ const sentinelRef = reactExports.useRef(null);
175660
176001
  const stickyContextRef = reactExports.useRef(null);
175661
176002
  const prevVisibleRef = reactExports.useRef(visible);
176003
+ const [scrollEl, setScrollEl] = reactExports.useState(null);
175662
176004
  reactExports.useEffect(() => {
175663
176005
  let raf = 0;
175664
176006
  let attempts = 0;
@@ -175667,6 +176009,7 @@ function ChatView({
175667
176009
  const el = stickyContextRef.current?.scrollRef?.current;
175668
176010
  if (el) {
175669
176011
  if (!el.dataset.testid) el.dataset.testid = "chat-pane__scroller";
176012
+ setScrollEl(el);
175670
176013
  return;
175671
176014
  }
175672
176015
  if (attempts >= 10) {
@@ -175781,7 +176124,7 @@ function ChatView({
175781
176124
  // factors in `document.visibilityState` internally.
175782
176125
  enabled: wsActive !== false
175783
176126
  });
175784
- const { messages, status, sessionId, queuedMessages, usage, send, cancel } = subscription;
176127
+ const { messages, status, sessionId, queuedMessages, usage, send, cancel, loadOlder } = subscription;
175785
176128
  const isStreaming = status === "submitting" || status === "streaming";
175786
176129
  const lastNotifiedSessionRef = reactExports.useRef(initialSessionId);
175787
176130
  reactExports.useEffect(() => {
@@ -175796,9 +176139,9 @@ function ChatView({
175796
176139
  }, [queuedMessages]);
175797
176140
  const queuedMessagesView = optimisticQueue ?? queuedMessages;
175798
176141
  const currentSessionId = initialSessionCleared ? void 0 : sessionId ?? initialSessionId;
175799
- const hasMore = false;
175800
- !isStreaming && messages.length === 0 && !!initialSessionId && !subscription.isConnected;
175801
- const loadingOlder = false;
176142
+ const hasMore = subscription.hasOlder;
176143
+ const loadingHistory = !isStreaming && messages.length === 0 && !!initialSessionId && !subscription.isConnected;
176144
+ const loadingOlder = subscription.loadingOlder;
175802
176145
  const handleStop = reactExports.useCallback(() => {
175803
176146
  void cancel();
175804
176147
  }, [cancel]);
@@ -175914,64 +176257,80 @@ function ChatView({
175914
176257
  const getMessageKey = reactExports.useCallback((message) => message.id, []);
175915
176258
  const messagesRef = reactExports.useRef(messages);
175916
176259
  messagesRef.current = messages;
175917
- const isStreamingRef = reactExports.useRef(isStreaming);
175918
- isStreamingRef.current = isStreaming;
175919
- const renderMessageItem = reactExports.useCallback((message, messageIndex) => {
175920
- const currentMessages = messagesRef.current;
175921
- const currentIsStreaming = isStreamingRef.current;
175922
- const isLastMessage = messageIndex === currentMessages.length - 1;
175923
- const isLastAssistant = message.role === "assistant" && isLastMessage;
175924
- const hasPendingInteractiveTool = isLastAssistant && message.parts.some((p2) => {
175925
- if (!isToolUIPart(p2) || !IN_PROGRESS_STATES.has(p2.state)) return false;
175926
- const name2 = getToolName(p2);
175927
- return name2 === "AskUserQuestion" || name2 === "ExitPlanMode";
175928
- });
175929
- const showThinking = isLastAssistant && currentIsStreaming && !hasPendingInteractiveTool;
175930
- const segments = groupMessageParts(message.parts);
175931
- if (message.role !== "assistant") {
175932
- if (segments.length === 0) return null;
175933
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Message, { from: "user", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { children: segments.map((segment) => {
175934
- if (segment.type === "text" && segment.part.type === "text" && segment.part.text.trim()) {
175935
- return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageResponse, { children: segment.part.text }, `${message.id}-text-${segment.partIndex}`);
175936
- }
175937
- if (segment.type === "file") {
175938
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
175939
- MessageFilePart,
175940
- {
175941
- part: segment.part
175942
- },
175943
- `${message.id}-file-${segment.partIndex}`
175944
- );
176260
+ reactExports.useEffect(() => {
176261
+ const sentinel = sentinelRef.current;
176262
+ if (!sentinel || !scrollEl || !hasMore || loadingHistory) return;
176263
+ const io2 = new IntersectionObserver(
176264
+ (entries2) => {
176265
+ for (const entry of entries2) {
176266
+ if (entry.isIntersecting) void loadOlder();
175945
176267
  }
175946
- return null;
175947
- }) }) });
175948
- }
175949
- if (segments.length === 0 && !showThinking) return null;
175950
- return /* @__PURE__ */ jsxRuntimeExports.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessageContent, { children: [
175951
- segments.map((segment) => {
175952
- if (segment.type === "text") {
175953
- const { part, partIndex } = segment;
175954
- if (part.type === "text" && part.text.trim()) {
175955
- return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageResponse, { children: part.text }, `${message.id}-text-${partIndex}`);
176268
+ },
176269
+ // Pre-fetch slightly before the sentinel is fully on-screen so the older
176270
+ // page is usually ready by the time the user reaches the very top.
176271
+ { root: scrollEl, rootMargin: "150px 0px 0px 0px" }
176272
+ );
176273
+ io2.observe(sentinel);
176274
+ return () => io2.disconnect();
176275
+ }, [scrollEl, hasMore, loadingHistory, loadOlder]);
176276
+ const renderMessageItem = reactExports.useCallback(
176277
+ (message, messageIndex) => {
176278
+ const currentMessages = messagesRef.current;
176279
+ const isLastMessage = messageIndex === currentMessages.length - 1;
176280
+ const isLastAssistant = message.role === "assistant" && isLastMessage;
176281
+ const hasPendingInteractiveTool = isLastAssistant && message.parts.some((p2) => {
176282
+ if (!isToolUIPart(p2) || !IN_PROGRESS_STATES.has(p2.state)) return false;
176283
+ const name2 = getToolName(p2);
176284
+ return name2 === "AskUserQuestion" || name2 === "ExitPlanMode";
176285
+ });
176286
+ const showThinking = isLastAssistant && isStreaming && !hasPendingInteractiveTool;
176287
+ const segments = groupMessageParts(message.parts);
176288
+ if (message.role !== "assistant") {
176289
+ if (segments.length === 0) return null;
176290
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Message, { from: "user", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MessageContent, { children: segments.map((segment) => {
176291
+ if (segment.type === "text" && segment.part.type === "text" && segment.part.text.trim()) {
176292
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageResponse, { children: segment.part.text }, `${message.id}-text-${segment.partIndex}`);
176293
+ }
176294
+ if (segment.type === "file") {
176295
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
176296
+ MessageFilePart,
176297
+ {
176298
+ part: segment.part
176299
+ },
176300
+ `${message.id}-file-${segment.partIndex}`
176301
+ );
175956
176302
  }
175957
176303
  return null;
175958
- }
175959
- if (segment.type === "file") {
175960
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
175961
- MessageFilePart,
175962
- {
175963
- part: segment.part
175964
- },
175965
- `${message.id}-file-${segment.partIndex}`
175966
- );
175967
- }
175968
- const item = toolPartToItem(segment.part);
175969
- if (isTaskTool(item.toolName)) return null;
175970
- return /* @__PURE__ */ jsxRuntimeExports.jsx(ToolCall, { item }, `${message.id}-tool-${segment.partIndex}`);
175971
- }),
175972
- showThinking && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingIndicator, {})
175973
- ] }) });
175974
- }, []);
176304
+ }) }) });
176305
+ }
176306
+ if (segments.length === 0 && !showThinking) return null;
176307
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(MessageContent, { children: [
176308
+ segments.map((segment) => {
176309
+ if (segment.type === "text") {
176310
+ const { part, partIndex } = segment;
176311
+ if (part.type === "text" && part.text.trim()) {
176312
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageResponse, { children: part.text }, `${message.id}-text-${partIndex}`);
176313
+ }
176314
+ return null;
176315
+ }
176316
+ if (segment.type === "file") {
176317
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
176318
+ MessageFilePart,
176319
+ {
176320
+ part: segment.part
176321
+ },
176322
+ `${message.id}-file-${segment.partIndex}`
176323
+ );
176324
+ }
176325
+ const item = toolPartToItem(segment.part);
176326
+ if (isTaskTool(item.toolName)) return null;
176327
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ToolCall, { item }, `${message.id}-tool-${segment.partIndex}`);
176328
+ }),
176329
+ showThinking && /* @__PURE__ */ jsxRuntimeExports.jsx(ThinkingIndicator, {})
176330
+ ] }) });
176331
+ },
176332
+ [isStreaming]
176333
+ );
175975
176334
  const getLastUserMessage = reactExports.useCallback(() => {
175976
176335
  const currentMessages = messagesRef.current;
175977
176336
  for (let i2 = currentMessages.length - 1; i2 >= 0; i2--) {
@@ -175992,9 +176351,21 @@ function ChatView({
175992
176351
  // (issue #539).
175993
176352
  /* @__PURE__ */ jsxRuntimeExports.jsx(FileLinkWorkspaceProvider, { workspaceId, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
175994
176353
  /* @__PURE__ */ jsxRuntimeExports.jsxs(Conversation, { className: "min-h-0 flex-1", contextRef: stickyContextRef, children: [
176354
+ loadingOlder && /* @__PURE__ */ jsxRuntimeExports.jsx(
176355
+ "output",
176356
+ {
176357
+ className: "pointer-events-none absolute inset-x-0 top-2 z-10 flex justify-center",
176358
+ "aria-busy": "true",
176359
+ "aria-label": "Loading older messages",
176360
+ "data-testid": "chat-pane__loading-older",
176361
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-2 rounded-full bg-background/90 px-3 py-1 text-xs text-muted-foreground shadow-sm", children: [
176362
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
176363
+ "Loading earlier messages…"
176364
+ ] })
176365
+ }
176366
+ ),
175995
176367
  /* @__PURE__ */ jsxRuntimeExports.jsxs(ConversationContent, { children: [
175996
- hasMore,
175997
- loadingOlder,
176368
+ hasMore && !loadingHistory && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: sentinelRef, className: "h-px w-full shrink-0", "aria-hidden": "true" }),
175998
176369
  messages.length === 0 && !subscription.isConnected && /* @__PURE__ */ jsxRuntimeExports.jsx(ConversationSkeleton, {}),
175999
176370
  messages.length === 0 && subscription.isConnected && /* @__PURE__ */ jsxRuntimeExports.jsx(
176000
176371
  ConversationEmptyState,
@@ -177024,12 +177395,13 @@ function ChatTab(props) {
177024
177395
  if (!sessionId) return;
177025
177396
  void writeClipboardText(sessionId);
177026
177397
  }, [sessionId]);
177398
+ const containerApi = props.containerApi;
177027
177399
  const handleClose2 = reactExports.useCallback(
177028
177400
  (e3) => {
177029
177401
  e3.stopPropagation();
177030
- closeTabRef.current?.(chatId);
177402
+ panelActionsByApiId.get(containerApi.id)?.current?.onClose(chatId);
177031
177403
  },
177032
- [chatId]
177404
+ [containerApi, chatId]
177033
177405
  );
177034
177406
  const showClose = panelCount > 1;
177035
177407
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -177092,52 +177464,57 @@ function ChatTab(props) {
177092
177464
  }
177093
177465
  );
177094
177466
  }
177095
- const addTabRef = {
177096
- current: { onAdd: () => {
177097
- }, onSplit: () => {
177098
- } }
177099
- };
177100
- const closeTabRef = {
177101
- current: null
177102
- };
177467
+ const panelActionsByApiId = /* @__PURE__ */ new Map();
177103
177468
  const RightHeaderActions = React$1.memo(function RightHeaderActions2(props) {
177104
177469
  const isGridGroup = (props.location?.type ?? "grid") === "grid";
177105
- const { onAdd: onAdd2, onSplit } = addTabRef.current;
177470
+ const apiId = props.containerApi.id;
177106
177471
  const groupId = props.group.id;
177107
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full w-full items-center justify-center", children: [
177108
- isGridGroup && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
177109
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177110
- "button",
177111
- {
177112
- type: "button",
177113
- className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177114
- onClick: () => onSplit(groupId, "right"),
177115
- title: "Split right",
177116
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Columns2, { className: "size-3.5" })
177117
- }
177118
- ),
177119
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177120
- "button",
177121
- {
177122
- type: "button",
177123
- className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177124
- onClick: () => onSplit(groupId, "below"),
177125
- title: "Split down",
177126
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Rows2, { className: "size-3.5" })
177127
- }
177128
- )
177129
- ] }),
177130
- /* @__PURE__ */ jsxRuntimeExports.jsx(
177131
- "button",
177472
+ return (
177473
+ // `data-testid` on grid-group toolbars only (edge groups get no testid)
177474
+ // gives integration tests a stable hook for the central action row
177475
+ // without the fragile CSS `:has(button[title=...])` workaround.
177476
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
177477
+ "div",
177132
177478
  {
177133
- type: "button",
177134
- className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177135
- onClick: () => onAdd2(void 0, groupId),
177136
- title: "New chat tab",
177137
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" })
177479
+ className: "flex h-full w-full items-center justify-center",
177480
+ "data-testid": isGridGroup ? "dockview-chat__toolbar" : void 0,
177481
+ children: [
177482
+ isGridGroup && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
177483
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
177484
+ "button",
177485
+ {
177486
+ type: "button",
177487
+ className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177488
+ onClick: () => panelActionsByApiId.get(apiId)?.current?.onSplit(groupId, "right"),
177489
+ title: "Split right",
177490
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Columns2, { className: "size-3.5" })
177491
+ }
177492
+ ),
177493
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
177494
+ "button",
177495
+ {
177496
+ type: "button",
177497
+ className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177498
+ onClick: () => panelActionsByApiId.get(apiId)?.current?.onSplit(groupId, "below"),
177499
+ title: "Split down",
177500
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Rows2, { className: "size-3.5" })
177501
+ }
177502
+ )
177503
+ ] }),
177504
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
177505
+ "button",
177506
+ {
177507
+ type: "button",
177508
+ className: "inline-flex size-8 items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent rounded transition-colors",
177509
+ onClick: () => panelActionsByApiId.get(apiId)?.current?.onAdd(void 0, groupId),
177510
+ title: "New chat tab",
177511
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" })
177512
+ }
177513
+ )
177514
+ ]
177138
177515
  }
177139
177516
  )
177140
- ] });
177517
+ );
177141
177518
  });
177142
177519
  const chatPanelComponents = {
177143
177520
  chatTab: ChatTabPanel
@@ -177367,10 +177744,19 @@ function DockviewChatContainer({
177367
177744
  }
177368
177745
  });
177369
177746
  }, [adapter2, workspaceId]);
177370
- addTabRef.current = { onAdd: handleAddTab, onSplit: handleSplit };
177371
- closeTabRef.current = closeTab;
177747
+ const actionsRef = reactExports.useRef({
177748
+ onAdd: () => {
177749
+ },
177750
+ onSplit: () => {
177751
+ },
177752
+ onClose: () => {
177753
+ }
177754
+ });
177755
+ actionsRef.current = { onAdd: handleAddTab, onSplit: handleSplit, onClose: closeTab };
177372
177756
  reactExports.useEffect(() => {
177373
177757
  return () => {
177758
+ const api = apiRef.current;
177759
+ if (api) panelActionsByApiId.delete(api.id);
177374
177760
  edgeDragDisposerRef.current?.();
177375
177761
  edgeDragDisposerRef.current = null;
177376
177762
  innerRegisterDisposerRef.current?.();
@@ -177383,7 +177769,10 @@ function DockviewChatContainer({
177383
177769
  initialChatIdsRef.current = initialData?.chatIds ?? null;
177384
177770
  const onReady = reactExports.useCallback(
177385
177771
  (event) => {
177772
+ const prevApi = apiRef.current;
177773
+ if (prevApi && prevApi.id !== event.api.id) panelActionsByApiId.delete(prevApi.id);
177386
177774
  apiRef.current = event.api;
177775
+ panelActionsByApiId.set(event.api.id, actionsRef);
177387
177776
  const savedLayout = initialLayoutRef.current;
177388
177777
  const knownChatIds = initialChatIdsRef.current;
177389
177778
  if (savedLayout && isDockviewLayout(savedLayout)) {
@@ -200947,12 +201336,12 @@ const PANEL_SHORTCUTS = {
200947
201336
  browser: "⇧⌘B"
200948
201337
  };
200949
201338
  const DockviewTerminalContainer = reactExports.lazy(
200950
- () => import("./DockviewTerminalContainer-bMEUzx6R.js").then((m2) => ({
201339
+ () => import("./DockviewTerminalContainer-B1Nw8LXB.js").then((m2) => ({
200951
201340
  default: m2.DockviewTerminalContainer
200952
201341
  }))
200953
201342
  );
200954
201343
  const DockviewBrowserContainer = reactExports.lazy(
200955
- () => import("./DockviewBrowserContainer-Btjtd2O1.js").then((m2) => ({
201344
+ () => import("./DockviewBrowserContainer-bdNwZbjc.js").then((m2) => ({
200956
201345
  default: m2.DockviewBrowserContainer
200957
201346
  }))
200958
201347
  );
@@ -201466,7 +201855,7 @@ function SharedDockviewLayout() {
201466
201855
  const handler = (e3) => {
201467
201856
  const ws = activeWorkspaceIdRef.current;
201468
201857
  const terminalFocused = document.activeElement?.closest(".xterm") != null;
201469
- if (e3.ctrlKey && !e3.metaKey && e3.key.toLowerCase() === "r" && !e3.shiftKey) {
201858
+ if (e3.ctrlKey && !e3.metaKey && e3.key.toLowerCase() === "r" && e3.shiftKey) {
201470
201859
  if (terminalFocused) return;
201471
201860
  e3.preventDefault();
201472
201861
  e3.stopPropagation();
@@ -201638,6 +202027,22 @@ function SharedDockviewLayout() {
201638
202027
  window.addEventListener("band:activate-panel", handler);
201639
202028
  return () => window.removeEventListener("band:activate-panel", handler);
201640
202029
  }, []);
202030
+ reactExports.useEffect(() => {
202031
+ const handler = (e3) => {
202032
+ const reference = e3.detail?.reference;
202033
+ const workspaceId = activeWorkspaceIdRef.current;
202034
+ if (!reference || !workspaceId) return;
202035
+ if (hiddenPanelsRef.current.includes("terminal")) return;
202036
+ apiRef.current?.getPanel("terminal")?.api.setActive();
202037
+ queueMicrotask(() => {
202038
+ window.dispatchEvent(
202039
+ new CustomEvent("band:terminal-insert", { detail: { reference, workspaceId } })
202040
+ );
202041
+ });
202042
+ };
202043
+ window.addEventListener("band:add-to-terminal", handler);
202044
+ return () => window.removeEventListener("band:add-to-terminal", handler);
202045
+ }, []);
201641
202046
  const addMissingPanel = reactExports.useCallback((api, panelId) => {
201642
202047
  if (!(panelId in components)) return;
201643
202048
  const anyExisting = api.getPanel("changes") ?? api.getPanel("files") ?? api.getPanel("terminal") ?? api.getPanel("chat");
@@ -202491,12 +202896,12 @@ function RootLayout() {
202491
202896
  ] })
202492
202897
  ] });
202493
202898
  }
202494
- const $$splitComponentImporter$1 = () => import("./index-DLV7EX0H.js");
202899
+ const $$splitComponentImporter$1 = () => import("./index-DzVgMYHM.js");
202495
202900
  const Route$1 = createFileRoute("/")({
202496
202901
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
202497
202902
  });
202498
- const $$splitNotFoundComponentImporter = () => import("./workspace._workspaceId-Dcw9dnbJ.js");
202499
- const $$splitComponentImporter = () => import("./workspace._workspaceId-CvbciLVC.js");
202903
+ const $$splitNotFoundComponentImporter = () => import("./workspace._workspaceId-CwFiKcq0.js");
202904
+ const $$splitComponentImporter = () => import("./workspace._workspaceId-DXxXFkGR.js");
202500
202905
  const Route2 = createFileRoute("/workspace/$workspaceId")({
202501
202906
  component: lazyRouteComponent($$splitComponentImporter, "component"),
202502
202907
  // Bookmarks / shared links from before route unification (`/workspace/$id/changes`,
@@ -202697,7 +203102,7 @@ export {
202697
203102
  isFunction$1 as by,
202698
203103
  isEmpty as bz,
202699
203104
  continuedIndent as c,
202700
- millisecond as c$,
203105
+ second as c$,
202701
203106
  SearchFilesDialog as c0,
202702
203107
  WorkspacePickerDialog as c1,
202703
203108
  useDiffTarget as c2,
@@ -202707,105 +203112,106 @@ export {
202707
203112
  array$2 as c6,
202708
203113
  ordinal as c7,
202709
203114
  getUserDefinedConfig as c8,
202710
- getIconSVG as c9,
202711
- DropdownMenuItem as cA,
202712
- TriangleAlert as cB,
202713
- RotateCw as cC,
202714
- Rgb as cD,
202715
- rgbConvert as cE,
202716
- define as cF,
202717
- extend$2 as cG,
202718
- Color as cH,
202719
- nogamma as cI,
202720
- hue as cJ,
202721
- time$2 as cK,
202722
- min$1 as cL,
202723
- max$1 as cM,
202724
- dayjs2 as cN,
202725
- timeFormat as cO,
202726
- timeMonth as cP,
202727
- timeSunday as cQ,
202728
- timeSaturday as cR,
202729
- timeFriday as cS,
202730
- timeThursday as cT,
202731
- timeWednesday as cU,
202732
- timeTuesday as cV,
202733
- timeMonday as cW,
202734
- timeDay as cX,
202735
- timeHour as cY,
202736
- timeMinute as cZ,
202737
- second as c_,
202738
- registerIconPacks as ca,
202739
- unknownIcon as cb,
202740
- writeClipboardText as cc,
202741
- readClipboardText as cd,
202742
- ArrowUp as ce,
202743
- ArrowDown as cf,
202744
- ArrowRight as cg,
202745
- ClipboardPaste as ch,
202746
- getCurrentZoomLevel as ci,
202747
- openExternalUrl as cj,
202748
- subscribeToZoomChanges as ck,
202749
- SearchBar as cl,
202750
- ZOOM_CSS_VAR as cm,
202751
- invoke as cn,
202752
- listen as co,
202753
- reactDomExports as cp,
202754
- Globe as cq,
202755
- Popover as cr,
202756
- PopoverTrigger as cs,
202757
- PopoverContent as ct,
202758
- Search as cu,
202759
- Trash2 as cv,
202760
- DropdownMenu as cw,
202761
- DropdownMenuTrigger as cx,
202762
- ChevronDown as cy,
202763
- DropdownMenuContent as cz,
203115
+ writeClipboardText as c9,
203116
+ DropdownMenuContent as cA,
203117
+ DropdownMenuItem as cB,
203118
+ TriangleAlert as cC,
203119
+ RotateCw as cD,
203120
+ Rgb as cE,
203121
+ rgbConvert as cF,
203122
+ define as cG,
203123
+ extend$2 as cH,
203124
+ Color as cI,
203125
+ nogamma as cJ,
203126
+ hue as cK,
203127
+ time$2 as cL,
203128
+ min$1 as cM,
203129
+ max$1 as cN,
203130
+ dayjs2 as cO,
203131
+ timeFormat as cP,
203132
+ timeMonth as cQ,
203133
+ timeSunday as cR,
203134
+ timeSaturday as cS,
203135
+ timeFriday as cT,
203136
+ timeThursday as cU,
203137
+ timeWednesday as cV,
203138
+ timeTuesday as cW,
203139
+ timeMonday as cX,
203140
+ timeDay as cY,
203141
+ timeHour as cZ,
203142
+ timeMinute as c_,
203143
+ readClipboardText as ca,
203144
+ ArrowUp as cb,
203145
+ ArrowDown as cc,
203146
+ ArrowRight as cd,
203147
+ ClipboardCopy as ce,
203148
+ ClipboardPaste as cf,
203149
+ getCurrentZoomLevel as cg,
203150
+ openExternalUrl as ch,
203151
+ subscribeToZoomChanges as ci,
203152
+ SearchBar as cj,
203153
+ ZOOM_CSS_VAR as ck,
203154
+ getIconSVG as cl,
203155
+ registerIconPacks as cm,
203156
+ unknownIcon as cn,
203157
+ invoke as co,
203158
+ listen as cp,
203159
+ reactDomExports as cq,
203160
+ Globe as cr,
203161
+ Popover as cs,
203162
+ PopoverTrigger as ct,
203163
+ PopoverContent as cu,
203164
+ Search as cv,
203165
+ Trash2 as cw,
203166
+ DropdownMenu as cx,
203167
+ DropdownMenuTrigger as cy,
203168
+ ChevronDown as cz,
202764
203169
  foldInside as d,
202765
- isObject$2 as d0,
202766
- isIterateeCall$1 as d1,
202767
- keysIn as d2,
202768
- eq as d3,
202769
- isArrayLike$1 as d4,
202770
- isArray$1 as d5,
202771
- identity$1 as d6,
202772
- isIndex$1 as d7,
202773
- assignValue as d8,
202774
- format as d9,
202775
- Stack as dA,
202776
- MapCache as dB,
202777
- Uint8Array$1 as dC,
202778
- isTypedArray$1 as dD,
202779
- isLength$1 as dE,
202780
- Set$1 as dF,
202781
- createAssigner as dG,
202782
- isPrototype as dH,
202783
- router as dI,
202784
- styles2String as da,
202785
- isLabelStyle as db,
202786
- setToString as dc,
202787
- overRest as dd,
202788
- baseFor as de,
202789
- baseAssignValue as df,
202790
- baseUnary as dg,
202791
- merge$1 as dh,
202792
- isObjectLike$1 as di,
202793
- baseGetTag as dj,
202794
- Symbol$1 as dk,
202795
- arrayLikeKeys as dl,
202796
- baseKeys as dm,
202797
- memoize as dn,
202798
- isArguments$1 as dp,
202799
- copyObject as dq,
202800
- getPrototype as dr,
202801
- cloneArrayBuffer as ds,
202802
- cloneTypedArray as dt,
202803
- getTag$1 as du,
202804
- nodeUtil as dv,
202805
- copyArray as dw,
202806
- isBuffer$1 as dx,
202807
- cloneBuffer as dy,
202808
- initCloneObject as dz,
203170
+ millisecond as d0,
203171
+ isObject$2 as d1,
203172
+ isIterateeCall$1 as d2,
203173
+ keysIn as d3,
203174
+ eq as d4,
203175
+ isArrayLike$1 as d5,
203176
+ isArray$1 as d6,
203177
+ identity$1 as d7,
203178
+ isIndex$1 as d8,
203179
+ assignValue as d9,
203180
+ initCloneObject as dA,
203181
+ Stack as dB,
203182
+ MapCache as dC,
203183
+ Uint8Array$1 as dD,
203184
+ isTypedArray$1 as dE,
203185
+ isLength$1 as dF,
203186
+ Set$1 as dG,
203187
+ createAssigner as dH,
203188
+ isPrototype as dI,
203189
+ router as dJ,
203190
+ format as da,
203191
+ styles2String as db,
203192
+ isLabelStyle as dc,
203193
+ setToString as dd,
203194
+ overRest as de,
203195
+ baseFor as df,
203196
+ baseAssignValue as dg,
203197
+ baseUnary as dh,
203198
+ merge$1 as di,
203199
+ isObjectLike$1 as dj,
203200
+ baseGetTag as dk,
203201
+ Symbol$1 as dl,
203202
+ arrayLikeKeys as dm,
203203
+ baseKeys as dn,
203204
+ memoize as dp,
203205
+ isArguments$1 as dq,
203206
+ copyObject as dr,
203207
+ getPrototype as ds,
203208
+ cloneArrayBuffer as dt,
203209
+ cloneTypedArray as du,
203210
+ getTag$1 as dv,
203211
+ nodeUtil as dw,
203212
+ copyArray as dx,
203213
+ isBuffer$1 as dy,
203214
+ cloneBuffer as dz,
202809
203215
  ifNotIn as e,
202810
203216
  foldNodeProp as f,
202811
203217
  completeFromList as g,