@band-app/server 0.9.2 → 0.10.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 (173) hide show
  1. package/dist/client/assets/{DockviewTerminalContainer-DWHIc-4-.js → DockviewTerminalContainer-C5yFKEoK.js} +2 -2
  2. package/dist/client/assets/TerminalPanel-DAwQhW0y.js +4 -0
  3. package/dist/client/assets/{_basePickBy-BKaMH_7t.js → _basePickBy-Cxy2uLa-.js} +1 -1
  4. package/dist/client/assets/{_baseUniq-CQkxA8qy.js → _baseUniq-jya1YXzy.js} +1 -1
  5. package/dist/client/assets/{arc-Bose4Nlr.js → arc-Dxa_mBOn.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-VXUJARFQ-2sFlOIMR.js → architectureDiagram-VXUJARFQ-DHLla5pN.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-VD42YOAC-DJAsEjOI.js → blockDiagram-VD42YOAC-CxqGHWD6.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-YG6GDRKO-DheiVuNi.js → c4Diagram-YG6GDRKO-CJ14R1KC.js} +1 -1
  9. package/dist/client/assets/channel-gL3XfYSv.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-DvXp34cF.js → chunk-4BX2VUAB-B7W58V1V.js} +1 -1
  11. package/dist/client/assets/{chunk-55IACEB6-CDyPx-Tg.js → chunk-55IACEB6-BexaNtN4.js} +1 -1
  12. package/dist/client/assets/{chunk-B4BG7PRW-BTtdtPVg.js → chunk-B4BG7PRW-DkzDTPIe.js} +1 -1
  13. package/dist/client/assets/{chunk-DI55MBZ5-9GoKl76p.js → chunk-DI55MBZ5-C_PHG7rI.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-C01REv3a.js → chunk-FMBD7UC4-9ESlUsET.js} +1 -1
  15. package/dist/client/assets/{chunk-QN33PNHL-CoCCh58U.js → chunk-QN33PNHL-DWo9MH1S.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-DDFTrbxS.js → chunk-QZHKN3VN-Bbgg8OcM.js} +1 -1
  17. package/dist/client/assets/{chunk-TZMSLE5B-DfvMfmy7.js → chunk-TZMSLE5B-CjGBNyAK.js} +1 -1
  18. package/dist/client/assets/classDiagram-2ON5EDUG-Dset5Kja.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-WZHVMYZB-Dset5Kja.js +1 -0
  20. package/dist/client/assets/clone-CGaELEce.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-B7exDDfj.js → cose-bilkent-S5V4N54A-Bdu80dtY.js} +1 -1
  22. package/dist/client/assets/{dagre-6UL2VRFP-Cel7r0v3.js → dagre-6UL2VRFP-CNpvZCIA.js} +2 -2
  23. package/dist/client/assets/{diagram-PSM6KHXK-C7lbk8Kf.js → diagram-PSM6KHXK-DBqxkCV6.js} +1 -1
  24. package/dist/client/assets/{diagram-QEK2KX5R-DvlCS56Z.js → diagram-QEK2KX5R-BJ70tnCT.js} +1 -1
  25. package/dist/client/assets/{diagram-S2PKOQOG-HSl5Oecr.js → diagram-S2PKOQOG-BJT9a_iD.js} +1 -1
  26. package/dist/client/assets/{erDiagram-Q2GNP2WA-B2_RJg2L.js → erDiagram-Q2GNP2WA-DlDgnxvr.js} +1 -1
  27. package/dist/client/assets/{flowDiagram-NV44I4VS-BPYCHaLb.js → flowDiagram-NV44I4VS-CtnfmEyX.js} +1 -1
  28. package/dist/client/assets/{ganttDiagram-JELNMOA3-CD-msupP.js → ganttDiagram-JELNMOA3-CDltME-1.js} +1 -1
  29. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-xwVYLUhE.js → gitGraphDiagram-V2S2FVAM-BSiSLqD_.js} +1 -1
  30. package/dist/client/assets/{graph-Dbv1AWta.js → graph-BXFhffUt.js} +1 -1
  31. package/dist/client/assets/{highlighted-body-B3W2YXNL-CGkNHhPo.js → highlighted-body-B3W2YXNL-baZl_B7-.js} +1 -1
  32. package/dist/client/assets/{index-Do3joW0D.js → index-B6iGb_w2.js} +1 -1
  33. package/dist/client/assets/{index-DGsskOgM.js → index-BIHulysR.js} +1 -1
  34. package/dist/client/assets/{index-DsmQlt3C.js → index-BjDbhfGt.js} +2 -2
  35. package/dist/client/assets/{index-BptuxjE6.js → index-C2qsZyf5.js} +1 -1
  36. package/dist/client/assets/{index-C_SXPmbV.js → index-CXk5lAWQ.js} +1 -1
  37. package/dist/client/assets/{index-B5YiIiNq.js → index-CbKmWyq9.js} +1 -1
  38. package/dist/client/assets/{index-BDzzWD64.js → index-D-swyWIZ.js} +1 -1
  39. package/dist/client/assets/{index-BwhOjkOO.js → index-DCOV9hmX.js} +1 -1
  40. package/dist/client/assets/{index-CESm9EUT.js → index-DDgejW9Y.js} +1 -1
  41. package/dist/client/assets/{index-CiPtBqSR.js → index-DIzuf_Dt.js} +1 -1
  42. package/dist/client/assets/{index-D9aDcgku.js → index-DNv51ILn.js} +1 -1
  43. package/dist/client/assets/{index-D5rP0BSv.js → index-DbdSOCzr.js} +1 -1
  44. package/dist/client/assets/{index-A2XaYyYw.js → index-DlZs_C_Z.js} +1 -1
  45. package/dist/client/assets/{index-C5NAzmgp.js → index-DlkLRARc.js} +1 -1
  46. package/dist/client/assets/{index-CF0KBM34.js → index-Y5qBvPAz.js} +1 -1
  47. package/dist/client/assets/{index-B7ZSAY53.js → index-l7pbZp6D.js} +1 -1
  48. package/dist/client/assets/{index-qKsRlhz3.js → index-muvgthqG.js} +1 -1
  49. package/dist/client/assets/{index-BBs4HyTg.js → index-n-QQQGkk.js} +1 -1
  50. package/dist/client/assets/{infoDiagram-HS3SLOUP-hfH1C_pr.js → infoDiagram-HS3SLOUP-C-8cQbzs.js} +1 -1
  51. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-ZSxc6ITj.js → journeyDiagram-XKPGCS4Q-Dp9Od5Lo.js} +1 -1
  52. package/dist/client/assets/{kanban-definition-3W4ZIXB7-U4z7vSSP.js → kanban-definition-3W4ZIXB7-CTeqP1Wl.js} +1 -1
  53. package/dist/client/assets/{layout-BkxMGu4B.js → layout-wpsrF_0j.js} +1 -1
  54. package/dist/client/assets/{linear-Bdy4hNwe.js → linear--cKtF_4-.js} +1 -1
  55. package/dist/client/assets/main-F2T48yRI.css +1 -0
  56. package/dist/client/assets/main-MjQQLQea.js +986 -0
  57. package/dist/client/assets/{mindmap-definition-VGOIOE7T-CJyNknV7.js → mindmap-definition-VGOIOE7T-CpbJEgPa.js} +1 -1
  58. package/dist/client/assets/{pieDiagram-ADFJNKIX-DwfChKVB.js → pieDiagram-ADFJNKIX-Bqm8Hi0T.js} +1 -1
  59. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-QD4JEDeD.js → quadrantDiagram-AYHSOK5B-KBK2cMVk.js} +1 -1
  60. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-DBOLPRLx.js → requirementDiagram-UZGBJVZJ-vQQFD9zc.js} +1 -1
  61. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-D73QuPjf.js → sankeyDiagram-TZEHDZUN-cTtL91Re.js} +1 -1
  62. package/dist/client/assets/{sequenceDiagram-WL72ISMW-sQ_Dekb1.js → sequenceDiagram-WL72ISMW-BuGTsJB7.js} +1 -1
  63. package/dist/client/assets/{square-terminal-BmZtdUqJ.js → square-terminal-6YppA-hI.js} +1 -1
  64. package/dist/client/assets/{stateDiagram-FKZM4ZOC-DejJZefR.js → stateDiagram-FKZM4ZOC-Cxlf071k.js} +1 -1
  65. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-C1zjRAy3.js +1 -0
  66. package/dist/client/assets/{timeline-definition-IT6M3QCI-5gT-CArs.js → timeline-definition-IT6M3QCI-CL3qYiMu.js} +1 -1
  67. package/dist/client/assets/{treemap-GDKQZRPO-Sm5U59Kz.js → treemap-GDKQZRPO-DRAWRdVd.js} +1 -1
  68. package/dist/client/assets/{useSessionListContext-iz8sf9L6.js → useSessionListContext-wCLhqmn8.js} +1 -1
  69. package/dist/client/assets/workspace._workspaceId-BZdlER3j.js +1 -0
  70. package/dist/client/assets/{workspace._workspaceId.changes-Dn42JgBH.js → workspace._workspaceId.changes-d_RXYsmI.js} +1 -1
  71. package/dist/client/assets/workspace._workspaceId.code-BIEwg7CK.js +1 -0
  72. package/dist/client/assets/{workspace._workspaceId.code._-OCcsWq1e.js → workspace._workspaceId.code._-DWbDHeSI.js} +1 -1
  73. package/dist/client/assets/{workspace._workspaceId.code.index-D8CkYPgV.js → workspace._workspaceId.code.index-DnBvnsEY.js} +1 -1
  74. package/dist/client/assets/{workspace._workspaceId.index-BBhBKPNM.js → workspace._workspaceId.index-BVKcI4Hz.js} +1 -1
  75. package/dist/client/assets/{workspace._workspaceId.terminal-B_mQrV6_.js → workspace._workspaceId.terminal-B6e3iDCL.js} +2 -2
  76. package/dist/client/assets/{xychartDiagram-PRI3JC2R-h6Sm8OTK.js → xychartDiagram-PRI3JC2R-Dk1ZOoyd.js} +1 -1
  77. package/dist/migrations/20260512125926_pin_worktrees/migration.sql +1 -0
  78. package/dist/migrations/20260512125926_pin_worktrees/snapshot.json +727 -0
  79. package/dist/server/assets/{DockviewTerminalContainer-TTt325-b.js → DockviewTerminalContainer-BClknz0C.js} +3 -3
  80. package/dist/server/assets/{TerminalPanel-DRzfuu-T.js → TerminalPanel-Dpk4kp0C.js} +44 -1
  81. package/dist/server/assets/{_basePickBy-wC54TbQu.js → _basePickBy-CQWrFHod.js} +2 -2
  82. package/dist/server/assets/{_baseUniq-rn84LOSK.js → _baseUniq-ChPDjMP0.js} +1 -1
  83. package/dist/server/assets/{_tanstack-start-manifest_v-fymioLKZ.js → _tanstack-start-manifest_v-D4996aDN.js} +1 -1
  84. package/dist/server/assets/{arc-DdlCXdeL.js → arc-D-SYKFhU.js} +1 -1
  85. package/dist/server/assets/{architecture-7HQA4BMR-CHMWBrpq.js → architecture-7HQA4BMR-Dko2LbDd.js} +6 -6
  86. package/dist/server/assets/{architectureDiagram-VXUJARFQ-CqvTF0VE.js → architectureDiagram-VXUJARFQ-DUGfoAf_.js} +6 -6
  87. package/dist/server/assets/{blockDiagram-VD42YOAC-Bc-Qk0S9.js → blockDiagram-VD42YOAC-pT0fTRP_.js} +6 -6
  88. package/dist/server/assets/{c4Diagram-YG6GDRKO-COi5PFIX.js → c4Diagram-YG6GDRKO-DPx-FvB1.js} +2 -2
  89. package/dist/server/assets/{channel-B2GZC_H9.js → channel-BtdYXKY6.js} +1 -1
  90. package/dist/server/assets/{chunk-4BX2VUAB-rhgtjYHc.js → chunk-4BX2VUAB-DwT0XB8f.js} +1 -1
  91. package/dist/server/assets/{chunk-55IACEB6-CLPQZ1p7.js → chunk-55IACEB6-42pp-S9e.js} +1 -1
  92. package/dist/server/assets/{chunk-B4BG7PRW-6Vb3MfoD.js → chunk-B4BG7PRW-B9HlFFeK.js} +4 -4
  93. package/dist/server/assets/{chunk-DI55MBZ5-D-VoOG5D.js → chunk-DI55MBZ5-UJ9TEI0f.js} +3 -3
  94. package/dist/server/assets/{chunk-FMBD7UC4-CByHMCvr.js → chunk-FMBD7UC4-D0p4jYwA.js} +1 -1
  95. package/dist/server/assets/{chunk-QN33PNHL-CRZHpta9.js → chunk-QN33PNHL-uyJLpuzt.js} +1 -1
  96. package/dist/server/assets/{chunk-QZHKN3VN-ncUfNOMa.js → chunk-QZHKN3VN-dIcVPiYR.js} +1 -1
  97. package/dist/server/assets/{chunk-TZMSLE5B-BGxlM2si.js → chunk-TZMSLE5B-3l__otri.js} +1 -1
  98. package/dist/server/assets/{classDiagram-v2-WZHVMYZB-SabF3eWj.js → classDiagram-2ON5EDUG-CxlZAW4M.js} +5 -5
  99. package/dist/server/assets/{classDiagram-2ON5EDUG-SabF3eWj.js → classDiagram-v2-WZHVMYZB-CxlZAW4M.js} +5 -5
  100. package/dist/server/assets/{clone-CQGJ84x8.js → clone-BtN5mmzP.js} +1 -1
  101. package/dist/server/assets/{cose-bilkent-S5V4N54A-WSuuldrv.js → cose-bilkent-S5V4N54A-CpHc0Viy.js} +1 -1
  102. package/dist/server/assets/{dagre-6UL2VRFP-DZfpOMzg.js → dagre-6UL2VRFP-BmlvwxMz.js} +6 -6
  103. package/dist/server/assets/{diagram-PSM6KHXK-DCKwYA11.js → diagram-PSM6KHXK-B0TgGZY7.js} +7 -7
  104. package/dist/server/assets/{diagram-QEK2KX5R-GhJ4dzVD.js → diagram-QEK2KX5R-D3Y8zwos.js} +6 -6
  105. package/dist/server/assets/{diagram-S2PKOQOG-DBeAGiPC.js → diagram-S2PKOQOG-BHuUrG2N.js} +6 -6
  106. package/dist/server/assets/{erDiagram-Q2GNP2WA-XphQqWxZ.js → erDiagram-Q2GNP2WA-DM8WJlsi.js} +4 -4
  107. package/dist/server/assets/{flowDiagram-NV44I4VS-Cw9n-l35.js → flowDiagram-NV44I4VS-BfyIqNem.js} +5 -5
  108. package/dist/server/assets/{ganttDiagram-JELNMOA3-CqqJbuET.js → ganttDiagram-JELNMOA3-BZQeLvAR.js} +2 -2
  109. package/dist/server/assets/{gitGraph-G5XIXVHT-DvgCllrO.js → gitGraph-G5XIXVHT-CCcYJ7dh.js} +6 -6
  110. package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-CUIK26NP.js → gitGraphDiagram-V2S2FVAM-bCVMHPpA.js} +7 -7
  111. package/dist/server/assets/{graph-B-wfb0D4.js → graph-CIjfCamy.js} +2 -2
  112. package/dist/server/assets/{highlighted-body-B3W2YXNL-BVGB-5j8.js → highlighted-body-B3W2YXNL-DgdfkSxA.js} +1 -1
  113. package/dist/server/assets/{index-zE6_NUk4.js → index-0_BGm0mn.js} +3 -3
  114. package/dist/server/assets/{index-g309PIeU.js → index-B2qKtyPL.js} +5 -5
  115. package/dist/server/assets/{index-BCNMZ2-I.js → index-BRIhAKe8.js} +2 -2
  116. package/dist/server/assets/{index-D6pmvl-E.js → index-BT09Zz2i.js} +2 -2
  117. package/dist/server/assets/{index-O9-otWU5.js → index-BcYdtAMM.js} +2 -2
  118. package/dist/server/assets/{index-DAlp0b3q.js → index-BgilcgRG.js} +2 -2
  119. package/dist/server/assets/{index-CMs8dLKE.js → index-BoanxRSH.js} +2 -2
  120. package/dist/server/assets/{index-DqCcM85h.js → index-CBXzgKOs.js} +2 -2
  121. package/dist/server/assets/{index-BUSq_KFc.js → index-CO5kqxG3.js} +5 -5
  122. package/dist/server/assets/{index-tbrMCGeF.js → index-CPgf4fox.js} +2 -2
  123. package/dist/server/assets/{index-BHR21Rwx.js → index-CQZMfw92.js} +2 -2
  124. package/dist/server/assets/{index-D4Zt6M4l.js → index-CUrmFB9U.js} +2 -2
  125. package/dist/server/assets/{index-BoCTcQyA.js → index-CW27f0k8.js} +2 -2
  126. package/dist/server/assets/{index-wCTie1M2.js → index-ChjA2VmA.js} +1 -1
  127. package/dist/server/assets/{index-CznnHJPs.js → index-DO78fmX2.js} +2 -2
  128. package/dist/server/assets/{index-a-16Ui_6.js → index-PcwomXXg.js} +1 -1
  129. package/dist/server/assets/{index-DEkonSBc.js → index-sBBVHJec.js} +4 -4
  130. package/dist/server/assets/{index-BUKmWu07.js → index-xHAcoUao.js} +3 -3
  131. package/dist/server/assets/{info-VBDWY6EO-7gpYhbqJ.js → info-VBDWY6EO-DeW_eJX1.js} +6 -6
  132. package/dist/server/assets/{infoDiagram-HS3SLOUP-DuA859Z1.js → infoDiagram-HS3SLOUP-RRsQoFFk.js} +5 -5
  133. package/dist/server/assets/{journeyDiagram-XKPGCS4Q-PiSB9SFS.js → journeyDiagram-XKPGCS4Q-BthUaNJH.js} +4 -4
  134. package/dist/server/assets/{kanban-definition-3W4ZIXB7-Fl-z0jKd.js → kanban-definition-3W4ZIXB7-g-dju6UR.js} +2 -2
  135. package/dist/server/assets/{layout-BwTTgoVB.js → layout-un8ibgzD.js} +4 -4
  136. package/dist/server/assets/{linear-6z47mrNn.js → linear-CLKN7W2t.js} +1 -1
  137. package/dist/server/assets/{mermaid-3ZIDBTTL-rjgzkBvP.js → mermaid-3ZIDBTTL-gGOjGhZZ.js} +1 -1
  138. package/dist/server/assets/{mermaid-parser.core-OR3z5VGq.js → mermaid-parser.core-Dt-fPNwe.js} +11 -11
  139. package/dist/server/assets/{mindmap-definition-VGOIOE7T-RsSUd0h5.js → mindmap-definition-VGOIOE7T-CyOPm1d2.js} +3 -3
  140. package/dist/server/assets/{packet-DYOGHKS2-DdI3YR11.js → packet-DYOGHKS2-4sSK9trD.js} +6 -6
  141. package/dist/server/assets/{pie-VRWISCQL-CvLwiHxU.js → pie-VRWISCQL-C2jGDe4p.js} +6 -6
  142. package/dist/server/assets/{pieDiagram-ADFJNKIX-CS1QqpkR.js → pieDiagram-ADFJNKIX-DWZOj9Y0.js} +7 -7
  143. package/dist/server/assets/{quadrantDiagram-AYHSOK5B-sOsgkH1q.js → quadrantDiagram-AYHSOK5B-D4ONUX7b.js} +2 -2
  144. package/dist/server/assets/{radar-ZZBFDIW7-DcuGjSpy.js → radar-ZZBFDIW7-BJ1GmVhh.js} +6 -6
  145. package/dist/server/assets/{requirementDiagram-UZGBJVZJ-DxsTf_dF.js → requirementDiagram-UZGBJVZJ-UgBPsTYb.js} +3 -3
  146. package/dist/server/assets/{router-zkGZin-Y.js → router-BLOX4jR4.js} +2946 -587
  147. package/dist/server/assets/{sankeyDiagram-TZEHDZUN-Dv69rb4x.js → sankeyDiagram-TZEHDZUN-DR346iyM.js} +1 -1
  148. package/dist/server/assets/{sequenceDiagram-WL72ISMW-DdZyEvL3.js → sequenceDiagram-WL72ISMW-ampkthMk.js} +3 -3
  149. package/dist/server/assets/{square-terminal-hlWJQE0a.js → square-terminal-CuUDJxG7.js} +1 -1
  150. package/dist/server/assets/{stateDiagram-FKZM4ZOC-D3Tj81-E.js → stateDiagram-FKZM4ZOC-BGJgIHAr.js} +8 -8
  151. package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-Dx5gqfCT.js → stateDiagram-v2-4FDKWEC3-DV0c4QE4.js} +4 -4
  152. package/dist/server/assets/{timeline-definition-IT6M3QCI-CcjZ3wnd.js → timeline-definition-IT6M3QCI-V6Yu7fCS.js} +2 -2
  153. package/dist/server/assets/{treemap-GDKQZRPO-BRethL8T.js → treemap-GDKQZRPO-Dwk_JN75.js} +6 -6
  154. package/dist/server/assets/{workspace._workspaceId-7fdVKeNu.js → workspace._workspaceId-BIUZ7lNJ.js} +15 -3
  155. package/dist/server/assets/{workspace._workspaceId.changes-OtWo7a6k.js → workspace._workspaceId.changes-Cz2Q9MYv.js} +1 -1
  156. package/dist/server/assets/{workspace._workspaceId.code._-C8dWBJOO.js → workspace._workspaceId.code._-mhiuiARp.js} +1 -1
  157. package/dist/server/assets/{workspace._workspaceId.code.index-DpGdriuG.js → workspace._workspaceId.code.index-DJE-_14B.js} +1 -1
  158. package/dist/server/assets/{workspace._workspaceId.index-DGG24yQO.js → workspace._workspaceId.index-BaBfW1nO.js} +1 -1
  159. package/dist/server/assets/{workspace._workspaceId.terminal-BCUV7dQN.js → workspace._workspaceId.terminal-CKX5RImf.js} +2 -2
  160. package/dist/server/assets/{xychartDiagram-PRI3JC2R-C01ACkIV.js → xychartDiagram-PRI3JC2R-DZLYbs7Q.js} +2 -2
  161. package/dist/server/server.js +2 -2
  162. package/dist/start-server.mjs +3381 -1104
  163. package/package.json +5 -5
  164. package/dist/client/assets/TerminalPanel-m73O5CIc.js +0 -4
  165. package/dist/client/assets/channel-BnzmiQbl.js +0 -1
  166. package/dist/client/assets/classDiagram-2ON5EDUG-BH5EB2Fv.js +0 -1
  167. package/dist/client/assets/classDiagram-v2-WZHVMYZB-BH5EB2Fv.js +0 -1
  168. package/dist/client/assets/clone-Bat0lHCp.js +0 -1
  169. package/dist/client/assets/main-DwiBxZvA.js +0 -974
  170. package/dist/client/assets/main-Tt4WZJMG.css +0 -1
  171. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-C3KpG1Lu.js +0 -1
  172. package/dist/client/assets/workspace._workspaceId-CgBppz9O.js +0 -1
  173. package/dist/client/assets/workspace._workspaceId.code-C3Nx-w_a.js +0 -1
@@ -1093,44 +1093,44 @@ const createLucideIcon = (iconName, iconNode) => {
1093
1093
  Component.displayName = toPascalCase(iconName);
1094
1094
  return Component;
1095
1095
  };
1096
- const __iconNode$1q = [
1096
+ const __iconNode$1u = [
1097
1097
  ["path", { d: "M12 17V3", key: "1cwfxf" }],
1098
1098
  ["path", { d: "m6 11 6 6 6-6", key: "12ii2o" }],
1099
1099
  ["path", { d: "M19 21H5", key: "150jfl" }]
1100
1100
  ];
1101
- const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$1q);
1102
- const __iconNode$1p = [
1101
+ const ArrowDownToLine = createLucideIcon("arrow-down-to-line", __iconNode$1u);
1102
+ const __iconNode$1t = [
1103
1103
  ["path", { d: "M12 5v14", key: "s699le" }],
1104
1104
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
1105
1105
  ];
1106
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$1p);
1107
- const __iconNode$1o = [
1106
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$1t);
1107
+ const __iconNode$1s = [
1108
1108
  ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
1109
1109
  ["path", { d: "M19 12H5", key: "x3x0zl" }]
1110
1110
  ];
1111
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$1o);
1112
- const __iconNode$1n = [
1111
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$1s);
1112
+ const __iconNode$1r = [
1113
1113
  ["path", { d: "M5 12h14", key: "1ays0h" }],
1114
1114
  ["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
1115
1115
  ];
1116
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$1n);
1117
- const __iconNode$1m = [
1116
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$1r);
1117
+ const __iconNode$1q = [
1118
1118
  ["path", { d: "m18 9-6-6-6 6", key: "kcunyi" }],
1119
1119
  ["path", { d: "M12 3v14", key: "7cf3v8" }],
1120
1120
  ["path", { d: "M5 21h14", key: "11awu3" }]
1121
1121
  ];
1122
- const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$1m);
1123
- const __iconNode$1l = [
1122
+ const ArrowUpFromLine = createLucideIcon("arrow-up-from-line", __iconNode$1q);
1123
+ const __iconNode$1p = [
1124
1124
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
1125
1125
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
1126
1126
  ];
1127
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$1l);
1128
- const __iconNode$1k = [
1127
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$1p);
1128
+ const __iconNode$1o = [
1129
1129
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1130
1130
  ["path", { d: "M4.929 4.929 19.07 19.071", key: "196cmz" }]
1131
1131
  ];
1132
- const Ban = createLucideIcon("ban", __iconNode$1k);
1133
- const __iconNode$1j = [
1132
+ const Ban = createLucideIcon("ban", __iconNode$1o);
1133
+ const __iconNode$1n = [
1134
1134
  ["path", { d: "M12 8V4H8", key: "hb8ula" }],
1135
1135
  ["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
1136
1136
  ["path", { d: "M2 14h2", key: "vft8re" }],
@@ -1138,8 +1138,8 @@ const __iconNode$1j = [
1138
1138
  ["path", { d: "M15 13v2", key: "1xurst" }],
1139
1139
  ["path", { d: "M9 13v2", key: "rq6x2g" }]
1140
1140
  ];
1141
- const Bot = createLucideIcon("bot", __iconNode$1j);
1142
- const __iconNode$1i = [
1141
+ const Bot = createLucideIcon("bot", __iconNode$1n);
1142
+ const __iconNode$1m = [
1143
1143
  [
1144
1144
  "path",
1145
1145
  { d: "M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1", key: "ezmyqa" }
@@ -1152,54 +1152,62 @@ const __iconNode$1i = [
1152
1152
  }
1153
1153
  ]
1154
1154
  ];
1155
- const Braces = createLucideIcon("braces", __iconNode$1i);
1156
- const __iconNode$1h = [
1155
+ const Braces = createLucideIcon("braces", __iconNode$1m);
1156
+ const __iconNode$1l = [
1157
1157
  ["path", { d: "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", key: "d5nyq2" }],
1158
1158
  ["path", { d: "M22 9v7", key: "pvm9v3" }],
1159
1159
  ["path", { d: "M3.304 13h6.392", key: "1q3zxz" }],
1160
1160
  ["circle", { cx: "18.5", cy: "12.5", r: "3.5", key: "z97x68" }]
1161
1161
  ];
1162
- const CaseSensitive = createLucideIcon("case-sensitive", __iconNode$1h);
1163
- const __iconNode$1g = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
1164
- const Check = createLucideIcon("check", __iconNode$1g);
1165
- const __iconNode$1f = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
1166
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$1f);
1167
- const __iconNode$1e = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
1168
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1e);
1169
- const __iconNode$1d = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
1170
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$1d);
1171
- const __iconNode$1c = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
1172
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$1c);
1173
- const __iconNode$1b = [
1162
+ const CaseSensitive = createLucideIcon("case-sensitive", __iconNode$1l);
1163
+ const __iconNode$1k = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
1164
+ const Check = createLucideIcon("check", __iconNode$1k);
1165
+ const __iconNode$1j = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
1166
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$1j);
1167
+ const __iconNode$1i = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
1168
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$1i);
1169
+ const __iconNode$1h = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
1170
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$1h);
1171
+ const __iconNode$1g = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
1172
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$1g);
1173
+ const __iconNode$1f = [
1174
1174
  ["path", { d: "m7 20 5-5 5 5", key: "13a0gw" }],
1175
1175
  ["path", { d: "m7 4 5 5 5-5", key: "1kwcof" }]
1176
1176
  ];
1177
- const ChevronsDownUp = createLucideIcon("chevrons-down-up", __iconNode$1b);
1178
- const __iconNode$1a = [
1177
+ const ChevronsDownUp = createLucideIcon("chevrons-down-up", __iconNode$1f);
1178
+ const __iconNode$1e = [
1179
1179
  ["path", { d: "m7 15 5 5 5-5", key: "1hf1tw" }],
1180
1180
  ["path", { d: "m7 9 5-5 5 5", key: "sgt6xg" }]
1181
1181
  ];
1182
- const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1a);
1183
- const __iconNode$19 = [
1182
+ const ChevronsUpDown = createLucideIcon("chevrons-up-down", __iconNode$1e);
1183
+ const __iconNode$1d = [
1184
1184
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1185
1185
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
1186
1186
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
1187
1187
  ];
1188
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$19);
1189
- const __iconNode$18 = [
1188
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$1d);
1189
+ const __iconNode$1c = [
1190
1190
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1191
1191
  ["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
1192
1192
  ];
1193
- const CircleCheck = createLucideIcon("circle-check", __iconNode$18);
1194
- const __iconNode$17 = [
1193
+ const CircleCheck = createLucideIcon("circle-check", __iconNode$1c);
1194
+ const __iconNode$1b = [
1195
1195
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1196
1196
  ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
1197
1197
  ["path", { d: "m9 9 6 6", key: "z0biqf" }]
1198
1198
  ];
1199
- const CircleX = createLucideIcon("circle-x", __iconNode$17);
1200
- const __iconNode$16 = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
1201
- const Circle = createLucideIcon("circle", __iconNode$16);
1202
- const __iconNode$15 = [
1199
+ const CircleX = createLucideIcon("circle-x", __iconNode$1b);
1200
+ const __iconNode$1a = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
1201
+ const Circle = createLucideIcon("circle", __iconNode$1a);
1202
+ const __iconNode$19 = [
1203
+ ["path", { d: "M11 14h10", key: "1w8e9d" }],
1204
+ ["path", { d: "M16 4h2a2 2 0 0 1 2 2v1.344", key: "1e62lh" }],
1205
+ ["path", { d: "m17 18 4-4-4-4", key: "z2g111" }],
1206
+ ["path", { d: "M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113", key: "bjbb7m" }],
1207
+ ["rect", { x: "8", y: "2", width: "8", height: "4", rx: "1", key: "ublpy" }]
1208
+ ];
1209
+ const ClipboardPaste = createLucideIcon("clipboard-paste", __iconNode$19);
1210
+ const __iconNode$18 = [
1203
1211
  ["rect", { width: "8", height: "4", x: "8", y: "2", rx: "1", ry: "1", key: "tgr4d6" }],
1204
1212
  [
1205
1213
  "path",
@@ -1209,59 +1217,59 @@ const __iconNode$15 = [
1209
1217
  }
1210
1218
  ]
1211
1219
  ];
1212
- const Clipboard = createLucideIcon("clipboard", __iconNode$15);
1213
- const __iconNode$14 = [
1220
+ const Clipboard = createLucideIcon("clipboard", __iconNode$18);
1221
+ const __iconNode$17 = [
1214
1222
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1215
1223
  ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
1216
1224
  ];
1217
- const Clock = createLucideIcon("clock", __iconNode$14);
1218
- const __iconNode$13 = [
1225
+ const Clock = createLucideIcon("clock", __iconNode$17);
1226
+ const __iconNode$16 = [
1219
1227
  ["path", { d: "m18 16 4-4-4-4", key: "1inbqp" }],
1220
1228
  ["path", { d: "m6 8-4 4 4 4", key: "15zrgr" }],
1221
1229
  ["path", { d: "m14.5 4-5 16", key: "e7oirm" }]
1222
1230
  ];
1223
- const CodeXml = createLucideIcon("code-xml", __iconNode$13);
1224
- const __iconNode$12 = [
1231
+ const CodeXml = createLucideIcon("code-xml", __iconNode$16);
1232
+ const __iconNode$15 = [
1225
1233
  ["path", { d: "m16 18 6-6-6-6", key: "eg8j8" }],
1226
1234
  ["path", { d: "m8 6-6 6 6 6", key: "ppft3o" }]
1227
1235
  ];
1228
- const Code = createLucideIcon("code", __iconNode$12);
1229
- const __iconNode$11 = [
1236
+ const Code = createLucideIcon("code", __iconNode$15);
1237
+ const __iconNode$14 = [
1230
1238
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1231
1239
  ["path", { d: "M12 3v18", key: "108xh3" }]
1232
1240
  ];
1233
- const Columns2 = createLucideIcon("columns-2", __iconNode$11);
1234
- const __iconNode$10 = [
1241
+ const Columns2 = createLucideIcon("columns-2", __iconNode$14);
1242
+ const __iconNode$13 = [
1235
1243
  [
1236
1244
  "path",
1237
1245
  { d: "M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3", key: "11bfej" }
1238
1246
  ]
1239
1247
  ];
1240
- const Command$1 = createLucideIcon("command", __iconNode$10);
1241
- const __iconNode$$ = [
1248
+ const Command$1 = createLucideIcon("command", __iconNode$13);
1249
+ const __iconNode$12 = [
1242
1250
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
1243
1251
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
1244
1252
  ];
1245
- const Copy = createLucideIcon("copy", __iconNode$$);
1246
- const __iconNode$_ = [
1253
+ const Copy = createLucideIcon("copy", __iconNode$12);
1254
+ const __iconNode$11 = [
1247
1255
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
1248
1256
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
1249
1257
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
1250
1258
  ];
1251
- const Database = createLucideIcon("database", __iconNode$_);
1252
- const __iconNode$Z = [
1259
+ const Database = createLucideIcon("database", __iconNode$11);
1260
+ const __iconNode$10 = [
1253
1261
  ["path", { d: "M12 15V3", key: "m9g1x1" }],
1254
1262
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
1255
1263
  ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
1256
1264
  ];
1257
- const Download = createLucideIcon("download", __iconNode$Z);
1258
- const __iconNode$Y = [
1265
+ const Download = createLucideIcon("download", __iconNode$10);
1266
+ const __iconNode$$ = [
1259
1267
  ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
1260
1268
  ["circle", { cx: "12", cy: "5", r: "1", key: "gxeob9" }],
1261
1269
  ["circle", { cx: "12", cy: "19", r: "1", key: "lyex9k" }]
1262
1270
  ];
1263
- const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$Y);
1264
- const __iconNode$X = [
1271
+ const EllipsisVertical = createLucideIcon("ellipsis-vertical", __iconNode$$);
1272
+ const __iconNode$_ = [
1265
1273
  ["path", { d: "m15 15 6 6", key: "1s409w" }],
1266
1274
  ["path", { d: "m15 9 6-6", key: "ko1vev" }],
1267
1275
  ["path", { d: "M21 16v5h-5", key: "1ck2sf" }],
@@ -1271,14 +1279,14 @@ const __iconNode$X = [
1271
1279
  ["path", { d: "M3 8V3h5", key: "1ln10m" }],
1272
1280
  ["path", { d: "M9 9 3 3", key: "v551iv" }]
1273
1281
  ];
1274
- const Expand = createLucideIcon("expand", __iconNode$X);
1275
- const __iconNode$W = [
1282
+ const Expand = createLucideIcon("expand", __iconNode$_);
1283
+ const __iconNode$Z = [
1276
1284
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
1277
1285
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
1278
1286
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
1279
1287
  ];
1280
- const ExternalLink$1 = createLucideIcon("external-link", __iconNode$W);
1281
- const __iconNode$V = [
1288
+ const ExternalLink$1 = createLucideIcon("external-link", __iconNode$Z);
1289
+ const __iconNode$Y = [
1282
1290
  [
1283
1291
  "path",
1284
1292
  {
@@ -1288,8 +1296,8 @@ const __iconNode$V = [
1288
1296
  ],
1289
1297
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
1290
1298
  ];
1291
- const Eye = createLucideIcon("eye", __iconNode$V);
1292
- const __iconNode$U = [
1299
+ const Eye = createLucideIcon("eye", __iconNode$Y);
1300
+ const __iconNode$X = [
1293
1301
  [
1294
1302
  "path",
1295
1303
  {
@@ -1307,8 +1315,8 @@ const __iconNode$U = [
1307
1315
  { d: "M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1", key: "mpwhp6" }
1308
1316
  ]
1309
1317
  ];
1310
- const FileBraces = createLucideIcon("file-braces", __iconNode$U);
1311
- const __iconNode$T = [
1318
+ const FileBraces = createLucideIcon("file-braces", __iconNode$X);
1319
+ const __iconNode$W = [
1312
1320
  [
1313
1321
  "path",
1314
1322
  {
@@ -1320,8 +1328,8 @@ const __iconNode$T = [
1320
1328
  ["path", { d: "m5 16-3 3 3 3", key: "331omg" }],
1321
1329
  ["path", { d: "m9 22 3-3-3-3", key: "lsp7cz" }]
1322
1330
  ];
1323
- const FileCodeCorner = createLucideIcon("file-code-corner", __iconNode$T);
1324
- const __iconNode$S = [
1331
+ const FileCodeCorner = createLucideIcon("file-code-corner", __iconNode$W);
1332
+ const __iconNode$V = [
1325
1333
  [
1326
1334
  "path",
1327
1335
  {
@@ -1332,8 +1340,21 @@ const __iconNode$S = [
1332
1340
  ["path", { d: "M12 9v4", key: "juzpu7" }],
1333
1341
  ["path", { d: "M12 17h.01", key: "p32p05" }]
1334
1342
  ];
1335
- const FileExclamationPoint = createLucideIcon("file-exclamation-point", __iconNode$S);
1336
- const __iconNode$R = [
1343
+ const FileExclamationPoint = createLucideIcon("file-exclamation-point", __iconNode$V);
1344
+ const __iconNode$U = [
1345
+ [
1346
+ "path",
1347
+ {
1348
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
1349
+ key: "1oefj6"
1350
+ }
1351
+ ],
1352
+ ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
1353
+ ["path", { d: "M9 15h6", key: "cctwl0" }],
1354
+ ["path", { d: "M12 18v-6", key: "17g6i2" }]
1355
+ ];
1356
+ const FilePlus = createLucideIcon("file-plus", __iconNode$U);
1357
+ const __iconNode$T = [
1337
1358
  [
1338
1359
  "path",
1339
1360
  {
@@ -1346,8 +1367,8 @@ const __iconNode$R = [
1346
1367
  ["path", { d: "M16 13H8", key: "t4e002" }],
1347
1368
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
1348
1369
  ];
1349
- const FileText = createLucideIcon("file-text", __iconNode$R);
1350
- const __iconNode$Q = [
1370
+ const FileText = createLucideIcon("file-text", __iconNode$T);
1371
+ const __iconNode$S = [
1351
1372
  [
1352
1373
  "path",
1353
1374
  {
@@ -1357,8 +1378,8 @@ const __iconNode$Q = [
1357
1378
  ],
1358
1379
  ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }]
1359
1380
  ];
1360
- const File = createLucideIcon("file", __iconNode$Q);
1361
- const __iconNode$P = [
1381
+ const File = createLucideIcon("file", __iconNode$S);
1382
+ const __iconNode$R = [
1362
1383
  [
1363
1384
  "path",
1364
1385
  {
@@ -1367,8 +1388,8 @@ const __iconNode$P = [
1367
1388
  }
1368
1389
  ]
1369
1390
  ];
1370
- const FolderOpen = createLucideIcon("folder-open", __iconNode$P);
1371
- const __iconNode$O = [
1391
+ const FolderOpen = createLucideIcon("folder-open", __iconNode$R);
1392
+ const __iconNode$Q = [
1372
1393
  ["path", { d: "M12 10v6", key: "1bos4e" }],
1373
1394
  ["path", { d: "M9 13h6", key: "1uhe8q" }],
1374
1395
  [
@@ -1379,8 +1400,8 @@ const __iconNode$O = [
1379
1400
  }
1380
1401
  ]
1381
1402
  ];
1382
- const FolderPlus = createLucideIcon("folder-plus", __iconNode$O);
1383
- const __iconNode$N = [
1403
+ const FolderPlus = createLucideIcon("folder-plus", __iconNode$Q);
1404
+ const __iconNode$P = [
1384
1405
  [
1385
1406
  "path",
1386
1407
  {
@@ -1389,8 +1410,8 @@ const __iconNode$N = [
1389
1410
  }
1390
1411
  ]
1391
1412
  ];
1392
- const Folder = createLucideIcon("folder", __iconNode$N);
1393
- const __iconNode$M = [
1413
+ const Folder = createLucideIcon("folder", __iconNode$P);
1414
+ const __iconNode$O = [
1394
1415
  [
1395
1416
  "path",
1396
1417
  {
@@ -1403,39 +1424,39 @@ const __iconNode$M = [
1403
1424
  { d: "M3 8.268a2 2 0 0 0-1 1.738V19a2 2 0 0 0 2 2h11a2 2 0 0 0 1.732-1", key: "yxbcw3" }
1404
1425
  ]
1405
1426
  ];
1406
- const Folders = createLucideIcon("folders", __iconNode$M);
1407
- const __iconNode$L = [
1427
+ const Folders = createLucideIcon("folders", __iconNode$O);
1428
+ const __iconNode$N = [
1408
1429
  ["path", { d: "M15 6a9 9 0 0 0-9 9V3", key: "1cii5b" }],
1409
1430
  ["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
1410
1431
  ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }]
1411
1432
  ];
1412
- const GitBranch = createLucideIcon("git-branch", __iconNode$L);
1413
- const __iconNode$K = [
1433
+ const GitBranch = createLucideIcon("git-branch", __iconNode$N);
1434
+ const __iconNode$M = [
1414
1435
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }],
1415
1436
  ["line", { x1: "3", x2: "9", y1: "12", y2: "12", key: "1dyftd" }],
1416
1437
  ["line", { x1: "15", x2: "21", y1: "12", y2: "12", key: "oup4p8" }]
1417
1438
  ];
1418
- const GitCommitHorizontal = createLucideIcon("git-commit-horizontal", __iconNode$K);
1419
- const __iconNode$J = [
1439
+ const GitCommitHorizontal = createLucideIcon("git-commit-horizontal", __iconNode$M);
1440
+ const __iconNode$L = [
1420
1441
  ["circle", { cx: "18", cy: "18", r: "3", key: "1xkwt0" }],
1421
1442
  ["circle", { cx: "6", cy: "6", r: "3", key: "1lh9wr" }],
1422
1443
  ["path", { d: "M13 6h3a2 2 0 0 1 2 2v7", key: "1yeb86" }],
1423
1444
  ["path", { d: "M11 18H8a2 2 0 0 1-2-2V9", key: "19pyzm" }]
1424
1445
  ];
1425
- const GitCompare = createLucideIcon("git-compare", __iconNode$J);
1426
- const __iconNode$I = [
1446
+ const GitCompare = createLucideIcon("git-compare", __iconNode$L);
1447
+ const __iconNode$K = [
1427
1448
  ["circle", { cx: "18", cy: "18", r: "3", key: "1xkwt0" }],
1428
1449
  ["circle", { cx: "6", cy: "6", r: "3", key: "1lh9wr" }],
1429
1450
  ["path", { d: "M6 21V9a9 9 0 0 0 9 9", key: "7kw0sc" }]
1430
1451
  ];
1431
- const GitMerge = createLucideIcon("git-merge", __iconNode$I);
1432
- const __iconNode$H = [
1452
+ const GitMerge = createLucideIcon("git-merge", __iconNode$K);
1453
+ const __iconNode$J = [
1433
1454
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
1434
1455
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
1435
1456
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
1436
1457
  ];
1437
- const Globe = createLucideIcon("globe", __iconNode$H);
1438
- const __iconNode$G = [
1458
+ const Globe = createLucideIcon("globe", __iconNode$J);
1459
+ const __iconNode$I = [
1439
1460
  ["circle", { cx: "12", cy: "9", r: "1", key: "124mty" }],
1440
1461
  ["circle", { cx: "19", cy: "9", r: "1", key: "1ruzo2" }],
1441
1462
  ["circle", { cx: "5", cy: "9", r: "1", key: "1a8b28" }],
@@ -1443,8 +1464,8 @@ const __iconNode$G = [
1443
1464
  ["circle", { cx: "19", cy: "15", r: "1", key: "1a92ep" }],
1444
1465
  ["circle", { cx: "5", cy: "15", r: "1", key: "5r1jwy" }]
1445
1466
  ];
1446
- const GripHorizontal = createLucideIcon("grip-horizontal", __iconNode$G);
1447
- const __iconNode$F = [
1467
+ const GripHorizontal = createLucideIcon("grip-horizontal", __iconNode$I);
1468
+ const __iconNode$H = [
1448
1469
  ["line", { x1: "2", x2: "22", y1: "2", y2: "22", key: "a6p6uj" }],
1449
1470
  ["path", { d: "M10.41 10.41a2 2 0 1 1-2.83-2.83", key: "1bzlo9" }],
1450
1471
  ["line", { x1: "13.5", x2: "6", y1: "13.5", y2: "21", key: "1q0aeu" }],
@@ -1458,31 +1479,31 @@ const __iconNode$F = [
1458
1479
  ],
1459
1480
  ["path", { d: "M21 15V5a2 2 0 0 0-2-2H9", key: "43el77" }]
1460
1481
  ];
1461
- const ImageOff = createLucideIcon("image-off", __iconNode$F);
1462
- const __iconNode$E = [
1482
+ const ImageOff = createLucideIcon("image-off", __iconNode$H);
1483
+ const __iconNode$G = [
1463
1484
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
1464
1485
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
1465
1486
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
1466
1487
  ];
1467
- const Image$1 = createLucideIcon("image", __iconNode$E);
1468
- const __iconNode$D = [
1488
+ const Image$1 = createLucideIcon("image", __iconNode$G);
1489
+ const __iconNode$F = [
1469
1490
  ["path", { d: "M16 5H3", key: "m91uny" }],
1470
1491
  ["path", { d: "M11 12H3", key: "51ecnj" }],
1471
1492
  ["path", { d: "M16 19H3", key: "zzsher" }],
1472
1493
  ["path", { d: "M21 12h-6", key: "bt1uis" }]
1473
1494
  ];
1474
- const ListMinus = createLucideIcon("list-minus", __iconNode$D);
1475
- const __iconNode$C = [
1495
+ const ListMinus = createLucideIcon("list-minus", __iconNode$F);
1496
+ const __iconNode$E = [
1476
1497
  ["path", { d: "M13 5h8", key: "a7qcls" }],
1477
1498
  ["path", { d: "M13 12h8", key: "h98zly" }],
1478
1499
  ["path", { d: "M13 19h8", key: "c3s6r1" }],
1479
1500
  ["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
1480
1501
  ["rect", { x: "3", y: "4", width: "6", height: "6", rx: "1", key: "cif1o7" }]
1481
1502
  ];
1482
- const ListTodo = createLucideIcon("list-todo", __iconNode$C);
1483
- const __iconNode$B = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
1484
- const LoaderCircle = createLucideIcon("loader-circle", __iconNode$B);
1485
- const __iconNode$A = [
1503
+ const ListTodo = createLucideIcon("list-todo", __iconNode$E);
1504
+ const __iconNode$D = [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]];
1505
+ const LoaderCircle = createLucideIcon("loader-circle", __iconNode$D);
1506
+ const __iconNode$C = [
1486
1507
  ["path", { d: "M12 2v4", key: "3427ic" }],
1487
1508
  ["path", { d: "m16.2 7.8 2.9-2.9", key: "r700ao" }],
1488
1509
  ["path", { d: "M18 12h4", key: "wj9ykh" }],
@@ -1492,26 +1513,26 @@ const __iconNode$A = [
1492
1513
  ["path", { d: "M2 12h4", key: "j09sii" }],
1493
1514
  ["path", { d: "m4.9 4.9 2.9 2.9", key: "giyufr" }]
1494
1515
  ];
1495
- const Loader = createLucideIcon("loader", __iconNode$A);
1496
- const __iconNode$z = [
1516
+ const Loader = createLucideIcon("loader", __iconNode$C);
1517
+ const __iconNode$B = [
1497
1518
  ["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2", key: "1w4ew1" }],
1498
1519
  ["path", { d: "M7 11V7a5 5 0 0 1 10 0v4", key: "fwvmzm" }]
1499
1520
  ];
1500
- const Lock = createLucideIcon("lock", __iconNode$z);
1501
- const __iconNode$y = [
1521
+ const Lock = createLucideIcon("lock", __iconNode$B);
1522
+ const __iconNode$A = [
1502
1523
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
1503
1524
  ["path", { d: "m21 3-7 7", key: "1l2asr" }],
1504
1525
  ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
1505
1526
  ["path", { d: "M9 21H3v-6", key: "wtvkvv" }]
1506
1527
  ];
1507
- const Maximize2 = createLucideIcon("maximize-2", __iconNode$y);
1508
- const __iconNode$x = [
1528
+ const Maximize2 = createLucideIcon("maximize-2", __iconNode$A);
1529
+ const __iconNode$z = [
1509
1530
  ["path", { d: "M4 5h16", key: "1tepv9" }],
1510
1531
  ["path", { d: "M4 12h16", key: "1lakjw" }],
1511
1532
  ["path", { d: "M4 19h16", key: "1djgab" }]
1512
1533
  ];
1513
- const Menu$1 = createLucideIcon("menu", __iconNode$x);
1514
- const __iconNode$w = [
1534
+ const Menu$1 = createLucideIcon("menu", __iconNode$z);
1535
+ const __iconNode$y = [
1515
1536
  [
1516
1537
  "path",
1517
1538
  {
@@ -1520,21 +1541,21 @@ const __iconNode$w = [
1520
1541
  }
1521
1542
  ]
1522
1543
  ];
1523
- const MessageSquare = createLucideIcon("message-square", __iconNode$w);
1524
- const __iconNode$v = [
1544
+ const MessageSquare = createLucideIcon("message-square", __iconNode$y);
1545
+ const __iconNode$x = [
1525
1546
  ["path", { d: "m14 10 7-7", key: "oa77jy" }],
1526
1547
  ["path", { d: "M20 10h-6V4", key: "mjg0md" }],
1527
1548
  ["path", { d: "m3 21 7-7", key: "tjx5ai" }],
1528
1549
  ["path", { d: "M4 14h6v6", key: "rmj7iw" }]
1529
1550
  ];
1530
- const Minimize2 = createLucideIcon("minimize-2", __iconNode$v);
1531
- const __iconNode$u = [
1551
+ const Minimize2 = createLucideIcon("minimize-2", __iconNode$x);
1552
+ const __iconNode$w = [
1532
1553
  ["path", { d: "M9 18V5l12-2v13", key: "1jmyc2" }],
1533
1554
  ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
1534
1555
  ["circle", { cx: "18", cy: "16", r: "3", key: "1hluhg" }]
1535
1556
  ];
1536
- const Music = createLucideIcon("music", __iconNode$u);
1537
- const __iconNode$t = [
1557
+ const Music = createLucideIcon("music", __iconNode$w);
1558
+ const __iconNode$v = [
1538
1559
  [
1539
1560
  "path",
1540
1561
  {
@@ -1546,18 +1567,18 @@ const __iconNode$t = [
1546
1567
  ["polyline", { points: "3.29 7 12 12 20.71 7", key: "ousv84" }],
1547
1568
  ["path", { d: "m7.5 4.27 9 5.15", key: "1c824w" }]
1548
1569
  ];
1549
- const Package = createLucideIcon("package", __iconNode$t);
1550
- const __iconNode$s = [
1570
+ const Package = createLucideIcon("package", __iconNode$v);
1571
+ const __iconNode$u = [
1551
1572
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1552
1573
  ["path", { d: "M9 3v18", key: "fh3hqa" }]
1553
1574
  ];
1554
- const PanelLeft = createLucideIcon("panel-left", __iconNode$s);
1555
- const __iconNode$r = [
1575
+ const PanelLeft = createLucideIcon("panel-left", __iconNode$u);
1576
+ const __iconNode$t = [
1556
1577
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1557
1578
  ["path", { d: "M3 9h18", key: "1pudct" }]
1558
1579
  ];
1559
- const PanelTop = createLucideIcon("panel-top", __iconNode$r);
1560
- const __iconNode$q = [
1580
+ const PanelTop = createLucideIcon("panel-top", __iconNode$t);
1581
+ const __iconNode$s = [
1561
1582
  [
1562
1583
  "path",
1563
1584
  {
@@ -1566,8 +1587,8 @@ const __iconNode$q = [
1566
1587
  }
1567
1588
  ]
1568
1589
  ];
1569
- const Paperclip = createLucideIcon("paperclip", __iconNode$q);
1570
- const __iconNode$p = [
1590
+ const Paperclip = createLucideIcon("paperclip", __iconNode$s);
1591
+ const __iconNode$r = [
1571
1592
  [
1572
1593
  "path",
1573
1594
  {
@@ -1577,8 +1598,21 @@ const __iconNode$p = [
1577
1598
  ],
1578
1599
  ["path", { d: "m15 5 4 4", key: "1mk7zo" }]
1579
1600
  ];
1580
- const Pencil = createLucideIcon("pencil", __iconNode$p);
1581
- const __iconNode$o = [
1601
+ const Pencil = createLucideIcon("pencil", __iconNode$r);
1602
+ const __iconNode$q = [
1603
+ ["path", { d: "M12 17v5", key: "bb1du9" }],
1604
+ ["path", { d: "M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89", key: "znwnzq" }],
1605
+ ["path", { d: "m2 2 20 20", key: "1ooewy" }],
1606
+ [
1607
+ "path",
1608
+ {
1609
+ d: "M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11",
1610
+ key: "c9qhm2"
1611
+ }
1612
+ ]
1613
+ ];
1614
+ const PinOff = createLucideIcon("pin-off", __iconNode$q);
1615
+ const __iconNode$p = [
1582
1616
  ["path", { d: "M12 17v5", key: "bb1du9" }],
1583
1617
  [
1584
1618
  "path",
@@ -1588,8 +1622,8 @@ const __iconNode$o = [
1588
1622
  }
1589
1623
  ]
1590
1624
  ];
1591
- const Pin = createLucideIcon("pin", __iconNode$o);
1592
- const __iconNode$n = [
1625
+ const Pin = createLucideIcon("pin", __iconNode$p);
1626
+ const __iconNode$o = [
1593
1627
  [
1594
1628
  "path",
1595
1629
  {
@@ -1598,20 +1632,20 @@ const __iconNode$n = [
1598
1632
  }
1599
1633
  ]
1600
1634
  ];
1601
- const Play = createLucideIcon("play", __iconNode$n);
1602
- const __iconNode$m = [
1635
+ const Play = createLucideIcon("play", __iconNode$o);
1636
+ const __iconNode$n = [
1603
1637
  ["path", { d: "M5 12h14", key: "1ays0h" }],
1604
1638
  ["path", { d: "M12 5v14", key: "s699le" }]
1605
1639
  ];
1606
- const Plus = createLucideIcon("plus", __iconNode$m);
1607
- const __iconNode$l = [
1640
+ const Plus = createLucideIcon("plus", __iconNode$n);
1641
+ const __iconNode$m = [
1608
1642
  ["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
1609
1643
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }],
1610
1644
  ["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
1611
1645
  ["path", { d: "M8 16H3v5", key: "1cv678" }]
1612
1646
  ];
1613
- const RefreshCw = createLucideIcon("refresh-cw", __iconNode$l);
1614
- const __iconNode$k = [
1647
+ const RefreshCw = createLucideIcon("refresh-cw", __iconNode$m);
1648
+ const __iconNode$l = [
1615
1649
  ["path", { d: "M17 3v10", key: "15fgeh" }],
1616
1650
  ["path", { d: "m12.67 5.5 8.66 5", key: "1gpheq" }],
1617
1651
  ["path", { d: "m12.67 10.5 8.66-5", key: "1dkfa6" }],
@@ -1620,23 +1654,23 @@ const __iconNode$k = [
1620
1654
  { d: "M9 17a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-2z", key: "swwfx4" }
1621
1655
  ]
1622
1656
  ];
1623
- const Regex = createLucideIcon("regex", __iconNode$k);
1624
- const __iconNode$j = [
1657
+ const Regex = createLucideIcon("regex", __iconNode$l);
1658
+ const __iconNode$k = [
1625
1659
  ["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
1626
1660
  ["path", { d: "M3 3v5h5", key: "1xhq8a" }]
1627
1661
  ];
1628
- const RotateCcw = createLucideIcon("rotate-ccw", __iconNode$j);
1629
- const __iconNode$i = [
1662
+ const RotateCcw = createLucideIcon("rotate-ccw", __iconNode$k);
1663
+ const __iconNode$j = [
1630
1664
  ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
1631
1665
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
1632
1666
  ];
1633
- const RotateCw = createLucideIcon("rotate-cw", __iconNode$i);
1634
- const __iconNode$h = [
1667
+ const RotateCw = createLucideIcon("rotate-cw", __iconNode$j);
1668
+ const __iconNode$i = [
1635
1669
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
1636
1670
  ["path", { d: "M3 12h18", key: "1i2n21" }]
1637
1671
  ];
1638
- const Rows2 = createLucideIcon("rows-2", __iconNode$h);
1639
- const __iconNode$g = [
1672
+ const Rows2 = createLucideIcon("rows-2", __iconNode$i);
1673
+ const __iconNode$h = [
1640
1674
  [
1641
1675
  "path",
1642
1676
  {
@@ -1647,7 +1681,15 @@ const __iconNode$g = [
1647
1681
  ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
1648
1682
  ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
1649
1683
  ];
1650
- const Save = createLucideIcon("save", __iconNode$g);
1684
+ const Save = createLucideIcon("save", __iconNode$h);
1685
+ const __iconNode$g = [
1686
+ ["circle", { cx: "6", cy: "6", r: "3", key: "1lh9wr" }],
1687
+ ["path", { d: "M8.12 8.12 12 12", key: "1alkpv" }],
1688
+ ["path", { d: "M20 4 8.12 15.88", key: "xgtan2" }],
1689
+ ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
1690
+ ["path", { d: "M14.8 14.8 20 20", key: "ptml3r" }]
1691
+ ];
1692
+ const Scissors = createLucideIcon("scissors", __iconNode$g);
1651
1693
  const __iconNode$f = [
1652
1694
  ["path", { d: "M15 12h-5", key: "r7krc0" }],
1653
1695
  ["path", { d: "M15 8h-5", key: "1khuty" }],
@@ -40504,53 +40546,53 @@ async function loadLanguage(lang) {
40504
40546
  try {
40505
40547
  switch (lang) {
40506
40548
  case "javascript":
40507
- return import("./index-BoCTcQyA.js").then((m2) => m2.javascript());
40549
+ return import("./index-CW27f0k8.js").then((m2) => m2.javascript());
40508
40550
  case "jsx":
40509
- return import("./index-BoCTcQyA.js").then((m2) => m2.javascript({ jsx: true }));
40551
+ return import("./index-CW27f0k8.js").then((m2) => m2.javascript({ jsx: true }));
40510
40552
  case "typescript":
40511
- return import("./index-BoCTcQyA.js").then(
40553
+ return import("./index-CW27f0k8.js").then(
40512
40554
  (m2) => m2.javascript({ typescript: true })
40513
40555
  );
40514
40556
  case "tsx":
40515
- return import("./index-BoCTcQyA.js").then(
40557
+ return import("./index-CW27f0k8.js").then(
40516
40558
  (m2) => m2.javascript({ jsx: true, typescript: true })
40517
40559
  );
40518
40560
  case "python":
40519
- return import("./index-tbrMCGeF.js").then((m2) => m2.python());
40561
+ return import("./index-CPgf4fox.js").then((m2) => m2.python());
40520
40562
  case "html":
40521
- return import("./index-DEkonSBc.js").then((m2) => m2.html());
40563
+ return import("./index-sBBVHJec.js").then((m2) => m2.html());
40522
40564
  case "css":
40523
- return import("./index-BHR21Rwx.js").then((m2) => m2.css());
40565
+ return import("./index-CQZMfw92.js").then((m2) => m2.css());
40524
40566
  case "scss":
40525
40567
  case "sass":
40526
- return import("./index-BUKmWu07.js").then((m2) => m2.sass());
40568
+ return import("./index-xHAcoUao.js").then((m2) => m2.sass());
40527
40569
  case "less":
40528
- return import("./index-zE6_NUk4.js").then((m2) => m2.less());
40570
+ return import("./index-0_BGm0mn.js").then((m2) => m2.less());
40529
40571
  case "json":
40530
40572
  case "jsonc":
40531
- return import("./index-CMs8dLKE.js").then((m2) => m2.json());
40573
+ return import("./index-BoanxRSH.js").then((m2) => m2.json());
40532
40574
  case "markdown":
40533
40575
  case "mdx":
40534
- return import("./index-g309PIeU.js").then((m2) => m2.markdown());
40576
+ return import("./index-B2qKtyPL.js").then((m2) => m2.markdown());
40535
40577
  case "xml":
40536
- return import("./index-DAlp0b3q.js").then((m2) => m2.xml());
40578
+ return import("./index-BgilcgRG.js").then((m2) => m2.xml());
40537
40579
  case "yaml":
40538
- return import("./index-CznnHJPs.js").then((m2) => m2.yaml());
40580
+ return import("./index-DO78fmX2.js").then((m2) => m2.yaml());
40539
40581
  case "sql":
40540
- return import("./index-BCNMZ2-I.js").then((m2) => m2.sql());
40582
+ return import("./index-BRIhAKe8.js").then((m2) => m2.sql());
40541
40583
  case "rust":
40542
- return import("./index-D4Zt6M4l.js").then((m2) => m2.rust());
40584
+ return import("./index-CUrmFB9U.js").then((m2) => m2.rust());
40543
40585
  case "go":
40544
- return import("./index-D6pmvl-E.js").then((m2) => m2.go());
40586
+ return import("./index-BT09Zz2i.js").then((m2) => m2.go());
40545
40587
  case "java":
40546
- return import("./index-O9-otWU5.js").then((m2) => m2.java());
40588
+ return import("./index-BcYdtAMM.js").then((m2) => m2.java());
40547
40589
  case "kotlin":
40548
- return import("./index-O9-otWU5.js").then((m2) => m2.java());
40590
+ return import("./index-BcYdtAMM.js").then((m2) => m2.java());
40549
40591
  case "c":
40550
40592
  case "cpp":
40551
- return import("./index-DqCcM85h.js").then((m2) => m2.cpp());
40593
+ return import("./index-CBXzgKOs.js").then((m2) => m2.cpp());
40552
40594
  case "php":
40553
- return import("./index-BUSq_KFc.js").then((m2) => m2.php());
40595
+ return import("./index-CO5kqxG3.js").then((m2) => m2.php());
40554
40596
  // Legacy modes via StreamLanguage
40555
40597
  case "bash":
40556
40598
  case "fish":
@@ -41612,6 +41654,44 @@ function CommitDialog({
41612
41654
  ] })
41613
41655
  ] }) });
41614
41656
  }
41657
+ function useAppUpdate() {
41658
+ const adapter2 = useAdapter();
41659
+ const [state2, setState] = reactExports.useState({ status: "none" });
41660
+ reactExports.useEffect(() => {
41661
+ if (!adapter2.getUpdateStatus || !adapter2.subscribeUpdateStatus) return;
41662
+ let cancelled = false;
41663
+ adapter2.getUpdateStatus().then((pending) => {
41664
+ if (cancelled) return;
41665
+ if (pending) {
41666
+ setState({ status: "available", version: pending.version });
41667
+ }
41668
+ }).catch(() => {
41669
+ });
41670
+ const unsubscribe = adapter2.subscribeUpdateStatus((pending) => {
41671
+ setState((prev2) => {
41672
+ if (prev2.status === "installing") return prev2;
41673
+ return pending ? { status: "available", version: pending.version } : { status: "none" };
41674
+ });
41675
+ });
41676
+ return () => {
41677
+ cancelled = true;
41678
+ unsubscribe();
41679
+ };
41680
+ }, [adapter2]);
41681
+ const install = async () => {
41682
+ if (!adapter2.installUpdate) return;
41683
+ setState({ status: "installing" });
41684
+ try {
41685
+ await adapter2.installUpdate();
41686
+ } catch (err) {
41687
+ setState({
41688
+ status: "error",
41689
+ message: err instanceof Error ? err.message : String(err)
41690
+ });
41691
+ }
41692
+ };
41693
+ return { state: state2, install };
41694
+ }
41615
41695
  function useCliSetup() {
41616
41696
  const adapter2 = useAdapter();
41617
41697
  const [state2, setState] = reactExports.useState({ status: "checking" });
@@ -41681,7 +41761,9 @@ function useCliSetup() {
41681
41761
  }
41682
41762
  const PROJECTS_COLLAPSE_KEY = "band.projects-list.collapsed-projects";
41683
41763
  const LABELS_COLLAPSE_KEY = "band.projects-list.collapsed-labels";
41764
+ const PINNED_COLLAPSE_KEY = "band.projects-list.collapsed-pinned";
41684
41765
  const UNLABELED_KEY = "__unlabeled";
41766
+ const PINNED_SECTION_ID = "__pinned";
41685
41767
  const SYNC_EVENT$1 = "band:collapse-state-change";
41686
41768
  function read$1(key2) {
41687
41769
  if (typeof window === "undefined") return /* @__PURE__ */ new Set();
@@ -41734,6 +41816,18 @@ function useCollapseState(storageKey2) {
41734
41816
  },
41735
41817
  [storageKey2]
41736
41818
  );
41819
+ const expand = reactExports.useCallback(
41820
+ (id28) => {
41821
+ setCollapsed((prev2) => {
41822
+ if (!prev2.has(id28)) return prev2;
41823
+ const next2 = new Set(prev2);
41824
+ next2.delete(id28);
41825
+ write$1(storageKey2, next2);
41826
+ return next2;
41827
+ });
41828
+ },
41829
+ [storageKey2]
41830
+ );
41737
41831
  const setAll = reactExports.useCallback(
41738
41832
  (ids2) => {
41739
41833
  const next2 = new Set(ids2);
@@ -41742,7 +41836,10 @@ function useCollapseState(storageKey2) {
41742
41836
  },
41743
41837
  [storageKey2]
41744
41838
  );
41745
- return reactExports.useMemo(() => ({ isCollapsed, toggle, setAll }), [isCollapsed, toggle, setAll]);
41839
+ return reactExports.useMemo(
41840
+ () => ({ isCollapsed, toggle, expand, setAll }),
41841
+ [isCollapsed, toggle, expand, setAll]
41842
+ );
41746
41843
  }
41747
41844
  function useHooksSetup() {
41748
41845
  const adapter2 = useAdapter();
@@ -46231,6 +46328,66 @@ function normalizeLocalDisabled(localDisabled, globalDisabled) {
46231
46328
  };
46232
46329
  }
46233
46330
  [KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left];
46331
+ function usePinnedWorkspaces() {
46332
+ const adapter2 = useAdapter();
46333
+ const queryClient2 = useQueryClient();
46334
+ const setError = useDashboardStore((s2) => s2.setError);
46335
+ const { projects } = useProjects();
46336
+ const pinned = reactExports.useMemo(() => {
46337
+ const list2 = [];
46338
+ for (const project of projects) {
46339
+ for (const wt2 of project.worktrees) {
46340
+ if (wt2.pinned) {
46341
+ list2.push({
46342
+ project,
46343
+ worktree: wt2,
46344
+ workspaceId: toWorkspaceId(project.name, wt2.branch)
46345
+ });
46346
+ }
46347
+ }
46348
+ }
46349
+ return list2;
46350
+ }, [projects]);
46351
+ const pinnedSet = reactExports.useMemo(() => new Set(pinned.map((p3) => p3.workspaceId)), [pinned]);
46352
+ const isPinned = reactExports.useCallback((id28) => pinnedSet.has(id28), [pinnedSet]);
46353
+ const mutation = useMutation({
46354
+ mutationFn: ({
46355
+ project,
46356
+ branch,
46357
+ pinned: nextPinned
46358
+ }) => adapter2.setWorkspacePinned(project, branch, nextPinned),
46359
+ onMutate: async ({ project, branch, pinned: nextPinned }) => {
46360
+ await queryClient2.cancelQueries({ queryKey: queryKeys.projects });
46361
+ const previous2 = queryClient2.getQueryData(queryKeys.projects);
46362
+ if (previous2) {
46363
+ const next2 = previous2.map(
46364
+ (p3) => p3.name === project ? {
46365
+ ...p3,
46366
+ worktrees: p3.worktrees.map(
46367
+ (w2) => w2.branch === branch ? { ...w2, pinned: nextPinned } : w2
46368
+ )
46369
+ } : p3
46370
+ );
46371
+ queryClient2.setQueryData(queryKeys.projects, next2);
46372
+ }
46373
+ return { previous: previous2 };
46374
+ },
46375
+ onError: (err, _vars, context2) => {
46376
+ if (context2?.previous) {
46377
+ queryClient2.setQueryData(queryKeys.projects, context2.previous);
46378
+ }
46379
+ setError(String(err));
46380
+ },
46381
+ onSettled: () => {
46382
+ queryClient2.invalidateQueries({ queryKey: queryKeys.projects });
46383
+ }
46384
+ });
46385
+ const toggle = reactExports.useCallback(
46386
+ (project, branch, currentlyPinned) => mutation.mutate({ project, branch, pinned: !currentlyPinned }),
46387
+ [mutation.mutate]
46388
+ );
46389
+ return { pinned, isPinned, toggle };
46390
+ }
46234
46391
  function DeleteWorkspaceDialog({
46235
46392
  open: open2,
46236
46393
  onOpenChange,
@@ -46406,7 +46563,9 @@ const WorkspaceCard = reactExports.memo(function WorkspaceCard2({
46406
46563
  branchStatus,
46407
46564
  setupStatus,
46408
46565
  isFocused,
46409
- onShowDeleteDialog
46566
+ onShowDeleteDialog,
46567
+ showProjectName,
46568
+ onTogglePinned
46410
46569
  }) {
46411
46570
  const cardRef = reactExports.useRef(null);
46412
46571
  const capabilities2 = useCapabilities();
@@ -46421,6 +46580,7 @@ const WorkspaceCard = reactExports.memo(function WorkspaceCard2({
46421
46580
  const gitPull = useDashboardStore((s2) => s2.gitPull);
46422
46581
  const gitPush = useDashboardStore((s2) => s2.gitPush);
46423
46582
  const removeWorkspaceMutation = useRemoveWorkspace();
46583
+ const isPinned = worktree.pinned;
46424
46584
  const workspaceId = toWorkspaceId(projectName, worktree.branch);
46425
46585
  const isActive = useDashboardStore((s2) => s2.activeWorkspaceId === workspaceId);
46426
46586
  const href = capabilities2.getWorkspaceHref?.(workspaceId);
@@ -46474,11 +46634,11 @@ const WorkspaceCard = reactExports.memo(function WorkspaceCard2({
46474
46634
  "span",
46475
46635
  {
46476
46636
  className: `text-sm truncate ${isActive ? "font-semibold text-foreground" : "font-medium text-muted-foreground"}`,
46477
- children: worktree.branch
46637
+ children: showProjectName ? `${projectName}/${worktree.branch}` : worktree.branch
46478
46638
  }
46479
46639
  )
46480
46640
  ] }) }),
46481
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "top", children: worktree.branch })
46641
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "top", children: showProjectName ? worktree.path : worktree.branch })
46482
46642
  ] }),
46483
46643
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "hidden @[10rem]:flex group-hover:flex items-center gap-2 shrink-0 ml-auto pl-2", children: [
46484
46644
  /* @__PURE__ */ jsxRuntimeExports.jsx(SetupStatusIndicator, { setup: setupStatus }),
@@ -46487,6 +46647,11 @@ const WorkspaceCard = reactExports.memo(function WorkspaceCard2({
46487
46647
  ] })
46488
46648
  ] }) }),
46489
46649
  /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { children: [
46650
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onClick: () => onTogglePinned(projectName, worktree.branch, isPinned), children: [
46651
+ isPinned ? /* @__PURE__ */ jsxRuntimeExports.jsx(PinOff, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(Pin, {}),
46652
+ isPinned ? "Unpin workspace" : "Pin workspace"
46653
+ ] }),
46654
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
46490
46655
  capabilities2.copyPath && /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onClick: () => navigator.clipboard.writeText(worktree.path), children: [
46491
46656
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clipboard, {}),
46492
46657
  "Copy path"
@@ -46531,7 +46696,9 @@ function SortableProject({
46531
46696
  focusedIndex,
46532
46697
  workspaceIndexStart,
46533
46698
  collapsed,
46534
- onToggleCollapse
46699
+ onToggleCollapse,
46700
+ hasPinnedSiblings,
46701
+ onTogglePinned
46535
46702
  }) {
46536
46703
  const { attributes, listeners: listeners2, setNodeRef, transform: transform2, transition, isDragging } = useSortable({
46537
46704
  id: project.name
@@ -46635,7 +46802,7 @@ function SortableProject({
46635
46802
  ] })
46636
46803
  ] })
46637
46804
  ] }),
46638
- !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 overflow-hidden", children: project.worktrees.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground px-4 py-2", children: "No workspaces yet" }) : project.worktrees.map((wt2) => {
46805
+ !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 overflow-hidden", children: project.worktrees.length === 0 ? hasPinnedSiblings ? null : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground px-4 py-2", children: "No workspaces yet" }) : project.worktrees.map((wt2) => {
46639
46806
  const wsId = toWorkspaceId(project.name, wt2.branch);
46640
46807
  const currentIndex = workspaceIndex++;
46641
46808
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -46648,7 +46815,8 @@ function SortableProject({
46648
46815
  branchStatus: branchStatuses.get(wsId),
46649
46816
  setupStatus: setupStatuses.get(wsId),
46650
46817
  isFocused: currentIndex === focusedIndex,
46651
- onShowDeleteDialog
46818
+ onShowDeleteDialog,
46819
+ onTogglePinned
46652
46820
  },
46653
46821
  wt2.branch
46654
46822
  );
@@ -46721,15 +46889,35 @@ function ProjectList({ labelFilter }) {
46721
46889
  const keyboardNavRef = reactExports.useRef(false);
46722
46890
  const projectCollapse = useCollapseState(PROJECTS_COLLAPSE_KEY);
46723
46891
  const labelCollapse = useCollapseState(LABELS_COLLAPSE_KEY);
46892
+ const pinnedCollapse = useCollapseState(PINNED_COLLAPSE_KEY);
46893
+ const { pinned: pinnedEntries, toggle: togglePinned } = usePinnedWorkspaces();
46724
46894
  const sensors = useSensors(
46725
46895
  useSensor(MouseSensor, { activationConstraint: { distance: 8 } }),
46726
46896
  useSensor(TouchSensor, { activationConstraint: { delay: 250, tolerance: 5 } })
46727
46897
  );
46898
+ const { displayProjects, projectsWithPinned } = reactExports.useMemo(() => {
46899
+ const withPinned = /* @__PURE__ */ new Set();
46900
+ const display = projects.map((p3) => {
46901
+ const filtered = p3.worktrees.filter((w2) => !w2.pinned);
46902
+ if (filtered.length !== p3.worktrees.length) withPinned.add(p3.name);
46903
+ return { ...p3, worktrees: filtered };
46904
+ });
46905
+ return { displayProjects: display, projectsWithPinned: withPinned };
46906
+ }, [projects]);
46907
+ const pinnedSectionCollapsed = pinnedCollapse.isCollapsed(PINNED_SECTION_ID);
46908
+ const showPinnedSection = pinnedEntries.length > 0;
46909
+ const pinnedNavCount = showPinnedSection && !pinnedSectionCollapsed ? pinnedEntries.length : 0;
46728
46910
  const groups = reactExports.useMemo(() => {
46729
46911
  if (labels.length === 0)
46730
- return [{ labelId: null, label: null, projects }];
46912
+ return [
46913
+ {
46914
+ labelId: null,
46915
+ label: null,
46916
+ projects: displayProjects
46917
+ }
46918
+ ];
46731
46919
  const byLabel = /* @__PURE__ */ new Map();
46732
- for (const p3 of projects) {
46920
+ for (const p3 of displayProjects) {
46733
46921
  const key2 = p3.label ?? null;
46734
46922
  if (!byLabel.has(key2)) byLabel.set(key2, []);
46735
46923
  byLabel.get(key2).push(p3);
@@ -46746,14 +46934,15 @@ function ProjectList({ labelFilter }) {
46746
46934
  result.push({ labelId: null, label: null, projects: unlabeled });
46747
46935
  }
46748
46936
  return result;
46749
- }, [projects, labels]);
46937
+ }, [displayProjects, labels]);
46750
46938
  const visibleGroups = reactExports.useMemo(() => {
46751
46939
  if (!labelFilter) return groups;
46752
46940
  return groups.filter((g2) => g2.labelId === labelFilter);
46753
46941
  }, [groups, labelFilter]);
46754
46942
  const allWorkspaceIds = reactExports.useMemo(() => {
46755
46943
  const headerVisible = labels.length > 0 && !labelFilter;
46756
- return visibleGroups.flatMap((g2) => {
46944
+ const pinnedPart = pinnedNavCount > 0 ? pinnedEntries.map((e2) => e2.workspaceId) : [];
46945
+ const rest = visibleGroups.flatMap((g2) => {
46757
46946
  const groupKey = g2.labelId ?? UNLABELED_KEY;
46758
46947
  if (headerVisible && labelCollapse.isCollapsed(groupKey)) return [];
46759
46948
  return g2.projects.flatMap((p3) => {
@@ -46761,10 +46950,19 @@ function ProjectList({ labelFilter }) {
46761
46950
  return p3.worktrees.map((wt2) => toWorkspaceId(p3.name, wt2.branch));
46762
46951
  });
46763
46952
  });
46764
- }, [visibleGroups, labels.length, labelFilter, labelCollapse, projectCollapse]);
46953
+ return [...pinnedPart, ...rest];
46954
+ }, [
46955
+ visibleGroups,
46956
+ labels.length,
46957
+ labelFilter,
46958
+ labelCollapse,
46959
+ projectCollapse,
46960
+ pinnedEntries,
46961
+ pinnedNavCount
46962
+ ]);
46765
46963
  const workspaceIndexMap = reactExports.useMemo(() => {
46766
46964
  const map2 = /* @__PURE__ */ new Map();
46767
- let index2 = 0;
46965
+ let index2 = pinnedNavCount;
46768
46966
  const headerVisible = labels.length > 0 && !labelFilter;
46769
46967
  for (const group of visibleGroups) {
46770
46968
  const groupKey = group.labelId ?? UNLABELED_KEY;
@@ -46777,7 +46975,7 @@ function ProjectList({ labelFilter }) {
46777
46975
  }
46778
46976
  }
46779
46977
  return map2;
46780
- }, [visibleGroups, labels.length, labelFilter, labelCollapse, projectCollapse]);
46978
+ }, [visibleGroups, labels.length, labelFilter, labelCollapse, projectCollapse, pinnedNavCount]);
46781
46979
  reactExports.useEffect(() => {
46782
46980
  if (keyboardNavRef.current) return;
46783
46981
  if (activeWorkspaceId) {
@@ -46787,6 +46985,51 @@ function ProjectList({ labelFilter }) {
46787
46985
  setFocusedIndex(-1);
46788
46986
  }
46789
46987
  }, [activeWorkspaceId, allWorkspaceIds]);
46988
+ const revealedWorkspaceRef = reactExports.useRef(null);
46989
+ const revealedAsPinnedRef = reactExports.useRef(false);
46990
+ reactExports.useEffect(() => {
46991
+ if (!activeWorkspaceId) {
46992
+ revealedWorkspaceRef.current = null;
46993
+ revealedAsPinnedRef.current = false;
46994
+ return;
46995
+ }
46996
+ const isActivePinned = pinnedEntries.some((e2) => e2.workspaceId === activeWorkspaceId);
46997
+ if (revealedWorkspaceRef.current === activeWorkspaceId && revealedAsPinnedRef.current === isActivePinned) {
46998
+ return;
46999
+ }
47000
+ revealedWorkspaceRef.current = activeWorkspaceId;
47001
+ revealedAsPinnedRef.current = isActivePinned;
47002
+ if (isActivePinned) {
47003
+ pinnedCollapse.expand(PINNED_SECTION_ID);
47004
+ keyboardNavRef.current = false;
47005
+ return;
47006
+ }
47007
+ for (const group of groups) {
47008
+ for (const project of group.projects) {
47009
+ const containsActive = project.worktrees.some(
47010
+ (wt2) => toWorkspaceId(project.name, wt2.branch) === activeWorkspaceId
47011
+ );
47012
+ if (!containsActive) continue;
47013
+ if (labelFilter && group.labelId !== labelFilter) return;
47014
+ const headerVisible = labels.length > 0 && !labelFilter;
47015
+ if (headerVisible) {
47016
+ labelCollapse.expand(group.labelId ?? UNLABELED_KEY);
47017
+ }
47018
+ projectCollapse.expand(project.name);
47019
+ keyboardNavRef.current = false;
47020
+ return;
47021
+ }
47022
+ }
47023
+ }, [
47024
+ activeWorkspaceId,
47025
+ groups,
47026
+ labelFilter,
47027
+ labels.length,
47028
+ labelCollapse,
47029
+ projectCollapse,
47030
+ pinnedCollapse,
47031
+ pinnedEntries
47032
+ ]);
46790
47033
  const hasProjects = projects.length > 0;
46791
47034
  reactExports.useEffect(() => {
46792
47035
  if (hasProjects) {
@@ -46862,7 +47105,7 @@ function ProjectList({ labelFilter }) {
46862
47105
  ] });
46863
47106
  }
46864
47107
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
46865
- /* @__PURE__ */ jsxRuntimeExports.jsx(
47108
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
46866
47109
  "div",
46867
47110
  {
46868
47111
  ref: containerRef,
@@ -46872,61 +47115,102 @@ function ProjectList({ labelFilter }) {
46872
47115
  keyboardNavRef.current = false;
46873
47116
  },
46874
47117
  className: "flex flex-col gap-0.5 outline-none min-w-0",
46875
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
46876
- DndContext,
46877
- {
46878
- sensors,
46879
- collisionDetection: closestCenter,
46880
- onDragStart: handleDragStart,
46881
- onDragEnd: handleDragEnd,
46882
- children: [
46883
- /* @__PURE__ */ jsxRuntimeExports.jsx(SortableContext, { items: allProjectNames, strategy: verticalListSortingStrategy, children: visibleGroups.map((group) => {
46884
- const groupKey = group.labelId ?? UNLABELED_KEY;
46885
- const headerVisible = labels.length > 0 && !labelFilter;
46886
- const groupCollapsed = headerVisible && labelCollapse.isCollapsed(groupKey);
46887
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
46888
- headerVisible && (group.label ? /* @__PURE__ */ jsxRuntimeExports.jsx(
46889
- DroppableLabelHeader,
46890
- {
46891
- labelId: group.labelId,
46892
- label: group.label,
46893
- collapsed: groupCollapsed,
46894
- onToggle: () => labelCollapse.toggle(groupKey)
46895
- }
46896
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
46897
- DroppableUnlabeledHeader,
46898
- {
46899
- collapsed: groupCollapsed,
46900
- onToggle: () => labelCollapse.toggle(groupKey)
46901
- }
46902
- )),
46903
- !groupCollapsed && group.projects.map((project) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
46904
- SortableProject,
47118
+ children: [
47119
+ showPinnedSection && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
47120
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
47121
+ "button",
47122
+ {
47123
+ type: "button",
47124
+ onClick: () => pinnedCollapse.toggle(PINNED_SECTION_ID),
47125
+ "aria-expanded": !pinnedSectionCollapsed,
47126
+ className: "flex h-9 w-full items-center gap-2 pl-3 pr-4 mb-0.5 text-left transition-colors hover:bg-primary/10 bg-accent",
47127
+ children: [
47128
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pin, { className: "size-3.5 -rotate-45 text-muted-foreground" }),
47129
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-foreground/80", children: "Pinned" }),
47130
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
47131
+ ChevronRight,
46905
47132
  {
46906
- project,
46907
- statuses,
46908
- branchStatuses,
46909
- setupStatuses,
46910
- removeProject: (name2) => removeProjectMutation.mutate(name2),
46911
- updateProjectLabel: (name2, label) => updateProjectLabelMutation.mutate({ name: name2, label }),
46912
- labels,
46913
- setWorkspaceDialog,
46914
- onShowDeleteDialog: setDeleteDialog,
46915
- focusedIndex,
46916
- workspaceIndexStart: workspaceIndexMap.get(project.name) ?? 0,
46917
- collapsed: projectCollapse.isCollapsed(project.name),
46918
- onToggleCollapse: projectCollapse.toggle
47133
+ className: `ml-auto size-3.5 shrink-0 text-muted-foreground transition-transform ${pinnedSectionCollapsed ? "" : "rotate-90"}`
46919
47134
  }
46920
- ) }, project.name))
46921
- ] }, groupKey);
46922
- }) }),
46923
- /* @__PURE__ */ jsxRuntimeExports.jsx(DragOverlay, { dropAnimation: null, children: activeDragId ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-1 py-1 bg-background rounded shadow-lg border", children: [
46924
- /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-3.5 shrink-0 text-muted-foreground" }),
46925
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-foreground", children: activeDragId })
46926
- ] }) : null })
46927
- ]
46928
- }
46929
- )
47135
+ )
47136
+ ]
47137
+ }
47138
+ ),
47139
+ !pinnedSectionCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 px-2", children: pinnedEntries.map(({ project, worktree, workspaceId }, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
47140
+ WorkspaceCard,
47141
+ {
47142
+ worktree,
47143
+ projectName: project.name,
47144
+ defaultBranch: project.defaultBranch,
47145
+ status: statuses.get(workspaceId),
47146
+ branchStatus: branchStatuses.get(workspaceId),
47147
+ setupStatus: setupStatuses.get(workspaceId),
47148
+ isFocused: i2 === focusedIndex,
47149
+ onShowDeleteDialog: setDeleteDialog,
47150
+ showProjectName: true,
47151
+ onTogglePinned: togglePinned
47152
+ },
47153
+ workspaceId
47154
+ )) })
47155
+ ] }, "__pinned"),
47156
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
47157
+ DndContext,
47158
+ {
47159
+ sensors,
47160
+ collisionDetection: closestCenter,
47161
+ onDragStart: handleDragStart,
47162
+ onDragEnd: handleDragEnd,
47163
+ children: [
47164
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SortableContext, { items: allProjectNames, strategy: verticalListSortingStrategy, children: visibleGroups.map((group) => {
47165
+ const groupKey = group.labelId ?? UNLABELED_KEY;
47166
+ const headerVisible = labels.length > 0 && !labelFilter;
47167
+ const groupCollapsed = headerVisible && labelCollapse.isCollapsed(groupKey);
47168
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
47169
+ headerVisible && (group.label ? /* @__PURE__ */ jsxRuntimeExports.jsx(
47170
+ DroppableLabelHeader,
47171
+ {
47172
+ labelId: group.labelId,
47173
+ label: group.label,
47174
+ collapsed: groupCollapsed,
47175
+ onToggle: () => labelCollapse.toggle(groupKey)
47176
+ }
47177
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
47178
+ DroppableUnlabeledHeader,
47179
+ {
47180
+ collapsed: groupCollapsed,
47181
+ onToggle: () => labelCollapse.toggle(groupKey)
47182
+ }
47183
+ )),
47184
+ !groupCollapsed && group.projects.map((project) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
47185
+ SortableProject,
47186
+ {
47187
+ project,
47188
+ statuses,
47189
+ branchStatuses,
47190
+ setupStatuses,
47191
+ removeProject: (name2) => removeProjectMutation.mutate(name2),
47192
+ updateProjectLabel: (name2, label) => updateProjectLabelMutation.mutate({ name: name2, label }),
47193
+ labels,
47194
+ setWorkspaceDialog,
47195
+ onShowDeleteDialog: setDeleteDialog,
47196
+ focusedIndex,
47197
+ workspaceIndexStart: workspaceIndexMap.get(project.name) ?? 0,
47198
+ collapsed: projectCollapse.isCollapsed(project.name),
47199
+ onToggleCollapse: projectCollapse.toggle,
47200
+ hasPinnedSiblings: projectsWithPinned.has(project.name),
47201
+ onTogglePinned: togglePinned
47202
+ }
47203
+ ) }, project.name))
47204
+ ] }, groupKey);
47205
+ }) }),
47206
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DragOverlay, { dropAnimation: null, children: activeDragId ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-1 py-1 bg-background rounded shadow-lg border", children: [
47207
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-3.5 shrink-0 text-muted-foreground" }),
47208
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-foreground", children: activeDragId })
47209
+ ] }) : null })
47210
+ ]
47211
+ }
47212
+ )
47213
+ ]
46930
47214
  }
46931
47215
  ),
46932
47216
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -47134,6 +47418,9 @@ function SettingsPage({ open: open2, onOpenChange }) {
47134
47418
  const [useWebGLTerminalRenderer, setUseWebGLTerminalRenderer] = reactExports.useState(
47135
47419
  settings.useWebGLTerminalRenderer ?? true
47136
47420
  );
47421
+ const [webBrowserCdpEnabled, setWebBrowserCdpEnabled] = reactExports.useState(
47422
+ settings.webBrowserCdpEnabled ?? false
47423
+ );
47137
47424
  const [agentModels, setAgentModels] = reactExports.useState({});
47138
47425
  const [contextMeterEnabled, setContextMeterEnabled] = useExperimentalContextMeter();
47139
47426
  const adapter2 = useAdapter();
@@ -47163,6 +47450,7 @@ function SettingsPage({ open: open2, onOpenChange }) {
47163
47450
  if (maxCachedWorkspaces !== (settings.maxCachedWorkspaces?.toString() ?? "")) return true;
47164
47451
  if (selectedTheme !== (settings.theme ?? "system")) return true;
47165
47452
  if (useWebGLTerminalRenderer !== (settings.useWebGLTerminalRenderer ?? true)) return true;
47453
+ if (webBrowserCdpEnabled !== (settings.webBrowserCdpEnabled ?? false)) return true;
47166
47454
  return false;
47167
47455
  }, [
47168
47456
  worktreesDir,
@@ -47179,6 +47467,7 @@ function SettingsPage({ open: open2, onOpenChange }) {
47179
47467
  maxCachedWorkspaces,
47180
47468
  selectedTheme,
47181
47469
  useWebGLTerminalRenderer,
47470
+ webBrowserCdpEnabled,
47182
47471
  settings
47183
47472
  ]);
47184
47473
  reactExports.useEffect(() => {
@@ -47196,6 +47485,7 @@ function SettingsPage({ open: open2, onOpenChange }) {
47196
47485
  setMaxCachedWorkspaces(settings.maxCachedWorkspaces?.toString() ?? "");
47197
47486
  setSelectedTheme(settings.theme ?? "system");
47198
47487
  setUseWebGLTerminalRenderer(settings.useWebGLTerminalRenderer ?? true);
47488
+ setWebBrowserCdpEnabled(settings.webBrowserCdpEnabled ?? false);
47199
47489
  }, [
47200
47490
  settings.worktreesDir,
47201
47491
  settings.codingAgents,
@@ -47209,7 +47499,8 @@ function SettingsPage({ open: open2, onOpenChange }) {
47209
47499
  settings.claudeCodePartialMessages,
47210
47500
  settings.maxCachedWorkspaces,
47211
47501
  settings.theme,
47212
- settings.useWebGLTerminalRenderer
47502
+ settings.useWebGLTerminalRenderer,
47503
+ settings.webBrowserCdpEnabled
47213
47504
  ]);
47214
47505
  const handleBrowse = async () => {
47215
47506
  if (!capabilities2.pickFolder) return;
@@ -47253,7 +47544,8 @@ function SettingsPage({ open: open2, onOpenChange }) {
47253
47544
  claudeCodePartialMessages,
47254
47545
  maxCachedWorkspaces: parsedMaxCachedWorkspaces,
47255
47546
  theme: selectedTheme,
47256
- useWebGLTerminalRenderer
47547
+ useWebGLTerminalRenderer,
47548
+ webBrowserCdpEnabled
47257
47549
  });
47258
47550
  };
47259
47551
  const handleSaveAndClose = async () => {
@@ -47380,6 +47672,22 @@ function SettingsPage({ open: open2, onOpenChange }) {
47380
47672
  }
47381
47673
  )
47382
47674
  ] }),
47675
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SettingsSection, { title: "Browser", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
47676
+ SettingsRow,
47677
+ {
47678
+ htmlFor: "web-browser-cdp",
47679
+ label: "Stream desktop tabs to web (experimental)",
47680
+ description: "When enabled, the desktop opens a chromium debug port and lets web clients view + drive your Browser-pane tabs over CDP. Disable to save CPU/memory if you don't use the web UI for browsing.",
47681
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
47682
+ Switch,
47683
+ {
47684
+ id: "web-browser-cdp",
47685
+ checked: webBrowserCdpEnabled,
47686
+ onCheckedChange: setWebBrowserCdpEnabled
47687
+ }
47688
+ )
47689
+ }
47690
+ ) }),
47383
47691
  /* @__PURE__ */ jsxRuntimeExports.jsx(
47384
47692
  SettingsSection,
47385
47693
  {
@@ -47794,6 +48102,7 @@ function DashboardShell({ toolbarMenuItems, hideTitleBar, hideMenu }) {
47794
48102
  const [labelFilter, setLabelFilter] = useLabelFilter();
47795
48103
  const { state: hooksState, install: installHooks } = useHooksSetup();
47796
48104
  const { state: cliState, install: installCli } = useCliSetup();
48105
+ const { state: updateState, install: installUpdate } = useAppUpdate();
47797
48106
  const [appTitle, setAppTitle] = reactExports.useState("Band");
47798
48107
  reactExports.useEffect(() => {
47799
48108
  if (!isDesktop$1) return;
@@ -47806,10 +48115,12 @@ function DashboardShell({ toolbarMenuItems, hideTitleBar, hideMenu }) {
47806
48115
  const handleSettingsClick = reactExports.useCallback(() => setShowSettingsDialog(true), []);
47807
48116
  const projectCollapse = useCollapseState(PROJECTS_COLLAPSE_KEY);
47808
48117
  const labelCollapse = useCollapseState(LABELS_COLLAPSE_KEY);
48118
+ const pinnedCollapse = useCollapseState(PINNED_COLLAPSE_KEY);
47809
48119
  const collapseAll = reactExports.useCallback(() => {
47810
48120
  projectCollapse.setAll(projects.map((p3) => p3.name));
47811
48121
  labelCollapse.setAll([...labels.map((l4) => l4.id), UNLABELED_KEY]);
47812
- }, [projectCollapse, labelCollapse, projects, labels]);
48122
+ pinnedCollapse.setAll([PINNED_SECTION_ID]);
48123
+ }, [projectCollapse, labelCollapse, pinnedCollapse, projects, labels]);
47813
48124
  const activeLabel = reactExports.useMemo(
47814
48125
  () => labelFilter ? labels.find((l4) => l4.id === labelFilter) : null,
47815
48126
  [labelFilter, labels]
@@ -48004,6 +48315,18 @@ function DashboardShell({ toolbarMenuItems, hideTitleBar, hideMenu }) {
48004
48315
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ProjectList, { labelFilter }) })
48005
48316
  }
48006
48317
  ),
48318
+ updateState.status === "available" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-4 mb-2 px-4 py-2 bg-blue-500/10 border border-blue-500/30 rounded-lg text-sm flex items-center justify-between gap-2", children: [
48319
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-700 dark:text-blue-200", children: `Band v${updateState.version} is available` }),
48320
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", className: "shrink-0 text-xs", onClick: installUpdate, children: "Install" })
48321
+ ] }),
48322
+ updateState.status === "installing" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-4 mb-2 px-4 py-2 bg-blue-500/10 border border-blue-500/30 rounded-lg text-sm flex items-center justify-between gap-2", children: [
48323
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-700 dark:text-blue-200", children: "Installing update…" }),
48324
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", className: "shrink-0 text-xs", disabled: true, children: "Install" })
48325
+ ] }),
48326
+ updateState.status === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-4 mb-2 px-4 py-2 bg-destructive/10 border border-destructive/30 rounded-lg text-sm text-destructive flex items-center justify-between gap-2", children: [
48327
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: `Update failed: ${updateState.message}` }),
48328
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", className: "shrink-0 text-xs", onClick: installUpdate, children: "Retry" })
48329
+ ] }),
48007
48330
  (cliState.status === "manual" || cliState.status === "conflict") && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-4 mb-2 px-4 py-2 bg-blue-500/10 border border-blue-500/30 rounded-lg text-sm flex items-center justify-between gap-2", children: [
48008
48331
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-700 dark:text-blue-200", children: cliState.status === "conflict" ? "A different `band` binary exists — replace it to use the bundled CLI" : `Install band CLI${cliState.status === "manual" && cliState.reason ? ` — ${cliState.reason}` : ""}` }),
48009
48332
  /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", size: "sm", className: "shrink-0 text-xs", onClick: installCli, children: "Install" })
@@ -49906,6 +50229,19 @@ function extensionToLanguage(ext) {
49906
50229
  function filenameToLanguage(filename) {
49907
50230
  return FILENAME_MAP[filename];
49908
50231
  }
50232
+ function useDeferredMenuAction() {
50233
+ const pendingRef = reactExports.useRef(null);
50234
+ const queue = reactExports.useCallback((fn2) => {
50235
+ pendingRef.current = fn2;
50236
+ }, []);
50237
+ const flush = reactExports.useCallback((e2) => {
50238
+ e2.preventDefault();
50239
+ const fn2 = pendingRef.current;
50240
+ pendingRef.current = null;
50241
+ fn2?.();
50242
+ }, []);
50243
+ return { queue, flush };
50244
+ }
49909
50245
  const extensionIconMap = {
49910
50246
  // Code files
49911
50247
  ts: FileCodeCorner,
@@ -50067,18 +50403,25 @@ function FileStatusBadge({ status }) {
50067
50403
  }
50068
50404
  );
50069
50405
  }
50406
+ function collectLeafPaths(node2) {
50407
+ if (!node2.children) return [node2.path];
50408
+ return node2.children.flatMap(collectLeafPaths);
50409
+ }
50070
50410
  function ChangesTreeNode({
50071
50411
  node: node2,
50072
50412
  depth,
50073
50413
  expandedPaths,
50074
50414
  onToggle,
50075
50415
  onSelectFile,
50416
+ onRequestReset,
50417
+ canReset,
50076
50418
  activeFile
50077
50419
  }) {
50078
50420
  const isDir = node2.children !== void 0;
50079
50421
  const isExpanded = isDir && expandedPaths.has(node2.path);
50080
50422
  const isActive = !isDir && activeFile === node2.path;
50081
50423
  const btnRef = reactExports.useRef(null);
50424
+ const menu = useDeferredMenuAction();
50082
50425
  reactExports.useEffect(() => {
50083
50426
  if (isActive && btnRef.current) {
50084
50427
  btnRef.current.scrollIntoView({ block: "nearest" });
@@ -50091,28 +50434,42 @@ function ChangesTreeNode({
50091
50434
  onSelectFile(node2.path);
50092
50435
  }
50093
50436
  };
50437
+ const button = /* @__PURE__ */ jsxRuntimeExports.jsxs(
50438
+ "button",
50439
+ {
50440
+ ref: isActive ? btnRef : void 0,
50441
+ type: "button",
50442
+ "data-band-active": isActive ? "true" : void 0,
50443
+ onClick: handleClick,
50444
+ 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" : ""}`,
50445
+ style: { paddingLeft: `${depth * 12 + 4}px` },
50446
+ children: [
50447
+ isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3.5 shrink-0" }),
50448
+ isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : (() => {
50449
+ const fileName = node2.name.includes("/") ? node2.name.split("/").pop() : node2.name;
50450
+ const FileIcon = getFileIcon(fileName);
50451
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
50452
+ })(),
50453
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate", children: node2.name }),
50454
+ !isDir && node2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(FileStatusBadge, { status: node2.status })
50455
+ ]
50456
+ }
50457
+ );
50094
50458
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
50095
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
50096
- "button",
50097
- {
50098
- ref: isActive ? btnRef : void 0,
50099
- type: "button",
50100
- "data-band-active": isActive ? "true" : void 0,
50101
- onClick: handleClick,
50102
- className: `flex h-[26px] w-full items-center gap-1 pr-3 text-left text-xs ${isActive ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"}`,
50103
- style: { paddingLeft: `${depth * 12 + 4}px` },
50104
- children: [
50105
- isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3.5 shrink-0" }),
50106
- isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : (() => {
50107
- const fileName = node2.name.includes("/") ? node2.name.split("/").pop() : node2.name;
50108
- const FileIcon = getFileIcon(fileName);
50109
- return /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
50110
- })(),
50111
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate", children: node2.name }),
50112
- !isDir && node2.status && /* @__PURE__ */ jsxRuntimeExports.jsx(FileStatusBadge, { status: node2.status })
50113
- ]
50114
- }
50115
- ),
50459
+ canReset ? /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenu, { children: [
50460
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTrigger, { asChild: true, children: button }),
50461
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuContent, { onCloseAutoFocus: menu.flush, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
50462
+ ContextMenuItem,
50463
+ {
50464
+ variant: "destructive",
50465
+ onSelect: () => menu.queue(() => onRequestReset(node2)),
50466
+ children: [
50467
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "size-4" }),
50468
+ "Reset changes"
50469
+ ]
50470
+ }
50471
+ ) })
50472
+ ] }) : button,
50116
50473
  isExpanded && node2.children?.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50117
50474
  ChangesTreeNode,
50118
50475
  {
@@ -50121,6 +50478,8 @@ function ChangesTreeNode({
50121
50478
  expandedPaths,
50122
50479
  onToggle,
50123
50480
  onSelectFile,
50481
+ onRequestReset,
50482
+ canReset,
50124
50483
  activeFile
50125
50484
  },
50126
50485
  child.path
@@ -50137,7 +50496,12 @@ function collectDirPaths(nodes) {
50137
50496
  }
50138
50497
  return paths;
50139
50498
  }
50140
- function ChangesFileTree({ fileStatuses, onSelectFile, activeFile }) {
50499
+ function ChangesFileTree({
50500
+ fileStatuses,
50501
+ onSelectFile,
50502
+ activeFile,
50503
+ onRevertPaths
50504
+ }) {
50141
50505
  const tree = reactExports.useMemo(() => buildFileTree(fileStatuses), [fileStatuses]);
50142
50506
  const [expandedPaths, setExpandedPaths] = reactExports.useState(() => {
50143
50507
  return new Set(collectDirPaths(tree));
@@ -50156,21 +50520,120 @@ function ChangesFileTree({ fileStatuses, onSelectFile, activeFile }) {
50156
50520
  return next2;
50157
50521
  });
50158
50522
  };
50523
+ const [pendingReset, setPendingReset] = reactExports.useState(null);
50524
+ const [resetSubmitting, setResetSubmitting] = reactExports.useState(false);
50525
+ const handleRequestReset = reactExports.useCallback((node2) => {
50526
+ const paths = collectLeafPaths(node2);
50527
+ if (paths.length === 0) return;
50528
+ if (node2.children) {
50529
+ setPendingReset({
50530
+ label: node2.path,
50531
+ isFolder: true,
50532
+ paths
50533
+ });
50534
+ } else {
50535
+ setPendingReset({
50536
+ label: node2.path,
50537
+ isFolder: false,
50538
+ paths: [node2.path],
50539
+ status: node2.status
50540
+ });
50541
+ }
50542
+ }, []);
50543
+ const cancelReset = reactExports.useCallback(() => {
50544
+ if (resetSubmitting) return;
50545
+ setPendingReset(null);
50546
+ }, [resetSubmitting]);
50547
+ const confirmReset = reactExports.useCallback(async () => {
50548
+ if (!pendingReset || !onRevertPaths) return;
50549
+ setResetSubmitting(true);
50550
+ try {
50551
+ await onRevertPaths(pendingReset.paths);
50552
+ setPendingReset(null);
50553
+ } finally {
50554
+ setResetSubmitting(false);
50555
+ }
50556
+ }, [pendingReset, onRevertPaths]);
50557
+ const canReset = Boolean(onRevertPaths);
50159
50558
  if (tree.length === 0) {
50160
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-16 items-center justify-center text-xs text-muted-foreground", children: "No files" });
50559
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-16 items-center justify-center text-[13px] text-muted-foreground", children: "No files" });
50560
+ }
50561
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
50562
+ tree.map((node2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50563
+ ChangesTreeNode,
50564
+ {
50565
+ node: node2,
50566
+ depth: 0,
50567
+ expandedPaths,
50568
+ onToggle: handleToggle,
50569
+ onSelectFile,
50570
+ onRequestReset: handleRequestReset,
50571
+ canReset,
50572
+ activeFile
50573
+ },
50574
+ node2.path
50575
+ )),
50576
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50577
+ Dialog,
50578
+ {
50579
+ open: pendingReset !== null,
50580
+ onOpenChange: (open2) => {
50581
+ if (!open2) cancelReset();
50582
+ },
50583
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "sm:max-w-[425px]", onClick: (e2) => e2.stopPropagation(), children: [
50584
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
50585
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: "Reset changes" }),
50586
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: pendingReset?.isFolder ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
50587
+ "Reset changes for all ",
50588
+ pendingReset.paths.length,
50589
+ " file",
50590
+ pendingReset.paths.length === 1 ? "" : "s",
50591
+ " inside",
50592
+ " ",
50593
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "break-all", children: pendingReset.label }),
50594
+ "?"
50595
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
50596
+ "Reset changes to ",
50597
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "break-all", children: pendingReset?.label }),
50598
+ "?"
50599
+ ] }) })
50600
+ ] }),
50601
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-2 text-sm", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
50602
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "mt-0.5 size-4 shrink-0 text-yellow-500" }),
50603
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: pendingReset?.isFolder ? "Every change inside this folder will be discarded. Added files are deleted, deleted files are restored, modifications are reverted. This action cannot be undone." : resetDescriptionForFile(pendingReset?.status) })
50604
+ ] }) }),
50605
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [
50606
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", onClick: cancelReset, disabled: resetSubmitting, children: "Cancel" }),
50607
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50608
+ Button,
50609
+ {
50610
+ variant: "destructive",
50611
+ onClick: () => void confirmReset(),
50612
+ disabled: resetSubmitting,
50613
+ children: resetSubmitting ? "Resetting…" : "Reset"
50614
+ }
50615
+ )
50616
+ ] })
50617
+ ] })
50618
+ }
50619
+ )
50620
+ ] });
50621
+ }
50622
+ function resetDescriptionForFile(status) {
50623
+ switch (status) {
50624
+ case "A":
50625
+ return "This file was added and will be deleted. This action cannot be undone.";
50626
+ case "U":
50627
+ return "This file is untracked and will be deleted. This action cannot be undone.";
50628
+ case "D":
50629
+ return "This file was deleted and will be restored. This action cannot be undone.";
50630
+ case "M":
50631
+ return "All changes to this file will be discarded. This action cannot be undone.";
50632
+ case "R":
50633
+ return "This file was renamed and will be restored to its original path. This action cannot be undone.";
50634
+ default:
50635
+ return "All changes to this file will be discarded. This action cannot be undone.";
50161
50636
  }
50162
- return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: tree.map((node2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50163
- ChangesTreeNode,
50164
- {
50165
- node: node2,
50166
- depth: 0,
50167
- expandedPaths,
50168
- onToggle: handleToggle,
50169
- onSelectFile,
50170
- activeFile
50171
- },
50172
- node2.path
50173
- )) });
50174
50637
  }
50175
50638
  function statusDescription(status) {
50176
50639
  switch (status) {
@@ -51299,6 +51762,30 @@ function DiffView({
51299
51762
  },
51300
51763
  [adapter2, workspaceId, diffMode, compareBranch]
51301
51764
  );
51765
+ const handleRevertPaths = reactExports.useCallback(
51766
+ async (paths) => {
51767
+ const revertFile = adapter2.revertFile;
51768
+ if (!revertFile || paths.length === 0) return;
51769
+ const results = await Promise.allSettled(
51770
+ paths.map(
51771
+ (p3) => revertFile.call(adapter2, workspaceId, p3, diffMode, compareBranch ?? void 0)
51772
+ )
51773
+ );
51774
+ setDiffCache((prev2) => {
51775
+ const next2 = new Map(prev2);
51776
+ for (const p3 of paths) next2.delete(p3);
51777
+ return next2;
51778
+ });
51779
+ for (const p3 of paths) expandedFilesRef.current.delete(p3);
51780
+ fetchSummaryRef.current?.(true);
51781
+ for (const r2 of results) {
51782
+ if (r2.status === "rejected") {
51783
+ console.error("Failed to revert path:", r2.reason);
51784
+ }
51785
+ }
51786
+ },
51787
+ [adapter2, workspaceId, diffMode, compareBranch]
51788
+ );
51302
51789
  reactExports.useEffect(() => {
51303
51790
  const getWorkspaceDiffSummary = adapter2.getWorkspaceDiffSummary;
51304
51791
  if (!getWorkspaceDiffSummary) return;
@@ -51507,12 +51994,13 @@ function DiffView({
51507
51994
  style: { width: sidebarWidth },
51508
51995
  children: [
51509
51996
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-9 shrink-0 items-center border-b border-border px-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Files" }) }),
51510
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 overflow-y-auto py-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
51997
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 overflow-y-auto py-1 pl-px", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
51511
51998
  ChangesFileTree,
51512
51999
  {
51513
52000
  fileStatuses,
51514
52001
  onSelectFile: handleScrollToFile,
51515
- activeFile
52002
+ activeFile,
52003
+ onRevertPaths: adapter2.revertFile ? handleRevertPaths : void 0
51516
52004
  }
51517
52005
  ) })
51518
52006
  ]
@@ -51812,6 +52300,129 @@ function getCachedContents(wsId) {
51812
52300
  }
51813
52301
  return map2;
51814
52302
  }
52303
+ function EntryNameInput({
52304
+ kind,
52305
+ depth,
52306
+ compact,
52307
+ initialValue = "",
52308
+ siblings: siblings2,
52309
+ placeholder,
52310
+ onSubmit,
52311
+ onCancel
52312
+ }) {
52313
+ const [value, setValue] = reactExports.useState(initialValue);
52314
+ const [submitting, setSubmitting] = reactExports.useState(false);
52315
+ const [error, setError] = reactExports.useState(null);
52316
+ const inputRef = reactExports.useRef(null);
52317
+ reactExports.useEffect(() => {
52318
+ const el = inputRef.current;
52319
+ if (!el) return;
52320
+ el.focus();
52321
+ if (initialValue) {
52322
+ const dotIdx = initialValue.lastIndexOf(".");
52323
+ const end = dotIdx > 0 ? dotIdx : initialValue.length;
52324
+ try {
52325
+ el.setSelectionRange(0, end);
52326
+ } catch {
52327
+ }
52328
+ }
52329
+ }, [initialValue]);
52330
+ const indent2 = compact ? 12 : 16;
52331
+ const basePad = compact ? 4 : 8;
52332
+ const height = compact ? 28 : 32;
52333
+ const validate2 = (name2) => {
52334
+ const trimmed = name2.trim();
52335
+ if (!trimmed) return "Name is required";
52336
+ if (trimmed === "." || trimmed === "..") return "Invalid name";
52337
+ if (trimmed.includes("/") || trimmed.includes("\\")) {
52338
+ return "Name cannot contain slashes";
52339
+ }
52340
+ if (siblings2.has(trimmed)) return "A file or folder with this name already exists";
52341
+ return null;
52342
+ };
52343
+ const handleSubmit = async () => {
52344
+ const trimmed = value.trim();
52345
+ if (trimmed === initialValue) {
52346
+ onCancel();
52347
+ return;
52348
+ }
52349
+ const validationError = validate2(trimmed);
52350
+ if (validationError) {
52351
+ setError(validationError);
52352
+ return;
52353
+ }
52354
+ setSubmitting(true);
52355
+ setError(null);
52356
+ try {
52357
+ await onSubmit(trimmed);
52358
+ } catch (err) {
52359
+ const message = err instanceof Error ? err.message : String(err);
52360
+ setError(message);
52361
+ setSubmitting(false);
52362
+ }
52363
+ };
52364
+ const Icon2 = kind === "directory" ? Folder : File;
52365
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex w-full flex-col", style: { paddingLeft: `${depth * indent2 + basePad}px` }, children: [
52366
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
52367
+ "div",
52368
+ {
52369
+ className: `flex items-center ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"}`,
52370
+ style: { height },
52371
+ children: [
52372
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3.5 shrink-0" }),
52373
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
52374
+ Icon2,
52375
+ {
52376
+ className: kind === "directory" ? "size-4 shrink-0 text-blue-600 dark:text-blue-400" : "size-4 shrink-0 text-muted-foreground"
52377
+ }
52378
+ ),
52379
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
52380
+ "input",
52381
+ {
52382
+ ref: inputRef,
52383
+ type: "text",
52384
+ value,
52385
+ onChange: (e2) => {
52386
+ setValue(e2.target.value);
52387
+ if (error) setError(null);
52388
+ },
52389
+ disabled: submitting,
52390
+ onKeyDown: (e2) => {
52391
+ if (e2.key === "Enter") {
52392
+ e2.preventDefault();
52393
+ void handleSubmit();
52394
+ } else if (e2.key === "Escape") {
52395
+ e2.preventDefault();
52396
+ onCancel();
52397
+ }
52398
+ },
52399
+ onBlur: () => {
52400
+ if (!submitting) {
52401
+ if (value.trim()) {
52402
+ void handleSubmit();
52403
+ } else {
52404
+ onCancel();
52405
+ }
52406
+ }
52407
+ },
52408
+ placeholder: placeholder ?? (kind === "directory" ? "Folder name" : "File name"),
52409
+ className: "min-w-0 flex-1 rounded-sm border border-border bg-background px-1 py-0 text-foreground outline-none ring-1 ring-ring/40 focus:ring-2 focus:ring-ring disabled:opacity-60",
52410
+ "aria-label": kind === "directory" ? "Folder name" : "File name"
52411
+ }
52412
+ )
52413
+ ]
52414
+ }
52415
+ ),
52416
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx(
52417
+ "div",
52418
+ {
52419
+ className: "pointer-events-none text-xs text-destructive",
52420
+ style: { paddingLeft: `${18 + 6}px`, paddingBottom: 4 },
52421
+ children: error
52422
+ }
52423
+ )
52424
+ ] });
52425
+ }
51815
52426
  function TreeNode2({
51816
52427
  entry,
51817
52428
  parentPath,
@@ -51822,22 +52433,45 @@ function TreeNode2({
51822
52433
  onToggle,
51823
52434
  onOpenFile,
51824
52435
  onOpenFilePinned,
52436
+ onSelectRow,
52437
+ onRequestNewEntry,
52438
+ onRequestDelete,
52439
+ onRequestRename,
52440
+ onCut,
52441
+ onCopy,
52442
+ onPaste,
52443
+ canDelete,
52444
+ canRename,
52445
+ canCut,
52446
+ canCopy,
52447
+ canPaste,
51825
52448
  compact,
51826
- selectedFile,
51827
- selectedRef
52449
+ treeSelection,
52450
+ clipboard,
52451
+ selectedRef,
52452
+ newEntry,
52453
+ onNewEntrySubmit,
52454
+ onNewEntryCancel,
52455
+ renamingPath,
52456
+ onRenameSubmit,
52457
+ onRenameCancel
51828
52458
  }) {
51829
52459
  const entryPath = parentPath ? `${parentPath}/${entry.name}` : entry.name;
51830
52460
  const isDir = entry.type === "directory";
51831
52461
  const isExpanded = isDir && expandedPaths.has(entryPath);
51832
- const isSelected = !isDir && selectedFile === entryPath;
52462
+ const isSelected = treeSelection?.path === entryPath && treeSelection.kind === "directory" === isDir;
52463
+ const isCut = clipboard?.op === "cut" && (clipboard.path === entryPath || entryPath.startsWith(`${clipboard.path}/`));
51833
52464
  const isLoading = isDir && loadingPaths.has(entryPath);
51834
52465
  const children2 = isDir ? dirContents.get(entryPath) : void 0;
52466
+ const menu = useDeferredMenuAction();
51835
52467
  const indent2 = compact ? 12 : 16;
51836
52468
  const basePad = compact ? 4 : 8;
51837
52469
  const handleClick = () => {
51838
52470
  if (isDir) {
52471
+ onSelectRow(entryPath, "directory");
51839
52472
  onToggle(entryPath);
51840
52473
  } else {
52474
+ onSelectRow(entryPath, "file");
51841
52475
  onOpenFile(entryPath);
51842
52476
  }
51843
52477
  };
@@ -51846,51 +52480,144 @@ function TreeNode2({
51846
52480
  onOpenFilePinned(entryPath);
51847
52481
  }
51848
52482
  };
51849
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
51850
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
51851
- "button",
51852
- {
51853
- ref: isSelected ? selectedRef : void 0,
51854
- type: "button",
51855
- "data-band-active": isSelected ? "true" : void 0,
51856
- onClick: handleClick,
51857
- onDoubleClick: handleDoubleClick,
51858
- className: `flex w-full items-center text-left hover:bg-accent/50 ${compact ? "h-[26px] gap-1 pr-3 text-xs" : "h-[30px] gap-1.5 pr-4 text-sm"} ${isSelected ? "bg-accent text-accent-foreground" : ""}`,
51859
- style: { paddingLeft: `${depth * indent2 + basePad}px` },
51860
- children: [
51861
- isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3.5 shrink-0" }),
51862
- isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : (() => {
51863
- const FileIcon = getFileIcon(entry.name);
51864
- return /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
51865
- })(),
51866
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name })
51867
- ]
52483
+ const button = /* @__PURE__ */ jsxRuntimeExports.jsxs(
52484
+ "button",
52485
+ {
52486
+ ref: isSelected ? selectedRef : void 0,
52487
+ type: "button",
52488
+ "data-band-active": isSelected ? "true" : void 0,
52489
+ onClick: handleClick,
52490
+ onDoubleClick: handleDoubleClick,
52491
+ onContextMenu: (e2) => e2.stopPropagation(),
52492
+ onPointerDown: (e2) => e2.stopPropagation(),
52493
+ className: `flex w-full items-center text-left select-none hover:bg-accent/50 [-webkit-touch-callout:none] ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"} ${isSelected ? "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" : ""} ${isCut ? "opacity-50" : ""}`,
52494
+ style: { paddingLeft: `${depth * indent2 + basePad}px` },
52495
+ children: [
52496
+ isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-3.5 shrink-0" }),
52497
+ isDir ? isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : (() => {
52498
+ const FileIcon = getFileIcon(entry.name);
52499
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
52500
+ })(),
52501
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name })
52502
+ ]
52503
+ }
52504
+ );
52505
+ const isRenaming = renamingPath === entryPath;
52506
+ const renameSiblings = (() => {
52507
+ const set2 = /* @__PURE__ */ new Set();
52508
+ const cached2 = dirContents.get(parentPath);
52509
+ if (cached2) {
52510
+ for (const e2 of cached2) {
52511
+ if (e2.name !== entry.name) set2.add(e2.name);
51868
52512
  }
51869
- ),
51870
- isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
51871
- isLoading && !children2?.length && /* @__PURE__ */ jsxRuntimeExports.jsx(
51872
- "div",
51873
- {
51874
- className: "flex items-center text-xs text-muted-foreground/70",
51875
- style: {
51876
- paddingLeft: `${(depth + 1) * indent2 + basePad + 18}px`,
51877
- height: compact ? 26 : 30
51878
- },
51879
- children: "Loading…"
51880
- }
51881
- ),
51882
- !isLoading && children2 && children2.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
51883
- "div",
51884
- {
51885
- className: "flex items-center text-xs italic text-muted-foreground/50",
51886
- style: {
51887
- paddingLeft: `${(depth + 1) * indent2 + basePad + 18}px`,
51888
- height: compact ? 26 : 30
51889
- },
51890
- children: "Empty"
51891
- }
51892
- ),
51893
- children2?.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
52513
+ }
52514
+ return set2;
52515
+ })();
52516
+ const row2 = isRenaming ? (
52517
+ // EntryNameInput computes its own `paddingLeft = depth * indent + basePad`
52518
+ // passing the row's actual depth keeps the input row perfectly aligned
52519
+ // with sibling row buttons (which use the same formula). Wrapping it in
52520
+ // a padding div with `depth={0}` would double-apply `basePad`, shifting
52521
+ // the input ~4px to the right and giving it visibly less horizontal
52522
+ // room than the rest of the tree.
52523
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
52524
+ EntryNameInput,
52525
+ {
52526
+ kind: isDir ? "directory" : "file",
52527
+ depth,
52528
+ compact,
52529
+ initialValue: entry.name,
52530
+ siblings: renameSiblings,
52531
+ placeholder: isDir ? "Folder name" : "File name",
52532
+ onSubmit: onRenameSubmit,
52533
+ onCancel: onRenameCancel
52534
+ },
52535
+ `rename-${entryPath}`
52536
+ )
52537
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
52538
+ ContextMenu,
52539
+ {
52540
+ onOpenChange: (open2) => {
52541
+ if (open2) onSelectRow(entryPath, isDir ? "directory" : "file");
52542
+ },
52543
+ children: [
52544
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTrigger, { asChild: true, children: button }),
52545
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { onCloseAutoFocus: menu.flush, children: [
52546
+ isDir && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
52547
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
52548
+ ContextMenuItem,
52549
+ {
52550
+ onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "file")),
52551
+ children: [
52552
+ /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "size-4" }),
52553
+ "New File"
52554
+ ]
52555
+ }
52556
+ ),
52557
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
52558
+ ContextMenuItem,
52559
+ {
52560
+ onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "directory")),
52561
+ children: [
52562
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-4" }),
52563
+ "New Folder"
52564
+ ]
52565
+ }
52566
+ ),
52567
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {})
52568
+ ] }),
52569
+ canCut && /* @__PURE__ */ jsxRuntimeExports.jsxs(
52570
+ ContextMenuItem,
52571
+ {
52572
+ onSelect: () => menu.queue(() => onCut(entryPath, isDir ? "directory" : "file")),
52573
+ children: [
52574
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Scissors, { className: "size-4" }),
52575
+ "Cut"
52576
+ ]
52577
+ }
52578
+ ),
52579
+ canCopy && /* @__PURE__ */ jsxRuntimeExports.jsxs(
52580
+ ContextMenuItem,
52581
+ {
52582
+ onSelect: () => menu.queue(() => onCopy(entryPath, isDir ? "directory" : "file")),
52583
+ children: [
52584
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-4" }),
52585
+ "Copy"
52586
+ ]
52587
+ }
52588
+ ),
52589
+ isDir && canPaste && /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => menu.queue(() => void onPaste(entryPath)), children: [
52590
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardPaste, { className: "size-4" }),
52591
+ "Paste"
52592
+ ] }),
52593
+ (canCut || canCopy || isDir && canPaste) && (canRename || canDelete) && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
52594
+ canRename && /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => menu.queue(() => onRequestRename(entryPath)), children: [
52595
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-4" }),
52596
+ "Rename"
52597
+ ] }),
52598
+ canDelete && /* @__PURE__ */ jsxRuntimeExports.jsxs(
52599
+ ContextMenuItem,
52600
+ {
52601
+ variant: "destructive",
52602
+ onSelect: () => menu.queue(() => onRequestDelete(entryPath, isDir ? "directory" : "file")),
52603
+ children: [
52604
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" }),
52605
+ "Delete"
52606
+ ]
52607
+ }
52608
+ )
52609
+ ] })
52610
+ ]
52611
+ }
52612
+ );
52613
+ const showInlineInput = newEntry?.parentPath === entryPath;
52614
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
52615
+ row2,
52616
+ isExpanded && (() => {
52617
+ const splitIdx = children2?.findIndex((c2) => c2.type === "file") ?? -1;
52618
+ const folderChildren = splitIdx === -1 ? children2 ?? [] : (children2 ?? []).slice(0, splitIdx);
52619
+ const fileChildren = splitIdx === -1 ? [] : (children2 ?? []).slice(splitIdx);
52620
+ const renderChild = (child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
51894
52621
  TreeNode2,
51895
52622
  {
51896
52623
  entry: child,
@@ -51902,22 +52629,83 @@ function TreeNode2({
51902
52629
  onToggle,
51903
52630
  onOpenFile,
51904
52631
  onOpenFilePinned,
52632
+ onSelectRow,
52633
+ onRequestNewEntry,
52634
+ onRequestDelete,
52635
+ onRequestRename,
52636
+ onCut,
52637
+ onCopy,
52638
+ onPaste,
52639
+ canDelete,
52640
+ canRename,
52641
+ canCut,
52642
+ canCopy,
52643
+ canPaste,
51905
52644
  compact,
51906
- selectedFile,
51907
- selectedRef
52645
+ treeSelection,
52646
+ clipboard,
52647
+ selectedRef,
52648
+ newEntry,
52649
+ onNewEntrySubmit,
52650
+ onNewEntryCancel,
52651
+ renamingPath,
52652
+ onRenameSubmit,
52653
+ onRenameCancel
51908
52654
  },
51909
52655
  child.name
51910
- ))
51911
- ] })
52656
+ );
52657
+ const newEntryInput = showInlineInput ? /* @__PURE__ */ jsxRuntimeExports.jsx(
52658
+ EntryNameInput,
52659
+ {
52660
+ kind: newEntry.kind,
52661
+ depth: depth + 1,
52662
+ compact,
52663
+ siblings: new Set((children2 ?? []).map((c2) => c2.name)),
52664
+ onSubmit: onNewEntrySubmit,
52665
+ onCancel: onNewEntryCancel
52666
+ },
52667
+ `new-${newEntry.kind}-${entryPath}`
52668
+ ) : null;
52669
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
52670
+ showInlineInput && newEntry.kind === "directory" && newEntryInput,
52671
+ isLoading && !children2?.length && /* @__PURE__ */ jsxRuntimeExports.jsx(
52672
+ "div",
52673
+ {
52674
+ className: `flex items-center text-muted-foreground/70 ${compact ? "text-[13px]" : "text-[15px]"}`,
52675
+ style: {
52676
+ paddingLeft: `${(depth + 1) * indent2 + basePad + 18}px`,
52677
+ height: compact ? 28 : 32
52678
+ },
52679
+ children: "Loading…"
52680
+ }
52681
+ ),
52682
+ !isLoading && !showInlineInput && children2 && children2.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
52683
+ "div",
52684
+ {
52685
+ className: `flex items-center italic text-muted-foreground/50 ${compact ? "text-[13px]" : "text-[15px]"}`,
52686
+ style: {
52687
+ paddingLeft: `${(depth + 1) * indent2 + basePad + 18}px`,
52688
+ height: compact ? 28 : 32
52689
+ },
52690
+ children: "Empty"
52691
+ }
52692
+ ),
52693
+ folderChildren.map(renderChild),
52694
+ showInlineInput && newEntry.kind === "file" && newEntryInput,
52695
+ fileChildren.map(renderChild)
52696
+ ] });
52697
+ })()
51912
52698
  ] });
51913
52699
  }
51914
- function FileBrowser({
52700
+ const FileBrowser = reactExports.forwardRef(function FileBrowser2({
51915
52701
  workspaceId,
51916
52702
  onOpenFile,
51917
52703
  onOpenFilePinned,
51918
52704
  compact,
51919
- selectedFile
51920
- }) {
52705
+ selectedFile,
52706
+ onPathRenamed,
52707
+ onPathDeleted
52708
+ }, handleRef) {
51921
52709
  const adapter2 = useAdapter();
51922
52710
  const [expandedPaths, setExpandedPaths] = reactExports.useState(
51923
52711
  () => new Set(getCachedExpanded(workspaceId))
@@ -51926,6 +52714,13 @@ function FileBrowser({
51926
52714
  () => new Map(getCachedContents(workspaceId))
51927
52715
  );
51928
52716
  const [loadingPaths, setLoadingPaths] = reactExports.useState(/* @__PURE__ */ new Set());
52717
+ const [newEntry, setNewEntry] = reactExports.useState(null);
52718
+ const [pendingDelete, setPendingDelete] = reactExports.useState(null);
52719
+ const [deleteError, setDeleteError] = reactExports.useState(null);
52720
+ const [deleteSubmitting, setDeleteSubmitting] = reactExports.useState(false);
52721
+ const [renamingPath, setRenamingPath] = reactExports.useState(null);
52722
+ const [clipboard, setClipboard] = reactExports.useState(null);
52723
+ const [treeSelection, setTreeSelection] = reactExports.useState(() => selectedFile ? { path: selectedFile, kind: "file" } : null);
51929
52724
  const selectedRef = reactExports.useRef(null);
51930
52725
  const prevWorkspaceRef = reactExports.useRef(workspaceId);
51931
52726
  reactExports.useEffect(() => {
@@ -51934,13 +52729,31 @@ function FileBrowser({
51934
52729
  setExpandedPaths(new Set(getCachedExpanded(workspaceId)));
51935
52730
  setDirContents(new Map(getCachedContents(workspaceId)));
51936
52731
  setLoadingPaths(/* @__PURE__ */ new Set());
52732
+ setNewEntry(null);
52733
+ setTreeSelection(null);
52734
+ setPendingDelete(null);
52735
+ setDeleteError(null);
52736
+ setDeleteSubmitting(false);
52737
+ setRenamingPath(null);
52738
+ setClipboard(null);
51937
52739
  }
51938
52740
  }, [workspaceId]);
52741
+ reactExports.useEffect(() => {
52742
+ if (selectedFile) {
52743
+ setTreeSelection({ path: selectedFile, kind: "file" });
52744
+ }
52745
+ }, [selectedFile]);
52746
+ const handleSelectRow = reactExports.useCallback((path2, kind) => {
52747
+ setTreeSelection({ path: path2, kind });
52748
+ }, []);
52749
+ const clearTreeSelection = reactExports.useCallback(() => {
52750
+ setTreeSelection(null);
52751
+ }, []);
51939
52752
  const fetchDir = reactExports.useCallback(
51940
- async (dirPath) => {
52753
+ async (dirPath, opts) => {
51941
52754
  if (!adapter2.listWorkspaceFiles) return;
51942
52755
  const cache = getCachedContents(workspaceId);
51943
- if (cache.has(dirPath)) {
52756
+ if (!opts?.force && cache.has(dirPath)) {
51944
52757
  setDirContents((prev2) => prev2.has(dirPath) ? prev2 : new Map(cache));
51945
52758
  return;
51946
52759
  }
@@ -52015,34 +52828,473 @@ function FileBrowser({
52015
52828
  },
52016
52829
  [workspaceId, fetchDir]
52017
52830
  );
52831
+ const ensureDirExpanded = reactExports.useCallback(
52832
+ async (dirPath) => {
52833
+ const cached2 = getCachedExpanded(workspaceId);
52834
+ if (!cached2.has(dirPath)) {
52835
+ cached2.add(dirPath);
52836
+ expandedStateCache.set(workspaceId, new Set(cached2));
52837
+ setExpandedPaths(new Set(cached2));
52838
+ }
52839
+ await fetchDir(dirPath);
52840
+ },
52841
+ [workspaceId, fetchDir]
52842
+ );
52843
+ const requestNewEntry = reactExports.useCallback(
52844
+ (parentPath, kind) => {
52845
+ void ensureDirExpanded(parentPath);
52846
+ setNewEntry({ parentPath, kind });
52847
+ },
52848
+ [ensureDirExpanded]
52849
+ );
52850
+ const cancelNewEntry = reactExports.useCallback(() => {
52851
+ setNewEntry(null);
52852
+ }, []);
52853
+ const submitNewEntry = reactExports.useCallback(
52854
+ async (name2) => {
52855
+ if (!newEntry) return;
52856
+ const fullPath = newEntry.parentPath ? `${newEntry.parentPath}/${name2}` : name2;
52857
+ if (newEntry.kind === "file") {
52858
+ if (!adapter2.createWorkspaceFile) {
52859
+ throw new Error("Creating files is not supported");
52860
+ }
52861
+ await adapter2.createWorkspaceFile(workspaceId, fullPath);
52862
+ } else {
52863
+ if (!adapter2.createWorkspaceDirectory) {
52864
+ throw new Error("Creating folders is not supported");
52865
+ }
52866
+ await adapter2.createWorkspaceDirectory(workspaceId, fullPath);
52867
+ }
52868
+ await fetchDir(newEntry.parentPath, { force: true });
52869
+ setNewEntry(null);
52870
+ if (newEntry.kind === "file") {
52871
+ setTreeSelection({ path: fullPath, kind: "file" });
52872
+ onOpenFile(fullPath);
52873
+ } else {
52874
+ const cached2 = getCachedExpanded(workspaceId);
52875
+ if (!cached2.has(fullPath)) {
52876
+ cached2.add(fullPath);
52877
+ expandedStateCache.set(workspaceId, new Set(cached2));
52878
+ setExpandedPaths(new Set(cached2));
52879
+ }
52880
+ setTreeSelection({ path: fullPath, kind: "directory" });
52881
+ }
52882
+ },
52883
+ [adapter2, newEntry, fetchDir, onOpenFile, workspaceId]
52884
+ );
52885
+ const canDelete = Boolean(adapter2.deleteWorkspacePath);
52886
+ const requestDelete = reactExports.useCallback((path2, kind) => {
52887
+ setDeleteError(null);
52888
+ setPendingDelete({ path: path2, kind });
52889
+ }, []);
52890
+ const cancelDelete = reactExports.useCallback(() => {
52891
+ if (deleteSubmitting) return;
52892
+ setPendingDelete(null);
52893
+ setDeleteError(null);
52894
+ }, [deleteSubmitting]);
52895
+ const confirmDelete = reactExports.useCallback(async () => {
52896
+ if (!pendingDelete || !adapter2.deleteWorkspacePath) return;
52897
+ setDeleteSubmitting(true);
52898
+ setDeleteError(null);
52899
+ try {
52900
+ await adapter2.deleteWorkspacePath(workspaceId, pendingDelete.path);
52901
+ const cache = getCachedContents(workspaceId);
52902
+ const prefix = `${pendingDelete.path}/`;
52903
+ cache.delete(pendingDelete.path);
52904
+ for (const key2 of Array.from(cache.keys())) {
52905
+ if (key2.startsWith(prefix)) cache.delete(key2);
52906
+ }
52907
+ const cachedExpanded = getCachedExpanded(workspaceId);
52908
+ cachedExpanded.delete(pendingDelete.path);
52909
+ for (const key2 of Array.from(cachedExpanded)) {
52910
+ if (key2.startsWith(prefix)) cachedExpanded.delete(key2);
52911
+ }
52912
+ expandedStateCache.set(workspaceId, new Set(cachedExpanded));
52913
+ setExpandedPaths(new Set(cachedExpanded));
52914
+ setTreeSelection((prev2) => {
52915
+ if (prev2 == null) return prev2;
52916
+ if (prev2.path === pendingDelete.path || prev2.path.startsWith(prefix)) {
52917
+ return null;
52918
+ }
52919
+ return prev2;
52920
+ });
52921
+ setNewEntry((prev2) => {
52922
+ if (!prev2) return prev2;
52923
+ if (prev2.parentPath === pendingDelete.path || prev2.parentPath.startsWith(prefix)) {
52924
+ return null;
52925
+ }
52926
+ return prev2;
52927
+ });
52928
+ const idx = pendingDelete.path.lastIndexOf("/");
52929
+ const parent = idx === -1 ? "" : pendingDelete.path.slice(0, idx);
52930
+ await fetchDir(parent, { force: true });
52931
+ onPathDeleted?.(pendingDelete.path, pendingDelete.kind);
52932
+ setPendingDelete(null);
52933
+ } catch (err) {
52934
+ const message = err instanceof Error ? err.message : String(err);
52935
+ setDeleteError(message);
52936
+ } finally {
52937
+ setDeleteSubmitting(false);
52938
+ }
52939
+ }, [adapter2, pendingDelete, fetchDir, workspaceId, onPathDeleted]);
52940
+ const canRename = Boolean(adapter2.renameWorkspacePath);
52941
+ const requestRename = reactExports.useCallback((path2) => {
52942
+ setRenamingPath(path2);
52943
+ }, []);
52944
+ const cancelRename = reactExports.useCallback(() => {
52945
+ setRenamingPath(null);
52946
+ }, []);
52947
+ const submitRename = reactExports.useCallback(
52948
+ async (newName) => {
52949
+ if (renamingPath == null || !adapter2.renameWorkspacePath) return;
52950
+ const oldPath = renamingPath;
52951
+ const slashIdx = oldPath.lastIndexOf("/");
52952
+ const parent = slashIdx === -1 ? "" : oldPath.slice(0, slashIdx);
52953
+ const newPath = parent ? `${parent}/${newName}` : newName;
52954
+ const result = await adapter2.renameWorkspacePath(workspaceId, oldPath, newPath);
52955
+ const cache = getCachedContents(workspaceId);
52956
+ const oldPrefix = `${oldPath}/`;
52957
+ const newKeys = /* @__PURE__ */ new Map();
52958
+ for (const [key2, value] of cache.entries()) {
52959
+ if (key2 === oldPath) {
52960
+ newKeys.set(newPath, value);
52961
+ } else if (key2.startsWith(oldPrefix)) {
52962
+ newKeys.set(newPath + key2.slice(oldPath.length), value);
52963
+ } else {
52964
+ newKeys.set(key2, value);
52965
+ }
52966
+ }
52967
+ cache.clear();
52968
+ for (const [k2, v2] of newKeys) cache.set(k2, v2);
52969
+ const cachedExpanded = getCachedExpanded(workspaceId);
52970
+ const newExpanded = /* @__PURE__ */ new Set();
52971
+ for (const key2 of cachedExpanded) {
52972
+ if (key2 === oldPath) {
52973
+ newExpanded.add(newPath);
52974
+ } else if (key2.startsWith(oldPrefix)) {
52975
+ newExpanded.add(newPath + key2.slice(oldPath.length));
52976
+ } else {
52977
+ newExpanded.add(key2);
52978
+ }
52979
+ }
52980
+ expandedStateCache.set(workspaceId, newExpanded);
52981
+ setExpandedPaths(new Set(newExpanded));
52982
+ setTreeSelection((prev2) => {
52983
+ if (prev2 == null) return prev2;
52984
+ if (prev2.path === oldPath) return { ...prev2, path: newPath };
52985
+ if (prev2.path.startsWith(oldPrefix)) {
52986
+ return { ...prev2, path: newPath + prev2.path.slice(oldPath.length) };
52987
+ }
52988
+ return prev2;
52989
+ });
52990
+ setNewEntry((prev2) => {
52991
+ if (!prev2) return prev2;
52992
+ if (prev2.parentPath === oldPath || prev2.parentPath.startsWith(oldPrefix)) {
52993
+ return null;
52994
+ }
52995
+ return prev2;
52996
+ });
52997
+ await fetchDir(parent, { force: true });
52998
+ setRenamingPath(null);
52999
+ onPathRenamed?.(oldPath, newPath, result.kind);
53000
+ },
53001
+ [adapter2, renamingPath, fetchDir, onPathRenamed, workspaceId]
53002
+ );
53003
+ const resolveDefaultTarget = reactExports.useCallback(() => {
53004
+ if (treeSelection?.kind === "directory") return treeSelection.path;
53005
+ if (treeSelection?.kind === "file") {
53006
+ const idx = treeSelection.path.lastIndexOf("/");
53007
+ return idx === -1 ? "" : treeSelection.path.slice(0, idx);
53008
+ }
53009
+ return "";
53010
+ }, [treeSelection]);
53011
+ const canCutCopy = Boolean(adapter2.renameWorkspacePath);
53012
+ const canCopyOp = Boolean(adapter2.copyWorkspacePath);
53013
+ const canPaste = Boolean(
53014
+ clipboard && (clipboard.op === "copy" && adapter2.copyWorkspacePath || clipboard.op === "cut" && adapter2.renameWorkspacePath)
53015
+ );
53016
+ const cutPath = reactExports.useCallback((path2, kind) => {
53017
+ setClipboard({ path: path2, kind, op: "cut" });
53018
+ }, []);
53019
+ const copyPath = reactExports.useCallback((path2, kind) => {
53020
+ setClipboard({ path: path2, kind, op: "copy" });
53021
+ }, []);
53022
+ const uniqueCopyName = reactExports.useCallback(
53023
+ (baseName, destFolder, kind) => {
53024
+ const siblings2 = new Set(
53025
+ (getCachedContents(workspaceId).get(destFolder) ?? []).map((e2) => e2.name)
53026
+ );
53027
+ if (!siblings2.has(baseName)) return baseName;
53028
+ const dotIdx = kind === "file" ? baseName.lastIndexOf(".") : -1;
53029
+ const stem = dotIdx > 0 ? baseName.slice(0, dotIdx) : baseName;
53030
+ const ext = dotIdx > 0 ? baseName.slice(dotIdx) : "";
53031
+ let n2 = 1;
53032
+ while (true) {
53033
+ const candidate = n2 === 1 ? `${stem} copy${ext}` : `${stem} copy ${n2}${ext}`;
53034
+ if (!siblings2.has(candidate)) return candidate;
53035
+ n2 += 1;
53036
+ }
53037
+ },
53038
+ [workspaceId]
53039
+ );
53040
+ const pasteInto = reactExports.useCallback(
53041
+ async (destFolder) => {
53042
+ if (!clipboard) return;
53043
+ const sourcePath = clipboard.path;
53044
+ const sourceParent = (() => {
53045
+ const idx = sourcePath.lastIndexOf("/");
53046
+ return idx === -1 ? "" : sourcePath.slice(0, idx);
53047
+ })();
53048
+ const baseName = sourcePath.slice(sourceParent.length === 0 ? 0 : sourceParent.length + 1);
53049
+ if (clipboard.kind === "directory") {
53050
+ if (destFolder === sourcePath || destFolder.startsWith(`${sourcePath}/`)) {
53051
+ return;
53052
+ }
53053
+ }
53054
+ if (clipboard.op === "copy") {
53055
+ if (!adapter2.copyWorkspacePath) return;
53056
+ const newName = uniqueCopyName(baseName, destFolder, clipboard.kind);
53057
+ const destPath = destFolder ? `${destFolder}/${newName}` : newName;
53058
+ await adapter2.copyWorkspacePath(workspaceId, sourcePath, destPath);
53059
+ await fetchDir(destFolder, { force: true });
53060
+ setTreeSelection({ path: destPath, kind: clipboard.kind });
53061
+ } else {
53062
+ if (destFolder === sourceParent) return;
53063
+ if (!adapter2.renameWorkspacePath) return;
53064
+ const destPath = destFolder ? `${destFolder}/${baseName}` : baseName;
53065
+ const result = await adapter2.renameWorkspacePath(workspaceId, sourcePath, destPath);
53066
+ const cache = getCachedContents(workspaceId);
53067
+ const oldPrefix = `${sourcePath}/`;
53068
+ const remapped = /* @__PURE__ */ new Map();
53069
+ for (const [key2, value] of cache.entries()) {
53070
+ if (key2 === sourcePath) {
53071
+ remapped.set(destPath, value);
53072
+ } else if (key2.startsWith(oldPrefix)) {
53073
+ remapped.set(destPath + key2.slice(sourcePath.length), value);
53074
+ } else {
53075
+ remapped.set(key2, value);
53076
+ }
53077
+ }
53078
+ cache.clear();
53079
+ for (const [k2, v2] of remapped) cache.set(k2, v2);
53080
+ const cachedExpanded = getCachedExpanded(workspaceId);
53081
+ const remappedExpanded = /* @__PURE__ */ new Set();
53082
+ for (const key2 of cachedExpanded) {
53083
+ if (key2 === sourcePath) {
53084
+ remappedExpanded.add(destPath);
53085
+ } else if (key2.startsWith(oldPrefix)) {
53086
+ remappedExpanded.add(destPath + key2.slice(sourcePath.length));
53087
+ } else {
53088
+ remappedExpanded.add(key2);
53089
+ }
53090
+ }
53091
+ expandedStateCache.set(workspaceId, remappedExpanded);
53092
+ setExpandedPaths(new Set(remappedExpanded));
53093
+ await Promise.all([
53094
+ fetchDir(sourceParent, { force: true }),
53095
+ fetchDir(destFolder, { force: true })
53096
+ ]);
53097
+ onPathRenamed?.(sourcePath, destPath, result.kind);
53098
+ setTreeSelection({ path: destPath, kind: clipboard.kind });
53099
+ setClipboard(null);
53100
+ }
53101
+ },
53102
+ [adapter2, clipboard, fetchDir, onPathRenamed, uniqueCopyName, workspaceId]
53103
+ );
53104
+ reactExports.useImperativeHandle(
53105
+ handleRef,
53106
+ () => ({
53107
+ startNewFile(parentPath) {
53108
+ requestNewEntry(parentPath ?? resolveDefaultTarget(), "file");
53109
+ },
53110
+ startNewFolder(parentPath) {
53111
+ requestNewEntry(parentPath ?? resolveDefaultTarget(), "directory");
53112
+ }
53113
+ }),
53114
+ [requestNewEntry, resolveDefaultTarget]
53115
+ );
53116
+ const rootMenu = useDeferredMenuAction();
52018
53117
  if (!adapter2.listWorkspaceFiles) {
52019
53118
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "File browsing not supported" });
52020
53119
  }
52021
53120
  const rootEntries = dirContents.get("") ?? [];
52022
53121
  const rootLoading = loadingPaths.has("");
52023
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto py-1", children: [
52024
- rootLoading && rootEntries.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Loading…" }),
52025
- !rootLoading && rootEntries.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Empty directory" }),
52026
- rootEntries.map((entry) => /* @__PURE__ */ jsxRuntimeExports.jsx(
52027
- TreeNode2,
53122
+ const rootSiblings = new Set(rootEntries.map((e2) => e2.name));
53123
+ const showRootInput = newEntry?.parentPath === "";
53124
+ const handleKeyDown = (e2) => {
53125
+ const target = e2.target;
53126
+ if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable)) {
53127
+ return;
53128
+ }
53129
+ if ((e2.key === "Delete" || e2.key === "Backspace") && !e2.metaKey && !e2.ctrlKey && !e2.shiftKey && !e2.altKey) {
53130
+ if (!treeSelection || !canDelete) return;
53131
+ e2.preventDefault();
53132
+ requestDelete(treeSelection.path, treeSelection.kind);
53133
+ return;
53134
+ }
53135
+ if (!(e2.metaKey || e2.ctrlKey) || e2.shiftKey || e2.altKey) return;
53136
+ const key2 = e2.key.toLowerCase();
53137
+ if (key2 === "c") {
53138
+ if (!treeSelection || !canCutCopy) return;
53139
+ e2.preventDefault();
53140
+ copyPath(treeSelection.path, treeSelection.kind);
53141
+ return;
53142
+ }
53143
+ if (key2 === "x") {
53144
+ if (!treeSelection || !canCutCopy) return;
53145
+ e2.preventDefault();
53146
+ cutPath(treeSelection.path, treeSelection.kind);
53147
+ return;
53148
+ }
53149
+ if (key2 === "v") {
53150
+ if (!canPaste) return;
53151
+ e2.preventDefault();
53152
+ void pasteInto(resolveDefaultTarget());
53153
+ }
53154
+ };
53155
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col overflow-hidden", onKeyDown: handleKeyDown, children: [
53156
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
53157
+ ContextMenu,
52028
53158
  {
52029
- entry,
52030
- parentPath: "",
52031
- depth: 0,
52032
- expandedPaths,
52033
- dirContents,
52034
- loadingPaths,
52035
- onToggle: toggleExpand,
52036
- onOpenFile,
52037
- onOpenFilePinned,
52038
- compact,
52039
- selectedFile,
52040
- selectedRef
52041
- },
52042
- entry.name
52043
- ))
52044
- ] }) });
52045
- }
53159
+ onOpenChange: (open2) => {
53160
+ if (open2) clearTreeSelection();
53161
+ },
53162
+ children: [
53163
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto py-1 pl-px", children: [
53164
+ (() => {
53165
+ const rootSplitIdx = rootEntries.findIndex((e2) => e2.type === "file");
53166
+ const rootFolders = rootSplitIdx === -1 ? rootEntries : rootEntries.slice(0, rootSplitIdx);
53167
+ const rootFiles = rootSplitIdx === -1 ? [] : rootEntries.slice(rootSplitIdx);
53168
+ const renderRow = (entry) => /* @__PURE__ */ jsxRuntimeExports.jsx(
53169
+ TreeNode2,
53170
+ {
53171
+ entry,
53172
+ parentPath: "",
53173
+ depth: 0,
53174
+ expandedPaths,
53175
+ dirContents,
53176
+ loadingPaths,
53177
+ onToggle: toggleExpand,
53178
+ onOpenFile,
53179
+ onOpenFilePinned,
53180
+ onSelectRow: handleSelectRow,
53181
+ onRequestNewEntry: requestNewEntry,
53182
+ onRequestDelete: requestDelete,
53183
+ onRequestRename: requestRename,
53184
+ onCut: cutPath,
53185
+ onCopy: copyPath,
53186
+ onPaste: pasteInto,
53187
+ canDelete,
53188
+ canRename,
53189
+ canCut: canCutCopy,
53190
+ canCopy: canCopyOp,
53191
+ canPaste,
53192
+ compact,
53193
+ treeSelection,
53194
+ clipboard,
53195
+ selectedRef,
53196
+ newEntry,
53197
+ onNewEntrySubmit: submitNewEntry,
53198
+ onNewEntryCancel: cancelNewEntry,
53199
+ renamingPath,
53200
+ onRenameSubmit: submitRename,
53201
+ onRenameCancel: cancelRename
53202
+ },
53203
+ entry.name
53204
+ );
53205
+ const rootInput = showRootInput ? /* @__PURE__ */ jsxRuntimeExports.jsx(
53206
+ EntryNameInput,
53207
+ {
53208
+ kind: newEntry.kind,
53209
+ depth: 0,
53210
+ compact,
53211
+ siblings: rootSiblings,
53212
+ onSubmit: submitNewEntry,
53213
+ onCancel: cancelNewEntry
53214
+ },
53215
+ `new-${newEntry.kind}-root`
53216
+ ) : null;
53217
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
53218
+ showRootInput && newEntry.kind === "directory" && rootInput,
53219
+ rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Loading…" }),
53220
+ !rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Empty directory" }),
53221
+ rootFolders.map(renderRow),
53222
+ showRootInput && newEntry.kind === "file" && rootInput,
53223
+ rootFiles.map(renderRow)
53224
+ ] });
53225
+ })(),
53226
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-[40px] flex-1" })
53227
+ ] }) }),
53228
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { onCloseAutoFocus: rootMenu.flush, children: [
53229
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "file")), children: [
53230
+ /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "size-4" }),
53231
+ "New File"
53232
+ ] }),
53233
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "directory")), children: [
53234
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-4" }),
53235
+ "New Folder"
53236
+ ] }),
53237
+ canPaste && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
53238
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
53239
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onSelect: () => rootMenu.queue(() => void pasteInto("")), children: [
53240
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClipboardPaste, { className: "size-4" }),
53241
+ "Paste"
53242
+ ] })
53243
+ ] })
53244
+ ] })
53245
+ ]
53246
+ }
53247
+ ),
53248
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
53249
+ Dialog,
53250
+ {
53251
+ open: pendingDelete !== null,
53252
+ onOpenChange: (open2) => {
53253
+ if (!open2) cancelDelete();
53254
+ },
53255
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogContent, { className: "sm:max-w-[425px]", onClick: (e2) => e2.stopPropagation(), children: [
53256
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
53257
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { children: [
53258
+ "Delete ",
53259
+ pendingDelete?.kind === "directory" ? "folder" : "file"
53260
+ ] }),
53261
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogDescription, { children: [
53262
+ "Are you sure you want to delete ",
53263
+ /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: pendingDelete?.path }),
53264
+ "?"
53265
+ ] })
53266
+ ] }),
53267
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
53268
+ pendingDelete?.kind === "directory" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
53269
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
53270
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "The folder and all of its contents will be deleted from disk. This cannot be undone." })
53271
+ ] }),
53272
+ pendingDelete?.kind === "file" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
53273
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
53274
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "The file will be deleted from disk. This cannot be undone." })
53275
+ ] }),
53276
+ deleteError && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 p-3 text-destructive", children: [
53277
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-4 shrink-0 mt-0.5" }),
53278
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: deleteError })
53279
+ ] })
53280
+ ] }),
53281
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [
53282
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", onClick: cancelDelete, disabled: deleteSubmitting, children: "Cancel" }),
53283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
53284
+ Button,
53285
+ {
53286
+ variant: "destructive",
53287
+ onClick: () => void confirmDelete(),
53288
+ disabled: deleteSubmitting,
53289
+ children: deleteSubmitting ? "Deleting…" : "Delete"
53290
+ }
53291
+ )
53292
+ ] })
53293
+ ] })
53294
+ }
53295
+ )
53296
+ ] });
53297
+ });
52046
53298
  const IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
52047
53299
  ".png",
52048
53300
  ".jpg",
@@ -52375,12 +53627,12 @@ function FileViewer({
52375
53627
  error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-32 items-center justify-center text-sm text-destructive", children: error }),
52376
53628
  !loading && !error && previewType === "image" && fileUrl && /* @__PURE__ */ jsxRuntimeExports.jsx(ImagePreview$1, { src: fileUrl, alt: getFilename(filePath) }),
52377
53629
  !loading && !error && previewType === "pdf" && fileUrl && /* @__PURE__ */ jsxRuntimeExports.jsx(PdfPreview, { src: fileUrl, filename: getFilename(filePath) }),
52378
- !loading && !error && previewType === "markdown" && renderMarkdown2 && viewMode === "preview" && displayContent && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto max-w-3xl px-8 py-6 text-sm", children: renderMarkdown2(displayContent) }) }),
52379
- !loading && !error && data?.content && (previewType === "code" || previewType === "markdown" && (!renderMarkdown2 || viewMode === "source")) && (canEdit ? /* @__PURE__ */ jsxRuntimeExports.jsx(
53630
+ !loading && !error && previewType === "markdown" && renderMarkdown2 && viewMode === "preview" && displayContent !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full overflow-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-auto max-w-3xl px-8 py-6 text-sm", children: renderMarkdown2(displayContent) }) }),
53631
+ !loading && !error && data?.content !== void 0 && (previewType === "code" || previewType === "markdown" && (!renderMarkdown2 || viewMode === "source")) && (canEdit ? /* @__PURE__ */ jsxRuntimeExports.jsx(
52380
53632
  CodeMirrorEditor,
52381
53633
  {
52382
- content: displayContent,
52383
- originalContent: data?.content,
53634
+ content: displayContent ?? "",
53635
+ originalContent: data.content,
52384
53636
  language: lang,
52385
53637
  className: "h-full",
52386
53638
  filePath,
@@ -52775,6 +54027,7 @@ function WorkspacePickerDialog({ open: open2, onOpenChange }) {
52775
54027
  const statuses = useDashboardStore((s2) => s2.statuses);
52776
54028
  const openWorkspace = useDashboardStore((s2) => s2.openWorkspace);
52777
54029
  const clearNeedsAttention = useDashboardStore((s2) => s2.clearNeedsAttention);
54030
+ const { isPinned, toggle: togglePinned, pinned } = usePinnedWorkspaces();
52778
54031
  const [query, setQuery] = reactExports.useState("");
52779
54032
  const [recentOrder, setRecentOrder] = reactExports.useState([]);
52780
54033
  reactExports.useEffect(() => {
@@ -52784,6 +54037,7 @@ function WorkspacePickerDialog({ open: open2, onOpenChange }) {
52784
54037
  setQuery("");
52785
54038
  }
52786
54039
  }, [open2]);
54040
+ const pinnedRank = reactExports.useMemo(() => new Map(pinned.map((p3, i2) => [p3.workspaceId, i2])), [pinned]);
52787
54041
  const sortedWorkspaces = reactExports.useMemo(() => {
52788
54042
  const entries2 = [];
52789
54043
  for (const project of projects) {
@@ -52799,12 +54053,19 @@ function WorkspacePickerDialog({ open: open2, onOpenChange }) {
52799
54053
  }
52800
54054
  const orderMap = new Map(recentOrder.map((id28, i2) => [id28, i2]));
52801
54055
  entries2.sort((a2, b2) => {
54056
+ if (a2.workspaceId === activeWorkspaceId) return -1;
54057
+ if (b2.workspaceId === activeWorkspaceId) return 1;
54058
+ const ap = pinnedRank.get(a2.workspaceId);
54059
+ const bp = pinnedRank.get(b2.workspaceId);
54060
+ if (ap !== void 0 && bp === void 0) return -1;
54061
+ if (bp !== void 0 && ap === void 0) return 1;
54062
+ if (ap !== void 0 && bp !== void 0) return ap - bp;
52802
54063
  const ai = orderMap.get(a2.workspaceId) ?? Number.MAX_SAFE_INTEGER;
52803
54064
  const bi = orderMap.get(b2.workspaceId) ?? Number.MAX_SAFE_INTEGER;
52804
54065
  return ai - bi;
52805
54066
  });
52806
54067
  return entries2;
52807
- }, [projects, statuses, recentOrder]);
54068
+ }, [projects, statuses, recentOrder, activeWorkspaceId, pinnedRank]);
52808
54069
  const handleSelect = reactExports.useCallback(
52809
54070
  (workspaceId) => {
52810
54071
  clearNeedsAttention(workspaceId);
@@ -52830,11 +54091,13 @@ function WorkspacePickerDialog({ open: open2, onOpenChange }) {
52830
54091
  /* @__PURE__ */ jsxRuntimeExports.jsx(CommandEmpty, { children: "No workspaces found." }),
52831
54092
  sortedWorkspaces.map((entry) => {
52832
54093
  const isActive = activeWorkspaceId === entry.workspaceId;
54094
+ const pinnedNow = isPinned(entry.workspaceId);
52833
54095
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
52834
54096
  CommandItem,
52835
54097
  {
52836
54098
  value: `${entry.projectName} ${entry.branch}`,
52837
54099
  onSelect: () => handleSelect(entry.workspaceId),
54100
+ className: "group",
52838
54101
  children: [
52839
54102
  /* @__PURE__ */ jsxRuntimeExports.jsx(AgentStatusIndicator, { agent: entry.agent }),
52840
54103
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium", children: [
@@ -52842,7 +54105,30 @@ function WorkspacePickerDialog({ open: open2, onOpenChange }) {
52842
54105
  "/",
52843
54106
  entry.branch
52844
54107
  ] }),
52845
- isActive && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto shrink-0 text-xs text-muted-foreground", children: "current" })
54108
+ pinnedNow && /* @__PURE__ */ jsxRuntimeExports.jsx(Pin, { className: "size-3 -rotate-45 text-muted-foreground shrink-0" }),
54109
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
54110
+ isActive && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: "current" }),
54111
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
54112
+ "button",
54113
+ {
54114
+ type: "button",
54115
+ "aria-label": pinnedNow ? "Unpin workspace" : "Pin workspace",
54116
+ className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
54117
+ onMouseDown: (e2) => {
54118
+ e2.preventDefault();
54119
+ e2.stopPropagation();
54120
+ togglePinned(entry.projectName, entry.branch, pinnedNow);
54121
+ },
54122
+ onClick: (e2) => {
54123
+ if (e2.detail !== 0) return;
54124
+ e2.preventDefault();
54125
+ e2.stopPropagation();
54126
+ togglePinned(entry.projectName, entry.branch, pinnedNow);
54127
+ },
54128
+ children: pinnedNow ? /* @__PURE__ */ jsxRuntimeExports.jsx(PinOff, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Pin, { className: "size-3.5" })
54129
+ }
54130
+ )
54131
+ ] })
52846
54132
  ]
52847
54133
  },
52848
54134
  entry.workspaceId
@@ -59335,6 +60621,9 @@ class WebDashboardAdapter {
59335
60621
  async removeWorkspace(project, branch) {
59336
60622
  await this.trpc.workspaces.remove.mutate({ project, branch });
59337
60623
  }
60624
+ async setWorkspacePinned(project, branch, pinned) {
60625
+ await this.trpc.workspaces.setPinned.mutate({ project, branch, pinned });
60626
+ }
59338
60627
  async clearNeedsAttention(workspaceId) {
59339
60628
  await this.trpc.statuses.clearNeedsAttention.mutate({ workspaceId });
59340
60629
  }
@@ -59476,6 +60765,29 @@ class WebDashboardAdapter {
59476
60765
  async saveWorkspaceFile(workspaceId, path2, content2) {
59477
60766
  await this.trpc.workspace.saveFile.mutate({ workspaceId, path: path2, content: content2 });
59478
60767
  }
60768
+ async createWorkspaceFile(workspaceId, path2, content2 = "") {
60769
+ await this.trpc.workspace.createFile.mutate({ workspaceId, path: path2, content: content2 });
60770
+ }
60771
+ async createWorkspaceDirectory(workspaceId, path2) {
60772
+ await this.trpc.workspace.createDirectory.mutate({ workspaceId, path: path2 });
60773
+ }
60774
+ async deleteWorkspacePath(workspaceId, path2) {
60775
+ return await this.trpc.workspace.deletePath.mutate({ workspaceId, path: path2 });
60776
+ }
60777
+ async renameWorkspacePath(workspaceId, fromPath, toPath) {
60778
+ return await this.trpc.workspace.renamePath.mutate({
60779
+ workspaceId,
60780
+ fromPath,
60781
+ toPath
60782
+ });
60783
+ }
60784
+ async copyWorkspacePath(workspaceId, fromPath, toPath) {
60785
+ return await this.trpc.workspace.copyPath.mutate({
60786
+ workspaceId,
60787
+ fromPath,
60788
+ toPath
60789
+ });
60790
+ }
59479
60791
  async revertFile(workspaceId, filePath, diffMode, compareBranch) {
59480
60792
  await this.trpc.workspace.revertFile.mutate({
59481
60793
  workspaceId,
@@ -59579,6 +60891,34 @@ class DesktopDashboardAdapter extends WebDashboardAdapter {
59579
60891
  throw err;
59580
60892
  }
59581
60893
  }
60894
+ // ---- Background app-update banner (see updater.ts) -----------------------
60895
+ // The web adapter intentionally omits these so a plain browser tab never
60896
+ // sees the banner (the hook short-circuits to "none" when the adapter
60897
+ // method is undefined). Only the desktop shell can drive electron-updater.
60898
+ /** Read the current pending update, if any. Used by the hook on mount to
60899
+ * catch the race where the renderer mounts after the startup check
60900
+ * already populated main-process state. */
60901
+ async getUpdateStatus() {
60902
+ return desktopInvoke("updater_status");
60903
+ }
60904
+ /** Kick off the download + install. On success the OS quits the process,
60905
+ * so this promise typically never resolves in production. */
60906
+ async installUpdate() {
60907
+ await desktopInvoke("updater_install");
60908
+ }
60909
+ /** Subscribe to `updater-status-changed` events emitted by the main
60910
+ * process. Returns the unlisten. Throws if called outside the shell —
60911
+ * callers should gate on `getUpdateStatus` being defined first. */
60912
+ subscribeUpdateStatus(cb) {
60913
+ const bridge = electronBridge$1();
60914
+ if (!bridge) {
60915
+ throw new Error("subscribeUpdateStatus called outside the desktop shell");
60916
+ }
60917
+ return bridge.on(
60918
+ "updater-status-changed",
60919
+ (payload) => cb(payload)
60920
+ );
60921
+ }
59582
60922
  }
59583
60923
  class NativeShellCapabilities {
59584
60924
  web = new WebCapabilities();
@@ -59625,6 +60965,66 @@ async function listen(event, cb) {
59625
60965
  }
59626
60966
  throw new Error(`listen('${event}') called outside the desktop shell`);
59627
60967
  }
60968
+ const wsClient = createWSClient({
60969
+ url: () => {
60970
+ const proto2 = location.protocol === "https:" ? "wss:" : "ws:";
60971
+ return `${proto2}//${location.host}/trpc`;
60972
+ }
60973
+ });
60974
+ const trpc = createTRPCClient({
60975
+ links: [
60976
+ splitLink({
60977
+ condition: (op2) => op2.type === "subscription",
60978
+ true: wsLink({ client: wsClient }),
60979
+ false: httpBatchLink({ url: "/trpc" })
60980
+ })
60981
+ ]
60982
+ });
60983
+ function BrowserHostBridge() {
60984
+ const { settings } = useSettingsQuery();
60985
+ const cdpEnabled = settings.webBrowserCdpEnabled ?? false;
60986
+ reactExports.useEffect(() => {
60987
+ if (!isDesktop) return;
60988
+ if (!cdpEnabled) return;
60989
+ const ensureSub = trpc.browserHost.ensureView.subscribe(void 0, {
60990
+ onData(event) {
60991
+ void (async () => {
60992
+ try {
60993
+ await invoke("browser_ensure", {
60994
+ browserId: event.bandTabId,
60995
+ url: event.url
60996
+ });
60997
+ const cdpTargetId = await invoke("browser_get_cdp_target", {
60998
+ browserId: event.bandTabId
60999
+ });
61000
+ await trpc.browserHost.targetReady.mutate({
61001
+ bandTabId: event.bandTabId,
61002
+ cdpTargetId
61003
+ });
61004
+ } catch (err) {
61005
+ console.error("[BrowserHostBridge] ensureView failed:", err);
61006
+ }
61007
+ })();
61008
+ },
61009
+ onError(err) {
61010
+ console.warn("[BrowserHostBridge] ensureView subscription error:", err);
61011
+ }
61012
+ });
61013
+ let unlisten;
61014
+ void listen("browser-view-destroyed", (e2) => {
61015
+ const bandTabId = e2.payload.browser_id;
61016
+ if (!bandTabId) return;
61017
+ trpc.browserHost.viewDestroyed.mutate({ bandTabId }).catch((err) => console.warn("[BrowserHostBridge] viewDestroyed mutate failed:", err));
61018
+ }).then((u4) => {
61019
+ unlisten = u4;
61020
+ });
61021
+ return () => {
61022
+ ensureSub.unsubscribe();
61023
+ unlisten?.();
61024
+ };
61025
+ }, [cdpEnabled]);
61026
+ return null;
61027
+ }
59628
61028
  function useIsFullscreen() {
59629
61029
  const [isFullscreen, setIsFullscreen] = reactExports.useState(false);
59630
61030
  reactExports.useEffect(() => {
@@ -74998,21 +76398,6 @@ function useRecentFiles(workspaceId) {
74998
76398
  );
74999
76399
  return { recentFiles, trackFile };
75000
76400
  }
75001
- const wsClient = createWSClient({
75002
- url: () => {
75003
- const proto2 = location.protocol === "https:" ? "wss:" : "ws:";
75004
- return `${proto2}//${location.host}/trpc`;
75005
- }
75006
- });
75007
- const trpc = createTRPCClient({
75008
- links: [
75009
- splitLink({
75010
- condition: (op2) => op2.type === "subscription",
75011
- true: wsLink({ client: wsClient }),
75012
- false: httpBatchLink({ url: "/trpc" })
75013
- })
75014
- ]
75015
- });
75016
76401
  const codes = (
75017
76402
  /** @type {const} */
75018
76403
  {
@@ -134799,12 +136184,12 @@ var registerDefaultLayoutLoaders = /* @__PURE__ */ __name(() => {
134799
136184
  registerLayoutLoaders([
134800
136185
  {
134801
136186
  name: "dagre",
134802
- loader: /* @__PURE__ */ __name(async () => await import("./dagre-6UL2VRFP-DZfpOMzg.js"), "loader")
136187
+ loader: /* @__PURE__ */ __name(async () => await import("./dagre-6UL2VRFP-BmlvwxMz.js"), "loader")
134803
136188
  },
134804
136189
  ...[
134805
136190
  {
134806
136191
  name: "cose-bilkent",
134807
- loader: /* @__PURE__ */ __name(async () => await import("./cose-bilkent-S5V4N54A-WSuuldrv.js"), "loader")
136192
+ loader: /* @__PURE__ */ __name(async () => await import("./cose-bilkent-S5V4N54A-CpHc0Viy.js"), "loader")
134808
136193
  }
134809
136194
  ]
134810
136195
  ]);
@@ -135243,7 +136628,7 @@ var detector = /* @__PURE__ */ __name((txt) => {
135243
136628
  return /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(txt);
135244
136629
  }, "detector");
135245
136630
  var loader = /* @__PURE__ */ __name(async () => {
135246
- const { diagram: diagram2 } = await import("./c4Diagram-YG6GDRKO-COi5PFIX.js");
136631
+ const { diagram: diagram2 } = await import("./c4Diagram-YG6GDRKO-DPx-FvB1.js");
135247
136632
  return { id, diagram: diagram2 };
135248
136633
  }, "loader");
135249
136634
  var plugin = {
@@ -135260,7 +136645,7 @@ var detector2 = /* @__PURE__ */ __name((txt, config2) => {
135260
136645
  return /^\s*graph/.test(txt);
135261
136646
  }, "detector");
135262
136647
  var loader2 = /* @__PURE__ */ __name(async () => {
135263
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-Cw9n-l35.js");
136648
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-BfyIqNem.js");
135264
136649
  return { id: id2, diagram: diagram2 };
135265
136650
  }, "loader");
135266
136651
  var plugin2 = {
@@ -135283,7 +136668,7 @@ var detector3 = /* @__PURE__ */ __name((txt, config2) => {
135283
136668
  return /^\s*flowchart/.test(txt);
135284
136669
  }, "detector");
135285
136670
  var loader3 = /* @__PURE__ */ __name(async () => {
135286
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-Cw9n-l35.js");
136671
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-BfyIqNem.js");
135287
136672
  return { id: id3, diagram: diagram2 };
135288
136673
  }, "loader");
135289
136674
  var plugin3 = {
@@ -135297,7 +136682,7 @@ var detector4 = /* @__PURE__ */ __name((txt) => {
135297
136682
  return /^\s*erDiagram/.test(txt);
135298
136683
  }, "detector");
135299
136684
  var loader4 = /* @__PURE__ */ __name(async () => {
135300
- const { diagram: diagram2 } = await import("./erDiagram-Q2GNP2WA-XphQqWxZ.js");
136685
+ const { diagram: diagram2 } = await import("./erDiagram-Q2GNP2WA-DM8WJlsi.js");
135301
136686
  return { id: id4, diagram: diagram2 };
135302
136687
  }, "loader");
135303
136688
  var plugin4 = {
@@ -135311,7 +136696,7 @@ var detector5 = /* @__PURE__ */ __name((txt) => {
135311
136696
  return /^\s*gitGraph/.test(txt);
135312
136697
  }, "detector");
135313
136698
  var loader5 = /* @__PURE__ */ __name(async () => {
135314
- const { diagram: diagram2 } = await import("./gitGraphDiagram-V2S2FVAM-CUIK26NP.js");
136699
+ const { diagram: diagram2 } = await import("./gitGraphDiagram-V2S2FVAM-bCVMHPpA.js");
135315
136700
  return { id: id5, diagram: diagram2 };
135316
136701
  }, "loader");
135317
136702
  var plugin5 = {
@@ -135325,7 +136710,7 @@ var detector6 = /* @__PURE__ */ __name((txt) => {
135325
136710
  return /^\s*gantt/.test(txt);
135326
136711
  }, "detector");
135327
136712
  var loader6 = /* @__PURE__ */ __name(async () => {
135328
- const { diagram: diagram2 } = await import("./ganttDiagram-JELNMOA3-CqqJbuET.js");
136713
+ const { diagram: diagram2 } = await import("./ganttDiagram-JELNMOA3-BZQeLvAR.js");
135329
136714
  return { id: id6, diagram: diagram2 };
135330
136715
  }, "loader");
135331
136716
  var plugin6 = {
@@ -135339,7 +136724,7 @@ var detector7 = /* @__PURE__ */ __name((txt) => {
135339
136724
  return /^\s*info/.test(txt);
135340
136725
  }, "detector");
135341
136726
  var loader7 = /* @__PURE__ */ __name(async () => {
135342
- const { diagram: diagram2 } = await import("./infoDiagram-HS3SLOUP-DuA859Z1.js");
136727
+ const { diagram: diagram2 } = await import("./infoDiagram-HS3SLOUP-RRsQoFFk.js");
135343
136728
  return { id: id7, diagram: diagram2 };
135344
136729
  }, "loader");
135345
136730
  var info = {
@@ -135352,7 +136737,7 @@ var detector8 = /* @__PURE__ */ __name((txt) => {
135352
136737
  return /^\s*pie/.test(txt);
135353
136738
  }, "detector");
135354
136739
  var loader8 = /* @__PURE__ */ __name(async () => {
135355
- const { diagram: diagram2 } = await import("./pieDiagram-ADFJNKIX-CS1QqpkR.js");
136740
+ const { diagram: diagram2 } = await import("./pieDiagram-ADFJNKIX-DWZOj9Y0.js");
135356
136741
  return { id: id8, diagram: diagram2 };
135357
136742
  }, "loader");
135358
136743
  var pie = {
@@ -135365,7 +136750,7 @@ var detector9 = /* @__PURE__ */ __name((txt) => {
135365
136750
  return /^\s*quadrantChart/.test(txt);
135366
136751
  }, "detector");
135367
136752
  var loader9 = /* @__PURE__ */ __name(async () => {
135368
- const { diagram: diagram2 } = await import("./quadrantDiagram-AYHSOK5B-sOsgkH1q.js");
136753
+ const { diagram: diagram2 } = await import("./quadrantDiagram-AYHSOK5B-D4ONUX7b.js");
135369
136754
  return { id: id9, diagram: diagram2 };
135370
136755
  }, "loader");
135371
136756
  var plugin7 = {
@@ -135379,7 +136764,7 @@ var detector10 = /* @__PURE__ */ __name((txt) => {
135379
136764
  return /^\s*xychart(-beta)?/.test(txt);
135380
136765
  }, "detector");
135381
136766
  var loader10 = /* @__PURE__ */ __name(async () => {
135382
- const { diagram: diagram2 } = await import("./xychartDiagram-PRI3JC2R-C01ACkIV.js");
136767
+ const { diagram: diagram2 } = await import("./xychartDiagram-PRI3JC2R-DZLYbs7Q.js");
135383
136768
  return { id: id10, diagram: diagram2 };
135384
136769
  }, "loader");
135385
136770
  var plugin8 = {
@@ -135393,7 +136778,7 @@ var detector11 = /* @__PURE__ */ __name((txt) => {
135393
136778
  return /^\s*requirement(Diagram)?/.test(txt);
135394
136779
  }, "detector");
135395
136780
  var loader11 = /* @__PURE__ */ __name(async () => {
135396
- const { diagram: diagram2 } = await import("./requirementDiagram-UZGBJVZJ-DxsTf_dF.js");
136781
+ const { diagram: diagram2 } = await import("./requirementDiagram-UZGBJVZJ-UgBPsTYb.js");
135397
136782
  return { id: id11, diagram: diagram2 };
135398
136783
  }, "loader");
135399
136784
  var plugin9 = {
@@ -135407,7 +136792,7 @@ var detector12 = /* @__PURE__ */ __name((txt) => {
135407
136792
  return /^\s*sequenceDiagram/.test(txt);
135408
136793
  }, "detector");
135409
136794
  var loader12 = /* @__PURE__ */ __name(async () => {
135410
- const { diagram: diagram2 } = await import("./sequenceDiagram-WL72ISMW-DdZyEvL3.js");
136795
+ const { diagram: diagram2 } = await import("./sequenceDiagram-WL72ISMW-ampkthMk.js");
135411
136796
  return { id: id12, diagram: diagram2 };
135412
136797
  }, "loader");
135413
136798
  var plugin10 = {
@@ -135424,7 +136809,7 @@ var detector13 = /* @__PURE__ */ __name((txt, config2) => {
135424
136809
  return /^\s*classDiagram/.test(txt);
135425
136810
  }, "detector");
135426
136811
  var loader13 = /* @__PURE__ */ __name(async () => {
135427
- const { diagram: diagram2 } = await import("./classDiagram-2ON5EDUG-SabF3eWj.js");
136812
+ const { diagram: diagram2 } = await import("./classDiagram-2ON5EDUG-CxlZAW4M.js");
135428
136813
  return { id: id13, diagram: diagram2 };
135429
136814
  }, "loader");
135430
136815
  var plugin11 = {
@@ -135441,7 +136826,7 @@ var detector14 = /* @__PURE__ */ __name((txt, config2) => {
135441
136826
  return /^\s*classDiagram-v2/.test(txt);
135442
136827
  }, "detector");
135443
136828
  var loader14 = /* @__PURE__ */ __name(async () => {
135444
- const { diagram: diagram2 } = await import("./classDiagram-v2-WZHVMYZB-SabF3eWj.js");
136829
+ const { diagram: diagram2 } = await import("./classDiagram-v2-WZHVMYZB-CxlZAW4M.js");
135445
136830
  return { id: id14, diagram: diagram2 };
135446
136831
  }, "loader");
135447
136832
  var plugin12 = {
@@ -135458,7 +136843,7 @@ var detector15 = /* @__PURE__ */ __name((txt, config2) => {
135458
136843
  return /^\s*stateDiagram/.test(txt);
135459
136844
  }, "detector");
135460
136845
  var loader15 = /* @__PURE__ */ __name(async () => {
135461
- const { diagram: diagram2 } = await import("./stateDiagram-FKZM4ZOC-D3Tj81-E.js");
136846
+ const { diagram: diagram2 } = await import("./stateDiagram-FKZM4ZOC-BGJgIHAr.js");
135462
136847
  return { id: id15, diagram: diagram2 };
135463
136848
  }, "loader");
135464
136849
  var plugin13 = {
@@ -135478,7 +136863,7 @@ var detector16 = /* @__PURE__ */ __name((txt, config2) => {
135478
136863
  return false;
135479
136864
  }, "detector");
135480
136865
  var loader16 = /* @__PURE__ */ __name(async () => {
135481
- const { diagram: diagram2 } = await import("./stateDiagram-v2-4FDKWEC3-Dx5gqfCT.js");
136866
+ const { diagram: diagram2 } = await import("./stateDiagram-v2-4FDKWEC3-DV0c4QE4.js");
135482
136867
  return { id: id16, diagram: diagram2 };
135483
136868
  }, "loader");
135484
136869
  var plugin14 = {
@@ -135492,7 +136877,7 @@ var detector17 = /* @__PURE__ */ __name((txt) => {
135492
136877
  return /^\s*journey/.test(txt);
135493
136878
  }, "detector");
135494
136879
  var loader17 = /* @__PURE__ */ __name(async () => {
135495
- const { diagram: diagram2 } = await import("./journeyDiagram-XKPGCS4Q-PiSB9SFS.js");
136880
+ const { diagram: diagram2 } = await import("./journeyDiagram-XKPGCS4Q-BthUaNJH.js");
135496
136881
  return { id: id17, diagram: diagram2 };
135497
136882
  }, "loader");
135498
136883
  var plugin15 = {
@@ -135559,7 +136944,7 @@ var detector18 = /* @__PURE__ */ __name((txt, config2 = {}) => {
135559
136944
  return false;
135560
136945
  }, "detector");
135561
136946
  var loader18 = /* @__PURE__ */ __name(async () => {
135562
- const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-Cw9n-l35.js");
136947
+ const { diagram: diagram2 } = await import("./flowDiagram-NV44I4VS-BfyIqNem.js");
135563
136948
  return { id: id18, diagram: diagram2 };
135564
136949
  }, "loader");
135565
136950
  var plugin16 = {
@@ -135573,7 +136958,7 @@ var detector19 = /* @__PURE__ */ __name((txt) => {
135573
136958
  return /^\s*timeline/.test(txt);
135574
136959
  }, "detector");
135575
136960
  var loader19 = /* @__PURE__ */ __name(async () => {
135576
- const { diagram: diagram2 } = await import("./timeline-definition-IT6M3QCI-CcjZ3wnd.js");
136961
+ const { diagram: diagram2 } = await import("./timeline-definition-IT6M3QCI-V6Yu7fCS.js");
135577
136962
  return { id: id19, diagram: diagram2 };
135578
136963
  }, "loader");
135579
136964
  var plugin17 = {
@@ -135587,7 +136972,7 @@ var detector20 = /* @__PURE__ */ __name((txt) => {
135587
136972
  return /^\s*mindmap/.test(txt);
135588
136973
  }, "detector");
135589
136974
  var loader20 = /* @__PURE__ */ __name(async () => {
135590
- const { diagram: diagram2 } = await import("./mindmap-definition-VGOIOE7T-RsSUd0h5.js");
136975
+ const { diagram: diagram2 } = await import("./mindmap-definition-VGOIOE7T-CyOPm1d2.js");
135591
136976
  return { id: id20, diagram: diagram2 };
135592
136977
  }, "loader");
135593
136978
  var plugin18 = {
@@ -135601,7 +136986,7 @@ var detector21 = /* @__PURE__ */ __name((txt) => {
135601
136986
  return /^\s*kanban/.test(txt);
135602
136987
  }, "detector");
135603
136988
  var loader21 = /* @__PURE__ */ __name(async () => {
135604
- const { diagram: diagram2 } = await import("./kanban-definition-3W4ZIXB7-Fl-z0jKd.js");
136989
+ const { diagram: diagram2 } = await import("./kanban-definition-3W4ZIXB7-g-dju6UR.js");
135605
136990
  return { id: id21, diagram: diagram2 };
135606
136991
  }, "loader");
135607
136992
  var plugin19 = {
@@ -135615,7 +137000,7 @@ var detector22 = /* @__PURE__ */ __name((txt) => {
135615
137000
  return /^\s*sankey(-beta)?/.test(txt);
135616
137001
  }, "detector");
135617
137002
  var loader22 = /* @__PURE__ */ __name(async () => {
135618
- const { diagram: diagram2 } = await import("./sankeyDiagram-TZEHDZUN-Dv69rb4x.js");
137003
+ const { diagram: diagram2 } = await import("./sankeyDiagram-TZEHDZUN-DR346iyM.js");
135619
137004
  return { id: id22, diagram: diagram2 };
135620
137005
  }, "loader");
135621
137006
  var plugin20 = {
@@ -135629,7 +137014,7 @@ var detector23 = /* @__PURE__ */ __name((txt) => {
135629
137014
  return /^\s*packet(-beta)?/.test(txt);
135630
137015
  }, "detector");
135631
137016
  var loader23 = /* @__PURE__ */ __name(async () => {
135632
- const { diagram: diagram2 } = await import("./diagram-S2PKOQOG-DBeAGiPC.js");
137017
+ const { diagram: diagram2 } = await import("./diagram-S2PKOQOG-BHuUrG2N.js");
135633
137018
  return { id: id23, diagram: diagram2 };
135634
137019
  }, "loader");
135635
137020
  var packet = {
@@ -135642,7 +137027,7 @@ var detector24 = /* @__PURE__ */ __name((txt) => {
135642
137027
  return /^\s*radar-beta/.test(txt);
135643
137028
  }, "detector");
135644
137029
  var loader24 = /* @__PURE__ */ __name(async () => {
135645
- const { diagram: diagram2 } = await import("./diagram-QEK2KX5R-GhJ4dzVD.js");
137030
+ const { diagram: diagram2 } = await import("./diagram-QEK2KX5R-D3Y8zwos.js");
135646
137031
  return { id: id24, diagram: diagram2 };
135647
137032
  }, "loader");
135648
137033
  var radar = {
@@ -135655,7 +137040,7 @@ var detector25 = /* @__PURE__ */ __name((txt) => {
135655
137040
  return /^\s*block(-beta)?/.test(txt);
135656
137041
  }, "detector");
135657
137042
  var loader25 = /* @__PURE__ */ __name(async () => {
135658
- const { diagram: diagram2 } = await import("./blockDiagram-VD42YOAC-Bc-Qk0S9.js");
137043
+ const { diagram: diagram2 } = await import("./blockDiagram-VD42YOAC-pT0fTRP_.js");
135659
137044
  return { id: id25, diagram: diagram2 };
135660
137045
  }, "loader");
135661
137046
  var plugin21 = {
@@ -135669,7 +137054,7 @@ var detector26 = /* @__PURE__ */ __name((txt) => {
135669
137054
  return /^\s*architecture/.test(txt);
135670
137055
  }, "detector");
135671
137056
  var loader26 = /* @__PURE__ */ __name(async () => {
135672
- const { diagram: diagram2 } = await import("./architectureDiagram-VXUJARFQ-CqvTF0VE.js");
137057
+ const { diagram: diagram2 } = await import("./architectureDiagram-VXUJARFQ-DUGfoAf_.js");
135673
137058
  return { id: id26, diagram: diagram2 };
135674
137059
  }, "loader");
135675
137060
  var architecture = {
@@ -135683,7 +137068,7 @@ var detector27 = /* @__PURE__ */ __name((txt) => {
135683
137068
  return /^\s*treemap/.test(txt);
135684
137069
  }, "detector");
135685
137070
  var loader27 = /* @__PURE__ */ __name(async () => {
135686
- const { diagram: diagram2 } = await import("./diagram-PSM6KHXK-DCKwYA11.js");
137071
+ const { diagram: diagram2 } = await import("./diagram-PSM6KHXK-B0TgGZY7.js");
135687
137072
  return { id: id27, diagram: diagram2 };
135688
137073
  }, "loader");
135689
137074
  var treemap = {
@@ -153396,7 +154781,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
153396
154781
  var et2 = ({ className: e2, language: t2, style: o3, isIncomplete: n2, ...s2 }) => jsxRuntimeExports.jsx("div", { className: f("my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2", e2), "data-incomplete": n2 || void 0, "data-language": t2, "data-streamdown": "code-block", style: { contentVisibility: "auto", containIntrinsicSize: "auto 200px", ...o3 }, ...s2 });
153397
154782
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
153398
154783
  var ot2 = ({ language: e2 }) => jsxRuntimeExports.jsx("div", { className: "flex h-8 items-center text-muted-foreground text-xs", "data-language": e2, "data-streamdown": "code-block-header", children: jsxRuntimeExports.jsx("span", { className: "ml-1 font-mono lowercase", children: e2 }) });
153399
- var cn = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-BVGB-5j8.js").then((e2) => ({ default: e2.HighlightedCodeBlockBody }))), rt = ({ code: e2, language: t2, className: o3, children: n2, isIncomplete: s2 = false, ...r2 }) => {
154784
+ var cn = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-DgdfkSxA.js").then((e2) => ({ default: e2.HighlightedCodeBlockBody }))), rt = ({ code: e2, language: t2, className: o3, children: n2, isIncomplete: s2 = false, ...r2 }) => {
153400
154785
  let i2 = reactExports.useMemo(() => e2.replace(cn, ""), [e2]), c2 = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i2.split(`
153401
154786
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i2]);
153402
154787
  return jsxRuntimeExports.jsx(Se.Provider, { value: { code: e2 }, children: jsxRuntimeExports.jsxs(et2, { isIncomplete: s2, language: t2, children: [jsxRuntimeExports.jsx(ot2, { 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, { className: o3, language: t2, result: c2, ...r2 }), children: jsxRuntimeExports.jsx(dn, { className: o3, code: i2, language: t2, raw: c2, ...r2 }) })] }) });
@@ -153718,7 +155103,7 @@ var Dt = ({ children: e2, className: t2, onDownload: o3, onError: n2 }) => {
153718
155103
  }, []), jsxRuntimeExports.jsxs("div", { className: "relative", ref: i2, children: [jsxRuntimeExports.jsx("button", { className: f("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: e2 != null ? e2 : jsxRuntimeExports.jsx(Z, { 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] });
153719
155104
  };
153720
155105
  var Vt = ({ children: e2, 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("w-full divide-y divide-border", t2), "data-streamdown": "table", ...n2, children: e2 }) })] });
153721
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-rjgzkBvP.js").then((e2) => ({ default: e2.Mermaid }))), Kn = /language-([^\s]+)/;
155106
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-gGOjGhZZ.js").then((e2) => ({ default: e2.Mermaid }))), Kn = /language-([^\s]+)/;
153722
155107
  function ke(e2, t2) {
153723
155108
  if (!(e2 != null && e2.position || t2 != null && t2.position)) return true;
153724
155109
  if (!(e2 != null && e2.position && (t2 != null && t2.position))) return false;
@@ -154323,6 +155708,65 @@ function useFileTabs(workspaceId) {
154323
155708
  setOpenTabs([]);
154324
155709
  setActiveTabPathState(null);
154325
155710
  }, []);
155711
+ const rewritePath = reactExports.useCallback(
155712
+ (path2, oldPath, newPath) => {
155713
+ if (path2 === oldPath) return newPath;
155714
+ const prefix = `${oldPath}/`;
155715
+ if (path2.startsWith(prefix)) return newPath + path2.slice(oldPath.length);
155716
+ return null;
155717
+ },
155718
+ []
155719
+ );
155720
+ const renameFile = reactExports.useCallback(
155721
+ (oldPath, newPath) => {
155722
+ if (oldPath === newPath) return;
155723
+ setOpenTabs((prev2) => {
155724
+ let changed = false;
155725
+ const next2 = prev2.map((tab2) => {
155726
+ const rewritten = rewritePath(tab2.filePath, oldPath, newPath);
155727
+ if (rewritten === null) return tab2;
155728
+ changed = true;
155729
+ return tab2.isPreview ? { filePath: rewritten, isPreview: true } : { filePath: rewritten };
155730
+ });
155731
+ return changed ? next2 : prev2;
155732
+ });
155733
+ setActiveTabPathState((current) => {
155734
+ if (current === null) return current;
155735
+ const rewritten = rewritePath(current, oldPath, newPath);
155736
+ return rewritten ?? current;
155737
+ });
155738
+ },
155739
+ [rewritePath]
155740
+ );
155741
+ const removePath = reactExports.useCallback((path2) => {
155742
+ const prefix = `${path2}/`;
155743
+ setOpenTabs((prev2) => {
155744
+ const next2 = prev2.filter((tab2) => tab2.filePath !== path2 && !tab2.filePath.startsWith(prefix));
155745
+ if (next2.length === prev2.length) {
155746
+ return prev2;
155747
+ }
155748
+ setActiveTabPathState((currentActive) => {
155749
+ if (currentActive !== null && (currentActive === path2 || currentActive.startsWith(prefix))) {
155750
+ if (next2.length === 0) return null;
155751
+ const removedIdx = prev2.findIndex((t2) => t2.filePath === currentActive);
155752
+ if (removedIdx === -1) return next2[0].filePath;
155753
+ for (let i2 = removedIdx; i2 < prev2.length; i2++) {
155754
+ if (next2.some((t2) => t2.filePath === prev2[i2].filePath)) {
155755
+ return prev2[i2].filePath;
155756
+ }
155757
+ }
155758
+ for (let i2 = removedIdx - 1; i2 >= 0; i2--) {
155759
+ if (next2.some((t2) => t2.filePath === prev2[i2].filePath)) {
155760
+ return prev2[i2].filePath;
155761
+ }
155762
+ }
155763
+ return next2[0].filePath;
155764
+ }
155765
+ return currentActive;
155766
+ });
155767
+ return next2;
155768
+ });
155769
+ }, []);
154326
155770
  return {
154327
155771
  openTabs,
154328
155772
  activeTabPath,
@@ -154333,7 +155777,9 @@ function useFileTabs(workspaceId) {
154333
155777
  closeTab,
154334
155778
  setActiveTab,
154335
155779
  closeOtherTabs,
154336
- closeAllTabs
155780
+ closeAllTabs,
155781
+ renameFile,
155782
+ removePath
154337
155783
  };
154338
155784
  }
154339
155785
  const DESKTOP_QUERY = "(min-width: 1024px)";
@@ -154410,7 +155856,54 @@ function useTabState(workspaceId) {
154410
155856
  },
154411
155857
  [workspaceId]
154412
155858
  );
154413
- return { get: get2, update, getViewMode, setViewMode, isDirty, removeFile };
155859
+ const renameFile = reactExports.useCallback(
155860
+ (oldPath, newPath) => {
155861
+ if (oldPath === newPath) return;
155862
+ const prefix = `${oldPath}/`;
155863
+ let changed = false;
155864
+ const next2 = {};
155865
+ for (const [key2, value] of Object.entries(stateRef.current)) {
155866
+ if (key2 === oldPath) {
155867
+ next2[newPath] = value;
155868
+ changed = true;
155869
+ } else if (key2.startsWith(prefix)) {
155870
+ next2[newPath + key2.slice(oldPath.length)] = value;
155871
+ changed = true;
155872
+ } else {
155873
+ next2[key2] = value;
155874
+ }
155875
+ }
155876
+ if (changed) {
155877
+ stateRef.current = next2;
155878
+ saveState(workspaceId, stateRef.current);
155879
+ }
155880
+ },
155881
+ [workspaceId]
155882
+ );
155883
+ const removePath = reactExports.useCallback(
155884
+ (path2) => {
155885
+ const prefix = `${path2}/`;
155886
+ let changed = false;
155887
+ for (const key2 of Object.keys(stateRef.current)) {
155888
+ if (key2 === path2 || key2.startsWith(prefix)) {
155889
+ delete stateRef.current[key2];
155890
+ changed = true;
155891
+ }
155892
+ }
155893
+ if (changed) saveState(workspaceId, stateRef.current);
155894
+ },
155895
+ [workspaceId]
155896
+ );
155897
+ return {
155898
+ get: get2,
155899
+ update,
155900
+ getViewMode,
155901
+ setViewMode,
155902
+ isDirty,
155903
+ removeFile,
155904
+ renameFile,
155905
+ removePath
155906
+ };
154414
155907
  }
154415
155908
  function getBasename$1(filePath) {
154416
155909
  if (typeof filePath !== "string") return String(filePath ?? "");
@@ -154721,43 +156214,158 @@ function renderMarkdown(content2) {
154721
156214
  }
154722
156215
  );
154723
156216
  }
154724
- function FileTreeToolbar({ onQuickOpen, onSearchFiles }) {
154725
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 shrink-0 items-center gap-0.5 border-b border-border/50 pl-3 pr-1.5", children: [
154726
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Files" }),
154727
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1" }),
154728
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
154729
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
154730
- "button",
154731
- {
154732
- type: "button",
154733
- onClick: onQuickOpen,
154734
- className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
154735
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-3.5" })
154736
- }
154737
- ) }),
154738
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { side: "bottom", className: "text-xs", children: [
154739
- "Quick Open",
154740
- " ",
154741
- /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-1.5 rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[14px]", children: "⌘P" })
154742
- ] })
154743
- ] }),
154744
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
154745
- /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
154746
- "button",
154747
- {
154748
- type: "button",
154749
- onClick: onSearchFiles,
154750
- className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
154751
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(TextSearch, { className: "size-3.5" })
154752
- }
154753
- ) }),
154754
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { side: "bottom", className: "text-xs", children: [
154755
- "Search in Files",
154756
- " ",
154757
- /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-1.5 rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[14px]", children: "⌘⇧F" })
154758
- ] })
154759
- ] })
154760
- ] });
156217
+ const TOOLBAR_COMPACT_BREAKPOINT = 200;
156218
+ const touchPointerUp = (fn2) => (e2) => {
156219
+ if (!fn2 || e2.pointerType === "mouse") return;
156220
+ e2.preventDefault();
156221
+ fn2();
156222
+ };
156223
+ const fireOpenQuickOpen = () => window.dispatchEvent(new CustomEvent("band:open-quick-open"));
156224
+ const fireOpenSearchFiles = () => window.dispatchEvent(new CustomEvent("band:open-search-files"));
156225
+ function FileTreeToolbar({ onNewFile, onNewFolder }) {
156226
+ const rootRef = reactExports.useRef(null);
156227
+ const [compact, setCompact] = reactExports.useState(false);
156228
+ reactExports.useLayoutEffect(() => {
156229
+ const el = rootRef.current;
156230
+ if (!el) return;
156231
+ setCompact(el.clientWidth < TOOLBAR_COMPACT_BREAKPOINT);
156232
+ }, []);
156233
+ reactExports.useEffect(() => {
156234
+ const el = rootRef.current;
156235
+ if (!el) return;
156236
+ const ro2 = new ResizeObserver((entries2) => {
156237
+ for (const entry of entries2) {
156238
+ setCompact(entry.contentRect.width < TOOLBAR_COMPACT_BREAKPOINT);
156239
+ }
156240
+ });
156241
+ ro2.observe(el);
156242
+ return () => ro2.disconnect();
156243
+ }, []);
156244
+ const pendingMenuAction = reactExports.useRef(null);
156245
+ const queueMenuAction = reactExports.useCallback((fn2) => {
156246
+ pendingMenuAction.current = fn2;
156247
+ }, []);
156248
+ const flushMenuAction = reactExports.useCallback((e2) => {
156249
+ e2.preventDefault();
156250
+ const fn2 = pendingMenuAction.current;
156251
+ pendingMenuAction.current = null;
156252
+ fn2?.();
156253
+ }, []);
156254
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
156255
+ "div",
156256
+ {
156257
+ ref: rootRef,
156258
+ className: "flex h-9 shrink-0 items-center gap-0.5 border-b border-border/50 pl-3 pr-1.5",
156259
+ children: [
156260
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Files" }),
156261
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1" }),
156262
+ compact ? /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
156263
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
156264
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
156265
+ "button",
156266
+ {
156267
+ type: "button",
156268
+ "aria-label": "File tree actions",
156269
+ className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors data-[state=open]:bg-accent data-[state=open]:text-foreground",
156270
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(EllipsisVertical, { className: "size-3.5" })
156271
+ }
156272
+ ) }) }),
156273
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "More" })
156274
+ ] }),
156275
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
156276
+ DropdownMenuContent,
156277
+ {
156278
+ align: "end",
156279
+ className: "min-w-[10rem]",
156280
+ onCloseAutoFocus: flushMenuAction,
156281
+ children: [
156282
+ onNewFile && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onSelect: () => queueMenuAction(onNewFile), children: [
156283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "size-4" }),
156284
+ "New File"
156285
+ ] }),
156286
+ onNewFolder && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onSelect: () => queueMenuAction(onNewFolder), children: [
156287
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-4" }),
156288
+ "New Folder"
156289
+ ] }),
156290
+ (onNewFile || onNewFolder) && /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuSeparator, {}),
156291
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onSelect: () => queueMenuAction(fireOpenQuickOpen), children: [
156292
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-4" }),
156293
+ "Quick Open",
156294
+ /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-auto rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[10px]", children: "⌘P" })
156295
+ ] }),
156296
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuItem, { onSelect: () => queueMenuAction(fireOpenSearchFiles), children: [
156297
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TextSearch, { className: "size-4" }),
156298
+ "Search in Files",
156299
+ /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-auto rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[10px]", children: "⌘⇧F" })
156300
+ ] })
156301
+ ]
156302
+ }
156303
+ )
156304
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
156305
+ onNewFile && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
156306
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
156307
+ "button",
156308
+ {
156309
+ type: "button",
156310
+ onClick: onNewFile,
156311
+ onPointerUp: touchPointerUp(onNewFile),
156312
+ className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
156313
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "size-3.5" })
156314
+ }
156315
+ ) }),
156316
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "New File" })
156317
+ ] }),
156318
+ onNewFolder && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
156319
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
156320
+ "button",
156321
+ {
156322
+ type: "button",
156323
+ onClick: onNewFolder,
156324
+ onPointerUp: touchPointerUp(onNewFolder),
156325
+ className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
156326
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-3.5" })
156327
+ }
156328
+ ) }),
156329
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { side: "bottom", className: "text-xs", children: "New Folder" })
156330
+ ] }),
156331
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
156332
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
156333
+ "button",
156334
+ {
156335
+ type: "button",
156336
+ onClick: fireOpenQuickOpen,
156337
+ onPointerUp: touchPointerUp(fireOpenQuickOpen),
156338
+ className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
156339
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "size-3.5" })
156340
+ }
156341
+ ) }),
156342
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { side: "bottom", className: "text-xs", children: [
156343
+ "Quick Open",
156344
+ " ",
156345
+ /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-1.5 rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[14px]", children: "⌘P" })
156346
+ ] })
156347
+ ] }),
156348
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
156349
+ /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
156350
+ "button",
156351
+ {
156352
+ type: "button",
156353
+ onClick: fireOpenSearchFiles,
156354
+ onPointerUp: touchPointerUp(fireOpenSearchFiles),
156355
+ className: "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
156356
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(TextSearch, { className: "size-3.5" })
156357
+ }
156358
+ ) }),
156359
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(TooltipContent, { side: "bottom", className: "text-xs", children: [
156360
+ "Search in Files",
156361
+ " ",
156362
+ /* @__PURE__ */ jsxRuntimeExports.jsx("kbd", { className: "ml-1.5 rounded border border-popover-foreground/25 bg-popover-foreground/10 px-1 py-0.5 font-mono text-[14px]", children: "⌘⇧F" })
156363
+ ] })
156364
+ ] })
156365
+ ] })
156366
+ ]
156367
+ }
156368
+ );
154761
156369
  }
154762
156370
  function CodeBrowserView({
154763
156371
  workspaceId,
@@ -154765,9 +156373,7 @@ function CodeBrowserView({
154765
156373
  onSelectFile,
154766
156374
  openFilePath,
154767
156375
  onFileOpened,
154768
- onFindInFile,
154769
- onQuickOpen,
154770
- onSearchFiles
156376
+ onFindInFile
154771
156377
  }) {
154772
156378
  const isDesktop2 = useIsDesktop();
154773
156379
  const fileTabs = useFileTabs(workspaceId);
@@ -155246,6 +156852,89 @@ function CodeBrowserView({
155246
156852
  window.addEventListener("keydown", handler, { capture: true });
155247
156853
  return () => window.removeEventListener("keydown", handler, { capture: true });
155248
156854
  }, [fileTabs.activeTabPath, handleTabClose]);
156855
+ const fileBrowserRef = reactExports.useRef(null);
156856
+ const handleNewFile = reactExports.useCallback(() => {
156857
+ fileBrowserRef.current?.startNewFile();
156858
+ }, []);
156859
+ const handleNewFolder = reactExports.useCallback(() => {
156860
+ fileBrowserRef.current?.startNewFolder();
156861
+ }, []);
156862
+ const flushActiveEditorState = reactExports.useCallback(() => {
156863
+ const view = editorViewRef.current;
156864
+ const fp = viewFilePathRef.current;
156865
+ if (!view || !fp) return null;
156866
+ try {
156867
+ const state2 = serializeEditorState(view);
156868
+ return { path: fp, state: state2 };
156869
+ } catch {
156870
+ return null;
156871
+ }
156872
+ }, []);
156873
+ const handlePathRenamed = reactExports.useCallback(
156874
+ (oldPath, newPath, _kind) => {
156875
+ const flushed = flushActiveEditorState();
156876
+ fileTabs.renameFile(oldPath, newPath);
156877
+ tabState.renameFile(oldPath, newPath);
156878
+ const oldPrefix = `${oldPath}/`;
156879
+ const newStates = {};
156880
+ for (const [key2, value] of Object.entries(savedEditorStatesRef.current)) {
156881
+ if (key2 === oldPath) {
156882
+ newStates[newPath] = value;
156883
+ } else if (key2.startsWith(oldPrefix)) {
156884
+ newStates[newPath + key2.slice(oldPath.length)] = value;
156885
+ } else {
156886
+ newStates[key2] = value;
156887
+ }
156888
+ }
156889
+ if (flushed) {
156890
+ const rewritten = flushed.path === oldPath ? newPath : flushed.path.startsWith(oldPrefix) ? newPath + flushed.path.slice(oldPath.length) : flushed.path;
156891
+ newStates[rewritten] = flushed.state;
156892
+ tabState.update(rewritten, {
156893
+ editorState: flushed.state.editorState,
156894
+ scrollTop: flushed.state.scrollTop
156895
+ });
156896
+ }
156897
+ savedEditorStatesRef.current = newStates;
156898
+ if (viewFilePath === oldPath) {
156899
+ skipFileEffectRef.current = true;
156900
+ setViewFilePath(newPath);
156901
+ onSelectFile?.(newPath);
156902
+ } else if (viewFilePath.startsWith(oldPrefix)) {
156903
+ const rewritten = newPath + viewFilePath.slice(oldPath.length);
156904
+ skipFileEffectRef.current = true;
156905
+ setViewFilePath(rewritten);
156906
+ onSelectFile?.(rewritten);
156907
+ }
156908
+ },
156909
+ [
156910
+ fileTabs.renameFile,
156911
+ tabState.renameFile,
156912
+ tabState.update,
156913
+ flushActiveEditorState,
156914
+ viewFilePath,
156915
+ onSelectFile
156916
+ ]
156917
+ );
156918
+ const handlePathDeleted = reactExports.useCallback(
156919
+ (path2, _kind) => {
156920
+ const prefix = `${path2}/`;
156921
+ for (const key2 of Object.keys(savedEditorStatesRef.current)) {
156922
+ if (key2 === path2 || key2.startsWith(prefix)) {
156923
+ delete savedEditorStatesRef.current[key2];
156924
+ }
156925
+ }
156926
+ tabState.removePath(path2);
156927
+ fileTabs.removePath(path2);
156928
+ if (viewFilePath === path2 || viewFilePath.startsWith(prefix)) {
156929
+ setViewFilePath("");
156930
+ setViewLine(void 0);
156931
+ setViewLineEnd(void 0);
156932
+ setViewColumn(void 0);
156933
+ onSelectFile?.(null);
156934
+ }
156935
+ },
156936
+ [fileTabs.removePath, tabState.removePath, viewFilePath, onSelectFile]
156937
+ );
155249
156938
  const treePanelRef = ln$1();
155250
156939
  const [treeCollapsed, setTreeCollapsed] = reactExports.useState(() => loadFileTreeCollapsed(workspaceId));
155251
156940
  const skipFirstLayoutCallback = reactExports.useRef(true);
@@ -155309,14 +156998,28 @@ function CodeBrowserView({
155309
156998
  savedScrollTop: savedEditorStatesRef.current[viewFilePath]?.scrollTop ?? tabState.get(viewFilePath)?.scrollTop,
155310
156999
  onEditedContentChange: handleEditedContentChange
155311
157000
  }
155312
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
155313
- FileBrowser,
155314
- {
155315
- workspaceId,
155316
- onOpenFile: handleSelectFile,
155317
- onOpenFilePinned: handleSelectFilePinned,
155318
- selectedFile: viewFilePath
155319
- }
157001
+ ) : (
157002
+ // Same toolbar-above-tree layout the desktop side-by-side uses,
157003
+ // so New File / New Folder / Quick Open / Search in Files are
157004
+ // reachable on touch without relying on the (undiscoverable)
157005
+ // long-press → context menu. The toolbar already handles its
157006
+ // own narrow-width collapse into a kebab, so this works at any
157007
+ // mobile viewport.
157008
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
157009
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileTreeToolbar, { onNewFile: handleNewFile, onNewFolder: handleNewFolder }),
157010
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
157011
+ FileBrowser,
157012
+ {
157013
+ ref: fileBrowserRef,
157014
+ workspaceId,
157015
+ onOpenFile: handleSelectFile,
157016
+ onOpenFilePinned: handleSelectFilePinned,
157017
+ selectedFile: viewFilePath,
157018
+ onPathRenamed: handlePathRenamed,
157019
+ onPathDeleted: handlePathDeleted
157020
+ }
157021
+ ) })
157022
+ ] })
155320
157023
  )
155321
157024
  ) : (
155322
157025
  // Desktop: side-by-side layout with resizable file tree
@@ -155343,15 +157046,18 @@ function CodeBrowserView({
155343
157046
  saveFileTreeCollapsed(workspaceId, collapsed);
155344
157047
  },
155345
157048
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col overflow-hidden border-r border-border", children: [
155346
- /* @__PURE__ */ jsxRuntimeExports.jsx(FileTreeToolbar, { onQuickOpen, onSearchFiles }),
157049
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileTreeToolbar, { onNewFile: handleNewFile, onNewFolder: handleNewFolder }),
155347
157050
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
155348
157051
  FileBrowser,
155349
157052
  {
157053
+ ref: fileBrowserRef,
155350
157054
  workspaceId,
155351
157055
  onOpenFile: handleSelectFile,
155352
157056
  onOpenFilePinned: handleSelectFilePinned,
155353
157057
  compact: true,
155354
- selectedFile: viewFilePath
157058
+ selectedFile: viewFilePath,
157059
+ onPathRenamed: handlePathRenamed,
157060
+ onPathDeleted: handlePathDeleted
155355
157061
  }
155356
157062
  ) })
155357
157063
  ] })
@@ -155461,21 +157167,21 @@ function CodeBrowserView({
155461
157167
  const DEFAULT_URL = "";
155462
157168
  const BLANK_URL = "about:blank";
155463
157169
  const faviconMap = /* @__PURE__ */ new Map();
155464
- const faviconListeners = /* @__PURE__ */ new Set();
157170
+ const faviconListeners$1 = /* @__PURE__ */ new Set();
155465
157171
  function setFaviconUrl(browserId, url) {
155466
157172
  if (faviconMap.get(browserId) !== url) {
155467
157173
  faviconMap.set(browserId, url);
155468
- for (const listener of faviconListeners) listener();
157174
+ for (const listener of faviconListeners$1) listener();
155469
157175
  }
155470
157176
  }
155471
- function subscribeFavicons(cb) {
155472
- faviconListeners.add(cb);
157177
+ function subscribeFavicons$1(cb) {
157178
+ faviconListeners$1.add(cb);
155473
157179
  return () => {
155474
- faviconListeners.delete(cb);
157180
+ faviconListeners$1.delete(cb);
155475
157181
  };
155476
157182
  }
155477
157183
  function useFavicon(browserId) {
155478
- return reactExports.useSyncExternalStore(subscribeFavicons, () => faviconMap.get(browserId));
157184
+ return reactExports.useSyncExternalStore(subscribeFavicons$1, () => faviconMap.get(browserId));
155479
157185
  }
155480
157186
  function BrowserPaneComponent({
155481
157187
  params,
@@ -169061,6 +170767,613 @@ function createDefaultPanel(api, workspaceId) {
169061
170767
  }
169062
170768
  });
169063
170769
  }
170770
+ const TABS_POLL_MS = 5e3;
170771
+ const screencastTabTheme = {
170772
+ name: "band",
170773
+ className: "dockview-theme-band dockview-browser-tabs"
170774
+ };
170775
+ function ScreencastPanel({ workspaceId, visible }) {
170776
+ const [tabs, setTabs] = reactExports.useState([]);
170777
+ const [error, setError] = reactExports.useState(null);
170778
+ const [loaded, setLoaded] = reactExports.useState(false);
170779
+ const fetchTabs = reactExports.useCallback(
170780
+ async (signal) => {
170781
+ try {
170782
+ const res = await fetch(`/api/cdp/tabs?workspaceId=${encodeURIComponent(workspaceId)}`, {
170783
+ signal,
170784
+ cache: "no-store"
170785
+ });
170786
+ const body2 = await res.json();
170787
+ setTabs(body2.tabs ?? []);
170788
+ setError(body2.error ?? null);
170789
+ } catch (err) {
170790
+ if (err.name === "AbortError") return;
170791
+ setError(err instanceof Error ? err.message : String(err));
170792
+ } finally {
170793
+ setLoaded(true);
170794
+ }
170795
+ },
170796
+ [workspaceId]
170797
+ );
170798
+ reactExports.useEffect(() => {
170799
+ if (!visible) return;
170800
+ const ctrl = new AbortController();
170801
+ fetchTabs(ctrl.signal);
170802
+ const id28 = setInterval(() => fetchTabs(ctrl.signal), TABS_POLL_MS);
170803
+ return () => {
170804
+ ctrl.abort();
170805
+ clearInterval(id28);
170806
+ };
170807
+ }, [visible, fetchTabs]);
170808
+ if (loaded && error) {
170809
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorPanel, { error }) });
170810
+ }
170811
+ if (loaded && tabs.length === 0) {
170812
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(EmptyPanel, {}) });
170813
+ }
170814
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ScreencastDockview, { tabs, outerVisible: visible, workspaceId });
170815
+ }
170816
+ const newTabRef = { current: null };
170817
+ const ScreencastRightHeaderActions = React$1.memo(function ScreencastRightHeaderActions2(_props) {
170818
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center pr-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
170819
+ "button",
170820
+ {
170821
+ type: "button",
170822
+ className: "inline-flex size-8 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
170823
+ onClick: () => newTabRef.current?.(),
170824
+ title: "New browser tab",
170825
+ "aria-label": "New browser tab",
170826
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" })
170827
+ }
170828
+ ) });
170829
+ });
170830
+ function ScreencastDockview({ tabs, outerVisible, workspaceId }) {
170831
+ const apiRef = reactExports.useRef(null);
170832
+ const handleNewTab = reactExports.useCallback(() => {
170833
+ trpc.browsers.create.mutate({ workspaceId }).catch((err) => console.warn("[ScreencastPanel] browsers.create failed:", err));
170834
+ }, [workspaceId]);
170835
+ newTabRef.current = handleNewTab;
170836
+ reactExports.useEffect(() => {
170837
+ const api = apiRef.current;
170838
+ if (!api) return;
170839
+ const wantIds = new Set(tabs.map((t2) => t2.id));
170840
+ const haveIds = new Set(api.panels.map((p3) => p3.id));
170841
+ for (const id28 of haveIds) {
170842
+ if (!wantIds.has(id28)) {
170843
+ const panel = api.getPanel(id28);
170844
+ if (panel) api.removePanel(panel);
170845
+ }
170846
+ }
170847
+ for (const tab2 of tabs) {
170848
+ const existing = api.getPanel(tab2.id);
170849
+ if (existing) {
170850
+ existing.api.updateParameters({
170851
+ bandTabId: tab2.id,
170852
+ url: tab2.url,
170853
+ outerVisible
170854
+ });
170855
+ } else {
170856
+ api.addPanel({
170857
+ id: tab2.id,
170858
+ component: "stream",
170859
+ title: tab2.title || tab2.url || "(no title)",
170860
+ params: { bandTabId: tab2.id, url: tab2.url, outerVisible }
170861
+ });
170862
+ }
170863
+ }
170864
+ if (!api.activePanel && api.panels.length > 0) {
170865
+ api.panels[0].api.setActive();
170866
+ }
170867
+ }, [tabs, outerVisible]);
170868
+ reactExports.useEffect(() => {
170869
+ const api = apiRef.current;
170870
+ if (!api) return;
170871
+ for (const panel of api.panels) {
170872
+ const params = panel.api.getParameters();
170873
+ if (params.outerVisible !== outerVisible) {
170874
+ panel.api.updateParameters({ ...params, outerVisible });
170875
+ }
170876
+ }
170877
+ }, [outerVisible]);
170878
+ const onReady = reactExports.useCallback((event) => {
170879
+ apiRef.current = event.api;
170880
+ }, []);
170881
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full w-full flex-col overflow-hidden bg-background text-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
170882
+ DockviewReact,
170883
+ {
170884
+ theme: screencastTabTheme,
170885
+ className: "h-full",
170886
+ components: panelComponents,
170887
+ defaultTabComponent: ScreencastTab,
170888
+ rightHeaderActionsComponent: ScreencastRightHeaderActions,
170889
+ onReady
170890
+ }
170891
+ ) });
170892
+ }
170893
+ const faviconByBandTabId = /* @__PURE__ */ new Map();
170894
+ const faviconListeners = /* @__PURE__ */ new Set();
170895
+ function setFaviconForBandTab(bandTabId, url) {
170896
+ const current = faviconByBandTabId.get(bandTabId);
170897
+ if (url) {
170898
+ if (current === url) return;
170899
+ faviconByBandTabId.set(bandTabId, url);
170900
+ } else {
170901
+ if (current === void 0) return;
170902
+ faviconByBandTabId.delete(bandTabId);
170903
+ }
170904
+ for (const listener of faviconListeners) listener();
170905
+ }
170906
+ function subscribeFavicons(cb) {
170907
+ faviconListeners.add(cb);
170908
+ return () => {
170909
+ faviconListeners.delete(cb);
170910
+ };
170911
+ }
170912
+ function useFaviconForBandTab(bandTabId) {
170913
+ return reactExports.useSyncExternalStore(
170914
+ subscribeFavicons,
170915
+ () => faviconByBandTabId.get(bandTabId),
170916
+ () => void 0
170917
+ );
170918
+ }
170919
+ function ScreencastTab(props) {
170920
+ const [title, setTitle] = reactExports.useState(props.api.title ?? "");
170921
+ const [faviconErrored, setFaviconErrored] = reactExports.useState(false);
170922
+ reactExports.useEffect(() => {
170923
+ const d2 = props.api.onDidTitleChange(() => setTitle(props.api.title ?? ""));
170924
+ return () => d2.dispose();
170925
+ }, [props.api]);
170926
+ const bandTabId = props.params.bandTabId;
170927
+ const favicon = useFaviconForBandTab(bandTabId);
170928
+ const prevFaviconRef = reactExports.useRef(favicon);
170929
+ if (favicon !== prevFaviconRef.current) {
170930
+ prevFaviconRef.current = favicon;
170931
+ if (faviconErrored) setFaviconErrored(false);
170932
+ }
170933
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "dv-default-tab", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
170934
+ favicon && !faviconErrored ? /* @__PURE__ */ jsxRuntimeExports.jsx(
170935
+ "img",
170936
+ {
170937
+ src: favicon,
170938
+ alt: "",
170939
+ className: "size-3.5 shrink-0",
170940
+ onError: () => setFaviconErrored(true)
170941
+ }
170942
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { className: "size-3.5 shrink-0 text-muted-foreground" }),
170943
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: title || "(no title)" })
170944
+ ] }) });
170945
+ }
170946
+ function StreamPanel({ params, api }) {
170947
+ const [panelVisible, setPanelVisible] = reactExports.useState(api.isVisible);
170948
+ reactExports.useEffect(() => {
170949
+ const d2 = api.onDidVisibilityChange((e2) => setPanelVisible(e2.isVisible));
170950
+ return () => d2.dispose();
170951
+ }, [api]);
170952
+ const visible = panelVisible && params.outerVisible;
170953
+ const sendCdpRef = reactExports.useRef(null);
170954
+ const [currentUrl, setCurrentUrl] = reactExports.useState(params.url);
170955
+ const [loading, setLoading] = reactExports.useState(false);
170956
+ reactExports.useEffect(() => {
170957
+ setCurrentUrl(params.url);
170958
+ }, [params.url]);
170959
+ const navigate = reactExports.useCallback((rawUrl) => {
170960
+ const trimmed = rawUrl.trim();
170961
+ if (!trimmed) return;
170962
+ const url = /^[a-z][a-z0-9+.-]*:/i.test(trimmed) ? trimmed : `https://${trimmed}`;
170963
+ sendCdpRef.current?.("Page.navigate", { url });
170964
+ }, []);
170965
+ const reload = reactExports.useCallback(() => {
170966
+ sendCdpRef.current?.("Page.reload");
170967
+ }, []);
170968
+ const stopLoading = reactExports.useCallback(() => {
170969
+ sendCdpRef.current?.("Page.stopLoading");
170970
+ }, []);
170971
+ const goBack = reactExports.useCallback(() => {
170972
+ sendCdpRef.current?.("Runtime.evaluate", { expression: "history.back()" });
170973
+ }, []);
170974
+ const goForward = reactExports.useCallback(() => {
170975
+ sendCdpRef.current?.("Runtime.evaluate", { expression: "history.forward()" });
170976
+ }, []);
170977
+ const handlePageMetaChange = reactExports.useCallback(
170978
+ (meta2) => {
170979
+ if (typeof meta2.title === "string") {
170980
+ const next2 = meta2.title.trim() || params.url || "(no title)";
170981
+ if ((api.title ?? "") !== next2) {
170982
+ api.setTitle(next2);
170983
+ }
170984
+ }
170985
+ if (meta2.favicon !== void 0) {
170986
+ setFaviconForBandTab(params.bandTabId, meta2.favicon);
170987
+ }
170988
+ },
170989
+ [api, params.url, params.bandTabId]
170990
+ );
170991
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [
170992
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
170993
+ AddressBar,
170994
+ {
170995
+ url: currentUrl,
170996
+ loading,
170997
+ onNavigate: navigate,
170998
+ onBack: goBack,
170999
+ onForward: goForward,
171000
+ onReload: reload,
171001
+ onStop: stopLoading
171002
+ }
171003
+ ),
171004
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative flex-1 overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
171005
+ StreamView,
171006
+ {
171007
+ bandTabId: params.bandTabId,
171008
+ visible,
171009
+ sendCdpRef,
171010
+ onUrlChange: setCurrentUrl,
171011
+ onLoadingChange: setLoading,
171012
+ onPageMetaChange: handlePageMetaChange
171013
+ }
171014
+ ) })
171015
+ ] });
171016
+ }
171017
+ const panelComponents = {
171018
+ stream: StreamPanel
171019
+ };
171020
+ function AddressBar({
171021
+ url,
171022
+ loading,
171023
+ onNavigate,
171024
+ onBack,
171025
+ onForward,
171026
+ onReload,
171027
+ onStop
171028
+ }) {
171029
+ const [inputUrl, setInputUrl] = reactExports.useState(url);
171030
+ const inputRef = reactExports.useRef(null);
171031
+ reactExports.useEffect(() => {
171032
+ if (document.activeElement !== inputRef.current) {
171033
+ setInputUrl(url);
171034
+ }
171035
+ }, [url]);
171036
+ const onKeyDown = reactExports.useCallback(
171037
+ (e2) => {
171038
+ if (e2.key === "Enter") {
171039
+ e2.preventDefault();
171040
+ onNavigate(inputUrl);
171041
+ }
171042
+ },
171043
+ [inputUrl, onNavigate]
171044
+ );
171045
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex h-10 shrink-0 items-center gap-1 border-b border-border bg-background px-2", children: [
171046
+ /* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: `@keyframes screencast-bar-slide {
171047
+ 0% { transform: translateX(-100%); }
171048
+ 50% { transform: translateX(200%); }
171049
+ 100% { transform: translateX(-100%); }
171050
+ }` }),
171051
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
171052
+ "button",
171053
+ {
171054
+ type: "button",
171055
+ onClick: onBack,
171056
+ title: "Back",
171057
+ "aria-label": "Back",
171058
+ className: "flex items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
171059
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "size-4" })
171060
+ }
171061
+ ),
171062
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
171063
+ "button",
171064
+ {
171065
+ type: "button",
171066
+ onClick: onForward,
171067
+ title: "Forward",
171068
+ "aria-label": "Forward",
171069
+ className: "flex items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
171070
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { className: "size-4" })
171071
+ }
171072
+ ),
171073
+ loading ? /* @__PURE__ */ jsxRuntimeExports.jsx(
171074
+ "button",
171075
+ {
171076
+ type: "button",
171077
+ onClick: onStop,
171078
+ title: "Stop",
171079
+ "aria-label": "Stop",
171080
+ className: "flex items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
171081
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { className: "size-4" })
171082
+ }
171083
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
171084
+ "button",
171085
+ {
171086
+ type: "button",
171087
+ onClick: onReload,
171088
+ title: "Reload",
171089
+ "aria-label": "Reload",
171090
+ className: "flex items-center justify-center rounded p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
171091
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-4" })
171092
+ }
171093
+ ),
171094
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
171095
+ "input",
171096
+ {
171097
+ ref: inputRef,
171098
+ type: "text",
171099
+ value: inputUrl,
171100
+ onChange: (e2) => setInputUrl(e2.target.value),
171101
+ onKeyDown,
171102
+ onFocus: (e2) => e2.target.select(),
171103
+ placeholder: "Enter URL or search…",
171104
+ className: "min-w-0 flex-1 rounded border border-transparent bg-muted/50 px-3 py-1.5 text-sm text-foreground outline-none transition-colors focus:border-border"
171105
+ }
171106
+ ),
171107
+ loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-x-0 bottom-0 h-0.5 overflow-hidden bg-blue-500/10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
171108
+ "div",
171109
+ {
171110
+ className: "h-full w-2/5 rounded-full bg-blue-500",
171111
+ style: {
171112
+ animation: "screencast-bar-slide 1.4s ease-in-out infinite"
171113
+ }
171114
+ }
171115
+ ) })
171116
+ ] });
171117
+ }
171118
+ const PAGE_META_EXPRESSION = `(() => {
171119
+ const links = Array.from(document.querySelectorAll('link[rel*="icon" i]'));
171120
+ const explicit = links.find((l) => /^(?:shortcut\\s+)?icon$/i.test(l.rel));
171121
+ let favicon = explicit ? explicit.href : (links[0] ? links[0].href : null);
171122
+ if (!favicon) {
171123
+ try { favicon = new URL('/favicon.ico', location.href).href; } catch { favicon = null; }
171124
+ }
171125
+ return { title: document.title || '', favicon };
171126
+ })()`;
171127
+ function StreamView({
171128
+ bandTabId,
171129
+ visible,
171130
+ sendCdpRef,
171131
+ onUrlChange,
171132
+ onLoadingChange,
171133
+ onPageMetaChange
171134
+ }) {
171135
+ const wsRef = reactExports.useRef(null);
171136
+ const nextIdRef = reactExports.useRef(1);
171137
+ const lastMetaRef = reactExports.useRef(null);
171138
+ const imgRef = reactExports.useRef(null);
171139
+ const pendingResponsesRef = reactExports.useRef(
171140
+ // biome-ignore lint/suspicious/noExplicitAny: heterogeneous CDP responses
171141
+ /* @__PURE__ */ new Map()
171142
+ );
171143
+ const lastMetaFetchTimerRef = reactExports.useRef(null);
171144
+ const frameCountRef = reactExports.useRef(0);
171145
+ const [fps, setFps] = reactExports.useState(0);
171146
+ const [frameSrc, setFrameSrc] = reactExports.useState(null);
171147
+ const [status, setStatus] = reactExports.useState("connecting");
171148
+ const [errorMessage, setErrorMessage] = reactExports.useState(null);
171149
+ const sendCdp = reactExports.useCallback((method, params) => {
171150
+ const ws = wsRef.current;
171151
+ if (!ws || ws.readyState !== WebSocket.OPEN) return;
171152
+ const id28 = nextIdRef.current++;
171153
+ ws.send(JSON.stringify({ id: id28, method, params: params ?? {} }));
171154
+ }, []);
171155
+ const sendCdpExpectResponse = reactExports.useCallback(
171156
+ (method, params, onResponse) => {
171157
+ const ws = wsRef.current;
171158
+ if (!ws || ws.readyState !== WebSocket.OPEN) return;
171159
+ const id28 = nextIdRef.current++;
171160
+ pendingResponsesRef.current.set(id28, onResponse);
171161
+ ws.send(JSON.stringify({ id: id28, method, params }));
171162
+ },
171163
+ []
171164
+ );
171165
+ const fetchPageMeta = reactExports.useCallback(() => {
171166
+ sendCdpExpectResponse(
171167
+ "Runtime.evaluate",
171168
+ { expression: PAGE_META_EXPRESSION, returnByValue: true },
171169
+ (result, error) => {
171170
+ if (error) return;
171171
+ const value = result?.result?.value;
171172
+ if (!value) return;
171173
+ onPageMetaChange({
171174
+ title: typeof value.title === "string" ? value.title : void 0,
171175
+ favicon: value.favicon ?? null
171176
+ });
171177
+ }
171178
+ );
171179
+ }, [sendCdpExpectResponse, onPageMetaChange]);
171180
+ reactExports.useEffect(() => {
171181
+ if (!visible) return;
171182
+ const proto2 = location.protocol === "https:" ? "wss:" : "ws:";
171183
+ const url = `${proto2}//${location.host}/cdp?bandTabId=${encodeURIComponent(bandTabId)}`;
171184
+ const ws = new WebSocket(url);
171185
+ wsRef.current = ws;
171186
+ sendCdpRef.current = sendCdp;
171187
+ setStatus("connecting");
171188
+ setErrorMessage(null);
171189
+ ws.onopen = () => {
171190
+ setStatus("open");
171191
+ sendCdp("Page.enable");
171192
+ sendCdp("Page.bringToFront");
171193
+ sendCdp("Page.startScreencast", {
171194
+ format: "jpeg",
171195
+ quality: 60,
171196
+ everyNthFrame: 1
171197
+ });
171198
+ fetchPageMeta();
171199
+ };
171200
+ ws.onmessage = (event) => {
171201
+ let msg;
171202
+ try {
171203
+ msg = JSON.parse(event.data);
171204
+ } catch {
171205
+ return;
171206
+ }
171207
+ if (typeof msg.id === "number") {
171208
+ const cb = pendingResponsesRef.current.get(msg.id);
171209
+ if (cb) {
171210
+ pendingResponsesRef.current.delete(msg.id);
171211
+ cb(msg.result, msg.error);
171212
+ return;
171213
+ }
171214
+ }
171215
+ if (msg.error) {
171216
+ setErrorMessage(msg.error.message ?? "CDP error");
171217
+ return;
171218
+ }
171219
+ if (msg.method === "Page.screencastFrame" && msg.params) {
171220
+ const frame2 = msg.params;
171221
+ lastMetaRef.current = frame2.metadata;
171222
+ setFrameSrc(`data:image/jpeg;base64,${frame2.data}`);
171223
+ frameCountRef.current += 1;
171224
+ sendCdp("Page.screencastFrameAck", { sessionId: frame2.sessionId });
171225
+ return;
171226
+ }
171227
+ if (msg.method === "Page.frameNavigated" && msg.params?.frame) {
171228
+ const frame2 = msg.params.frame;
171229
+ if (!frame2.parentId && typeof frame2.url === "string") {
171230
+ onUrlChange(frame2.url);
171231
+ fetchPageMeta();
171232
+ if (lastMetaFetchTimerRef.current) {
171233
+ clearTimeout(lastMetaFetchTimerRef.current);
171234
+ }
171235
+ lastMetaFetchTimerRef.current = setTimeout(() => {
171236
+ lastMetaFetchTimerRef.current = null;
171237
+ fetchPageMeta();
171238
+ }, 1500);
171239
+ }
171240
+ return;
171241
+ }
171242
+ if (msg.method === "Page.frameStartedLoading") {
171243
+ onLoadingChange(true);
171244
+ return;
171245
+ }
171246
+ if (msg.method === "Page.frameStoppedLoading") {
171247
+ onLoadingChange(false);
171248
+ fetchPageMeta();
171249
+ return;
171250
+ }
171251
+ };
171252
+ ws.onerror = () => {
171253
+ setStatus("error");
171254
+ };
171255
+ ws.onclose = (ev) => {
171256
+ setStatus("closed");
171257
+ if (ev.code !== 1e3) {
171258
+ setErrorMessage(ev.reason || `Connection closed (code ${ev.code})`);
171259
+ }
171260
+ };
171261
+ return () => {
171262
+ try {
171263
+ if (ws.readyState === WebSocket.OPEN) {
171264
+ ws.send(JSON.stringify({ id: nextIdRef.current++, method: "Page.stopScreencast" }));
171265
+ }
171266
+ ws.close();
171267
+ } catch {
171268
+ }
171269
+ wsRef.current = null;
171270
+ if (sendCdpRef.current === sendCdp) {
171271
+ sendCdpRef.current = null;
171272
+ }
171273
+ if (lastMetaFetchTimerRef.current) {
171274
+ clearTimeout(lastMetaFetchTimerRef.current);
171275
+ lastMetaFetchTimerRef.current = null;
171276
+ }
171277
+ pendingResponsesRef.current.clear();
171278
+ };
171279
+ }, [bandTabId, visible, sendCdp, sendCdpRef, onUrlChange, onLoadingChange, fetchPageMeta]);
171280
+ reactExports.useEffect(() => {
171281
+ if (!visible) return;
171282
+ const id28 = setInterval(() => {
171283
+ setFps(frameCountRef.current);
171284
+ frameCountRef.current = 0;
171285
+ }, 1e3);
171286
+ return () => clearInterval(id28);
171287
+ }, [visible]);
171288
+ const dispatchMouse = reactExports.useCallback(
171289
+ (type2, e2, extra) => {
171290
+ const img = imgRef.current;
171291
+ const meta2 = lastMetaRef.current;
171292
+ if (!img || !meta2) return;
171293
+ const rect2 = img.getBoundingClientRect();
171294
+ const scaleX = meta2.deviceWidth / rect2.width;
171295
+ const scaleY = meta2.deviceHeight / rect2.height;
171296
+ const x2 = (e2.clientX - rect2.left) * scaleX;
171297
+ const y3 = (e2.clientY - rect2.top) * scaleY - (meta2.offsetTop ?? 0);
171298
+ const buttonMap = {
171299
+ 0: "left",
171300
+ 1: "middle",
171301
+ 2: "right"
171302
+ };
171303
+ const mouseEvent = e2;
171304
+ const button = type2 === "mouseWheel" ? "none" : buttonMap[mouseEvent.button] ?? "left";
171305
+ const params = {
171306
+ type: type2,
171307
+ x: x2,
171308
+ y: y3,
171309
+ button,
171310
+ clickCount: type2 === "mousePressed" || type2 === "mouseReleased" ? 1 : 0,
171311
+ modifiers: 0
171312
+ };
171313
+ if (type2 === "mouseWheel") {
171314
+ params.deltaX = (extra?.deltaX ?? 0) * scaleX;
171315
+ params.deltaY = (extra?.deltaY ?? 0) * scaleY;
171316
+ }
171317
+ sendCdp("Input.dispatchMouseEvent", params);
171318
+ },
171319
+ [sendCdp]
171320
+ );
171321
+ const onMouseDown = (e2) => {
171322
+ e2.preventDefault();
171323
+ dispatchMouse("mousePressed", e2);
171324
+ };
171325
+ const onMouseUp = (e2) => {
171326
+ e2.preventDefault();
171327
+ dispatchMouse("mouseReleased", e2);
171328
+ };
171329
+ const onMouseMove = (e2) => {
171330
+ dispatchMouse("mouseMoved", e2);
171331
+ };
171332
+ const onWheel = (e2) => {
171333
+ e2.preventDefault();
171334
+ dispatchMouse("mouseWheel", e2, { deltaX: -e2.deltaX, deltaY: -e2.deltaY });
171335
+ };
171336
+ const onContextMenu = (e2) => {
171337
+ e2.preventDefault();
171338
+ };
171339
+ const statusLabel = reactExports.useMemo(() => {
171340
+ if (status === "connecting") return "Connecting…";
171341
+ if (status === "open") return `${fps} fps`;
171342
+ if (status === "closed") return errorMessage ?? "Disconnected";
171343
+ return errorMessage ?? "Connection error";
171344
+ }, [status, errorMessage, fps]);
171345
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
171346
+ frameSrc ? /* @__PURE__ */ jsxRuntimeExports.jsx(
171347
+ "img",
171348
+ {
171349
+ ref: imgRef,
171350
+ src: frameSrc,
171351
+ alt: "Live tab",
171352
+ className: "h-full w-full select-none object-contain",
171353
+ draggable: false,
171354
+ onMouseDown,
171355
+ onMouseUp,
171356
+ onMouseMove,
171357
+ onWheel,
171358
+ onContextMenu
171359
+ }
171360
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full w-full items-center justify-center text-sm text-muted-foreground", children: status === "error" || errorMessage ? errorMessage ?? "Connection error" : "Waiting for first frame…" }),
171361
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pointer-events-none absolute right-2 top-2 rounded-full bg-background/80 px-2 py-0.5 text-[10px] font-medium text-muted-foreground shadow-sm backdrop-blur", children: statusLabel })
171362
+ ] });
171363
+ }
171364
+ function EmptyPanel() {
171365
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-md rounded-md border border-dashed border-border p-6 text-sm text-muted-foreground", children: [
171366
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-2 font-medium text-foreground", children: "No Band tabs in this workspace." }),
171367
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Create a browser tab from the desktop app and it will show up here." })
171368
+ ] });
171369
+ }
171370
+ function ErrorPanel({ error }) {
171371
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-md rounded-md border border-border bg-muted/30 p-6 text-sm", children: [
171372
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-2 font-medium text-foreground", children: "Open the Band desktop app to use the Browser pane" }),
171373
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-3 text-muted-foreground", children: "Tabs are owned by the Band desktop app — when it's running on the same machine as this server, your tabs show up here so you can drive them remotely from the web." }),
171374
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: error })
171375
+ ] });
171376
+ }
169064
171377
  const HEALTH_POLL_INTERVAL = 3e4;
169065
171378
  function useTunnel() {
169066
171379
  const adapter2 = useAdapter();
@@ -171455,7 +173768,7 @@ const PANEL_SHORTCUTS = {
171455
173768
  browser: "⇧⌘B"
171456
173769
  };
171457
173770
  const DockviewTerminalContainer = reactExports.lazy(
171458
- () => import("./DockviewTerminalContainer-TTt325-b.js").then((m2) => ({
173771
+ () => import("./DockviewTerminalContainer-BClknz0C.js").then((m2) => ({
171459
173772
  default: m2.DockviewTerminalContainer
171460
173773
  }))
171461
173774
  );
@@ -171502,9 +173815,7 @@ function FilesPanelComponent({ params }) {
171502
173815
  onSelectFile: params.onSelectFile,
171503
173816
  openFilePath: params.openFilePath,
171504
173817
  onFileOpened: params.onFileOpened,
171505
- onFindInFile: params.onFindInFile,
171506
- onQuickOpen: params.onQuickOpen,
171507
- onSearchFiles: params.onSearchFiles
173818
+ onFindInFile: params.onFindInFile
171508
173819
  }
171509
173820
  );
171510
173821
  }
@@ -171598,12 +173909,26 @@ function BadgeTab(props) {
171598
173909
  function BrowserPanelComponent({ params, api }) {
171599
173910
  const [isVisible, setIsVisible] = reactExports.useState(api.isVisible);
171600
173911
  const wsActive = useWsActive(params.workspaceId ?? "");
173912
+ const { settings } = useSettingsQuery();
173913
+ const cdpEnabled = settings.webBrowserCdpEnabled ?? false;
171601
173914
  reactExports.useEffect(() => {
171602
173915
  const d2 = api.onDidVisibilityChange((e2) => setIsVisible(e2.isVisible));
171603
173916
  return () => d2.dispose();
171604
173917
  }, [api]);
171605
173918
  const visible = wsActive && isVisible;
171606
173919
  if (!params.workspaceId) return /* @__PURE__ */ jsxRuntimeExports.jsx(NoWorkspaceMessage, { Icon: Globe });
173920
+ if (!isDesktop) {
173921
+ if (cdpEnabled) {
173922
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(ScreencastPanel, { workspaceId: params.workspaceId, visible });
173923
+ }
173924
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center p-6 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-md text-center", children: [
173925
+ "The Browser pane is only available in the desktop app. Enable",
173926
+ " ",
173927
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: "Settings → Browser → Stream desktop tabs to web" }),
173928
+ " ",
173929
+ "to use it from a browser tab."
173930
+ ] }) });
173931
+ }
171607
173932
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
171608
173933
  DockviewBrowserContainer,
171609
173934
  {
@@ -171678,6 +174003,7 @@ function useDiffFileCount(workspaceId, isActive) {
171678
174003
  return count2;
171679
174004
  }
171680
174005
  const REQUIRED_PANEL_IDS = ["projects", "chat", "changes", "files", "terminal", "browser"];
174006
+ const REMOVED_PANEL_IDS = ["screencast"];
171681
174007
  const GLOBAL_LAYOUT_KEY = "band:dockview-layout-v6";
171682
174008
  const ACTIVE_STATE_KEY_PREFIX = "band:dockview-active:";
171683
174009
  const EDGE_GROUP_IDS = {
@@ -171779,11 +174105,31 @@ function saveLayout(api, workspaceId, lastStructureRef) {
171779
174105
  return false;
171780
174106
  }
171781
174107
  }
174108
+ function stripRemovedPanels(layout) {
174109
+ const panels = layout.panels;
174110
+ if (panels) {
174111
+ for (const id28 of REMOVED_PANEL_IDS) {
174112
+ delete panels[id28];
174113
+ }
174114
+ }
174115
+ const grid = layout.grid;
174116
+ if (grid?.root) {
174117
+ walkGridNode(grid.root, (leaf) => {
174118
+ const data = leaf.data;
174119
+ if (!data || !Array.isArray(data.views)) return;
174120
+ data.views = data.views.filter((v2) => !REMOVED_PANEL_IDS.includes(v2));
174121
+ if (data.activeView && REMOVED_PANEL_IDS.includes(data.activeView)) {
174122
+ data.activeView = data.views[0];
174123
+ }
174124
+ });
174125
+ }
174126
+ }
171782
174127
  function loadLayout(workspaceId) {
171783
174128
  try {
171784
174129
  const raw2 = localStorage.getItem(GLOBAL_LAYOUT_KEY);
171785
174130
  if (!raw2) return null;
171786
174131
  const layout = JSON.parse(raw2);
174132
+ stripRemovedPanels(layout);
171787
174133
  const activeRaw = localStorage.getItem(`${ACTIVE_STATE_KEY_PREFIX}${workspaceId}`);
171788
174134
  if (activeRaw) {
171789
174135
  const activeState = JSON.parse(activeRaw);
@@ -172008,6 +174354,17 @@ const DockviewWorkspaceLayout = reactExports.memo(function DockviewWorkspaceLayo
172008
174354
  window.addEventListener("band:open-file", handler);
172009
174355
  return () => window.removeEventListener("band:open-file", handler);
172010
174356
  }, [isActive]);
174357
+ reactExports.useEffect(() => {
174358
+ if (!isActive) return;
174359
+ const openQO = () => setQuickOpenOpen(true);
174360
+ const openSF = () => setSearchFilesOpen(true);
174361
+ window.addEventListener("band:open-quick-open", openQO);
174362
+ window.addEventListener("band:open-search-files", openSF);
174363
+ return () => {
174364
+ window.removeEventListener("band:open-quick-open", openQO);
174365
+ window.removeEventListener("band:open-search-files", openSF);
174366
+ };
174367
+ }, [isActive]);
172011
174368
  reactExports.useEffect(() => {
172012
174369
  if (!isActive) return;
172013
174370
  const handler = (e2) => {
@@ -172037,9 +174394,7 @@ const DockviewWorkspaceLayout = reactExports.memo(function DockviewWorkspaceLayo
172037
174394
  openFilePath,
172038
174395
  onSelectFile: handleSelectFile,
172039
174396
  onFileOpened: handleFileOpened,
172040
- onFindInFile: setFindInFile,
172041
- onQuickOpen: () => setQuickOpenOpen(true),
172042
- onSearchFiles: () => setSearchFilesOpen(true)
174397
+ onFindInFile: setFindInFile
172043
174398
  });
172044
174399
  api.getPanel("terminal")?.api.updateParameters({
172045
174400
  workspaceId
@@ -172784,7 +175139,9 @@ function AppShell() {
172784
175139
  { id: "changes", label: "Changes", icon: GitCompare, shortcut: "⇧⌘G" },
172785
175140
  { id: "files", label: "Files", icon: FolderOpen, shortcut: "⇧⌘E" },
172786
175141
  { id: "terminal", label: "Terminal", icon: Terminal, shortcut: "⌃`" },
172787
- ...isDesktop ? [{ id: "browser", label: "Browser", icon: Globe, shortcut: "⇧⌘B" }] : []
175142
+ // Browser pane works on both desktop (native webviews) and web (CDP
175143
+ // screencast of the desktop app's tabs — see ScreencastPanel).
175144
+ { id: "browser", label: "Browser", icon: Globe, shortcut: "⇧⌘B" }
172788
175145
  ],
172789
175146
  []
172790
175147
  );
@@ -172847,7 +175204,8 @@ function AppShell() {
172847
175204
  ),
172848
175205
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full min-w-0 overflow-hidden relative", children: [
172849
175206
  /* @__PURE__ */ jsxRuntimeExports.jsx(Outlet, {}),
172850
- /* @__PURE__ */ jsxRuntimeExports.jsx(DockviewInstanceManager, {})
175207
+ /* @__PURE__ */ jsxRuntimeExports.jsx(DockviewInstanceManager, {}),
175208
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BrowserHostBridge, {})
172851
175209
  ] }) })
172852
175210
  ] }) });
172853
175211
  }
@@ -172868,11 +175226,11 @@ function RootLayout() {
172868
175226
  ] })
172869
175227
  ] });
172870
175228
  }
172871
- const $$splitComponentImporter$7 = () => import("./index-a-16Ui_6.js");
175229
+ const $$splitComponentImporter$7 = () => import("./index-PcwomXXg.js");
172872
175230
  const Route$7 = createFileRoute("/")({
172873
175231
  component: lazyRouteComponent($$splitComponentImporter$7, "component")
172874
175232
  });
172875
- const $$splitComponentImporter$6 = () => import("./workspace._workspaceId-7fdVKeNu.js");
175233
+ const $$splitComponentImporter$6 = () => import("./workspace._workspaceId-BIUZ7lNJ.js");
172876
175234
  const Route$6 = createFileRoute("/workspace/$workspaceId")({
172877
175235
  component: lazyRouteComponent($$splitComponentImporter$6, "component")
172878
175236
  });
@@ -172891,11 +175249,11 @@ const FindInFileContext = reactExports.createContext({
172891
175249
  function useFindInFileContext() {
172892
175250
  return reactExports.useContext(FindInFileContext);
172893
175251
  }
172894
- const $$splitComponentImporter$5 = () => import("./workspace._workspaceId.index-DGG24yQO.js");
175252
+ const $$splitComponentImporter$5 = () => import("./workspace._workspaceId.index-BaBfW1nO.js");
172895
175253
  const Route$5 = createFileRoute("/workspace/$workspaceId/")({
172896
175254
  component: lazyRouteComponent($$splitComponentImporter$5, "component")
172897
175255
  });
172898
- const $$splitComponentImporter$4 = () => import("./workspace._workspaceId.terminal-BCUV7dQN.js");
175256
+ const $$splitComponentImporter$4 = () => import("./workspace._workspaceId.terminal-CKX5RImf.js");
172899
175257
  const Route$4 = createFileRoute("/workspace/$workspaceId/terminal")({
172900
175258
  component: lazyRouteComponent($$splitComponentImporter$4, "component")
172901
175259
  });
@@ -172903,15 +175261,15 @@ const $$splitComponentImporter$3 = () => import("./workspace._workspaceId.code-C
172903
175261
  const Route$3 = createFileRoute("/workspace/$workspaceId/code")({
172904
175262
  component: lazyRouteComponent($$splitComponentImporter$3, "component")
172905
175263
  });
172906
- const $$splitComponentImporter$2 = () => import("./workspace._workspaceId.changes-OtWo7a6k.js");
175264
+ const $$splitComponentImporter$2 = () => import("./workspace._workspaceId.changes-Cz2Q9MYv.js");
172907
175265
  const Route$2 = createFileRoute("/workspace/$workspaceId/changes")({
172908
175266
  component: lazyRouteComponent($$splitComponentImporter$2, "component")
172909
175267
  });
172910
- const $$splitComponentImporter$1 = () => import("./workspace._workspaceId.code.index-DpGdriuG.js");
175268
+ const $$splitComponentImporter$1 = () => import("./workspace._workspaceId.code.index-DJE-_14B.js");
172911
175269
  const Route$1 = createFileRoute("/workspace/$workspaceId/code/")({
172912
175270
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
172913
175271
  });
172914
- const $$splitComponentImporter = () => import("./workspace._workspaceId.code._-C8dWBJOO.js");
175272
+ const $$splitComponentImporter = () => import("./workspace._workspaceId.code._-mhiuiARp.js");
172915
175273
  const Route2 = createFileRoute("/workspace/$workspaceId/code/$")({
172916
175274
  component: lazyRouteComponent($$splitComponentImporter, "component")
172917
175275
  });
@@ -173079,7 +175437,7 @@ export {
173079
175437
  withPath as ay,
173080
175438
  halfPi as az,
173081
175439
  useSettingsQuery as b,
173082
- ToolbarOverflowMenuItems as b$,
175440
+ ToolbarOverflowProvider as b$,
173083
175441
  commonDb_exports as b0,
173084
175442
  insertCluster as b1,
173085
175443
  insertNode as b2,
@@ -173090,33 +175448,33 @@ export {
173090
175448
  getSubGraphTitleMargins as b7,
173091
175449
  replaceIconSubstring as b8,
173092
175450
  decodeEntities as b9,
173093
- EditorState as bA,
173094
- languageDataProp as bB,
173095
- LanguageDescription as bC,
173096
- ParseContext as bD,
173097
- bracketMatchingHandle as bE,
173098
- flatIndent as bF,
173099
- sublanguageProp as bG,
173100
- baseRest as bH,
173101
- isArrayLikeObject as bI,
173102
- constant as bJ,
173103
- isFunction as bK,
173104
- isEmpty as bL,
173105
- markers_default as bM,
173106
- clear2 as bN,
173107
- clear as bO,
173108
- clear$1 as bP,
173109
- updateNodeBounds as bQ,
173110
- setNodeElem as bR,
173111
- insertEdge as bS,
173112
- positionEdgeLabel as bT,
173113
- insertEdgeLabel as bU,
173114
- computeDimensionOfText as bV,
173115
- Ut$1 as bW,
173116
- Yt$1 as bX,
173117
- DashboardShell as bY,
173118
- Qt$1 as bZ,
173119
- ToolbarOverflowProvider as b_,
175451
+ CompletionContext as bA,
175452
+ EditorState as bB,
175453
+ languageDataProp as bC,
175454
+ LanguageDescription as bD,
175455
+ ParseContext as bE,
175456
+ bracketMatchingHandle as bF,
175457
+ flatIndent as bG,
175458
+ sublanguageProp as bH,
175459
+ baseRest as bI,
175460
+ isArrayLikeObject as bJ,
175461
+ constant as bK,
175462
+ isFunction as bL,
175463
+ isEmpty as bM,
175464
+ markers_default as bN,
175465
+ clear2 as bO,
175466
+ clear as bP,
175467
+ clear$1 as bQ,
175468
+ updateNodeBounds as bR,
175469
+ setNodeElem as bS,
175470
+ insertEdge as bT,
175471
+ positionEdgeLabel as bU,
175472
+ insertEdgeLabel as bV,
175473
+ computeDimensionOfText as bW,
175474
+ Ut$1 as bX,
175475
+ Yt$1 as bY,
175476
+ DashboardShell as bZ,
175477
+ Qt$1 as b_,
173120
175478
  getStylesFromArray as ba,
173121
175479
  openExternalUrl as bb,
173122
175480
  SearchBar as bc,
@@ -173128,84 +175486,85 @@ export {
173128
175486
  DesktopDragRegion as bi,
173129
175487
  ArrowLeft as bj,
173130
175488
  QuickOpenDialog as bk,
173131
- delimitedIndent as bl,
173132
- NodeWeakMap as bm,
173133
- snippetCompletion as bn,
173134
- Tag as bo,
173135
- parseMixed as bp,
173136
- EditorSelection as bq,
173137
- countColumn as br,
173138
- Prec as bs,
173139
- keymap as bt,
173140
- EditorView as bu,
173141
- Language as bv,
173142
- indentUnit as bw,
173143
- foldService as bx,
173144
- defineLanguageFacet as by,
173145
- CompletionContext as bz,
175489
+ SearchFilesDialog as bl,
175490
+ delimitedIndent as bm,
175491
+ NodeWeakMap as bn,
175492
+ snippetCompletion as bo,
175493
+ Tag as bp,
175494
+ parseMixed as bq,
175495
+ EditorSelection as br,
175496
+ countColumn as bs,
175497
+ Prec as bt,
175498
+ keymap as bu,
175499
+ EditorView as bv,
175500
+ Language as bw,
175501
+ indentUnit as bx,
175502
+ foldService as by,
175503
+ defineLanguageFacet as bz,
173146
175504
  agentTypeSupportsSessionListing as c,
173147
- DockviewWorkspaceLayout as c0,
173148
- array$2 as c1,
173149
- getUserDefinedConfig as c2,
173150
- getIconSVG as c3,
173151
- registerIconPacks as c4,
173152
- unknownIcon as c5,
173153
- isObject$1 as c6,
173154
- isIterateeCall as c7,
173155
- keysIn as c8,
173156
- eq as c9,
173157
- isObjectLike as cA,
173158
- baseGetTag as cB,
173159
- Symbol$1 as cC,
173160
- arrayLikeKeys as cD,
173161
- baseKeys as cE,
173162
- memoize as cF,
173163
- isArguments as cG,
173164
- copyObject as cH,
173165
- getPrototype as cI,
173166
- cloneArrayBuffer as cJ,
173167
- cloneTypedArray as cK,
173168
- getTag as cL,
173169
- nodeUtil as cM,
173170
- copyArray as cN,
173171
- isBuffer as cO,
173172
- cloneBuffer as cP,
173173
- initCloneObject as cQ,
173174
- Stack as cR,
173175
- MapCache as cS,
173176
- Uint8Array$1 as cT,
173177
- isTypedArray as cU,
173178
- isLength as cV,
173179
- Set$1 as cW,
173180
- createAssigner as cX,
173181
- isPrototype as cY,
173182
- router as cZ,
173183
- isArrayLike as ca,
173184
- isArray as cb,
173185
- identity as cc,
173186
- isIndex as cd,
173187
- assignValue as ce,
173188
- constant$2 as cf,
173189
- interpolateNumber as cg,
173190
- color as ch,
173191
- interpolateRgb as ci,
173192
- interpolateString as cj,
173193
- styles2String as ck,
173194
- isLabelStyle as cl,
173195
- Rgb as cm,
173196
- rgbConvert as cn,
173197
- define as co,
173198
- extend$4 as cp,
173199
- Color as cq,
173200
- nogamma as cr,
173201
- hue as cs,
173202
- dayjs2 as ct,
173203
- setToString as cu,
173204
- overRest as cv,
173205
- baseFor as cw,
173206
- baseAssignValue as cx,
173207
- baseUnary as cy,
173208
- merge$1 as cz,
175505
+ ToolbarOverflowMenuItems as c0,
175506
+ DockviewWorkspaceLayout as c1,
175507
+ array$2 as c2,
175508
+ getUserDefinedConfig as c3,
175509
+ getIconSVG as c4,
175510
+ registerIconPacks as c5,
175511
+ unknownIcon as c6,
175512
+ isObject$1 as c7,
175513
+ isIterateeCall as c8,
175514
+ keysIn as c9,
175515
+ merge$1 as cA,
175516
+ isObjectLike as cB,
175517
+ baseGetTag as cC,
175518
+ Symbol$1 as cD,
175519
+ arrayLikeKeys as cE,
175520
+ baseKeys as cF,
175521
+ memoize as cG,
175522
+ isArguments as cH,
175523
+ copyObject as cI,
175524
+ getPrototype as cJ,
175525
+ cloneArrayBuffer as cK,
175526
+ cloneTypedArray as cL,
175527
+ getTag as cM,
175528
+ nodeUtil as cN,
175529
+ copyArray as cO,
175530
+ isBuffer as cP,
175531
+ cloneBuffer as cQ,
175532
+ initCloneObject as cR,
175533
+ Stack as cS,
175534
+ MapCache as cT,
175535
+ Uint8Array$1 as cU,
175536
+ isTypedArray as cV,
175537
+ isLength as cW,
175538
+ Set$1 as cX,
175539
+ createAssigner as cY,
175540
+ isPrototype as cZ,
175541
+ router as c_,
175542
+ eq as ca,
175543
+ isArrayLike as cb,
175544
+ isArray as cc,
175545
+ identity as cd,
175546
+ isIndex as ce,
175547
+ assignValue as cf,
175548
+ constant$2 as cg,
175549
+ interpolateNumber as ch,
175550
+ color as ci,
175551
+ interpolateRgb as cj,
175552
+ interpolateString as ck,
175553
+ styles2String as cl,
175554
+ isLabelStyle as cm,
175555
+ Rgb as cn,
175556
+ rgbConvert as co,
175557
+ define as cp,
175558
+ extend$4 as cq,
175559
+ Color as cr,
175560
+ nogamma as cs,
175561
+ hue as ct,
175562
+ dayjs2 as cu,
175563
+ setToString as cv,
175564
+ overRest as cw,
175565
+ baseFor as cx,
175566
+ baseAssignValue as cy,
175567
+ baseUnary as cz,
173209
175568
  Route$4 as d,
173210
175569
  Route$2 as e,
173211
175570
  useNavigate as f,