@band-app/server 0.12.0 → 0.13.1

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 (171) hide show
  1. package/dist/client/assets/{DockviewTerminalContainer-B6ls12RP.js → DockviewTerminalContainer-DY9YDc8o.js} +2 -2
  2. package/dist/client/assets/TerminalPanel-TQGgFc5g.js +4 -0
  3. package/dist/client/assets/{_basePickBy-D4ggI4i0.js → _basePickBy-CvS-VtsR.js} +1 -1
  4. package/dist/client/assets/{_baseUniq-E0-L58sh.js → _baseUniq-DFCKF5vj.js} +1 -1
  5. package/dist/client/assets/{arc-Cd0JgGvM.js → arc-BatjPjaN.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-VXUJARFQ-BngJQDkI.js → architectureDiagram-VXUJARFQ-Cnb8SKvZ.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-VD42YOAC-dcYRXfph.js → blockDiagram-VD42YOAC-B6-qvfYN.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-YG6GDRKO-B_8XfvfL.js → c4Diagram-YG6GDRKO-DAjB1VyY.js} +1 -1
  9. package/dist/client/assets/channel-DSgmIANq.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-CFd2iELe.js → chunk-4BX2VUAB-vjmc3quM.js} +1 -1
  11. package/dist/client/assets/{chunk-55IACEB6-ZI-o1tfy.js → chunk-55IACEB6-DDZjRfYY.js} +1 -1
  12. package/dist/client/assets/{chunk-B4BG7PRW-GcKh0u0t.js → chunk-B4BG7PRW-CKceWukV.js} +1 -1
  13. package/dist/client/assets/{chunk-DI55MBZ5-asFoohq8.js → chunk-DI55MBZ5-CRnRm2L0.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-GmvgLSQe.js → chunk-FMBD7UC4-Cogf-yAQ.js} +1 -1
  15. package/dist/client/assets/{chunk-QN33PNHL-CbSPviK8.js → chunk-QN33PNHL-D72Zq7QV.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-C5_8IhWQ.js → chunk-QZHKN3VN-HUKu5hjd.js} +1 -1
  17. package/dist/client/assets/{chunk-TZMSLE5B-CvwKA6rf.js → chunk-TZMSLE5B-I8YlhesW.js} +1 -1
  18. package/dist/client/assets/classDiagram-2ON5EDUG-D57JPCVZ.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-WZHVMYZB-D57JPCVZ.js +1 -0
  20. package/dist/client/assets/clone-DAQJfloD.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-CFOKjm00.js → cose-bilkent-S5V4N54A-CEay61-1.js} +1 -1
  22. package/dist/client/assets/{dagre-6UL2VRFP-XkiKAfAP.js → dagre-6UL2VRFP-BcAohjbk.js} +2 -2
  23. package/dist/client/assets/{diagram-PSM6KHXK-D7OJGDF1.js → diagram-PSM6KHXK-DdrIOdqS.js} +1 -1
  24. package/dist/client/assets/{diagram-QEK2KX5R-CNDqB5ur.js → diagram-QEK2KX5R-Bn79GyS6.js} +1 -1
  25. package/dist/client/assets/{diagram-S2PKOQOG-DHWhfYWy.js → diagram-S2PKOQOG-g66OM_Vs.js} +1 -1
  26. package/dist/client/assets/{erDiagram-Q2GNP2WA-DlhzEgw7.js → erDiagram-Q2GNP2WA-BD0geyEq.js} +1 -1
  27. package/dist/client/assets/{flowDiagram-NV44I4VS-BabYr6zd.js → flowDiagram-NV44I4VS-B2LLnQ89.js} +1 -1
  28. package/dist/client/assets/{ganttDiagram-JELNMOA3-CUHxh1TA.js → ganttDiagram-JELNMOA3-DsMjiqCd.js} +1 -1
  29. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-DSDd-EJ_.js → gitGraphDiagram-V2S2FVAM-BXAPNFr2.js} +1 -1
  30. package/dist/client/assets/{graph-DXNVnA6H.js → graph-CWoXix-C.js} +1 -1
  31. package/dist/client/assets/{highlighted-body-B3W2YXNL-B79dTSwx.js → highlighted-body-B3W2YXNL-DAdM8cs5.js} +1 -1
  32. package/dist/client/assets/{index-4srNURyv.js → index-6eC517Nz.js} +1 -1
  33. package/dist/client/assets/{index-D-7FXjIA.js → index-B-RxFKXA.js} +1 -1
  34. package/dist/client/assets/{index-EdY6fqdn.js → index-B9fPtAFu.js} +2 -2
  35. package/dist/client/assets/{index-Cu2rqq8f.js → index-BSQYe-ie.js} +1 -1
  36. package/dist/client/assets/{index-_J9aGl-d.js → index-B_aLrZ9l.js} +1 -1
  37. package/dist/client/assets/{index-CPo0kKmX.js → index-BcC597Ty.js} +1 -1
  38. package/dist/client/assets/{index-DktZbpGM.js → index-Bu7btU1P.js} +1 -1
  39. package/dist/client/assets/{index-Bvony7H7.js → index-C8jQlbkH.js} +1 -1
  40. package/dist/client/assets/{index-DRS8jN52.js → index-D-NVfOaX.js} +1 -1
  41. package/dist/client/assets/{index-CjixM2mV.js → index-D4Gbu0g1.js} +1 -1
  42. package/dist/client/assets/{index-okqFBuO9.js → index-DeUgVu9X.js} +1 -1
  43. package/dist/client/assets/{index-BVLYlk0y.js → index-DgRC8NQ1.js} +1 -1
  44. package/dist/client/assets/{index-5jOljAlc.js → index-Dkltc6JL.js} +1 -1
  45. package/dist/client/assets/{index-BNkxX-BD.js → index-GgiGfqqJ.js} +1 -1
  46. package/dist/client/assets/{index-DutxFSic.js → index-HueLRLHI.js} +1 -1
  47. package/dist/client/assets/{index-BqDdB0tU.js → index-U42qt8_H.js} +1 -1
  48. package/dist/client/assets/{index-BQU-JREs.js → index-W_gE5gc5.js} +1 -1
  49. package/dist/client/assets/{index-CTR_yHqa.js → index-iloqZ__Z.js} +1 -1
  50. package/dist/client/assets/{infoDiagram-HS3SLOUP-tDVIKvh1.js → infoDiagram-HS3SLOUP-DwKN27-C.js} +1 -1
  51. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-cFY68TOP.js → journeyDiagram-XKPGCS4Q-BAhwB5gg.js} +1 -1
  52. package/dist/client/assets/{kanban-definition-3W4ZIXB7-CTQ8WBzj.js → kanban-definition-3W4ZIXB7-OI1AHf6B.js} +1 -1
  53. package/dist/client/assets/{layout-BDsby01A.js → layout-CC7J3tBc.js} +1 -1
  54. package/dist/client/assets/{linear-B321DwjU.js → linear-CVYb-eZl.js} +1 -1
  55. package/dist/client/assets/main-4FaYQ5DQ.css +1 -0
  56. package/dist/client/assets/{main-gKX_m5Ko.js → main-CYVBBY3m.js} +217 -210
  57. package/dist/client/assets/{mindmap-definition-VGOIOE7T-CMbXBgve.js → mindmap-definition-VGOIOE7T-BPKIWA4L.js} +1 -1
  58. package/dist/client/assets/{pieDiagram-ADFJNKIX-pTHsfneI.js → pieDiagram-ADFJNKIX-DeHQukcp.js} +1 -1
  59. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-DNGhzaPi.js → quadrantDiagram-AYHSOK5B-DIA0izdW.js} +1 -1
  60. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-E5dChVU-.js → requirementDiagram-UZGBJVZJ-DsiZI-w_.js} +1 -1
  61. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-B858cwBV.js → sankeyDiagram-TZEHDZUN-B3Rxgvvo.js} +1 -1
  62. package/dist/client/assets/{sequenceDiagram-WL72ISMW-Clbop1Lh.js → sequenceDiagram-WL72ISMW-CdnagSZH.js} +1 -1
  63. package/dist/client/assets/{square-terminal-zBRLwN9m.js → square-terminal-BA_DN1Fj.js} +1 -1
  64. package/dist/client/assets/{stateDiagram-FKZM4ZOC-BRIoi38Z.js → stateDiagram-FKZM4ZOC-C9HYyYWO.js} +1 -1
  65. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-Jpp4ZnR3.js +1 -0
  66. package/dist/client/assets/{timeline-definition-IT6M3QCI-C26dPldo.js → timeline-definition-IT6M3QCI-BQXhdJ4l.js} +1 -1
  67. package/dist/client/assets/{treemap-GDKQZRPO-l9jcKCpW.js → treemap-GDKQZRPO-DbtL6I-E.js} +1 -1
  68. package/dist/client/assets/{useSessionListContext-MLsp0tQx.js → useSessionListContext-BDhxj2sp.js} +1 -1
  69. package/dist/client/assets/workspace._workspaceId-DrdBQ3ad.js +1 -0
  70. package/dist/client/assets/{workspace._workspaceId.changes-sSj8FhGC.js → workspace._workspaceId.changes-CV01j_RF.js} +1 -1
  71. package/dist/client/assets/workspace._workspaceId.code-Di11hnHW.js +1 -0
  72. package/dist/client/assets/{workspace._workspaceId.code._-BVzwjj6w.js → workspace._workspaceId.code._-4eyD4Vu7.js} +1 -1
  73. package/dist/client/assets/{workspace._workspaceId.code.index-V90FWX2z.js → workspace._workspaceId.code.index-BazGXzJC.js} +1 -1
  74. package/dist/client/assets/{workspace._workspaceId.index-Cczg6N56.js → workspace._workspaceId.index-CpmZsM_r.js} +1 -1
  75. package/dist/client/assets/{workspace._workspaceId.terminal-CFJVgZLo.js → workspace._workspaceId.terminal-Sx7Ov6J4.js} +2 -2
  76. package/dist/client/assets/{xychartDiagram-PRI3JC2R-Cwsp2BWQ.js → xychartDiagram-PRI3JC2R-B9LSl0HQ.js} +1 -1
  77. package/dist/server/assets/{DockviewTerminalContainer-B5lZSZ8Y.js → DockviewTerminalContainer-DVzWSMti.js} +3 -3
  78. package/dist/server/assets/TerminalPanel-BlWVFHNT.js +1016 -0
  79. package/dist/server/assets/{_basePickBy-CD1u5dYZ.js → _basePickBy-CTVBF0Kh.js} +2 -2
  80. package/dist/server/assets/{_baseUniq-BdmRs4hY.js → _baseUniq-BF3qFyKL.js} +1 -1
  81. package/dist/server/assets/{_tanstack-start-manifest_v-D4xipytj.js → _tanstack-start-manifest_v-sqmMCsD8.js} +1 -1
  82. package/dist/server/assets/{arc-CbjxAGh2.js → arc-CKzdlSDJ.js} +1 -1
  83. package/dist/server/assets/{architecture-7HQA4BMR-PvoHywyl.js → architecture-7HQA4BMR-C4KC3q3z.js} +6 -6
  84. package/dist/server/assets/{architectureDiagram-VXUJARFQ-CYVR-HeO.js → architectureDiagram-VXUJARFQ-ARkeTUdc.js} +6 -6
  85. package/dist/server/assets/{blockDiagram-VD42YOAC-oFwYjSKc.js → blockDiagram-VD42YOAC-lsOOO08K.js} +6 -6
  86. package/dist/server/assets/{c4Diagram-YG6GDRKO-BRcTuK4Y.js → c4Diagram-YG6GDRKO-CrZA0PWP.js} +2 -2
  87. package/dist/server/assets/{channel-DkpUIvTk.js → channel-Dd6dv_cn.js} +1 -1
  88. package/dist/server/assets/{chunk-4BX2VUAB-Db1P5ZKT.js → chunk-4BX2VUAB-CfcFinva.js} +1 -1
  89. package/dist/server/assets/{chunk-55IACEB6-CgF3c_s9.js → chunk-55IACEB6-C_zn3X68.js} +1 -1
  90. package/dist/server/assets/{chunk-B4BG7PRW-C4lPp_gR.js → chunk-B4BG7PRW-WqOdzIwb.js} +4 -4
  91. package/dist/server/assets/{chunk-DI55MBZ5-DBc5FE0O.js → chunk-DI55MBZ5-BazpEGnL.js} +3 -3
  92. package/dist/server/assets/{chunk-FMBD7UC4-BmyVhHTD.js → chunk-FMBD7UC4-abFXQK9X.js} +1 -1
  93. package/dist/server/assets/{chunk-QN33PNHL-MEMc-HV1.js → chunk-QN33PNHL-mQORkMwR.js} +1 -1
  94. package/dist/server/assets/{chunk-QZHKN3VN-D0s55-ob.js → chunk-QZHKN3VN-W_mObo75.js} +1 -1
  95. package/dist/server/assets/{chunk-TZMSLE5B-CHLAtcyP.js → chunk-TZMSLE5B-f9JxfLrS.js} +1 -1
  96. package/dist/server/assets/{classDiagram-v2-WZHVMYZB-D_KqC8CP.js → classDiagram-2ON5EDUG-D9B26ZaP.js} +5 -5
  97. package/dist/server/assets/{classDiagram-2ON5EDUG-D_KqC8CP.js → classDiagram-v2-WZHVMYZB-D9B26ZaP.js} +5 -5
  98. package/dist/server/assets/{clone-pAcegSV_.js → clone-dm3Dgnj4.js} +1 -1
  99. package/dist/server/assets/{cose-bilkent-S5V4N54A-I5bimXZO.js → cose-bilkent-S5V4N54A-FP17KwdC.js} +1 -1
  100. package/dist/server/assets/{dagre-6UL2VRFP-BFEXHp44.js → dagre-6UL2VRFP-D3G7rpV5.js} +6 -6
  101. package/dist/server/assets/{diagram-PSM6KHXK-B4UG8ra3.js → diagram-PSM6KHXK-CblBgzmP.js} +7 -7
  102. package/dist/server/assets/{diagram-QEK2KX5R-B65vkBbU.js → diagram-QEK2KX5R-GC4Djt9A.js} +6 -6
  103. package/dist/server/assets/{diagram-S2PKOQOG-DUV65VxH.js → diagram-S2PKOQOG-5B6KDW-y.js} +6 -6
  104. package/dist/server/assets/{erDiagram-Q2GNP2WA-eEKIOvT3.js → erDiagram-Q2GNP2WA-Be8xw8rI.js} +4 -4
  105. package/dist/server/assets/{flowDiagram-NV44I4VS-B0GxfKRu.js → flowDiagram-NV44I4VS-jzmSul5A.js} +5 -5
  106. package/dist/server/assets/{ganttDiagram-JELNMOA3-etJ_j_I0.js → ganttDiagram-JELNMOA3-DWzYYJJD.js} +2 -2
  107. package/dist/server/assets/{gitGraph-G5XIXVHT-DE59sCs-.js → gitGraph-G5XIXVHT-DBh_B9aL.js} +6 -6
  108. package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-BZuXPjR3.js → gitGraphDiagram-V2S2FVAM-DtVbt-rt.js} +7 -7
  109. package/dist/server/assets/{graph-HlbQNgKh.js → graph-DX5yyy2e.js} +2 -2
  110. package/dist/server/assets/{highlighted-body-B3W2YXNL-CGZmJ48I.js → highlighted-body-B3W2YXNL-jVL8aR3Z.js} +1 -1
  111. package/dist/server/assets/{index-DfuZ1SKx.js → index-B5nFl_AI.js} +2 -2
  112. package/dist/server/assets/{index-KO85K6gg.js → index-BAdVYDyw.js} +2 -2
  113. package/dist/server/assets/{index-oAvn7Kbw.js → index-BhOjaygO.js} +2 -2
  114. package/dist/server/assets/{index-BquoD96E.js → index-BirnOPeb.js} +2 -2
  115. package/dist/server/assets/{index-kEUC1eer.js → index-BjR3sOAq.js} +2 -2
  116. package/dist/server/assets/{index-DsW29Azb.js → index-BoxcvdZf.js} +4 -4
  117. package/dist/server/assets/{index-DoEmUqp6.js → index-BsKQIZIq.js} +2 -2
  118. package/dist/server/assets/{index-Cq-S8ocb.js → index-CBiZXyl4.js} +1 -1
  119. package/dist/server/assets/{index-0Vp2EuiF.js → index-CD24s2ge.js} +3 -3
  120. package/dist/server/assets/{index-B2NbB5n_.js → index-CJFioIPI.js} +2 -2
  121. package/dist/server/assets/{index-BYATJkV0.js → index-CVpPQcdL.js} +1 -1
  122. package/dist/server/assets/{index-CqJMMgyN.js → index-CeFUhbU-.js} +2 -2
  123. package/dist/server/assets/{index-DVIqYu1B.js → index-DHKWIWry.js} +5 -5
  124. package/dist/server/assets/{index-CozxyE6F.js → index-DYzy4J8Y.js} +2 -2
  125. package/dist/server/assets/{index-CcRwhNJ0.js → index-DiZw5Slc.js} +3 -3
  126. package/dist/server/assets/{index-B_gLaw5q.js → index-fJ18TF5w.js} +5 -5
  127. package/dist/server/assets/{index-CReShbyg.js → index-icISvAHb.js} +2 -2
  128. package/dist/server/assets/{index-BggD7xEz.js → index-x1PcD09R.js} +2 -2
  129. package/dist/server/assets/{info-VBDWY6EO-DFb5bmEE.js → info-VBDWY6EO-CgGw-KWo.js} +6 -6
  130. package/dist/server/assets/{infoDiagram-HS3SLOUP-DUDXdFYe.js → infoDiagram-HS3SLOUP-Bm300kuC.js} +5 -5
  131. package/dist/server/assets/{journeyDiagram-XKPGCS4Q-BnEH3kK2.js → journeyDiagram-XKPGCS4Q-i8WJyl2v.js} +4 -4
  132. package/dist/server/assets/{kanban-definition-3W4ZIXB7-BPnM08KT.js → kanban-definition-3W4ZIXB7-BxqtaaIr.js} +2 -2
  133. package/dist/server/assets/{layout-CnirhobE.js → layout-C81zgoUj.js} +4 -4
  134. package/dist/server/assets/{linear-CLJDiqhJ.js → linear-dyZZUN6P.js} +1 -1
  135. package/dist/server/assets/{mermaid-3ZIDBTTL-Dyndt6u2.js → mermaid-3ZIDBTTL-bTD72h2_.js} +1 -1
  136. package/dist/server/assets/{mermaid-parser.core-DxDjr9RA.js → mermaid-parser.core-BpodyVoJ.js} +11 -11
  137. package/dist/server/assets/{mindmap-definition-VGOIOE7T-CPnGCXl9.js → mindmap-definition-VGOIOE7T-CGVjAsWC.js} +3 -3
  138. package/dist/server/assets/{packet-DYOGHKS2-Bt7VjiqG.js → packet-DYOGHKS2-BeHd7ss_.js} +6 -6
  139. package/dist/server/assets/{pie-VRWISCQL-CpD4BgbA.js → pie-VRWISCQL-CtMn8fFZ.js} +6 -6
  140. package/dist/server/assets/{pieDiagram-ADFJNKIX-BSx8zl8i.js → pieDiagram-ADFJNKIX-CS0mGgZR.js} +7 -7
  141. package/dist/server/assets/{quadrantDiagram-AYHSOK5B-B08pRdHD.js → quadrantDiagram-AYHSOK5B-C0QMIITK.js} +2 -2
  142. package/dist/server/assets/{radar-ZZBFDIW7-BeHVWQbv.js → radar-ZZBFDIW7-DIYuMHay.js} +6 -6
  143. package/dist/server/assets/{requirementDiagram-UZGBJVZJ-BtjVtNFU.js → requirementDiagram-UZGBJVZJ-Cu_xdr4s.js} +3 -3
  144. package/dist/server/assets/{router-VlIt4cC5.js → router-emaiBwQ1.js} +377 -240
  145. package/dist/server/assets/{sankeyDiagram-TZEHDZUN-CG6DECc6.js → sankeyDiagram-TZEHDZUN-sK1eHAYK.js} +1 -1
  146. package/dist/server/assets/{sequenceDiagram-WL72ISMW-DEfVJQli.js → sequenceDiagram-WL72ISMW-BxdrIxsT.js} +3 -3
  147. package/dist/server/assets/{square-terminal-DTO02O7S.js → square-terminal-DaamWbdC.js} +1 -1
  148. package/dist/server/assets/{stateDiagram-FKZM4ZOC-DblYyAIC.js → stateDiagram-FKZM4ZOC-YKAev_OI.js} +8 -8
  149. package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-YhMCeOsH.js → stateDiagram-v2-4FDKWEC3-WXMNfM85.js} +4 -4
  150. package/dist/server/assets/{timeline-definition-IT6M3QCI-CDEJSclA.js → timeline-definition-IT6M3QCI-DrdVpYke.js} +2 -2
  151. package/dist/server/assets/{treemap-GDKQZRPO-Tg2S6NSt.js → treemap-GDKQZRPO-DZHSpt06.js} +6 -6
  152. package/dist/server/assets/{workspace._workspaceId-CVnwrhnX.js → workspace._workspaceId-KpmCwO8V.js} +10 -4
  153. package/dist/server/assets/{workspace._workspaceId.changes-CsJMr9Ve.js → workspace._workspaceId.changes-DF6oupkK.js} +1 -1
  154. package/dist/server/assets/{workspace._workspaceId.code._-CjSLVs7D.js → workspace._workspaceId.code._-fbsbn7Pa.js} +1 -1
  155. package/dist/server/assets/{workspace._workspaceId.code.index-BhUZuUX-.js → workspace._workspaceId.code.index-D2dHFGQr.js} +1 -1
  156. package/dist/server/assets/{workspace._workspaceId.index-CmBIxfCl.js → workspace._workspaceId.index-DpLhp52B.js} +1 -1
  157. package/dist/server/assets/{workspace._workspaceId.terminal-BehWU5SY.js → workspace._workspaceId.terminal-Dk3GXgkq.js} +2 -2
  158. package/dist/server/assets/{xychartDiagram-PRI3JC2R-DAT7FXvH.js → xychartDiagram-PRI3JC2R-BXCdvcf7.js} +2 -2
  159. package/dist/server/server.js +2 -2
  160. package/dist/start-server.mjs +662 -636
  161. package/package.json +6 -5
  162. package/dist/client/assets/TerminalPanel-CTjPLr1l.js +0 -4
  163. package/dist/client/assets/channel-BN9rr7kd.js +0 -1
  164. package/dist/client/assets/classDiagram-2ON5EDUG-f-3sWSXi.js +0 -1
  165. package/dist/client/assets/classDiagram-v2-WZHVMYZB-f-3sWSXi.js +0 -1
  166. package/dist/client/assets/clone-DyjKoDMl.js +0 -1
  167. package/dist/client/assets/main-7lUOPiu0.css +0 -1
  168. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BXdrXPzW.js +0 -1
  169. package/dist/client/assets/workspace._workspaceId-CKxw1xn1.js +0 -1
  170. package/dist/client/assets/workspace._workspaceId.code-CTG7u893.js +0 -1
  171. package/dist/server/assets/TerminalPanel-_8vdN94i.js +0 -442
@@ -6501,11 +6501,11 @@ var require_tools = __commonJS({
6501
6501
  }
6502
6502
  }
6503
6503
  }
6504
- function buildFormatters(level, bindings, log27) {
6504
+ function buildFormatters(level, bindings, log26) {
6505
6505
  return {
6506
6506
  level,
6507
6507
  bindings,
6508
- log: log27
6508
+ log: log26
6509
6509
  };
6510
6510
  }
6511
6511
  function normalizeDestFileDescriptor(destination) {
@@ -6888,11 +6888,11 @@ var require_proto = __commonJS({
6888
6888
  }
6889
6889
  } else instance[serializersSym] = serializers;
6890
6890
  if (options2.hasOwnProperty("formatters")) {
6891
- const { level, bindings: chindings, log: log27 } = options2.formatters;
6891
+ const { level, bindings: chindings, log: log26 } = options2.formatters;
6892
6892
  instance[formattersSym] = buildFormatters(
6893
6893
  level || formatters.level,
6894
6894
  chindings || resetChildingsFormatter,
6895
- log27 || formatters.log
6895
+ log26 || formatters.log
6896
6896
  );
6897
6897
  } else {
6898
6898
  instance[formattersSym] = buildFormatters(
@@ -30908,205 +30908,6 @@ var init_cursor_cli = __esm({
30908
30908
  }
30909
30909
  });
30910
30910
 
30911
- // ../../packages/coding-agent/src/adapters/openai-codex.ts
30912
- var openai_codex_exports = {};
30913
- __export(openai_codex_exports, {
30914
- OPENAI_CODEX_DEFAULT_BINARY: () => OPENAI_CODEX_DEFAULT_BINARY,
30915
- OpenAICodexAdapter: () => OpenAICodexAdapter,
30916
- getOpenAICodexInstallSkillsDir: () => getOpenAICodexInstallSkillsDir
30917
- });
30918
- import { homedir as homedir2 } from "node:os";
30919
- import { join as join5 } from "node:path";
30920
- function getOpenAICodexInstallSkillsDir(home = homedir2()) {
30921
- const codexHome = process.env.CODEX_HOME ?? join5(home, ".codex");
30922
- return join5(codexHome, "skills");
30923
- }
30924
- function discoverCodexSkills(workspaceDir) {
30925
- const globalSkillsDir = join5(CODEX_HOME, "skills");
30926
- const systemSkillsDir = join5(CODEX_HOME, "skills", ".system");
30927
- const projectSkillsDir = join5(workspaceDir, ".codex", "skills");
30928
- const systemSkills = readSkillsFromDir(systemSkillsDir);
30929
- const globalSkills = readSkillsFromDir(globalSkillsDir);
30930
- const projectSkills = readSkillsFromDir(projectSkillsDir);
30931
- const skillMap = /* @__PURE__ */ new Map();
30932
- for (const skill of systemSkills) {
30933
- skillMap.set(skill.name, skill);
30934
- }
30935
- for (const skill of globalSkills) {
30936
- skillMap.set(skill.name, skill);
30937
- }
30938
- for (const skill of projectSkills) {
30939
- skillMap.set(skill.name, skill);
30940
- }
30941
- return Array.from(skillMap.values()).sort((a6, b10) => a6.name.localeCompare(b10.name));
30942
- }
30943
- function parseInput(args) {
30944
- if (typeof args === "string") {
30945
- try {
30946
- return JSON.parse(args);
30947
- } catch {
30948
- return { raw: args };
30949
- }
30950
- }
30951
- if (typeof args === "object" && args !== null) {
30952
- return args;
30953
- }
30954
- return {};
30955
- }
30956
- var log4, OpenAICodexAdapter, CODEX_HOME, OPENAI_CODEX_DEFAULT_BINARY;
30957
- var init_openai_codex = __esm({
30958
- "../../packages/coding-agent/src/adapters/openai-codex.ts"() {
30959
- init_src();
30960
- init_skills();
30961
- log4 = createLogger("coding-agent:openai-codex");
30962
- OpenAICodexAdapter = class {
30963
- name = "OpenAI Codex";
30964
- supportedFeatures = {
30965
- costTracking: true,
30966
- sessionListing: false
30967
- };
30968
- workspaceDir;
30969
- maxTurns;
30970
- model;
30971
- sandboxMode;
30972
- activeIterator = null;
30973
- constructor(config2) {
30974
- this.workspaceDir = config2.workspaceDir;
30975
- this.maxTurns = config2.maxTurns;
30976
- this.model = config2.options.model ?? "codex-mini";
30977
- this.sandboxMode = config2.options.sandboxMode ?? "docker";
30978
- }
30979
- abort() {
30980
- if (this.activeIterator) {
30981
- log4.info("aborting active codex stream");
30982
- this.activeIterator.return?.(void 0);
30983
- this.activeIterator = null;
30984
- }
30985
- }
30986
- async *runSession(prompt, sessionId, options2) {
30987
- const effectiveMaxTurns = options2?.maxTurns ?? this.maxTurns;
30988
- const effectiveModel = options2?.model ?? this.model;
30989
- log4.info(
30990
- {
30991
- prompt: prompt.slice(0, 100),
30992
- sessionId,
30993
- model: effectiveModel,
30994
- cwd: this.workspaceDir,
30995
- maxTurns: effectiveMaxTurns
30996
- },
30997
- "runSession starting"
30998
- );
30999
- const moduleName = ["@openai", "codex-sdk"].join("/");
31000
- const sdk = await import(moduleName);
31001
- const codex = new sdk.Codex({ model: effectiveModel });
31002
- const startMs = Date.now();
31003
- let turnCount = 0;
31004
- const thread = sessionId ? codex.resumeThread(sessionId) : codex.startThread();
31005
- const stream = thread.runStreamed(prompt, {
31006
- cwd: this.workspaceDir,
31007
- maxTurns: effectiveMaxTurns,
31008
- sandbox: this.sandboxMode
31009
- });
31010
- const iterator = stream[Symbol.asyncIterator]();
31011
- this.activeIterator = iterator;
31012
- try {
31013
- for await (const event of { [Symbol.asyncIterator]: () => iterator }) {
31014
- const type = event.type;
31015
- log4.debug({ eventType: type }, "codex event");
31016
- switch (type) {
31017
- case "thread.started": {
31018
- yield {
31019
- type: "session-start",
31020
- sessionId: String(event.thread_id ?? sessionId ?? "")
31021
- };
31022
- break;
31023
- }
31024
- case "agent_message": {
31025
- const text4 = event.content;
31026
- if (text4) {
31027
- yield { type: "text-delta", text: text4 };
31028
- }
31029
- break;
31030
- }
31031
- case "item.started": {
31032
- const item = event.item;
31033
- if (item?.type === "function_call") {
31034
- turnCount++;
31035
- yield {
31036
- type: "tool-use",
31037
- toolCallId: String(item.call_id ?? crypto.randomUUID()),
31038
- toolName: String(item.name ?? "unknown"),
31039
- input: parseInput(item.arguments)
31040
- };
31041
- }
31042
- break;
31043
- }
31044
- case "item.completed": {
31045
- const item = event.item;
31046
- if (item?.type === "function_call_output" || item?.type === "function_call") {
31047
- yield {
31048
- type: "tool-result",
31049
- toolCallId: String(item.call_id ?? crypto.randomUUID()),
31050
- output: String(item.output ?? ""),
31051
- isError: false
31052
- };
31053
- }
31054
- break;
31055
- }
31056
- case "turn.completed": {
31057
- yield {
31058
- type: "session-result",
31059
- success: true,
31060
- sessionId: String(event.thread_id ?? sessionId ?? ""),
31061
- durationMs: Date.now() - startMs,
31062
- numTurns: turnCount,
31063
- costUsd: event.usage_usd ?? 0,
31064
- errors: []
31065
- };
31066
- break;
31067
- }
31068
- case "turn.failed": {
31069
- yield {
31070
- type: "session-result",
31071
- success: false,
31072
- sessionId: String(event.thread_id ?? sessionId ?? ""),
31073
- durationMs: Date.now() - startMs,
31074
- numTurns: turnCount,
31075
- costUsd: 0,
31076
- errors: [String(event.error ?? "Codex turn failed")]
31077
- };
31078
- break;
31079
- }
31080
- }
31081
- }
31082
- log4.info("codex stream done");
31083
- } catch (err) {
31084
- log4.error({ err }, "codex error");
31085
- throw err;
31086
- } finally {
31087
- this.activeIterator = null;
31088
- }
31089
- }
31090
- async listSkills() {
31091
- return discoverCodexSkills(this.workspaceDir);
31092
- }
31093
- listModels() {
31094
- return [
31095
- {
31096
- id: "codex-mini",
31097
- name: "Codex Mini",
31098
- description: "Fast and efficient",
31099
- contextWindow: 2e5
31100
- },
31101
- { id: "o4-mini", name: "o4-mini", contextWindow: 2e5 }
31102
- ];
31103
- }
31104
- };
31105
- CODEX_HOME = process.env.CODEX_HOME || join5(homedir2(), ".codex");
31106
- OPENAI_CODEX_DEFAULT_BINARY = "codex";
31107
- }
31108
- });
31109
-
31110
30911
  // ../../node_modules/.pnpm/@openai+codex-sdk@0.128.0/node_modules/@openai/codex-sdk/dist/index.js
31111
30912
  import { promises as fs2 } from "fs";
31112
30913
  import os from "os";
@@ -31579,8 +31380,8 @@ __export(codex_exports, {
31579
31380
  import { execFileSync } from "node:child_process";
31580
31381
  import { createReadStream as createReadStream2 } from "node:fs";
31581
31382
  import { readdir, stat as stat2 } from "node:fs/promises";
31582
- import { homedir as homedir3 } from "node:os";
31583
- import { join as join6 } from "node:path";
31383
+ import { homedir as homedir2 } from "node:os";
31384
+ import { join as join5 } from "node:path";
31584
31385
  import { createInterface } from "node:readline";
31585
31386
  function lruSet2(map2, key, value, cap) {
31586
31387
  if (map2.has(key)) map2.delete(key);
@@ -31599,14 +31400,14 @@ function resolveCodexBinary() {
31599
31400
  return void 0;
31600
31401
  }
31601
31402
  }
31602
- function getCodexInstallSkillsDir(home = homedir3()) {
31603
- const codexHome = process.env.CODEX_HOME ?? join6(home, ".codex");
31604
- return join6(codexHome, "skills");
31403
+ function getCodexInstallSkillsDir(home = homedir2()) {
31404
+ const codexHome = process.env.CODEX_HOME || join5(home, ".codex");
31405
+ return join5(codexHome, "skills");
31605
31406
  }
31606
- function discoverCodexSkills2(workspaceDir) {
31607
- const globalSkillsDir = join6(CODEX_HOME2, "skills");
31608
- const systemSkillsDir = join6(CODEX_HOME2, "skills", ".system");
31609
- const projectSkillsDir = join6(workspaceDir, ".codex", "skills");
31407
+ function discoverCodexSkills(workspaceDir) {
31408
+ const globalSkillsDir = join5(CODEX_HOME, "skills");
31409
+ const systemSkillsDir = join5(CODEX_HOME, "skills", ".system");
31410
+ const projectSkillsDir = join5(workspaceDir, ".codex", "skills");
31610
31411
  const systemSkills = readSkillsFromDir(systemSkillsDir);
31611
31412
  const globalSkills = readSkillsFromDir(globalSkillsDir);
31612
31413
  const projectSkills = readSkillsFromDir(projectSkillsDir);
@@ -31622,7 +31423,7 @@ function discoverCodexSkills2(workspaceDir) {
31622
31423
  }
31623
31424
  return Array.from(skillMap.values()).sort((a6, b10) => a6.name.localeCompare(b10.name));
31624
31425
  }
31625
- function parseInput2(args) {
31426
+ function parseInput(args) {
31626
31427
  if (typeof args === "string") {
31627
31428
  try {
31628
31429
  return JSON.parse(args);
@@ -31672,7 +31473,7 @@ function* handleItemStarted(item, toolNames) {
31672
31473
  type: "tool-use",
31673
31474
  toolCallId: item.id,
31674
31475
  toolName: name24,
31675
- input: parseInput2(item.arguments)
31476
+ input: parseInput(item.arguments)
31676
31477
  };
31677
31478
  break;
31678
31479
  }
@@ -31799,7 +31600,7 @@ async function findSessionFiles() {
31799
31600
  return;
31800
31601
  }
31801
31602
  for (const entry of entries) {
31802
- const full = join6(dir, entry);
31603
+ const full = join5(dir, entry);
31803
31604
  const s6 = await stat2(full).catch(() => null);
31804
31605
  if (!s6) continue;
31805
31606
  if (s6.isDirectory()) {
@@ -31853,7 +31654,7 @@ async function readCodexSessions() {
31853
31654
  });
31854
31655
  }
31855
31656
  } catch (err) {
31856
- log5.debug({ err, file: file2 }, "failed to parse codex session file");
31657
+ log4.debug({ err, file: file2 }, "failed to parse codex session file");
31857
31658
  }
31858
31659
  }
31859
31660
  return sessions;
@@ -31941,13 +31742,13 @@ async function readCodexSessionMessages(sessionId, options2) {
31941
31742
  const slice = hasMore ? collected.slice(0, requested) : collected;
31942
31743
  return { messages: slice, hasMore, firstOffset: offset4 };
31943
31744
  }
31944
- var log5, cumulativeUsageBySession2, MAX_CUMULATIVE_SESSIONS2, CodexAdapter, CODEX_CTX, CODEX_MODELS, CODEX_DEFAULT_BINARY, CODEX_HOME2, SESSIONS_DIR;
31745
+ var log4, cumulativeUsageBySession2, MAX_CUMULATIVE_SESSIONS2, CodexAdapter, CODEX_CTX, CODEX_MODELS, CODEX_DEFAULT_BINARY, CODEX_HOME, SESSIONS_DIR;
31945
31746
  var init_codex = __esm({
31946
31747
  "../../packages/coding-agent/src/adapters/codex.ts"() {
31947
31748
  init_src();
31948
31749
  init_dist2();
31949
31750
  init_skills();
31950
- log5 = createLogger("coding-agent:codex");
31751
+ log4 = createLogger("coding-agent:codex");
31951
31752
  cumulativeUsageBySession2 = /* @__PURE__ */ new Map();
31952
31753
  MAX_CUMULATIVE_SESSIONS2 = 500;
31953
31754
  CodexAdapter = class {
@@ -31969,7 +31770,7 @@ var init_codex = __esm({
31969
31770
  }
31970
31771
  abort() {
31971
31772
  if (this.activeIterator) {
31972
- log5.info("aborting active codex stream");
31773
+ log4.info("aborting active codex stream");
31973
31774
  this.activeIterator.return?.(void 0);
31974
31775
  this.activeIterator = null;
31975
31776
  }
@@ -31980,7 +31781,7 @@ var init_codex = __esm({
31980
31781
  const knownModelIds = new Set(CODEX_MODELS.map((m11) => m11.id));
31981
31782
  const effectiveModel = requestedModel && knownModelIds.has(requestedModel) ? requestedModel : void 0;
31982
31783
  const mode = options2?.mode ?? "edit";
31983
- log5.info(
31784
+ log4.info(
31984
31785
  {
31985
31786
  prompt: prompt.slice(0, 100),
31986
31787
  sessionId,
@@ -32046,17 +31847,17 @@ var init_codex = __esm({
32046
31847
  persistCumulative();
32047
31848
  };
32048
31849
  const runStreamedStartMs = Date.now();
32049
- log5.info("calling thread.runStreamed");
31850
+ log4.info("calling thread.runStreamed");
32050
31851
  let result;
32051
31852
  try {
32052
31853
  result = await thread.runStreamed(prompt);
32053
- log5.info(
31854
+ log4.info(
32054
31855
  { elapsedMs: Date.now() - runStreamedStartMs },
32055
31856
  "thread.runStreamed returned successfully"
32056
31857
  );
32057
31858
  } catch (err) {
32058
31859
  const msg = err instanceof Error ? err.message : String(err);
32059
- log5.error({ err, cwd: this.workspaceDir, model: effectiveModel }, "codex runStreamed failed");
31860
+ log4.error({ err, cwd: this.workspaceDir, model: effectiveModel }, "codex runStreamed failed");
32060
31861
  yield { type: "error", message: msg };
32061
31862
  yield {
32062
31863
  type: "session-result",
@@ -32077,13 +31878,13 @@ var init_codex = __esm({
32077
31878
  let lastTurnError = null;
32078
31879
  try {
32079
31880
  for await (const event of { [Symbol.asyncIterator]: () => iterator }) {
32080
- log5.debug({ eventType: event.type }, "codex event");
31881
+ log4.debug({ eventType: event.type }, "codex event");
32081
31882
  switch (event.type) {
32082
31883
  // ── Session lifecycle ──────────────────────────────────────────
32083
31884
  case "thread.started": {
32084
31885
  const resolvedSid = event.thread_id ?? sessionId ?? "";
32085
31886
  adoptSessionId(resolvedSid);
32086
- log5.info(
31887
+ log4.info(
32087
31888
  { threadId: event.thread_id, sessionIdParam: sessionId, actualSessionId },
32088
31889
  "codex thread.started"
32089
31890
  );
@@ -32127,7 +31928,7 @@ var init_codex = __esm({
32127
31928
  totalOutputTokens += outputTokens;
32128
31929
  totalReasoningOutputTokens += reasoningOutputTokens;
32129
31930
  persistCumulative();
32130
- log5.debug(
31931
+ log4.debug(
32131
31932
  {
32132
31933
  inputTokens,
32133
31934
  outputTokens,
@@ -32167,7 +31968,7 @@ var init_codex = __esm({
32167
31968
  }
32168
31969
  }
32169
31970
  }
32170
- log5.info(
31971
+ log4.info(
32171
31972
  {
32172
31973
  turnCount,
32173
31974
  totalInputTokens,
@@ -32191,7 +31992,7 @@ var init_codex = __esm({
32191
31992
  }
32192
31993
  } catch (err) {
32193
31994
  const msg = err instanceof Error ? err.message : String(err);
32194
- log5.error({ err, cwd: this.workspaceDir }, "codex stream error");
31995
+ log4.error({ err, cwd: this.workspaceDir }, "codex stream error");
32195
31996
  yield { type: "error", message: msg };
32196
31997
  yield {
32197
31998
  type: "session-result",
@@ -32207,7 +32008,7 @@ var init_codex = __esm({
32207
32008
  }
32208
32009
  }
32209
32010
  async listSkills() {
32210
- return discoverCodexSkills2(this.workspaceDir);
32011
+ return discoverCodexSkills(this.workspaceDir);
32211
32012
  }
32212
32013
  listModes() {
32213
32014
  return [
@@ -32219,12 +32020,12 @@ var init_codex = __esm({
32219
32020
  return CODEX_MODELS;
32220
32021
  }
32221
32022
  async listSessions(dir) {
32222
- log5.info({ dir }, "listSessions");
32023
+ log4.info({ dir }, "listSessions");
32223
32024
  const sessions = await readCodexSessions();
32224
32025
  return sessions.filter((s6) => s6.cwd === dir).sort((a6, b10) => b10.lastModified - a6.lastModified);
32225
32026
  }
32226
32027
  async getSessionMessages(sessionId, dir, options2) {
32227
- log5.info({ sessionId, dir, ...options2 }, "getSessionMessages");
32028
+ log4.info({ sessionId, dir, ...options2 }, "getSessionMessages");
32228
32029
  return readCodexSessionMessages(sessionId, options2);
32229
32030
  }
32230
32031
  };
@@ -32262,8 +32063,8 @@ var init_codex = __esm({
32262
32063
  }
32263
32064
  ];
32264
32065
  CODEX_DEFAULT_BINARY = "codex";
32265
- CODEX_HOME2 = process.env.CODEX_HOME || join6(homedir3(), ".codex");
32266
- SESSIONS_DIR = join6(CODEX_HOME2, "sessions");
32066
+ CODEX_HOME = process.env.CODEX_HOME || join5(homedir2(), ".codex");
32067
+ SESSIONS_DIR = join5(CODEX_HOME, "sessions");
32267
32068
  }
32268
32069
  });
32269
32070
 
@@ -32275,15 +32076,15 @@ __export(gemini_cli_exports, {
32275
32076
  getGeminiCliInstallSkillsDir: () => getGeminiCliInstallSkillsDir
32276
32077
  });
32277
32078
  import { spawn as spawn3 } from "node:child_process";
32278
- import { homedir as homedir4 } from "node:os";
32279
- import { join as join7 } from "node:path";
32079
+ import { homedir as homedir3 } from "node:os";
32080
+ import { join as join6 } from "node:path";
32280
32081
  import { createInterface as createInterface2 } from "node:readline";
32281
- function getGeminiCliInstallSkillsDir(home = homedir4()) {
32282
- return join7(home, ".gemini", "skills");
32082
+ function getGeminiCliInstallSkillsDir(home = homedir3()) {
32083
+ return join6(home, ".gemini", "skills");
32283
32084
  }
32284
32085
  function discoverGeminiSkills(workspaceDir) {
32285
- const globalSkillsDir = join7(homedir4(), ".gemini", "skills");
32286
- const projectSkillsDir = join7(workspaceDir, ".gemini", "skills");
32086
+ const globalSkillsDir = join6(homedir3(), ".gemini", "skills");
32087
+ const projectSkillsDir = join6(workspaceDir, ".gemini", "skills");
32287
32088
  const globalSkills = readSkillsFromDir(globalSkillsDir);
32288
32089
  const projectSkills = readSkillsFromDir(projectSkillsDir);
32289
32090
  const skillMap = /* @__PURE__ */ new Map();
@@ -32295,12 +32096,12 @@ function discoverGeminiSkills(workspaceDir) {
32295
32096
  }
32296
32097
  return Array.from(skillMap.values()).sort((a6, b10) => a6.name.localeCompare(b10.name));
32297
32098
  }
32298
- var log6, GeminiCliAdapter, GEMINI_CLI_DEFAULT_BINARY;
32099
+ var log5, GeminiCliAdapter, GEMINI_CLI_DEFAULT_BINARY;
32299
32100
  var init_gemini_cli = __esm({
32300
32101
  "../../packages/coding-agent/src/adapters/gemini-cli.ts"() {
32301
32102
  init_src();
32302
32103
  init_skills();
32303
- log6 = createLogger("coding-agent:gemini-cli");
32104
+ log5 = createLogger("coding-agent:gemini-cli");
32304
32105
  GeminiCliAdapter = class {
32305
32106
  name = "Gemini CLI";
32306
32107
  supportedFeatures = {
@@ -32320,7 +32121,7 @@ var init_gemini_cli = __esm({
32320
32121
  }
32321
32122
  abort() {
32322
32123
  if (this.activeChild) {
32323
- log6.info("aborting active gemini process");
32124
+ log5.info("aborting active gemini process");
32324
32125
  this.activeChild.kill();
32325
32126
  this.activeChild = null;
32326
32127
  }
@@ -32330,7 +32131,7 @@ var init_gemini_cli = __esm({
32330
32131
  const requestedModel = options2?.model ?? this.model;
32331
32132
  const knownGeminiModels = new Set(this.listModels().map((m11) => m11.id));
32332
32133
  const effectiveModel = requestedModel && knownGeminiModels.has(requestedModel) ? requestedModel : void 0;
32333
- log6.info(
32134
+ log5.info(
32334
32135
  {
32335
32136
  prompt: prompt.slice(0, 100),
32336
32137
  model: effectiveModel,
@@ -32353,7 +32154,7 @@ var init_gemini_cli = __esm({
32353
32154
  let spawnError = null;
32354
32155
  child.on("error", (err) => {
32355
32156
  spawnError = err;
32356
- log6.error({ err, executable: this.executablePath }, "gemini spawn error");
32157
+ log5.error({ err, executable: this.executablePath }, "gemini spawn error");
32357
32158
  });
32358
32159
  const startMs = Date.now();
32359
32160
  let turnCount = 0;
@@ -32367,11 +32168,11 @@ var init_gemini_cli = __esm({
32367
32168
  try {
32368
32169
  parsed = JSON.parse(line2);
32369
32170
  } catch {
32370
- log6.warn({ line: line2 }, "failed to parse NDJSON line");
32171
+ log5.warn({ line: line2 }, "failed to parse NDJSON line");
32371
32172
  continue;
32372
32173
  }
32373
32174
  const type = parsed.type;
32374
- log6.debug({ eventType: type }, "gemini event");
32175
+ log5.debug({ eventType: type }, "gemini event");
32375
32176
  switch (type) {
32376
32177
  case "message": {
32377
32178
  const text4 = parsed.text;
@@ -32437,11 +32238,11 @@ var init_gemini_cli = __esm({
32437
32238
  errors: [errMsg]
32438
32239
  };
32439
32240
  } else if (exitCode !== 0) {
32440
- log6.warn({ exitCode }, "gemini process exited with non-zero code");
32241
+ log5.warn({ exitCode }, "gemini process exited with non-zero code");
32441
32242
  }
32442
- log6.info("gemini stream done");
32243
+ log5.info("gemini stream done");
32443
32244
  } catch (err) {
32444
- log6.error({ err }, "gemini error");
32245
+ log5.error({ err }, "gemini error");
32445
32246
  child.kill();
32446
32247
  throw err;
32447
32248
  } finally {
@@ -32480,8 +32281,8 @@ __export(opencode_exports, {
32480
32281
  getOpenCodeInstallSkillsDir: () => getOpenCodeInstallSkillsDir
32481
32282
  });
32482
32283
  import { execFile, spawn as spawn4 } from "node:child_process";
32483
- import { homedir as homedir5 } from "node:os";
32484
- import { join as join8 } from "node:path";
32284
+ import { homedir as homedir4 } from "node:os";
32285
+ import { join as join7 } from "node:path";
32485
32286
  import { createInterface as createInterface3 } from "node:readline";
32486
32287
  function fetchOpenCodeModels(executablePath) {
32487
32288
  return new Promise((resolve8, reject) => {
@@ -32575,7 +32376,7 @@ async function fetchOpenCodeSessionMessages(executablePath, sessionId, options2)
32575
32376
  try {
32576
32377
  session = JSON.parse(raw.slice(jsonStart));
32577
32378
  } catch {
32578
- log7.warn({ sessionId }, "failed to parse exported session");
32379
+ log6.warn({ sessionId }, "failed to parse exported session");
32579
32380
  return { messages: [], hasMore: false, firstOffset: 0 };
32580
32381
  }
32581
32382
  const tail = options2?.tail;
@@ -32643,20 +32444,20 @@ async function fetchOpenCodeSessionMessages(executablePath, sessionId, options2)
32643
32444
  const slice = hasMore ? collected.slice(0, requested) : collected;
32644
32445
  return { messages: slice, hasMore, firstOffset: offset4 };
32645
32446
  }
32646
- function getOpenCodeInstallSkillsDir(home = homedir5()) {
32647
- return join8(home, ".config", "opencode", "skills");
32447
+ function getOpenCodeInstallSkillsDir(home = homedir4()) {
32448
+ return join7(home, ".config", "opencode", "skills");
32648
32449
  }
32649
32450
  function discoverOpenCodeSkills(workspaceDir) {
32650
- const home = homedir5();
32451
+ const home = homedir4();
32651
32452
  const dirs = [
32652
32453
  // Global (lowest priority first)
32653
- join8(home, ".agents", "skills"),
32654
- join8(home, ".claude", "skills"),
32655
- join8(home, ".config", "opencode", "skills"),
32454
+ join7(home, ".agents", "skills"),
32455
+ join7(home, ".claude", "skills"),
32456
+ join7(home, ".config", "opencode", "skills"),
32656
32457
  // Project-level (overrides global)
32657
- join8(workspaceDir, ".agents", "skills"),
32658
- join8(workspaceDir, ".claude", "skills"),
32659
- join8(workspaceDir, ".opencode", "skills")
32458
+ join7(workspaceDir, ".agents", "skills"),
32459
+ join7(workspaceDir, ".claude", "skills"),
32460
+ join7(workspaceDir, ".opencode", "skills")
32660
32461
  ];
32661
32462
  const skillMap = /* @__PURE__ */ new Map();
32662
32463
  for (const dir of dirs) {
@@ -32666,12 +32467,12 @@ function discoverOpenCodeSkills(workspaceDir) {
32666
32467
  }
32667
32468
  return Array.from(skillMap.values()).sort((a6, b10) => a6.name.localeCompare(b10.name));
32668
32469
  }
32669
- var log7, OpenCodeAdapter, DEFAULT_MODELS, OPENCODE_DEFAULT_BINARY;
32470
+ var log6, OpenCodeAdapter, DEFAULT_MODELS, OPENCODE_DEFAULT_BINARY;
32670
32471
  var init_opencode = __esm({
32671
32472
  "../../packages/coding-agent/src/adapters/opencode.ts"() {
32672
32473
  init_src();
32673
32474
  init_skills();
32674
- log7 = createLogger("coding-agent:opencode");
32475
+ log6 = createLogger("coding-agent:opencode");
32675
32476
  OpenCodeAdapter = class {
32676
32477
  name = "OpenCode";
32677
32478
  supportedFeatures = {
@@ -32690,7 +32491,7 @@ var init_opencode = __esm({
32690
32491
  }
32691
32492
  abort() {
32692
32493
  if (this.activeChild) {
32693
- log7.info("aborting active opencode process");
32494
+ log6.info("aborting active opencode process");
32694
32495
  this.activeChild.kill();
32695
32496
  this.activeChild = null;
32696
32497
  }
@@ -32699,7 +32500,7 @@ var init_opencode = __esm({
32699
32500
  const requestedModel = options2?.model ?? this.model;
32700
32501
  const knownModelIds = new Set((this.cachedModels ?? DEFAULT_MODELS).map((m11) => m11.id));
32701
32502
  const effectiveModel = requestedModel && knownModelIds.has(requestedModel) ? requestedModel : void 0;
32702
- log7.info(
32503
+ log6.info(
32703
32504
  {
32704
32505
  prompt: prompt.slice(0, 100),
32705
32506
  model: effectiveModel,
@@ -32735,7 +32536,7 @@ var init_opencode = __esm({
32735
32536
  this.activeChild = child;
32736
32537
  child.on("error", (err) => {
32737
32538
  spawnError = err;
32738
- log7.error({ err, executable: this.executablePath }, "opencode spawn error");
32539
+ log6.error({ err, executable: this.executablePath }, "opencode spawn error");
32739
32540
  });
32740
32541
  const stderrChunks = [];
32741
32542
  child.stderr.on("data", (chunk) => {
@@ -32752,12 +32553,12 @@ var init_opencode = __esm({
32752
32553
  try {
32753
32554
  parsed = JSON.parse(line2);
32754
32555
  } catch {
32755
- log7.warn({ line: line2 }, "failed to parse NDJSON line");
32556
+ log6.warn({ line: line2 }, "failed to parse NDJSON line");
32756
32557
  continue;
32757
32558
  }
32758
32559
  const eventType = parsed.type;
32759
32560
  const part = parsed.part;
32760
- log7.debug({ eventType }, "opencode event");
32561
+ log6.debug({ eventType }, "opencode event");
32761
32562
  switch (eventType) {
32762
32563
  case "text": {
32763
32564
  const text4 = part?.text;
@@ -32793,7 +32594,7 @@ var init_opencode = __esm({
32793
32594
  const errMsg = String(
32794
32595
  parsed.message ?? parsed.error ?? part?.text ?? part?.message ?? ""
32795
32596
  );
32796
- log7.error({ event: parsed }, "opencode error event");
32597
+ log6.error({ event: parsed }, "opencode error event");
32797
32598
  yield {
32798
32599
  type: "error",
32799
32600
  message: errMsg || `OpenCode error (raw: ${JSON.stringify(parsed)})`
@@ -32805,14 +32606,14 @@ var init_opencode = __esm({
32805
32606
  lastExitCode = await exitCodePromise;
32806
32607
  lastStderr = stderrChunks.join("");
32807
32608
  if (!gotOutput && effectiveSessionId && attempt < maxAttempts) {
32808
- log7.warn(
32609
+ log6.warn(
32809
32610
  { sessionId: effectiveSessionId, exitCode: lastExitCode, stderr: lastStderr },
32810
32611
  "opencode produced no output with session ID, retrying without session"
32811
32612
  );
32812
32613
  effectiveSessionId = void 0;
32813
32614
  }
32814
32615
  } catch (err) {
32815
- log7.error({ err }, "opencode error");
32616
+ log6.error({ err }, "opencode error");
32816
32617
  child.kill();
32817
32618
  throw err;
32818
32619
  } finally {
@@ -32829,20 +32630,20 @@ var init_opencode = __esm({
32829
32630
  };
32830
32631
  }
32831
32632
  if (lastExitCode !== 0) {
32832
- log7.warn({ exitCode: lastExitCode }, "opencode process exited with non-zero code");
32633
+ log6.warn({ exitCode: lastExitCode }, "opencode process exited with non-zero code");
32833
32634
  }
32834
32635
  let resolvedSessionId = generatedSessionId;
32835
32636
  if (!sessionId) {
32836
32637
  try {
32837
32638
  const sessions = await fetchOpenCodeSessions(this.executablePath, this.workspaceDir);
32838
32639
  const sorted = sessions.sort((a6, b10) => b10.updated - a6.updated);
32839
- log7.info(
32640
+ log6.info(
32840
32641
  { placeholder: generatedSessionId, sessionCount: sessions.length },
32841
32642
  "resolving OpenCode session ID"
32842
32643
  );
32843
32644
  if (sorted.length > 0 && sorted[0].id) {
32844
32645
  resolvedSessionId = sorted[0].id;
32845
- log7.info(
32646
+ log6.info(
32846
32647
  { placeholder: generatedSessionId, resolved: resolvedSessionId },
32847
32648
  "resolved real OpenCode session ID"
32848
32649
  );
@@ -32852,13 +32653,13 @@ var init_opencode = __esm({
32852
32653
  resolvedSessionId
32853
32654
  };
32854
32655
  } else {
32855
- log7.warn(
32656
+ log6.warn(
32856
32657
  { placeholder: generatedSessionId, workspaceDir: this.workspaceDir },
32857
32658
  "could NOT resolve real OpenCode session ID \u2014 no matching sessions found"
32858
32659
  );
32859
32660
  }
32860
32661
  } catch (err) {
32861
- log7.warn({ err }, "failed to resolve real OpenCode session ID");
32662
+ log6.warn({ err }, "failed to resolve real OpenCode session ID");
32862
32663
  }
32863
32664
  }
32864
32665
  const success2 = lastExitCode === 0 && gotOutput && !spawnError;
@@ -32881,7 +32682,7 @@ var init_opencode = __esm({
32881
32682
  costUsd: 0,
32882
32683
  errors
32883
32684
  };
32884
- log7.info("opencode stream done");
32685
+ log6.info("opencode stream done");
32885
32686
  }
32886
32687
  async listSkills() {
32887
32688
  return discoverOpenCodeSkills(this.workspaceDir);
@@ -32897,13 +32698,13 @@ var init_opencode = __esm({
32897
32698
  return models;
32898
32699
  }
32899
32700
  } catch (err) {
32900
- log7.warn({ err }, "failed to fetch models from opencode CLI, using defaults");
32701
+ log6.warn({ err }, "failed to fetch models from opencode CLI, using defaults");
32901
32702
  }
32902
32703
  return DEFAULT_MODELS;
32903
32704
  }
32904
32705
  async listSessions(dir) {
32905
32706
  const sessions = await fetchOpenCodeSessions(this.executablePath, dir);
32906
- log7.info({ dir, count: sessions.length }, "listSessions");
32707
+ log6.info({ dir, count: sessions.length }, "listSessions");
32907
32708
  return sessions.map((s6) => ({
32908
32709
  sessionId: s6.id,
32909
32710
  summary: s6.title || "Untitled session",
@@ -32912,7 +32713,7 @@ var init_opencode = __esm({
32912
32713
  })).sort((a6, b10) => b10.lastModified - a6.lastModified);
32913
32714
  }
32914
32715
  async getSessionMessages(sessionId, _dir, options2) {
32915
- log7.info({ sessionId, ...options2 }, "getSessionMessages");
32716
+ log6.info({ sessionId, ...options2 }, "getSessionMessages");
32916
32717
  return fetchOpenCodeSessionMessages(this.executablePath, sessionId, options2);
32917
32718
  }
32918
32719
  };
@@ -86773,11 +86574,11 @@ var require_core = __commonJS({
86773
86574
  Ajv2.ValidationError = validation_error_1.default;
86774
86575
  Ajv2.MissingRefError = ref_error_1.default;
86775
86576
  exports.default = Ajv2;
86776
- function checkOptions(checkOpts, options2, msg, log27 = "error") {
86577
+ function checkOptions(checkOpts, options2, msg, log26 = "error") {
86777
86578
  for (const key in checkOpts) {
86778
86579
  const opt = key;
86779
86580
  if (opt in options2)
86780
- this.logger[log27](`${msg}: option ${key}. ${checkOpts[opt]}`);
86581
+ this.logger[log26](`${msg}: option ${key}. ${checkOpts[opt]}`);
86781
86582
  }
86782
86583
  }
86783
86584
  function getSchEnv(keyRef) {
@@ -108431,7 +108232,7 @@ init_src();
108431
108232
 
108432
108233
  // src/lib/agent-pool.ts
108433
108234
  import { readFileSync as readFileSync5 } from "node:fs";
108434
- import { homedir as homedir8 } from "node:os";
108235
+ import { homedir as homedir7 } from "node:os";
108435
108236
  import { join as join12 } from "node:path";
108436
108237
 
108437
108238
  // ../../packages/coding-agent/src/config.ts
@@ -108461,15 +108262,6 @@ var cursorCliConfigSchema = external_exports2.object({
108461
108262
  model: external_exports2.string().default("auto")
108462
108263
  }).default({})
108463
108264
  });
108464
- var openaiCodexConfigSchema = external_exports2.object({
108465
- type: external_exports2.literal("openai-codex"),
108466
- workspaceDir: external_exports2.string().default(process.cwd()),
108467
- maxTurns: external_exports2.number().int().positive().default(3),
108468
- options: external_exports2.object({
108469
- model: external_exports2.string().optional(),
108470
- sandboxMode: external_exports2.enum(["docker", "firecracker"]).optional()
108471
- }).default({})
108472
- });
108473
108265
  var codexConfigSchema = external_exports2.object({
108474
108266
  type: external_exports2.literal("codex"),
108475
108267
  workspaceDir: external_exports2.string().default(process.cwd()),
@@ -108500,7 +108292,6 @@ var opencodeConfigSchema = external_exports2.object({
108500
108292
  var codingAgentConfigSchema = external_exports2.discriminatedUnion("type", [
108501
108293
  claudeCodeConfigSchema,
108502
108294
  cursorCliConfigSchema,
108503
- openaiCodexConfigSchema,
108504
108295
  codexConfigSchema,
108505
108296
  geminiCliConfigSchema,
108506
108297
  opencodeConfigSchema
@@ -108517,10 +108308,6 @@ async function createCodingAgent(config2) {
108517
108308
  const { CursorCliAdapter: CursorCliAdapter2 } = await Promise.resolve().then(() => (init_cursor_cli(), cursor_cli_exports));
108518
108309
  return new CursorCliAdapter2(config2);
108519
108310
  }
108520
- case "openai-codex": {
108521
- const { OpenAICodexAdapter: OpenAICodexAdapter2 } = await Promise.resolve().then(() => (init_openai_codex(), openai_codex_exports));
108522
- return new OpenAICodexAdapter2(config2);
108523
- }
108524
108311
  case "codex": {
108525
108312
  const { CodexAdapter: CodexAdapter2 } = await Promise.resolve().then(() => (init_codex(), codex_exports));
108526
108313
  return new CodexAdapter2(config2);
@@ -108539,8 +108326,9 @@ async function createCodingAgent(config2) {
108539
108326
  }
108540
108327
 
108541
108328
  // ../../packages/coding-agent/src/install-skills.ts
108542
- import { homedir as homedir6 } from "node:os";
108543
- async function getInstallSkillsDir(type, home = homedir6()) {
108329
+ import { homedir as homedir5 } from "node:os";
108330
+ import { join as join8 } from "node:path";
108331
+ async function getInstallSkillsDir(type, home = homedir5()) {
108544
108332
  switch (type) {
108545
108333
  case "claude-code": {
108546
108334
  const { getClaudeCodeInstallSkillsDir: getClaudeCodeInstallSkillsDir2 } = await Promise.resolve().then(() => (init_claude_code(), claude_code_exports));
@@ -108550,10 +108338,6 @@ async function getInstallSkillsDir(type, home = homedir6()) {
108550
108338
  const { getCodexInstallSkillsDir: getCodexInstallSkillsDir2 } = await Promise.resolve().then(() => (init_codex(), codex_exports));
108551
108339
  return getCodexInstallSkillsDir2(home);
108552
108340
  }
108553
- case "openai-codex": {
108554
- const { getOpenAICodexInstallSkillsDir: getOpenAICodexInstallSkillsDir2 } = await Promise.resolve().then(() => (init_openai_codex(), openai_codex_exports));
108555
- return getOpenAICodexInstallSkillsDir2(home);
108556
- }
108557
108341
  case "gemini-cli": {
108558
108342
  const { getGeminiCliInstallSkillsDir: getGeminiCliInstallSkillsDir2 } = await Promise.resolve().then(() => (init_gemini_cli(), gemini_cli_exports));
108559
108343
  return getGeminiCliInstallSkillsDir2(home);
@@ -108566,28 +108350,20 @@ async function getInstallSkillsDir(type, home = homedir6()) {
108566
108350
  return null;
108567
108351
  }
108568
108352
  }
108569
- async function getDefaultAgentBinary(type) {
108353
+ function getSharedSkillsDir(home = homedir5()) {
108354
+ return join8(home, ".agents", "skills");
108355
+ }
108356
+ var SUPPORTED_AGENT_TYPES = ["claude-code", "codex", "gemini-cli", "opencode"];
108357
+ function getAgentConfigDir(type, home = homedir5()) {
108570
108358
  switch (type) {
108571
- case "claude-code": {
108572
- const { CLAUDE_CODE_DEFAULT_BINARY: CLAUDE_CODE_DEFAULT_BINARY2 } = await Promise.resolve().then(() => (init_claude_code(), claude_code_exports));
108573
- return CLAUDE_CODE_DEFAULT_BINARY2;
108574
- }
108575
- case "codex": {
108576
- const { CODEX_DEFAULT_BINARY: CODEX_DEFAULT_BINARY2 } = await Promise.resolve().then(() => (init_codex(), codex_exports));
108577
- return CODEX_DEFAULT_BINARY2;
108578
- }
108579
- case "openai-codex": {
108580
- const { OPENAI_CODEX_DEFAULT_BINARY: OPENAI_CODEX_DEFAULT_BINARY2 } = await Promise.resolve().then(() => (init_openai_codex(), openai_codex_exports));
108581
- return OPENAI_CODEX_DEFAULT_BINARY2;
108582
- }
108583
- case "gemini-cli": {
108584
- const { GEMINI_CLI_DEFAULT_BINARY: GEMINI_CLI_DEFAULT_BINARY2 } = await Promise.resolve().then(() => (init_gemini_cli(), gemini_cli_exports));
108585
- return GEMINI_CLI_DEFAULT_BINARY2;
108586
- }
108587
- case "opencode": {
108588
- const { OPENCODE_DEFAULT_BINARY: OPENCODE_DEFAULT_BINARY2 } = await Promise.resolve().then(() => (init_opencode(), opencode_exports));
108589
- return OPENCODE_DEFAULT_BINARY2;
108590
- }
108359
+ case "claude-code":
108360
+ return join8(home, ".claude");
108361
+ case "codex":
108362
+ return process.env.CODEX_HOME || join8(home, ".codex");
108363
+ case "gemini-cli":
108364
+ return join8(home, ".gemini");
108365
+ case "opencode":
108366
+ return join8(home, ".config", "opencode");
108591
108367
  default:
108592
108368
  return null;
108593
108369
  }
@@ -108599,7 +108375,7 @@ init_src();
108599
108375
  // src/lib/state.ts
108600
108376
  import { randomBytes } from "node:crypto";
108601
108377
  import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync } from "node:fs";
108602
- import { homedir as homedir7 } from "node:os";
108378
+ import { homedir as homedir6 } from "node:os";
108603
108379
  import { dirname, join as join11 } from "node:path";
108604
108380
 
108605
108381
  // ../../node_modules/.pnpm/@radix-ui+react-visually-hidden@1.2.3_@types+react-dom@19.2.3_@types+react@19.2.14__@ty_fa89646d7248b32d1762bf88948f6339/node_modules/@radix-ui/react-visually-hidden/dist/index.mjs
@@ -120627,22 +120403,25 @@ var isElectron = typeof window !== "undefined" && "__BAND_DESKTOP__" in window;
120627
120403
 
120628
120404
  // ../../packages/dashboard-core/src/components/DiffView.tsx
120629
120405
  init_dist4();
120630
- var import_react29 = __toESM(require_react(), 1);
120406
+ var import_react30 = __toESM(require_react(), 1);
120631
120407
 
120632
- // ../../packages/dashboard-core/src/hooks/use-search.ts
120408
+ // ../../packages/dashboard-core/src/hooks/use-diff-target.ts
120633
120409
  var import_react25 = __toESM(require_react(), 1);
120634
120410
 
120411
+ // ../../packages/dashboard-core/src/hooks/use-search.ts
120412
+ var import_react26 = __toESM(require_react(), 1);
120413
+
120635
120414
  // ../../packages/dashboard-core/src/components/ChangesFileTree.tsx
120636
- var import_react27 = __toESM(require_react(), 1);
120415
+ var import_react28 = __toESM(require_react(), 1);
120637
120416
 
120638
120417
  // ../../packages/dashboard-core/src/hooks/use-deferred-menu-action.ts
120639
- var import_react26 = __toESM(require_react(), 1);
120418
+ var import_react27 = __toESM(require_react(), 1);
120640
120419
  function useDeferredMenuAction() {
120641
- const pendingRef = (0, import_react26.useRef)(null);
120642
- const queue = (0, import_react26.useCallback)((fn) => {
120420
+ const pendingRef = (0, import_react27.useRef)(null);
120421
+ const queue = (0, import_react27.useCallback)((fn) => {
120643
120422
  pendingRef.current = fn;
120644
120423
  }, []);
120645
- const flush = (0, import_react26.useCallback)((e2) => {
120424
+ const flush = (0, import_react27.useCallback)((e2) => {
120646
120425
  e2.preventDefault();
120647
120426
  const fn = pendingRef.current;
120648
120427
  pendingRef.current = null;
@@ -120801,7 +120580,7 @@ var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
120801
120580
 
120802
120581
  // ../../packages/dashboard-core/src/components/SearchBar.tsx
120803
120582
  var import_lucide_react7 = __toESM(require_lucide_react(), 1);
120804
- var import_react28 = __toESM(require_react(), 1);
120583
+ var import_react29 = __toESM(require_react(), 1);
120805
120584
  var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
120806
120585
  var DEFAULT_VISIBLE_OPTIONS = ["caseSensitive", "wholeWord", "regex"];
120807
120586
  function ToggleButton({
@@ -120821,7 +120600,7 @@ function ToggleButton({
120821
120600
  }
120822
120601
  );
120823
120602
  }
120824
- var SearchBar = (0, import_react28.forwardRef)(function SearchBar2({
120603
+ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
120825
120604
  query,
120826
120605
  onQueryChange,
120827
120606
  options: options2,
@@ -120837,18 +120616,18 @@ var SearchBar = (0, import_react28.forwardRef)(function SearchBar2({
120837
120616
  const showCase = visibleOptions.includes("caseSensitive");
120838
120617
  const showWholeWord = visibleOptions.includes("wholeWord");
120839
120618
  const showRegex = visibleOptions.includes("regex");
120840
- const inputRef = (0, import_react28.useRef)(null);
120841
- (0, import_react28.useImperativeHandle)(ref, () => ({
120619
+ const inputRef = (0, import_react29.useRef)(null);
120620
+ (0, import_react29.useImperativeHandle)(ref, () => ({
120842
120621
  focus: () => inputRef.current?.focus(),
120843
120622
  select: () => inputRef.current?.select()
120844
120623
  }));
120845
- const toggleCase = (0, import_react28.useCallback)(() => {
120624
+ const toggleCase = (0, import_react29.useCallback)(() => {
120846
120625
  onOptionsChange({ ...options2, caseSensitive: !options2.caseSensitive });
120847
120626
  }, [options2, onOptionsChange]);
120848
- const toggleWholeWord = (0, import_react28.useCallback)(() => {
120627
+ const toggleWholeWord = (0, import_react29.useCallback)(() => {
120849
120628
  onOptionsChange({ ...options2, wholeWord: !options2.wholeWord });
120850
120629
  }, [options2, onOptionsChange]);
120851
- const toggleRegex = (0, import_react28.useCallback)(() => {
120630
+ const toggleRegex = (0, import_react29.useCallback)(() => {
120852
120631
  onOptionsChange({ ...options2, regex: !options2.regex });
120853
120632
  }, [options2, onOptionsChange]);
120854
120633
  return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
@@ -120971,7 +120750,7 @@ var diffTheme = EditorView.theme({
120971
120750
 
120972
120751
  // ../../packages/dashboard-core/src/components/FileBrowser.tsx
120973
120752
  var import_lucide_react8 = __toESM(require_lucide_react(), 1);
120974
- var import_react30 = __toESM(require_react(), 1);
120753
+ var import_react31 = __toESM(require_react(), 1);
120975
120754
  var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
120976
120755
  var expandedStateCache = /* @__PURE__ */ new Map();
120977
120756
  var dirContentsCache = /* @__PURE__ */ new Map();
@@ -121001,11 +120780,11 @@ function EntryNameInput({
121001
120780
  onSubmit,
121002
120781
  onCancel
121003
120782
  }) {
121004
- const [value, setValue] = (0, import_react30.useState)(initialValue);
121005
- const [submitting, setSubmitting] = (0, import_react30.useState)(false);
121006
- const [error40, setError] = (0, import_react30.useState)(null);
121007
- const inputRef = (0, import_react30.useRef)(null);
121008
- (0, import_react30.useEffect)(() => {
120783
+ const [value, setValue] = (0, import_react31.useState)(initialValue);
120784
+ const [submitting, setSubmitting] = (0, import_react31.useState)(false);
120785
+ const [error40, setError] = (0, import_react31.useState)(null);
120786
+ const inputRef = (0, import_react31.useRef)(null);
120787
+ (0, import_react31.useEffect)(() => {
121009
120788
  const el = inputRef.current;
121010
120789
  if (!el) return;
121011
120790
  el.focus();
@@ -121388,7 +121167,7 @@ function TreeNode2({
121388
121167
  })()
121389
121168
  ] });
121390
121169
  }
121391
- var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121170
+ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
121392
121171
  workspaceId,
121393
121172
  onOpenFile,
121394
121173
  onOpenFilePinned,
@@ -121398,23 +121177,23 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121398
121177
  onPathDeleted
121399
121178
  }, handleRef) {
121400
121179
  const adapter = useAdapter();
121401
- const [expandedPaths, setExpandedPaths] = (0, import_react30.useState)(
121180
+ const [expandedPaths, setExpandedPaths] = (0, import_react31.useState)(
121402
121181
  () => new Set(getCachedExpanded(workspaceId))
121403
121182
  );
121404
- const [dirContents, setDirContents] = (0, import_react30.useState)(
121183
+ const [dirContents, setDirContents] = (0, import_react31.useState)(
121405
121184
  () => new Map(getCachedContents(workspaceId))
121406
121185
  );
121407
- const [loadingPaths, setLoadingPaths] = (0, import_react30.useState)(/* @__PURE__ */ new Set());
121408
- const [newEntry, setNewEntry] = (0, import_react30.useState)(null);
121409
- const [pendingDelete, setPendingDelete] = (0, import_react30.useState)(null);
121410
- const [deleteError, setDeleteError] = (0, import_react30.useState)(null);
121411
- const [deleteSubmitting, setDeleteSubmitting] = (0, import_react30.useState)(false);
121412
- const [renamingPath, setRenamingPath] = (0, import_react30.useState)(null);
121413
- const [clipboard, setClipboard] = (0, import_react30.useState)(null);
121414
- const [treeSelection, setTreeSelection] = (0, import_react30.useState)(() => selectedFile ? { path: selectedFile, kind: "file" } : null);
121415
- const selectedRef = (0, import_react30.useRef)(null);
121416
- const prevWorkspaceRef = (0, import_react30.useRef)(workspaceId);
121417
- (0, import_react30.useEffect)(() => {
121186
+ const [loadingPaths, setLoadingPaths] = (0, import_react31.useState)(/* @__PURE__ */ new Set());
121187
+ const [newEntry, setNewEntry] = (0, import_react31.useState)(null);
121188
+ const [pendingDelete, setPendingDelete] = (0, import_react31.useState)(null);
121189
+ const [deleteError, setDeleteError] = (0, import_react31.useState)(null);
121190
+ const [deleteSubmitting, setDeleteSubmitting] = (0, import_react31.useState)(false);
121191
+ const [renamingPath, setRenamingPath] = (0, import_react31.useState)(null);
121192
+ const [clipboard, setClipboard] = (0, import_react31.useState)(null);
121193
+ const [treeSelection, setTreeSelection] = (0, import_react31.useState)(() => selectedFile ? { path: selectedFile, kind: "file" } : null);
121194
+ const selectedRef = (0, import_react31.useRef)(null);
121195
+ const prevWorkspaceRef = (0, import_react31.useRef)(workspaceId);
121196
+ (0, import_react31.useEffect)(() => {
121418
121197
  if (prevWorkspaceRef.current !== workspaceId) {
121419
121198
  prevWorkspaceRef.current = workspaceId;
121420
121199
  setExpandedPaths(new Set(getCachedExpanded(workspaceId)));
@@ -121429,18 +121208,18 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121429
121208
  setClipboard(null);
121430
121209
  }
121431
121210
  }, [workspaceId]);
121432
- (0, import_react30.useEffect)(() => {
121211
+ (0, import_react31.useEffect)(() => {
121433
121212
  if (selectedFile) {
121434
121213
  setTreeSelection({ path: selectedFile, kind: "file" });
121435
121214
  }
121436
121215
  }, [selectedFile]);
121437
- const handleSelectRow = (0, import_react30.useCallback)((path3, kind) => {
121216
+ const handleSelectRow = (0, import_react31.useCallback)((path3, kind) => {
121438
121217
  setTreeSelection({ path: path3, kind });
121439
121218
  }, []);
121440
- const clearTreeSelection = (0, import_react30.useCallback)(() => {
121219
+ const clearTreeSelection = (0, import_react31.useCallback)(() => {
121441
121220
  setTreeSelection(null);
121442
121221
  }, []);
121443
- const fetchDir = (0, import_react30.useCallback)(
121222
+ const fetchDir = (0, import_react31.useCallback)(
121444
121223
  async (dirPath, opts) => {
121445
121224
  if (!adapter.listWorkspaceFiles) return;
121446
121225
  const cache = getCachedContents(workspaceId);
@@ -121464,10 +121243,10 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121464
121243
  },
121465
121244
  [adapter, workspaceId]
121466
121245
  );
121467
- (0, import_react30.useEffect)(() => {
121246
+ (0, import_react31.useEffect)(() => {
121468
121247
  fetchDir("");
121469
121248
  }, [fetchDir]);
121470
- (0, import_react30.useEffect)(() => {
121249
+ (0, import_react31.useEffect)(() => {
121471
121250
  if (!adapter.subscribeFileChanges) return;
121472
121251
  const unsubscribe = adapter.subscribeFileChanges(workspaceId, (changedPath) => {
121473
121252
  const cache = getCachedContents(workspaceId);
@@ -121476,8 +121255,8 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121476
121255
  });
121477
121256
  return unsubscribe;
121478
121257
  }, [adapter, workspaceId, fetchDir]);
121479
- const prevSelectedRef = (0, import_react30.useRef)(void 0);
121480
- (0, import_react30.useEffect)(() => {
121258
+ const prevSelectedRef = (0, import_react31.useRef)(void 0);
121259
+ (0, import_react31.useEffect)(() => {
121481
121260
  if (!selectedFile || selectedFile === prevSelectedRef.current) {
121482
121261
  prevSelectedRef.current = selectedFile;
121483
121262
  return;
@@ -121504,7 +121283,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121504
121283
  fetchDir(dir);
121505
121284
  }
121506
121285
  }, [selectedFile, workspaceId, fetchDir]);
121507
- (0, import_react30.useEffect)(() => {
121286
+ (0, import_react31.useEffect)(() => {
121508
121287
  if (selectedFile && selectedRef.current) {
121509
121288
  const timer = setTimeout(() => {
121510
121289
  selectedRef.current?.scrollIntoView({ block: "nearest" });
@@ -121512,7 +121291,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121512
121291
  return () => clearTimeout(timer);
121513
121292
  }
121514
121293
  }, [selectedFile, dirContents]);
121515
- const toggleExpand = (0, import_react30.useCallback)(
121294
+ const toggleExpand = (0, import_react31.useCallback)(
121516
121295
  (dirPath) => {
121517
121296
  setExpandedPaths((prev) => {
121518
121297
  const next = new Set(prev);
@@ -121528,7 +121307,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121528
121307
  },
121529
121308
  [workspaceId, fetchDir]
121530
121309
  );
121531
- const ensureDirExpanded = (0, import_react30.useCallback)(
121310
+ const ensureDirExpanded = (0, import_react31.useCallback)(
121532
121311
  async (dirPath) => {
121533
121312
  const cached2 = getCachedExpanded(workspaceId);
121534
121313
  if (!cached2.has(dirPath)) {
@@ -121540,17 +121319,17 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121540
121319
  },
121541
121320
  [workspaceId, fetchDir]
121542
121321
  );
121543
- const requestNewEntry = (0, import_react30.useCallback)(
121322
+ const requestNewEntry = (0, import_react31.useCallback)(
121544
121323
  (parentPath, kind) => {
121545
121324
  void ensureDirExpanded(parentPath);
121546
121325
  setNewEntry({ parentPath, kind });
121547
121326
  },
121548
121327
  [ensureDirExpanded]
121549
121328
  );
121550
- const cancelNewEntry = (0, import_react30.useCallback)(() => {
121329
+ const cancelNewEntry = (0, import_react31.useCallback)(() => {
121551
121330
  setNewEntry(null);
121552
121331
  }, []);
121553
- const submitNewEntry = (0, import_react30.useCallback)(
121332
+ const submitNewEntry = (0, import_react31.useCallback)(
121554
121333
  async (name24) => {
121555
121334
  if (!newEntry) return;
121556
121335
  const fullPath = newEntry.parentPath ? `${newEntry.parentPath}/${name24}` : name24;
@@ -121583,16 +121362,16 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121583
121362
  [adapter, newEntry, fetchDir, onOpenFile, workspaceId]
121584
121363
  );
121585
121364
  const canDelete = Boolean(adapter.deleteWorkspacePath);
121586
- const requestDelete = (0, import_react30.useCallback)((path3, kind) => {
121365
+ const requestDelete = (0, import_react31.useCallback)((path3, kind) => {
121587
121366
  setDeleteError(null);
121588
121367
  setPendingDelete({ path: path3, kind });
121589
121368
  }, []);
121590
- const cancelDelete = (0, import_react30.useCallback)(() => {
121369
+ const cancelDelete = (0, import_react31.useCallback)(() => {
121591
121370
  if (deleteSubmitting) return;
121592
121371
  setPendingDelete(null);
121593
121372
  setDeleteError(null);
121594
121373
  }, [deleteSubmitting]);
121595
- const confirmDelete = (0, import_react30.useCallback)(async () => {
121374
+ const confirmDelete = (0, import_react31.useCallback)(async () => {
121596
121375
  if (!pendingDelete || !adapter.deleteWorkspacePath) return;
121597
121376
  setDeleteSubmitting(true);
121598
121377
  setDeleteError(null);
@@ -121638,13 +121417,13 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121638
121417
  }
121639
121418
  }, [adapter, pendingDelete, fetchDir, workspaceId, onPathDeleted]);
121640
121419
  const canRename = Boolean(adapter.renameWorkspacePath);
121641
- const requestRename = (0, import_react30.useCallback)((path3) => {
121420
+ const requestRename = (0, import_react31.useCallback)((path3) => {
121642
121421
  setRenamingPath(path3);
121643
121422
  }, []);
121644
- const cancelRename = (0, import_react30.useCallback)(() => {
121423
+ const cancelRename = (0, import_react31.useCallback)(() => {
121645
121424
  setRenamingPath(null);
121646
121425
  }, []);
121647
- const submitRename = (0, import_react30.useCallback)(
121426
+ const submitRename = (0, import_react31.useCallback)(
121648
121427
  async (newName) => {
121649
121428
  if (renamingPath == null || !adapter.renameWorkspacePath) return;
121650
121429
  const oldPath = renamingPath;
@@ -121700,7 +121479,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121700
121479
  },
121701
121480
  [adapter, renamingPath, fetchDir, onPathRenamed, workspaceId]
121702
121481
  );
121703
- const resolveDefaultTarget = (0, import_react30.useCallback)(() => {
121482
+ const resolveDefaultTarget = (0, import_react31.useCallback)(() => {
121704
121483
  if (treeSelection?.kind === "directory") return treeSelection.path;
121705
121484
  if (treeSelection?.kind === "file") {
121706
121485
  const idx = treeSelection.path.lastIndexOf("/");
@@ -121713,13 +121492,13 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121713
121492
  const canPaste = Boolean(
121714
121493
  clipboard && (clipboard.op === "copy" && adapter.copyWorkspacePath || clipboard.op === "cut" && adapter.renameWorkspacePath)
121715
121494
  );
121716
- const cutPath = (0, import_react30.useCallback)((path3, kind) => {
121495
+ const cutPath = (0, import_react31.useCallback)((path3, kind) => {
121717
121496
  setClipboard({ path: path3, kind, op: "cut" });
121718
121497
  }, []);
121719
- const copyPath = (0, import_react30.useCallback)((path3, kind) => {
121498
+ const copyPath = (0, import_react31.useCallback)((path3, kind) => {
121720
121499
  setClipboard({ path: path3, kind, op: "copy" });
121721
121500
  }, []);
121722
- const uniqueCopyName = (0, import_react30.useCallback)(
121501
+ const uniqueCopyName = (0, import_react31.useCallback)(
121723
121502
  (baseName, destFolder, kind) => {
121724
121503
  const siblings = new Set(
121725
121504
  (getCachedContents(workspaceId).get(destFolder) ?? []).map((e2) => e2.name)
@@ -121737,7 +121516,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121737
121516
  },
121738
121517
  [workspaceId]
121739
121518
  );
121740
- const pasteInto = (0, import_react30.useCallback)(
121519
+ const pasteInto = (0, import_react31.useCallback)(
121741
121520
  async (destFolder) => {
121742
121521
  if (!clipboard) return;
121743
121522
  const sourcePath = clipboard.path;
@@ -121801,7 +121580,7 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121801
121580
  },
121802
121581
  [adapter, clipboard, fetchDir, onPathRenamed, uniqueCopyName, workspaceId]
121803
121582
  );
121804
- (0, import_react30.useImperativeHandle)(
121583
+ (0, import_react31.useImperativeHandle)(
121805
121584
  handleRef,
121806
121585
  () => ({
121807
121586
  startNewFile(parentPath) {
@@ -121997,10 +121776,10 @@ var FileBrowser = (0, import_react30.forwardRef)(function FileBrowser2({
121997
121776
  });
121998
121777
 
121999
121778
  // ../../packages/dashboard-core/src/components/FileViewer.tsx
122000
- var import_react32 = __toESM(require_react(), 1);
121779
+ var import_react33 = __toESM(require_react(), 1);
122001
121780
 
122002
121781
  // ../../packages/dashboard-core/src/components/ImagePreview.tsx
122003
- var import_react31 = __toESM(require_react(), 1);
121782
+ var import_react32 = __toESM(require_react(), 1);
122004
121783
  var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
122005
121784
 
122006
121785
  // ../../packages/dashboard-core/src/components/PdfPreview.tsx
@@ -122010,22 +121789,22 @@ var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
122010
121789
  var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
122011
121790
 
122012
121791
  // ../../packages/dashboard-core/src/components/QuickOpenDialog.tsx
122013
- var import_react33 = __toESM(require_react(), 1);
121792
+ var import_react34 = __toESM(require_react(), 1);
122014
121793
  var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
122015
121794
 
122016
121795
  // ../../packages/dashboard-core/src/components/SearchFilesDialog.tsx
122017
- var import_react34 = __toESM(require_react(), 1);
121796
+ var import_react35 = __toESM(require_react(), 1);
122018
121797
  var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
122019
121798
 
122020
121799
  // ../../packages/dashboard-core/src/components/WorkspacePickerDialog.tsx
122021
- var import_react35 = __toESM(require_react(), 1);
121800
+ var import_react36 = __toESM(require_react(), 1);
122022
121801
  var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
122023
121802
 
122024
121803
  // ../../packages/dashboard-core/src/components/WorkspaceTabNav.tsx
122025
121804
  var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
122026
121805
 
122027
121806
  // ../../packages/dashboard-core/src/hooks/use-editor-history.ts
122028
- var import_react36 = __toESM(require_react(), 1);
121807
+ var import_react37 = __toESM(require_react(), 1);
122029
121808
 
122030
121809
  // ../../node_modules/.pnpm/marked@15.0.12/node_modules/marked/lib/marked.esm.js
122031
121810
  function _getDefaults() {
@@ -131947,7 +131726,7 @@ function closeDb() {
131947
131726
  // src/lib/state.ts
131948
131727
  function bandHome() {
131949
131728
  if (process.env.BAND_HOME) return process.env.BAND_HOME;
131950
- return join11(homedir7(), ".band");
131729
+ return join11(homedir6(), ".band");
131951
131730
  }
131952
131731
  function loadState() {
131953
131732
  const db2 = getDb();
@@ -132145,7 +131924,7 @@ function deleteBranchStatus(workspaceId) {
132145
131924
  }
132146
131925
 
132147
131926
  // src/lib/agent-pool.ts
132148
- var log8 = createLogger("agent-pool");
131927
+ var log7 = createLogger("agent-pool");
132149
131928
  var POOL_KEY = Symbol.for("band.agent-pool.v2");
132150
131929
  var PENDING_KEY = Symbol.for("band.agent-pool.pending");
132151
131930
  var g2 = globalThis;
@@ -132155,7 +131934,7 @@ var pool = g2[POOL_KEY];
132155
131934
  var pending = g2[PENDING_KEY];
132156
131935
  function loadClaudeSettingsModel() {
132157
131936
  try {
132158
- const data = readFileSync5(join12(homedir8(), ".claude", "settings.json"), "utf-8");
131937
+ const data = readFileSync5(join12(homedir7(), ".claude", "settings.json"), "utf-8");
132159
131938
  const parsed = JSON.parse(data);
132160
131939
  return typeof parsed.model === "string" ? parsed.model : void 0;
132161
131940
  } catch {
@@ -132190,7 +131969,7 @@ function getAgent(chatId) {
132190
131969
  return pool.get(chatId)?.agent;
132191
131970
  }
132192
131971
  function removeAgent(chatId) {
132193
- log8.info({ chatId }, "removing agent from pool");
131972
+ log7.info({ chatId }, "removing agent from pool");
132194
131973
  return pool.delete(chatId);
132195
131974
  }
132196
131975
  async function getOrCreateAgent(chatId, worktreePath, agentId) {
@@ -132198,7 +131977,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
132198
131977
  if (existing) {
132199
131978
  const requestedDefId = resolveAgentDefId(agentId);
132200
131979
  if (existing.agentDefId !== requestedDefId) {
132201
- log8.info(
131980
+ log7.info(
132202
131981
  { chatId, cached: existing.agentDefId, requested: requestedDefId },
132203
131982
  "cached agent definition mismatch, replacing"
132204
131983
  );
@@ -132212,7 +131991,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
132212
131991
  return inFlight.promise;
132213
131992
  }
132214
131993
  const config2 = getAgentConfig(worktreePath, agentId);
132215
- log8.info({ chatId, type: config2.type, defId, cwd: worktreePath }, "creating agent");
131994
+ log7.info({ chatId, type: config2.type, defId, cwd: worktreePath }, "creating agent");
132216
131995
  const promise2 = createCodingAgent(config2).then(
132217
131996
  (agent) => {
132218
131997
  pool.set(chatId, { agent, agentDefId: defId });
@@ -133185,7 +132964,7 @@ function subscribe(listener) {
133185
132964
  }
133186
132965
 
133187
132966
  // src/lib/chat-manager.ts
133188
- var log9 = createLogger("chat-manager");
132967
+ var log8 = createLogger("chat-manager");
133189
132968
  var PANEL_TYPE = "chat";
133190
132969
  var chatSessions = /* @__PURE__ */ new Map();
133191
132970
  var workspaceChats = /* @__PURE__ */ new Map();
@@ -133256,7 +133035,7 @@ function createChat(workspaceId, options2) {
133256
133035
  addToIndex(session);
133257
133036
  addChatToLayout(workspaceId, session.id, { title: session.name });
133258
133037
  emit({ kind: "chat-created", workspaceId, chatId: session.id });
133259
- log9.info({ chatId: session.id, workspaceId, agent: session.agent }, "chat pane created");
133038
+ log8.info({ chatId: session.id, workspaceId, agent: session.agent }, "chat pane created");
133260
133039
  return session;
133261
133040
  }
133262
133041
  function getChat(chatId) {
@@ -133285,7 +133064,7 @@ function updateChat(chatId, updates) {
133285
133064
  state: serializeState(session),
133286
133065
  updatedAt: Date.now()
133287
133066
  });
133288
- log9.info({ chatId, updates }, "chat pane updated");
133067
+ log8.info({ chatId, updates }, "chat pane updated");
133289
133068
  return session;
133290
133069
  }
133291
133070
  function updateChatStatus(chatId, status) {
@@ -133337,7 +133116,7 @@ function removeChat(chatId) {
133337
133116
  removeChatFromLayout(session.workspaceId, chatId);
133338
133117
  removeFromIndex(chatId);
133339
133118
  emit({ kind: "chat-removed", workspaceId: session.workspaceId, chatId });
133340
- log9.info({ chatId, workspaceId: session.workspaceId }, "chat pane removed");
133119
+ log8.info({ chatId, workspaceId: session.workspaceId }, "chat pane removed");
133341
133120
  return true;
133342
133121
  }
133343
133122
  function removeWorkspaceChats(workspaceId) {
@@ -133349,7 +133128,7 @@ function removeWorkspaceChats(workspaceId) {
133349
133128
  }
133350
133129
  deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE);
133351
133130
  workspaceChats.delete(workspaceId);
133352
- log9.info({ workspaceId }, "all chat panes removed for workspace");
133131
+ log8.info({ workspaceId }, "all chat panes removed for workspace");
133353
133132
  }
133354
133133
  function loadChatsFromDb() {
133355
133134
  _initialized = true;
@@ -133377,7 +133156,7 @@ function loadChatsFromDb() {
133377
133156
  addToIndex(session);
133378
133157
  }
133379
133158
  if (rows.length > 0) {
133380
- log9.info({ count: rows.length }, "loaded chat panes from database");
133159
+ log8.info({ count: rows.length }, "loaded chat panes from database");
133381
133160
  }
133382
133161
  return rows.length;
133383
133162
  }
@@ -133557,7 +133336,7 @@ function hasPendingInputForWorkspace(workspaceId) {
133557
133336
 
133558
133337
  // src/lib/task-store.ts
133559
133338
  init_src();
133560
- var log10 = createLogger("task-store");
133339
+ var log9 = createLogger("task-store");
133561
133340
  function generateTaskId() {
133562
133341
  return `tsk_${Date.now()}`;
133563
133342
  }
@@ -133630,10 +133409,72 @@ function cleanupStaleTasks() {
133630
133409
  const result = db2.update(tasks).set({ status: "failed", completedAt: now }).where(eq2(tasks.status, "running")).run();
133631
133410
  const count3 = result.changes;
133632
133411
  if (count3 > 0) {
133633
- log10.info({ count: count3 }, "cleaned up stale tasks on startup");
133412
+ log9.info({ count: count3 }, "cleaned up stale tasks on startup");
133413
+ }
133414
+ return count3;
133415
+ }
133416
+ function deleteWorkspaceTasks(workspaceId) {
133417
+ const db2 = getDb();
133418
+ const result = db2.delete(tasks).where(eq2(tasks.workspaceId, workspaceId)).run();
133419
+ return result.changes;
133420
+ }
133421
+ function deleteTasksOlderThan(cutoffMs) {
133422
+ const db2 = getDb();
133423
+ const result = db2.delete(tasks).where(
133424
+ or(
133425
+ and(isNull(tasks.completedAt), lt(tasks.startedAt, cutoffMs)),
133426
+ // The explicit `isNotNull` guard is technically redundant — SQLite
133427
+ // treats `NULL < cutoffMs` as NULL (falsy) in a WHERE predicate, so
133428
+ // null-`completedAt` rows would be skipped here regardless. We keep
133429
+ // it so the intent is obvious without leaning on SQLite NULL
133430
+ // semantics, and so the query stays correct under a future Drizzle
133431
+ // or backend swap.
133432
+ and(isNotNull2(tasks.completedAt), lt(tasks.completedAt, cutoffMs))
133433
+ )
133434
+ ).run();
133435
+ return result.changes;
133436
+ }
133437
+ var TASK_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
133438
+ var TASK_PRUNE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
133439
+ var PRUNE_SCHEDULER_KEY = Symbol.for("band.task-prune-scheduler");
133440
+ var pruneG = globalThis;
133441
+ if (!pruneG[PRUNE_SCHEDULER_KEY]) {
133442
+ pruneG[PRUNE_SCHEDULER_KEY] = { timer: null };
133443
+ }
133444
+ var pruneState = pruneG[PRUNE_SCHEDULER_KEY];
133445
+ function pruneOldTasks(retentionMs = TASK_RETENTION_MS) {
133446
+ const cutoff = Date.now() - retentionMs;
133447
+ const count3 = deleteTasksOlderThan(cutoff);
133448
+ if (count3 > 0) {
133449
+ log9.info({ count: count3, retentionMs }, "pruned tasks older than retention window");
133634
133450
  }
133635
133451
  return count3;
133636
133452
  }
133453
+ function startTaskPruneScheduler(options2 = {}) {
133454
+ if (pruneState.timer) return;
133455
+ const retentionMs = options2.retentionMs ?? TASK_RETENTION_MS;
133456
+ const intervalMs = options2.intervalMs ?? TASK_PRUNE_INTERVAL_MS;
133457
+ try {
133458
+ pruneOldTasks(retentionMs);
133459
+ } catch (err) {
133460
+ log9.error({ err }, "initial task prune on boot failed");
133461
+ }
133462
+ const timer = setInterval(() => {
133463
+ try {
133464
+ pruneOldTasks(retentionMs);
133465
+ } catch (err) {
133466
+ log9.error({ err }, "scheduled task prune failed");
133467
+ }
133468
+ }, intervalMs);
133469
+ timer.unref();
133470
+ pruneState.timer = timer;
133471
+ }
133472
+ function stopTaskPruneScheduler() {
133473
+ if (pruneState.timer) {
133474
+ clearInterval(pruneState.timer);
133475
+ pruneState.timer = null;
133476
+ }
133477
+ }
133637
133478
  function markTaskFailed(id) {
133638
133479
  const task = loadTask(id);
133639
133480
  if (!task || task.status !== "running") return null;
@@ -133709,7 +133550,7 @@ function resolveWorkspace(workspaceId) {
133709
133550
  }
133710
133551
 
133711
133552
  // src/lib/task-runner.ts
133712
- var log11 = createLogger("task-runner");
133553
+ var log10 = createLogger("task-runner");
133713
133554
  function listFiles(dir) {
133714
133555
  try {
133715
133556
  return new Set(readdirSync6(dir));
@@ -133768,7 +133609,7 @@ function persistTask(task) {
133768
133609
  chatId: task.chatId
133769
133610
  });
133770
133611
  } catch (err) {
133771
- log11.warn({ err, taskId: task.taskRecordId }, "failed to persist task");
133612
+ log10.warn({ err, taskId: task.taskRecordId }, "failed to persist task");
133772
133613
  }
133773
133614
  }
133774
133615
  function broadcast(chatId, chunk) {
@@ -133792,7 +133633,7 @@ function broadcast(chatId, chunk) {
133792
133633
  }
133793
133634
  const subs = listeners2.get(chatId);
133794
133635
  if (!subs || subs.size === 0) {
133795
- log11.warn({ chatId, chunkType: chunk.type }, "broadcast: no listeners");
133636
+ log10.warn({ chatId, chunkType: chunk.type }, "broadcast: no listeners");
133796
133637
  return;
133797
133638
  }
133798
133639
  for (const listener of subs) {
@@ -133843,7 +133684,7 @@ function submitTask(options2) {
133843
133684
  tasks2.set(chatId, task);
133844
133685
  persistTask(task);
133845
133686
  runTask(chatId, task).catch((err) => {
133846
- log11.error({ chatId, err }, "task execution failed");
133687
+ log10.error({ chatId, err }, "task execution failed");
133847
133688
  if (task.status === "running") {
133848
133689
  task.status = "failed";
133849
133690
  task.completedAt = Date.now();
@@ -133877,7 +133718,7 @@ function abortTask(chatId) {
133877
133718
  updateChatStatus(chatId, "idle");
133878
133719
  const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
133879
133720
  emit({ kind: "update", status: updated });
133880
- log11.info({ chatId }, "task aborted by user");
133721
+ log10.info({ chatId }, "task aborted by user");
133881
133722
  return true;
133882
133723
  }
133883
133724
  function cancelTask(taskId) {
@@ -133897,7 +133738,7 @@ function cancelTask(taskId) {
133897
133738
  updateChatStatus(chatId, "idle");
133898
133739
  const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
133899
133740
  emit({ kind: "update", status: updated });
133900
- log11.info({ chatId, taskId }, "task cancelled (was running in-memory)");
133741
+ log10.info({ chatId, taskId }, "task cancelled (was running in-memory)");
133901
133742
  return { cancelled: true, workspaceId: task.workspaceId };
133902
133743
  }
133903
133744
  }
@@ -133905,7 +133746,7 @@ function cancelTask(taskId) {
133905
133746
  if (record2) {
133906
133747
  const updated = upsertWorkspaceStatus(record2.workspaceId, { status: "waiting" });
133907
133748
  emit({ kind: "update", status: updated });
133908
- log11.info({ taskId, workspaceId: record2.workspaceId }, "orphaned task cancelled");
133749
+ log10.info({ taskId, workspaceId: record2.workspaceId }, "orphaned task cancelled");
133909
133750
  return { cancelled: true, workspaceId: record2.workspaceId };
133910
133751
  }
133911
133752
  return { cancelled: false };
@@ -133925,7 +133766,7 @@ async function runTask(chatId, task) {
133925
133766
  const taskAgentId = task.codingAgentId;
133926
133767
  const resolvedAgentId = taskAgentId ?? chatSession?.agent;
133927
133768
  const needsReplace = taskAgentId && taskAgentId !== chatSession?.agent;
133928
- log11.info(
133769
+ log10.info(
133929
133770
  { chatId, taskAgentId, chatAgent: chatSession?.agent, resolvedAgentId, needsReplace },
133930
133771
  "resolving agent for task"
133931
133772
  );
@@ -133974,7 +133815,7 @@ async function runTask(chatId, task) {
133974
133815
  [File sharing: to send a file to the user, write or copy it to ${sharedDir}/ and it will appear as a downloadable file card in the chat.]`;
133975
133816
  const effectivePrompt = task.sessionId ? task.agentPrompt : task.agentPrompt + fileSharingHint;
133976
133817
  for await (const event of agent.runSession(effectivePrompt, task.sessionId, sessionOptions)) {
133977
- log11.info({ chatId, eventType: event.type }, "task event");
133818
+ log10.info({ chatId, eventType: event.type }, "task event");
133978
133819
  switch (event.type) {
133979
133820
  case "session-start": {
133980
133821
  task.sessionId = event.sessionId;
@@ -134155,7 +133996,7 @@ async function runTask(chatId, task) {
134155
133996
  break;
134156
133997
  }
134157
133998
  case "session-id-resolved": {
134158
- log11.info(
133999
+ log10.info(
134159
134000
  { chatId, previous: event.previousSessionId, resolved: event.resolvedSessionId },
134160
134001
  "session ID resolved"
134161
134002
  );
@@ -134250,7 +134091,7 @@ ${queued.text}`;
134250
134091
  });
134251
134092
  autoStarted = true;
134252
134093
  } catch (err) {
134253
- log11.warn({ chatId, err }, "failed to auto-start queued task");
134094
+ log10.warn({ chatId, err }, "failed to auto-start queued task");
134254
134095
  }
134255
134096
  }
134256
134097
  }
@@ -134350,7 +134191,7 @@ function getSessionEventsAfter(sessionId, afterEventId) {
134350
134191
  }
134351
134192
 
134352
134193
  // src/api/task-stream.ts
134353
- var log12 = createLogger("task-stream");
134194
+ var log11 = createLogger("task-stream");
134354
134195
  var INTERNAL_CHUNK_TYPES = /* @__PURE__ */ new Set(["user-message"]);
134355
134196
  function toUIChunk(chunk) {
134356
134197
  if (INTERNAL_CHUNK_TYPES.has(chunk.type)) return null;
@@ -134405,7 +134246,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
134405
134246
  const buf = getSessionBuffer(task.sessionId);
134406
134247
  if (buf && buf.events.length > 0) {
134407
134248
  const taskStartEventId = task.firstEventId ?? Number.POSITIVE_INFINITY;
134408
- log12.info(
134249
+ log11.info(
134409
134250
  {
134410
134251
  chatId,
134411
134252
  sessionId: task.sessionId,
@@ -134429,7 +134270,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
134429
134270
  }
134430
134271
  }
134431
134272
  if (queue.length === 0 && !caughtUp && (!task || task.status !== "running")) {
134432
- log12.warn(
134273
+ log11.warn(
134433
134274
  { chatId, taskStatus: task?.status, queueLen: queue.length },
134434
134275
  "task-stream: no running task and no events \u2014 closing stream early"
134435
134276
  );
@@ -134527,7 +134368,7 @@ ${prompt}`;
134527
134368
  }
134528
134369
  throw err;
134529
134370
  }
134530
- log12.info({ chatId, workspaceId }, "task-stream: POST \u2014 task submitted, opening SSE stream");
134371
+ log11.info({ chatId, workspaceId }, "task-stream: POST \u2014 task submitted, opening SSE stream");
134531
134372
  streamTask(res, chatId, sessionId, void 0);
134532
134373
  }
134533
134374
  function handleGet(req, res, chatId) {
@@ -134541,13 +134382,13 @@ function handleGet(req, res, chatId) {
134541
134382
  res.end();
134542
134383
  return;
134543
134384
  }
134544
- log12.info({ chatId, sessionId, afterEventId }, "task-stream: GET \u2014 reconnecting to active stream");
134385
+ log11.info({ chatId, sessionId, afterEventId }, "task-stream: GET \u2014 reconnecting to active stream");
134545
134386
  streamTask(res, chatId, sessionId ?? task.sessionId, afterEventId);
134546
134387
  }
134547
134388
  function handleTaskStream(req, res, chatId) {
134548
134389
  if (req.method === "POST") {
134549
134390
  handlePost(req, res, chatId).catch((err) => {
134550
- log12.error({ chatId, err }, "task-stream: POST handler error");
134391
+ log11.error({ chatId, err }, "task-stream: POST handler error");
134551
134392
  if (!res.headersSent) {
134552
134393
  res.writeHead(500, { "Content-Type": "application/json" });
134553
134394
  res.end(JSON.stringify({ error: "Internal server error" }));
@@ -134592,7 +134433,7 @@ function removeBrowserFromLayout(workspaceId, browserId) {
134592
134433
  }
134593
134434
 
134594
134435
  // src/lib/browser-manager.ts
134595
- var log13 = createLogger("browser-manager");
134436
+ var log12 = createLogger("browser-manager");
134596
134437
  var PANEL_TYPE2 = "browser";
134597
134438
  var browserTabs = /* @__PURE__ */ new Map();
134598
134439
  var workspaceBrowsers = /* @__PURE__ */ new Map();
@@ -134653,7 +134494,7 @@ function createBrowser(workspaceId, options2) {
134653
134494
  title: tab.name,
134654
134495
  initialUrl: tab.url || void 0
134655
134496
  });
134656
- log13.info({ browserId: tab.id, workspaceId, url: tab.url }, "browser tab created");
134497
+ log12.info({ browserId: tab.id, workspaceId, url: tab.url }, "browser tab created");
134657
134498
  return tab;
134658
134499
  }
134659
134500
  function getBrowser(browserId) {
@@ -134680,7 +134521,7 @@ function updateBrowser(browserId, updates) {
134680
134521
  state: serializeState2(tab),
134681
134522
  updatedAt: Date.now()
134682
134523
  });
134683
- log13.info({ browserId, updates }, "browser tab updated");
134524
+ log12.info({ browserId, updates }, "browser tab updated");
134684
134525
  return tab;
134685
134526
  }
134686
134527
  function updateBrowserUrl(browserId, url2) {
@@ -134697,7 +134538,7 @@ function removeBrowser(browserId) {
134697
134538
  if (!tab) return false;
134698
134539
  deletePanelState(browserId);
134699
134540
  removeFromIndex2(browserId);
134700
- log13.info({ browserId, workspaceId: tab.workspaceId }, "browser tab removed");
134541
+ log12.info({ browserId, workspaceId: tab.workspaceId }, "browser tab removed");
134701
134542
  return true;
134702
134543
  }
134703
134544
  function removeWorkspaceBrowsers(workspaceId) {
@@ -134708,7 +134549,7 @@ function removeWorkspaceBrowsers(workspaceId) {
134708
134549
  }
134709
134550
  deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE2);
134710
134551
  workspaceBrowsers.delete(workspaceId);
134711
- log13.info({ workspaceId }, "all browser tabs removed for workspace");
134552
+ log12.info({ workspaceId }, "all browser tabs removed for workspace");
134712
134553
  }
134713
134554
  function loadBrowsersFromDb() {
134714
134555
  _initialized2 = true;
@@ -134731,13 +134572,13 @@ function loadBrowsersFromDb() {
134731
134572
  addToIndex2(tab);
134732
134573
  }
134733
134574
  if (rows.length > 0) {
134734
- log13.info({ count: rows.length }, "loaded browser tabs from database");
134575
+ log12.info({ count: rows.length }, "loaded browser tabs from database");
134735
134576
  }
134736
134577
  return rows.length;
134737
134578
  }
134738
134579
 
134739
134580
  // src/lib/browser-host.ts
134740
- var log14 = createLogger("browser-host");
134581
+ var log13 = createLogger("browser-host");
134741
134582
  var DESKTOP_CDP_HOST = "127.0.0.1";
134742
134583
  var DESKTOP_CDP_PORT = 9223;
134743
134584
  var globalAny = globalThis;
@@ -134788,7 +134629,7 @@ async function ensureCdpTargetId(bandTabId) {
134788
134629
  reject: rejectFn,
134789
134630
  timeoutId
134790
134631
  });
134791
- log14.info(
134632
+ log13.info(
134792
134633
  "ensureCdpTargetId emitting ensureView for %s (url=%s, listeners=%d)",
134793
134634
  bandTabId,
134794
134635
  tab.url,
@@ -134802,13 +134643,13 @@ async function ensureCdpTargetId(bandTabId) {
134802
134643
  url: tab.url
134803
134644
  });
134804
134645
  } catch (err) {
134805
- log14.warn("ensureView listener threw: %s", err instanceof Error ? err.message : err);
134646
+ log13.warn("ensureView listener threw: %s", err instanceof Error ? err.message : err);
134806
134647
  }
134807
134648
  }
134808
134649
  return promise2;
134809
134650
  }
134810
134651
  function resolveTargetReady(bandTabId, cdpTargetId) {
134811
- log14.info("resolveTargetReady %s \u2192 %s", bandTabId, cdpTargetId);
134652
+ log13.info("resolveTargetReady %s \u2192 %s", bandTabId, cdpTargetId);
134812
134653
  targetIdByBandTabId.set(bandTabId, cdpTargetId);
134813
134654
  const pending2 = pendingEnsures.get(bandTabId);
134814
134655
  if (pending2) {
@@ -134818,7 +134659,7 @@ function resolveTargetReady(bandTabId, cdpTargetId) {
134818
134659
  }
134819
134660
  }
134820
134661
  function markTargetDestroyed(bandTabId) {
134821
- log14.info("markTargetDestroyed %s", bandTabId);
134662
+ log13.info("markTargetDestroyed %s", bandTabId);
134822
134663
  targetIdByBandTabId.delete(bandTabId);
134823
134664
  const pending2 = pendingEnsures.get(bandTabId);
134824
134665
  if (pending2) {
@@ -134829,10 +134670,10 @@ function markTargetDestroyed(bandTabId) {
134829
134670
  }
134830
134671
  function onEnsureView(listener) {
134831
134672
  ensureListeners.add(listener);
134832
- log14.info("onEnsureView subscriber added (total=%d)", ensureListeners.size);
134673
+ log13.info("onEnsureView subscriber added (total=%d)", ensureListeners.size);
134833
134674
  return () => {
134834
134675
  ensureListeners.delete(listener);
134835
- log14.info("onEnsureView subscriber removed (total=%d)", ensureListeners.size);
134676
+ log13.info("onEnsureView subscriber removed (total=%d)", ensureListeners.size);
134836
134677
  if (ensureListeners.size === 0) {
134837
134678
  for (const [bandTabId, pending2] of pendingEnsures) {
134838
134679
  clearTimeout(pending2.timeoutId);
@@ -134849,7 +134690,7 @@ function isDesktopHostConnected() {
134849
134690
 
134850
134691
  // src/lib/cdp-proxy.ts
134851
134692
  init_src();
134852
- var log15 = createLogger("cdp-proxy");
134693
+ var log14 = createLogger("cdp-proxy");
134853
134694
  async function handleCdpConnection(ws, req) {
134854
134695
  const url2 = new URL(req.url ?? "", `http://${req.headers.host}`);
134855
134696
  const bandTabId = url2.searchParams.get("bandTabId");
@@ -134872,17 +134713,17 @@ async function handleCdpConnection(ws, req) {
134872
134713
  cdpTargetId = await ensureCdpTargetId(bandTabId);
134873
134714
  } catch (err) {
134874
134715
  const message = err instanceof Error ? err.message : String(err);
134875
- log15.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
134716
+ log14.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
134876
134717
  if (ws.readyState === ws.OPEN) {
134877
134718
  ws.close(4001, message.slice(0, 123));
134878
134719
  }
134879
134720
  return;
134880
134721
  }
134881
134722
  const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
134882
- log15.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
134723
+ log14.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
134883
134724
  upstream = new wrapper_default(upstreamUrl);
134884
134725
  upstream.on("open", () => {
134885
- log15.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
134726
+ log14.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
134886
134727
  for (const msg of pending2) {
134887
134728
  upstream?.send(msg);
134888
134729
  }
@@ -134894,20 +134735,20 @@ async function handleCdpConnection(ws, req) {
134894
134735
  }
134895
134736
  });
134896
134737
  upstream.on("error", (err) => {
134897
- log15.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
134738
+ log14.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
134898
134739
  markTargetDestroyed(bandTabId);
134899
134740
  if (ws.readyState === ws.OPEN) {
134900
134741
  ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
134901
134742
  }
134902
134743
  });
134903
134744
  upstream.on("close", (code) => {
134904
- log15.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
134745
+ log14.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
134905
134746
  if (ws.readyState === ws.OPEN) {
134906
134747
  ws.close(1e3, "Upstream closed");
134907
134748
  }
134908
134749
  });
134909
134750
  ws.on("close", () => {
134910
- log15.debug("CDP client closed bandTabId=%s", bandTabId);
134751
+ log14.debug("CDP client closed bandTabId=%s", bandTabId);
134911
134752
  if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
134912
134753
  try {
134913
134754
  upstream.close();
@@ -134916,7 +134757,7 @@ async function handleCdpConnection(ws, req) {
134916
134757
  }
134917
134758
  });
134918
134759
  ws.on("error", (err) => {
134919
- log15.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
134760
+ log14.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
134920
134761
  try {
134921
134762
  upstream?.close();
134922
134763
  } catch {
@@ -134926,7 +134767,7 @@ async function handleCdpConnection(ws, req) {
134926
134767
 
134927
134768
  // src/lib/cdp-targets.ts
134928
134769
  init_src();
134929
- var log16 = createLogger("cdp-targets");
134770
+ var log15 = createLogger("cdp-targets");
134930
134771
  var CdpUnreachableError = class extends Error {
134931
134772
  constructor(message) {
134932
134773
  super(message);
@@ -134982,7 +134823,7 @@ async function captureSnapshot(bandTabId) {
134982
134823
  });
134983
134824
  ws.on("error", (err) => {
134984
134825
  clearTimeout(timeout);
134985
- log16.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
134826
+ log15.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
134986
134827
  markTargetDestroyed(bandTabId);
134987
134828
  settle(new CdpUnreachableError(err.message));
134988
134829
  });
@@ -135702,7 +135543,7 @@ function rowToDefinition(row) {
135702
135543
  }
135703
135544
 
135704
135545
  // src/lib/cronjob-scheduler.ts
135705
- var log17 = createLogger("cronjob-scheduler");
135546
+ var log16 = createLogger("cronjob-scheduler");
135706
135547
  var SCHEDULER_KEY = Symbol.for("band.cronjob-scheduler");
135707
135548
  var g14 = globalThis;
135708
135549
  if (!g14[SCHEDULER_KEY]) {
@@ -135722,16 +135563,16 @@ function scheduleJob(job, fileKey) {
135722
135563
  try {
135723
135564
  const cronInstance = new E2(job.cronExpression, () => {
135724
135565
  executeCronjob(job, fileKey).catch((err) => {
135725
- log17.error({ jobId: job.id, err }, "unhandled error in cronjob execution");
135566
+ log16.error({ jobId: job.id, err }, "unhandled error in cronjob execution");
135726
135567
  });
135727
135568
  });
135728
135569
  state.jobs.set(job.id, cronInstance);
135729
- log17.info(
135570
+ log16.info(
135730
135571
  { jobId: job.id, name: job.name, cron: job.cronExpression, scope: job.scope },
135731
135572
  "scheduled cronjob"
135732
135573
  );
135733
135574
  } catch (err) {
135734
- log17.error(
135575
+ log16.error(
135735
135576
  { jobId: job.id, cronExpression: job.cronExpression, err },
135736
135577
  "invalid cron expression, skipping job"
135737
135578
  );
@@ -135745,24 +135586,24 @@ async function executeCronjob(job, fileKey) {
135745
135586
  const appState = loadState();
135746
135587
  const project = appState.projects.find((p6) => p6.name === fileKey);
135747
135588
  if (!project) {
135748
- log17.warn({ jobId: job.id, fileKey }, "project not found for cronjob, skipping");
135589
+ log16.warn({ jobId: job.id, fileKey }, "project not found for cronjob, skipping");
135749
135590
  updateLastRun(job.id, "failed");
135750
135591
  return;
135751
135592
  }
135752
135593
  workspaceId = toWorkspaceId(project.name, project.defaultBranch);
135753
135594
  }
135754
- log17.info({ jobId: job.id, name: job.name, workspaceId }, "executing cronjob");
135595
+ log16.info({ jobId: job.id, name: job.name, workspaceId }, "executing cronjob");
135755
135596
  try {
135756
135597
  const chat = getOrCreateDefaultChat(workspaceId);
135757
135598
  submitTask({ workspaceId, chatId: chat.id, prompt: job.prompt });
135758
135599
  updateLastRun(job.id, "completed");
135759
135600
  } catch (err) {
135760
135601
  if (err instanceof TaskConflictError) {
135761
- log17.info({ jobId: job.id, workspaceId }, "task already running, skipping cronjob execution");
135602
+ log16.info({ jobId: job.id, workspaceId }, "task already running, skipping cronjob execution");
135762
135603
  updateLastRun(job.id, "skipped");
135763
135604
  return;
135764
135605
  }
135765
- log17.error({ jobId: job.id, err }, "cronjob execution failed");
135606
+ log16.error({ jobId: job.id, err }, "cronjob execution failed");
135766
135607
  updateLastRun(job.id, "failed");
135767
135608
  }
135768
135609
  }
@@ -135771,7 +135612,7 @@ function updateLastRun(jobId, status) {
135771
135612
  const db2 = getDb();
135772
135613
  db2.update(cronjobs).set({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString(), lastRunStatus: status }).where(eq2(cronjobs.id, jobId)).run();
135773
135614
  } catch (err) {
135774
- log17.warn({ jobId, err }, "failed to update lastRun on cronjob");
135615
+ log16.warn({ jobId, err }, "failed to update lastRun on cronjob");
135775
135616
  }
135776
135617
  }
135777
135618
  function loadAndScheduleAll() {
@@ -135782,13 +135623,13 @@ function loadAndScheduleAll() {
135782
135623
  for (const job of listAllCronjobs()) {
135783
135624
  scheduleJob(job, job.fileKey);
135784
135625
  }
135785
- log17.info({ count: state.jobs.size }, "loaded cronjob schedules");
135626
+ log16.info({ count: state.jobs.size }, "loaded cronjob schedules");
135786
135627
  }
135787
135628
  function startCronjobScheduler() {
135788
135629
  if (state.started) return;
135789
135630
  state.started = true;
135790
135631
  loadAndScheduleAll();
135791
- log17.info("cronjob scheduler started");
135632
+ log16.info("cronjob scheduler started");
135792
135633
  }
135793
135634
  function stopCronjobScheduler() {
135794
135635
  for (const [, cron] of state.jobs) {
@@ -135796,7 +135637,7 @@ function stopCronjobScheduler() {
135796
135637
  }
135797
135638
  state.jobs.clear();
135798
135639
  state.started = false;
135799
- log17.info("cronjob scheduler stopped");
135640
+ log16.info("cronjob scheduler stopped");
135800
135641
  }
135801
135642
  function reloadSchedules() {
135802
135643
  if (!state.started) return;
@@ -135809,7 +135650,7 @@ function stopJobsForKey(key) {
135809
135650
  if (cron) {
135810
135651
  cron.stop();
135811
135652
  state.jobs.delete(job.id);
135812
- log17.info({ jobId: job.id, key }, "stopped cronjob");
135653
+ log16.info({ jobId: job.id, key }, "stopped cronjob");
135813
135654
  }
135814
135655
  }
135815
135656
  }
@@ -135875,7 +135716,7 @@ async function checkPrereqs() {
135875
135716
 
135876
135717
  // src/lib/lsp-manager.ts
135877
135718
  var __dirname2 = dirname2(fileURLToPath(import.meta.url));
135878
- var log18 = createLogger("lsp");
135719
+ var log17 = createLogger("lsp");
135879
135720
  var LANG_SERVER_CONFIG = {
135880
135721
  typescript: { command: "typescript-language-server", args: ["--stdio"] }
135881
135722
  };
@@ -135903,7 +135744,7 @@ async function getOrSpawnServer(workspaceId, lang) {
135903
135744
  const workspaceBin = join17(cwd, "node_modules/.bin");
135904
135745
  const pathSep = process.platform === "win32" ? ";" : ":";
135905
135746
  const combinedPath = [bundledBin, appBin, workspaceBin, resolvedPath].join(pathSep);
135906
- log18.debug("Spawning %s language server in %s for workspace %s", lang, cwd, workspaceId);
135747
+ log17.debug("Spawning %s language server in %s for workspace %s", lang, cwd, workspaceId);
135907
135748
  const child = spawn6(config2.command, config2.args, {
135908
135749
  cwd,
135909
135750
  stdio: ["pipe", "pipe", "pipe"],
@@ -135931,15 +135772,15 @@ async function getOrSpawnServer(workspaceId, lang) {
135931
135772
  }
135932
135773
  ids.add(serverId);
135933
135774
  child.on("exit", (code) => {
135934
- log18.debug("Language server exited: %s (code %s)", serverId, String(code));
135775
+ log17.debug("Language server exited: %s (code %s)", serverId, String(code));
135935
135776
  removeSession();
135936
135777
  });
135937
135778
  child.on("error", (err) => {
135938
- log18.error("Language server error: %s \u2014 %s", serverId, err.message);
135779
+ log17.error("Language server error: %s \u2014 %s", serverId, err.message);
135939
135780
  removeSession();
135940
135781
  });
135941
135782
  child.stderr?.on("data", (chunk) => {
135942
- log18.debug("LSP stderr [%s]: %s", serverId, chunk.toString().trimEnd());
135783
+ log17.debug("LSP stderr [%s]: %s", serverId, chunk.toString().trimEnd());
135943
135784
  });
135944
135785
  await new Promise((resolve8, reject) => {
135945
135786
  child.once("spawn", resolve8);
@@ -135969,7 +135810,7 @@ function killAllServers() {
135969
135810
 
135970
135811
  // src/lib/lsp-proxy.ts
135971
135812
  init_src();
135972
- var log19 = createLogger("lsp-proxy");
135813
+ var log18 = createLogger("lsp-proxy");
135973
135814
  function frameMessage(json4) {
135974
135815
  const body = Buffer.from(json4, "utf-8");
135975
135816
  const header = `Content-Length: ${body.byteLength}\r
@@ -135987,7 +135828,7 @@ function createFrameParser(onMessage) {
135987
135828
  const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
135988
135829
  const match = headerStr.match(/Content-Length:\s*(\d+)/i);
135989
135830
  if (!match) {
135990
- log19.warn("Malformed LSP header: %s", headerStr);
135831
+ log18.warn("Malformed LSP header: %s", headerStr);
135991
135832
  buffer = buffer.subarray(separatorIdx + 4);
135992
135833
  continue;
135993
135834
  }
@@ -136020,7 +135861,7 @@ async function handleLspConnection(ws, req) {
136020
135861
  session = await getOrSpawnServer(workspaceId, lang);
136021
135862
  } catch (err) {
136022
135863
  const message = err instanceof Error ? err.message : String(err);
136023
- log19.error(
135864
+ log18.error(
136024
135865
  "Failed to spawn %s language server for workspace %s: %s",
136025
135866
  lang,
136026
135867
  workspaceId,
@@ -136034,12 +135875,12 @@ async function handleLspConnection(ws, req) {
136034
135875
  ws.close(4002, "Language server stdio not available");
136035
135876
  return;
136036
135877
  }
136037
- log19.debug("LSP client connected: %s/%s", workspaceId, lang);
135878
+ log18.debug("LSP client connected: %s/%s", workspaceId, lang);
136038
135879
  const pendingRequests = /* @__PURE__ */ new Map();
136039
135880
  const retriedIds = /* @__PURE__ */ new Set();
136040
135881
  const RETRY_DELAY_MS = 2e3;
136041
135882
  const parseFrame = createFrameParser((json4) => {
136042
- log19.debug(
135883
+ log18.debug(
136043
135884
  "LSP stdout [%s/%s]: %s",
136044
135885
  workspaceId,
136045
135886
  lang,
@@ -136051,7 +135892,7 @@ async function handleLspConnection(ws, req) {
136051
135892
  const originalRequest = pendingRequests.get(msg.id);
136052
135893
  retriedIds.add(msg.id);
136053
135894
  pendingRequests.delete(msg.id);
136054
- log19.debug(
135895
+ log18.debug(
136055
135896
  "LSP retrying request %d after 'No Project' error [%s/%s]",
136056
135897
  msg.id,
136057
135898
  workspaceId,
@@ -136073,14 +135914,14 @@ async function handleLspConnection(ws, req) {
136073
135914
  const onStdoutData = (chunk) => parseFrame(chunk);
136074
135915
  lspProcess.stdout.on("data", onStdoutData);
136075
135916
  const onExit = (code) => {
136076
- log19.debug("LSP server exited (code %s), closing WebSocket", String(code));
135917
+ log18.debug("LSP server exited (code %s), closing WebSocket", String(code));
136077
135918
  if (ws.readyState === ws.OPEN) {
136078
135919
  ws.close(1e3, "Language server exited");
136079
135920
  }
136080
135921
  };
136081
135922
  lspProcess.on("exit", onExit);
136082
135923
  function forwardToStdin(json4) {
136083
- log19.debug(
135924
+ log18.debug(
136084
135925
  "LSP stdin [%s/%s]: %s",
136085
135926
  workspaceId,
136086
135927
  lang,
@@ -136107,7 +135948,7 @@ async function handleLspConnection(ws, req) {
136107
135948
  ws.on("close", () => {
136108
135949
  lspProcess.stdout?.off("data", onStdoutData);
136109
135950
  lspProcess.off("exit", onExit);
136110
- log19.debug("LSP client disconnected: %s/%s (server kept alive)", workspaceId, lang);
135951
+ log18.debug("LSP client disconnected: %s/%s (server kept alive)", workspaceId, lang);
136111
135952
  });
136112
135953
  }
136113
135954
 
@@ -136119,14 +135960,15 @@ import { accessSync, constants, lstatSync as lstatSync2, realpathSync as realpat
136119
135960
  import { platform as platform2 } from "node:os";
136120
135961
  import { dirname as dirname3, join as join18, resolve as resolve5 } from "node:path";
136121
135962
  var SYMLINK_PATH = "/usr/local/bin/band";
136122
- function findCliBinary() {
135963
+ function findCliBinaryAt(opts) {
135964
+ const { cwd, dirname: dirname7 } = opts;
136123
135965
  const appsStrategies = [
136124
135966
  // cwd = apps/web/ (Vite dev and production server)
136125
- resolve5(process.cwd(), ".."),
135967
+ resolve5(cwd, ".."),
136126
135968
  // cwd = project root (fallback)
136127
- resolve5(process.cwd(), "apps"),
135969
+ resolve5(cwd, "apps"),
136128
135970
  // From this source file (apps/web/src/lib/ → apps/)
136129
- resolve5(import.meta.dirname, "..", "..", "..")
135971
+ resolve5(dirname7, "..", "..", "..")
136130
135972
  ];
136131
135973
  for (const appsDir of appsStrategies) {
136132
135974
  for (const profile of ["release", "debug"]) {
@@ -136140,10 +135982,11 @@ function findCliBinary() {
136140
135982
  }
136141
135983
  const exe = platform2() === "win32" ? "band.exe" : "band";
136142
135984
  const electronCandidates = [
136143
- // From cwd (<Resources>/web/dist) → <Resources>/binaries/band
136144
- resolve5(process.cwd(), "..", "..", "binaries", exe),
136145
- // From the bundled dist file (<Resources>/web/dist/...) → <Resources>/binaries/band
136146
- resolve5(import.meta.dirname, "..", "..", "..", "binaries", exe)
135985
+ // From cwd (<Resources>/web) → <Resources>/binaries/band
135986
+ resolve5(cwd, "..", "binaries", exe),
135987
+ // From the bundled dist file (<Resources>/web/dist/start-server.mjs)
135988
+ // <Resources>/binaries/band
135989
+ resolve5(dirname7, "..", "..", "binaries", exe)
136147
135990
  ];
136148
135991
  for (const p6 of electronCandidates) {
136149
135992
  try {
@@ -136154,6 +135997,9 @@ function findCliBinary() {
136154
135997
  }
136155
135998
  return null;
136156
135999
  }
136000
+ function findCliBinary() {
136001
+ return findCliBinaryAt({ cwd: process.cwd(), dirname: import.meta.dirname });
136002
+ }
136157
136003
  async function checkCli() {
136158
136004
  try {
136159
136005
  const stat5 = lstatSync2(SYMLINK_PATH);
@@ -136200,12 +136046,18 @@ function isDirWritable(dir) {
136200
136046
  return false;
136201
136047
  }
136202
136048
  }
136049
+ function noBinaryError(env = process.env) {
136050
+ if (env.BAND_PACKAGED === "1") {
136051
+ return new Error("Bundled CLI binary missing - try reinstalling Band");
136052
+ }
136053
+ return new Error(
136054
+ "Could not find band CLI binary. Build it first with: cargo build --release -p band-cli"
136055
+ );
136056
+ }
136203
136057
  async function installCli(_opts = {}) {
136204
136058
  const binaryPath = findCliBinary();
136205
136059
  if (!binaryPath) {
136206
- throw new Error(
136207
- "Could not find band CLI binary. Build it first with: cargo build --release -p band-cli"
136208
- );
136060
+ throw noBinaryError();
136209
136061
  }
136210
136062
  const dir = dirname3(SYMLINK_PATH);
136211
136063
  if (isDirWritable(dir)) {
@@ -136233,17 +136085,19 @@ function resolveCliPaths() {
136233
136085
  // src/lib/cli-skills.ts
136234
136086
  import { execFile as execFile4 } from "node:child_process";
136235
136087
  import {
136236
- accessSync as accessSync2,
136237
136088
  existsSync as existsSync5,
136238
- constants as fsConstants,
136089
+ lstatSync as lstatSync3,
136239
136090
  mkdirSync as mkdirSync5,
136240
136091
  mkdtempSync,
136241
136092
  readFileSync as readFileSync7,
136093
+ readlinkSync as readlinkSync2,
136094
+ realpathSync as realpathSync3,
136242
136095
  rmSync as rmSync2,
136243
136096
  statSync as statSync6,
136097
+ symlinkSync as symlinkSync3,
136244
136098
  writeFileSync as writeFileSync2
136245
136099
  } from "node:fs";
136246
- import { homedir as homedir9, tmpdir } from "node:os";
136100
+ import { homedir as homedir8, tmpdir } from "node:os";
136247
136101
  import { dirname as dirname4, join as join19 } from "node:path";
136248
136102
  var BAND_SKILL_NAMES = [
136249
136103
  "band",
@@ -136254,30 +136108,23 @@ var BAND_SKILL_NAMES = [
136254
136108
  "band-loop"
136255
136109
  ];
136256
136110
  var SKILL_FILE = "SKILL.md";
136257
- async function isAgentInstalled(agent) {
136258
- if (agent.command) {
136111
+ async function resolveSkillTargets(home = homedir8()) {
136112
+ const seen = /* @__PURE__ */ new Set();
136113
+ const out = [];
136114
+ for (const type of SUPPORTED_AGENT_TYPES) {
136115
+ const configDir = getAgentConfigDir(type, home);
136116
+ if (!configDir) continue;
136259
136117
  try {
136260
- accessSync2(agent.command, fsConstants.X_OK);
136261
- return true;
136118
+ const stat5 = statSync6(configDir);
136119
+ if (!stat5.isDirectory()) continue;
136262
136120
  } catch {
136263
- return false;
136121
+ continue;
136264
136122
  }
136265
- }
136266
- const binaryName = await getDefaultAgentBinary(agent.type);
136267
- if (!binaryName) return false;
136268
- const found = await whichBinary(binaryName);
136269
- return found !== null;
136270
- }
136271
- async function resolveSkillTargets(agents, home = homedir9()) {
136272
- const seen = /* @__PURE__ */ new Set();
136273
- const out = [];
136274
- for (const agent of agents) {
136275
- if (!await isAgentInstalled(agent)) continue;
136276
- const skillsDir = await getInstallSkillsDir(agent.type, home);
136123
+ const skillsDir = await getInstallSkillsDir(type, home);
136277
136124
  if (!skillsDir) continue;
136278
136125
  if (seen.has(skillsDir)) continue;
136279
136126
  seen.add(skillsDir);
136280
- out.push({ agentType: agent.type, skillsDir });
136127
+ out.push({ agentType: type, skillsDir });
136281
136128
  }
136282
136129
  return out;
136283
136130
  }
@@ -136313,67 +136160,99 @@ async function installSkills(opts = {}) {
136313
136160
  written: [],
136314
136161
  updated: [],
136315
136162
  unchanged: [],
136163
+ linked: [],
136164
+ alreadyLinked: [],
136165
+ conflicts: [],
136316
136166
  skipped: []
136317
136167
  };
136318
- const home = opts.home ?? homedir9();
136319
- const agents = opts.agents ?? loadSettings().codingAgents ?? [];
136320
- const targets = await resolveSkillTargets(agents, home);
136321
- if (targets.length === 0) {
136322
- return result;
136323
- }
136168
+ const home = opts.home ?? homedir8();
136169
+ const sharedDir = getSharedSkillsDir(home);
136170
+ const targets = await resolveSkillTargets(home);
136324
136171
  const bandPath = await findBandBinary();
136325
136172
  if (!bandPath) {
136326
136173
  opts.log?.warn(
136327
136174
  "Skipping CLI skills sync \u2014 band binary not found (no symlink, not on PATH, no bundled sidecar)"
136328
136175
  );
136329
- for (const target of targets) {
136330
- for (const name24 of BAND_SKILL_NAMES) {
136331
- result.skipped.push(join19(target.skillsDir, name24, SKILL_FILE));
136332
- }
136176
+ for (const name24 of BAND_SKILL_NAMES) {
136177
+ result.skipped.push(join19(sharedDir, name24, SKILL_FILE));
136333
136178
  }
136334
136179
  return result;
136335
136180
  }
136336
136181
  const stagingDir = mkdtempSync(join19(tmpdir(), "band-skills-"));
136337
136182
  try {
136338
136183
  await generateSkills(bandPath, stagingDir);
136184
+ for (const name24 of BAND_SKILL_NAMES) {
136185
+ const sourcePath = join19(stagingDir, name24, SKILL_FILE);
136186
+ const destPath = join19(sharedDir, name24, SKILL_FILE);
136187
+ if (!existsSync5(sourcePath)) {
136188
+ opts.log?.warn("Generated skill missing from staging dir: %s (skipping)", sourcePath);
136189
+ result.skipped.push(destPath);
136190
+ continue;
136191
+ }
136192
+ const sourceContent = readFileSync7(sourcePath);
136193
+ let existingContent = null;
136194
+ try {
136195
+ existingContent = readFileSync7(destPath);
136196
+ } catch (err) {
136197
+ const code = err.code;
136198
+ if (code !== "ENOENT") {
136199
+ opts.log?.warn(
136200
+ "Failed to read existing shared skill at %s: %s \u2014 overwriting",
136201
+ destPath,
136202
+ err instanceof Error ? err.message : String(err)
136203
+ );
136204
+ }
136205
+ }
136206
+ if (existingContent?.equals(sourceContent)) {
136207
+ result.unchanged.push(destPath);
136208
+ continue;
136209
+ }
136210
+ mkdirSync5(dirname4(destPath), { recursive: true });
136211
+ writeFileSync2(destPath, sourceContent);
136212
+ if (existingContent) {
136213
+ result.updated.push(destPath);
136214
+ opts.log?.info(
136215
+ "Updated %s skill at %s (content differed \u2014 local edits, if any, were overwritten)",
136216
+ name24,
136217
+ destPath
136218
+ );
136219
+ } else {
136220
+ result.written.push(destPath);
136221
+ opts.log?.info("Installed %s skill at %s", name24, destPath);
136222
+ }
136223
+ }
136224
+ if (targets.length === 0) {
136225
+ opts.log?.info(
136226
+ "No supported coding agents detected on host \u2014 skills installed to %s but no agent symlinks created",
136227
+ sharedDir
136228
+ );
136229
+ return result;
136230
+ }
136339
136231
  for (const target of targets) {
136340
136232
  for (const name24 of BAND_SKILL_NAMES) {
136341
- const sourcePath = join19(stagingDir, name24, SKILL_FILE);
136342
- const destPath = join19(target.skillsDir, name24, SKILL_FILE);
136343
- if (!existsSync5(sourcePath)) {
136344
- opts.log?.warn("Generated skill missing from staging dir: %s (skipping)", sourcePath);
136233
+ const shared2 = join19(sharedDir, name24);
136234
+ const link2 = join19(target.skillsDir, name24);
136235
+ if (!existsSync5(shared2)) {
136236
+ result.skipped.push(link2);
136345
136237
  continue;
136346
136238
  }
136347
- const sourceContent = readFileSync7(sourcePath);
136348
- let existingContent = null;
136349
- try {
136350
- existingContent = readFileSync7(destPath);
136351
- } catch (err) {
136352
- const code = err.code;
136353
- if (code !== "ENOENT") {
136239
+ const outcome = ensureSymlink({ link: link2, target: shared2, log: opts.log });
136240
+ switch (outcome.kind) {
136241
+ case "created":
136242
+ result.linked.push(link2);
136243
+ opts.log?.info("Linked %s skills/%s \u2192 %s", target.agentType, name24, shared2);
136244
+ break;
136245
+ case "already":
136246
+ result.alreadyLinked.push(link2);
136247
+ break;
136248
+ case "conflict":
136249
+ result.conflicts.push(`${link2}: ${outcome.reason}`);
136354
136250
  opts.log?.warn(
136355
- "Failed to read existing skill at %s: %s \u2014 overwriting",
136356
- destPath,
136357
- err instanceof Error ? err.message : String(err)
136251
+ "Skill symlink conflict at %s \u2014 %s (leaving as-is; remove it manually to re-link)",
136252
+ link2,
136253
+ outcome.reason
136358
136254
  );
136359
- }
136360
- }
136361
- if (existingContent?.equals(sourceContent)) {
136362
- result.unchanged.push(destPath);
136363
- continue;
136364
- }
136365
- mkdirSync5(dirname4(destPath), { recursive: true });
136366
- writeFileSync2(destPath, sourceContent);
136367
- if (existingContent) {
136368
- result.updated.push(destPath);
136369
- opts.log?.info(
136370
- "Updated %s skill at %s (content differed \u2014 local edits, if any, were overwritten)",
136371
- name24,
136372
- destPath
136373
- );
136374
- } else {
136375
- result.written.push(destPath);
136376
- opts.log?.info("Installed %s skill at %s", name24, destPath);
136255
+ break;
136377
136256
  }
136378
136257
  }
136379
136258
  }
@@ -136385,14 +136264,97 @@ async function installSkills(opts = {}) {
136385
136264
  }
136386
136265
  return result;
136387
136266
  }
136267
+ function ensureSymlink(args) {
136268
+ return ensureSymlinkInner(args, false);
136269
+ }
136270
+ function ensureSymlinkInner(args, retried) {
136271
+ const { link: link2, target } = args;
136272
+ mkdirSync5(dirname4(link2), { recursive: true });
136273
+ let existing = null;
136274
+ try {
136275
+ existing = lstatSync3(link2);
136276
+ } catch (err) {
136277
+ const code = err.code;
136278
+ if (code !== "ENOENT") {
136279
+ return {
136280
+ kind: "conflict",
136281
+ reason: `lstat failed: ${err instanceof Error ? err.message : String(err)}`
136282
+ };
136283
+ }
136284
+ }
136285
+ if (existing === null) {
136286
+ try {
136287
+ symlinkSync3(target, link2, "dir");
136288
+ return { kind: "created" };
136289
+ } catch (err) {
136290
+ if (err.code === "EEXIST") {
136291
+ if (retried) {
136292
+ return {
136293
+ kind: "conflict",
136294
+ reason: "EEXIST after retry \u2014 filesystem state is inconsistent"
136295
+ };
136296
+ }
136297
+ return ensureSymlinkInner(args, true);
136298
+ }
136299
+ return {
136300
+ kind: "conflict",
136301
+ reason: `failed to create symlink: ${err instanceof Error ? err.message : String(err)}`
136302
+ };
136303
+ }
136304
+ }
136305
+ if (existing.isSymbolicLink()) {
136306
+ let pointsAt;
136307
+ try {
136308
+ pointsAt = realpathSync3(link2);
136309
+ } catch (err) {
136310
+ return {
136311
+ kind: "conflict",
136312
+ reason: `existing symlink is broken (${err instanceof Error ? err.message : String(err)})`
136313
+ };
136314
+ }
136315
+ let targetReal;
136316
+ try {
136317
+ targetReal = realpathSync3(target);
136318
+ } catch (err) {
136319
+ return {
136320
+ kind: "conflict",
136321
+ reason: `target unreadable (${err instanceof Error ? err.message : String(err)})`
136322
+ };
136323
+ }
136324
+ if (pointsAt === targetReal) {
136325
+ return { kind: "already" };
136326
+ }
136327
+ return {
136328
+ kind: "conflict",
136329
+ reason: `symlink points to ${readlinkSafe(link2)} (expected ${target})`
136330
+ };
136331
+ }
136332
+ if (existing.isDirectory()) {
136333
+ return {
136334
+ kind: "conflict",
136335
+ reason: "path is a real directory (not a symlink)"
136336
+ };
136337
+ }
136338
+ return {
136339
+ kind: "conflict",
136340
+ reason: "path is a regular file (not a directory or symlink)"
136341
+ };
136342
+ }
136343
+ function readlinkSafe(p6) {
136344
+ try {
136345
+ return readlinkSync2(p6);
136346
+ } catch {
136347
+ return "<unreadable>";
136348
+ }
136349
+ }
136388
136350
 
136389
136351
  // src/lib/hooks.ts
136390
136352
  import { mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
136391
- import { homedir as homedir10 } from "node:os";
136353
+ import { homedir as homedir9 } from "node:os";
136392
136354
  import { dirname as dirname5, join as join20 } from "node:path";
136393
136355
  var HOOK_EVENTS = ["PreToolUse", "PermissionRequest", "UserPromptSubmit", "PostToolUse", "Stop"];
136394
136356
  function claudeSettingsPath() {
136395
- return join20(homedir10(), ".claude", "settings.json");
136357
+ return join20(homedir9(), ".claude", "settings.json");
136396
136358
  }
136397
136359
  function loadClaudeSettings() {
136398
136360
  try {
@@ -136482,7 +136444,7 @@ async function installHooks() {
136482
136444
  }
136483
136445
 
136484
136446
  // src/lib/setup.ts
136485
- var log20 = createLogger("setup");
136447
+ var log19 = createLogger("setup");
136486
136448
  var AGENT_CHECKS = [
136487
136449
  { id: "claude-code", type: "claude-code", label: "Claude Code", binary: "claude" },
136488
136450
  { id: "codex", type: "codex", label: "Codex", binary: "codex" },
@@ -136500,22 +136462,22 @@ async function ensureCliInstalled() {
136500
136462
  try {
136501
136463
  cliStatus = await checkCli();
136502
136464
  } catch (err) {
136503
- log20.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
136465
+ log19.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
136504
136466
  return;
136505
136467
  }
136506
136468
  if (cliStatus === "Installed") {
136507
136469
  return;
136508
136470
  }
136509
136471
  if (cliStatus !== "NotInstalled") {
136510
- log20.warn("CLI not auto-installed (status: %s)", cliStatus);
136472
+ log19.warn("CLI not auto-installed (status: %s)", cliStatus);
136511
136473
  return;
136512
136474
  }
136513
- log20.info("Installing band CLI...");
136475
+ log19.info("Installing band CLI...");
136514
136476
  try {
136515
136477
  await installCli();
136516
- log20.info("CLI installed to /usr/local/bin/band");
136478
+ log19.info("CLI installed to /usr/local/bin/band");
136517
136479
  } catch (err) {
136518
- log20.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
136480
+ log19.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
136519
136481
  }
136520
136482
  }
136521
136483
  async function ensureDefaultCodingAgents() {
@@ -136524,17 +136486,17 @@ async function ensureDefaultCodingAgents() {
136524
136486
  if (Array.isArray(existing) && existing.length > 0) {
136525
136487
  return;
136526
136488
  }
136527
- log20.info("Detecting installed coding agents...");
136489
+ log19.info("Detecting installed coding agents...");
136528
136490
  const detected = [];
136529
136491
  for (const check2 of AGENT_CHECKS) {
136530
136492
  const path3 = await whichBinary(check2.binary);
136531
136493
  if (path3) {
136532
- log20.info("Detected coding agent: %s (%s)", check2.id, path3);
136494
+ log19.info("Detected coding agent: %s (%s)", check2.id, path3);
136533
136495
  detected.push({ id: check2.id, type: check2.type, label: check2.label });
136534
136496
  }
136535
136497
  }
136536
136498
  if (detected.length === 0) {
136537
- log20.info("No coding agent CLIs detected on PATH");
136499
+ log19.info("No coding agent CLIs detected on PATH");
136538
136500
  return;
136539
136501
  }
136540
136502
  const current = loadSettings();
@@ -136543,7 +136505,7 @@ async function ensureDefaultCodingAgents() {
136543
136505
  current.defaultCodingAgent = detected[0].id;
136544
136506
  }
136545
136507
  saveSettings(current);
136546
- log20.info("Enabled %d coding agent(s); default = %s", detected.length, current.defaultCodingAgent);
136508
+ log19.info("Enabled %d coding agent(s); default = %s", detected.length, current.defaultCodingAgent);
136547
136509
  }
136548
136510
  function ensureNotificationDefaults() {
136549
136511
  const settings = loadSettings();
@@ -136555,7 +136517,7 @@ function ensureNotificationDefaults() {
136555
136517
  ...settings,
136556
136518
  notifications: { ...notifications, soundOnNeedsAttention: true }
136557
136519
  });
136558
- log20.info("Set default notifications.soundOnNeedsAttention = true");
136520
+ log19.info("Set default notifications.soundOnNeedsAttention = true");
136559
136521
  }
136560
136522
  async function ensureClaudeHooks() {
136561
136523
  try {
@@ -136564,9 +136526,9 @@ async function ensureClaudeHooks() {
136564
136526
  return;
136565
136527
  }
136566
136528
  await installHooks();
136567
- log20.info("Installed Claude Code hooks");
136529
+ log19.info("Installed Claude Code hooks");
136568
136530
  } catch (err) {
136569
- log20.warn(
136531
+ log19.warn(
136570
136532
  "Failed to install Claude Code hooks: %s",
136571
136533
  err instanceof Error ? err.message : String(err)
136572
136534
  );
@@ -136574,19 +136536,23 @@ async function ensureClaudeHooks() {
136574
136536
  }
136575
136537
  async function ensureSkillsInstalled() {
136576
136538
  try {
136577
- const result = await installSkills({ log: log20 });
136539
+ const result = await installSkills({ log: log19 });
136578
136540
  const wrote = result.written.length + result.updated.length;
136579
- if (wrote > 0) {
136580
- log20.info(
136581
- "Synced CLI skills (%d written, %d updated, %d unchanged, %d skipped)",
136541
+ const linkChange = result.linked.length;
136542
+ if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
136543
+ log19.info(
136544
+ "Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
136582
136545
  result.written.length,
136583
136546
  result.updated.length,
136584
136547
  result.unchanged.length,
136548
+ result.linked.length,
136549
+ result.alreadyLinked.length,
136550
+ result.conflicts.length,
136585
136551
  result.skipped.length
136586
136552
  );
136587
136553
  }
136588
136554
  } catch (err) {
136589
- log20.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
136555
+ log19.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
136590
136556
  }
136591
136557
  }
136592
136558
 
@@ -136620,7 +136586,7 @@ function removeTerminalFromLayout(workspaceId, terminalId) {
136620
136586
  }
136621
136587
 
136622
136588
  // src/lib/terminal-manager.ts
136623
- var log21 = createLogger("terminal");
136589
+ var log20 = createLogger("terminal");
136624
136590
  var MAX_SCROLLBACK_SIZE = 1e5;
136625
136591
  var terminals = /* @__PURE__ */ new Map();
136626
136592
  var workspaceTerminals = /* @__PURE__ */ new Map();
@@ -136651,11 +136617,11 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
136651
136617
  if (options2?.cwd) {
136652
136618
  const resolved = join21(workspaceRoot, options2.cwd);
136653
136619
  if (!resolved.startsWith(workspaceRoot)) {
136654
- log21.warn("Ignoring cwd %s \u2014 resolves outside workspace root %s", options2.cwd, workspaceRoot);
136620
+ log20.warn("Ignoring cwd %s \u2014 resolves outside workspace root %s", options2.cwd, workspaceRoot);
136655
136621
  } else if (existsSync6(resolved)) {
136656
136622
  cwd = resolved;
136657
136623
  } else {
136658
- log21.warn("Ignoring cwd %s \u2014 directory does not exist", options2.cwd);
136624
+ log20.warn("Ignoring cwd %s \u2014 directory does not exist", options2.cwd);
136659
136625
  }
136660
136626
  }
136661
136627
  if (!existsSync6(cwd)) {
@@ -136664,7 +136630,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
136664
136630
  if (!existsSync6(shell)) {
136665
136631
  throw new Error(`Shell not found: ${shell}`);
136666
136632
  }
136667
- log21.debug(
136633
+ log20.debug(
136668
136634
  "Spawning shell %s in %s for terminal %s (PATH=%s)",
136669
136635
  shell,
136670
136636
  cwd,
@@ -136683,7 +136649,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
136683
136649
  });
136684
136650
  } catch (err) {
136685
136651
  const msg = err instanceof Error ? err.message : String(err);
136686
- log21.error("pty.spawn failed: %s (shell=%s, cwd=%s)", msg, shell, cwd);
136652
+ log20.error("pty.spawn failed: %s (shell=%s, cwd=%s)", msg, shell, cwd);
136687
136653
  throw err;
136688
136654
  }
136689
136655
  const session = { pty: ptyProcess, scrollback: "", workspaceId };
@@ -136719,7 +136685,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
136719
136685
  }
136720
136686
  });
136721
136687
  ptyProcess.onExit(() => {
136722
- log21.debug("Terminal exited: %s (workspace %s)", terminalId, workspaceId);
136688
+ log20.debug("Terminal exited: %s (workspace %s)", terminalId, workspaceId);
136723
136689
  terminals.delete(terminalId);
136724
136690
  outputListeners.delete(terminalId);
136725
136691
  const set2 = workspaceTerminals.get(workspaceId);
@@ -136827,7 +136793,7 @@ function killAllTerminals() {
136827
136793
 
136828
136794
  // src/lib/terminal-ws.ts
136829
136795
  init_src();
136830
- var log22 = createLogger("terminal-ws");
136796
+ var log21 = createLogger("terminal-ws");
136831
136797
  async function handleTerminalConnection(ws, req) {
136832
136798
  const url2 = new URL(req.url, `http://${req.headers.host}`);
136833
136799
  const workspaceId = url2.searchParams.get("workspaceId");
@@ -136868,7 +136834,7 @@ async function handleTerminalConnection(ws, req) {
136868
136834
  session = await spawnTerminal(workspaceId, terminalId, spawnOpts);
136869
136835
  } catch (err) {
136870
136836
  const msg = err instanceof Error ? err.message : String(err);
136871
- log22.error("Failed to spawn terminal %s for workspace %s: %s", terminalId, workspaceId, msg);
136837
+ log21.error("Failed to spawn terminal %s for workspace %s: %s", terminalId, workspaceId, msg);
136872
136838
  ws.close(4001, msg);
136873
136839
  return;
136874
136840
  }
@@ -136882,7 +136848,7 @@ async function handleTerminalConnection(ws, req) {
136882
136848
  });
136883
136849
  }
136884
136850
  function attachSession(ws, terminalId, workspaceId, session, isNew) {
136885
- log22.debug(
136851
+ log21.debug(
136886
136852
  "Terminal %s: %s (workspace %s)",
136887
136853
  isNew ? "connected" : "reconnected",
136888
136854
  terminalId,
@@ -136911,7 +136877,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
136911
136877
  }, 3e3);
136912
136878
  const exitDisposable = session.pty.onExit(({ exitCode }) => {
136913
136879
  clearInterval(processInterval);
136914
- log22.debug("PTY exited with code %d for terminal %s", exitCode, terminalId);
136880
+ log21.debug("PTY exited with code %d for terminal %s", exitCode, terminalId);
136915
136881
  if (ws.readyState === ws.OPEN) {
136916
136882
  ws.close(1e3, "Terminal exited");
136917
136883
  }
@@ -136923,7 +136889,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
136923
136889
  clearInterval(processInterval);
136924
136890
  dataDisposable.dispose();
136925
136891
  exitDisposable.dispose();
136926
- log22.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
136892
+ log21.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
136927
136893
  });
136928
136894
  }
136929
136895
  function handleMessage(ws, terminalId, session, message) {
@@ -136961,7 +136927,7 @@ function getToken() {
136961
136927
  }
136962
136928
 
136963
136929
  // src/lib/tunnel.ts
136964
- var log23 = createLogger("tunnel");
136930
+ var log22 = createLogger("tunnel");
136965
136931
  var tunnelProcess = null;
136966
136932
  var tunnelUrl = null;
136967
136933
  var startInProgress = null;
@@ -136975,7 +136941,7 @@ function appendToken(baseUrl, token) {
136975
136941
  }
136976
136942
  function spawnTunnel(options2, resolvedPath) {
136977
136943
  const args = ["tunnel", "--config", "/dev/null", "--url", `http://localhost:${options2.port}`];
136978
- log23.debug("spawning cloudflared %s", args.join(" "));
136944
+ log22.debug("spawning cloudflared %s", args.join(" "));
136979
136945
  return new Promise((resolve8, reject) => {
136980
136946
  const child = spawn7("cloudflared", args, {
136981
136947
  env: { ...process.env, PATH: resolvedPath },
@@ -136989,12 +136955,12 @@ function spawnTunnel(options2, resolvedPath) {
136989
136955
  for (const line2 of text4.split("\n")) {
136990
136956
  const trimmed = line2.trim();
136991
136957
  if (!trimmed) continue;
136992
- log23.debug("output: %s", trimmed);
136958
+ log22.debug("output: %s", trimmed);
136993
136959
  const url2 = extractUrl(trimmed);
136994
136960
  if (url2) {
136995
136961
  const token = getToken();
136996
136962
  tunnelUrl = appendToken(url2, token);
136997
- log23.debug("detected URL: %s", tunnelUrl);
136963
+ log22.debug("detected URL: %s", tunnelUrl);
136998
136964
  emit({ kind: "tunnel-url", url: tunnelUrl });
136999
136965
  if (!settled) {
137000
136966
  settled = true;
@@ -137009,7 +136975,7 @@ function spawnTunnel(options2, resolvedPath) {
137009
136975
  handleOutput(data);
137010
136976
  });
137011
136977
  child.on("error", (err) => {
137012
- log23.debug("process error: %s", err.message);
136978
+ log22.debug("process error: %s", err.message);
137013
136979
  tunnelProcess = null;
137014
136980
  tunnelUrl = null;
137015
136981
  emit({ kind: "tunnel-error", error: err.message });
@@ -137019,7 +136985,7 @@ function spawnTunnel(options2, resolvedPath) {
137019
136985
  }
137020
136986
  });
137021
136987
  child.on("exit", (code) => {
137022
- log23.debug("process exited with code: %d", code ?? -1);
136988
+ log22.debug("process exited with code: %d", code ?? -1);
137023
136989
  const wasRunning = tunnelProcess !== null && settled;
137024
136990
  tunnelProcess = null;
137025
136991
  tunnelUrl = null;
@@ -137041,7 +137007,7 @@ function spawnTunnel(options2, resolvedPath) {
137041
137007
  });
137042
137008
  setTimeout(() => {
137043
137009
  if (!settled) {
137044
- log23.debug("30s timeout reached, resolving without URL");
137010
+ log22.debug("30s timeout reached, resolving without URL");
137045
137011
  settled = true;
137046
137012
  resolve8();
137047
137013
  }
@@ -137050,12 +137016,12 @@ function spawnTunnel(options2, resolvedPath) {
137050
137016
  }
137051
137017
  async function startTunnel(options2) {
137052
137018
  if (startInProgress) {
137053
- log23.debug("startTunnel: start already in progress, waiting...");
137019
+ log22.debug("startTunnel: start already in progress, waiting...");
137054
137020
  await startInProgress;
137055
137021
  return;
137056
137022
  }
137057
137023
  if (tunnelProcess) {
137058
- log23.debug("startTunnel: already running, re-emitting URL");
137024
+ log22.debug("startTunnel: already running, re-emitting URL");
137059
137025
  if (tunnelUrl) {
137060
137026
  emit({ kind: "tunnel-url", url: tunnelUrl });
137061
137027
  }
@@ -143979,13 +143945,14 @@ function createContext8() {
143979
143945
  }
143980
143946
 
143981
143947
  // src/trpc/router.ts
143982
- import { execFile as execFile5, execFileSync as execFileSync2 } from "node:child_process";
143948
+ import { execFile as execFile5, execFileSync as execFileSync2, spawn as spawn8 } from "node:child_process";
143983
143949
  import { randomUUID as randomUUID2 } from "node:crypto";
143984
143950
  import { existsSync as existsSync7, mkdirSync as mkdirSync7, unlinkSync as unlinkSync3 } from "node:fs";
143985
143951
  import { cp, mkdir as mkdir2, readdir as readdir2, readFile as readFile2, rename, rm, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
143986
143952
  import { basename, dirname as dirname6, extname as extname2, join as join22, resolve as resolve6, sep as sep2 } from "node:path";
143987
143953
  import { promisify } from "node:util";
143988
143954
  init_src();
143955
+ import { rgPath } from "@vscode/ripgrep";
143989
143956
  init_zod();
143990
143957
 
143991
143958
  // src/lib/browser-history-store.ts
@@ -144085,7 +144052,7 @@ function clearHistory(workspaceId, range, now = Date.now()) {
144085
144052
 
144086
144053
  // src/lib/chat-session-summary.ts
144087
144054
  init_src();
144088
- var log24 = createLogger("chat-session-summary");
144055
+ var log23 = createLogger("chat-session-summary");
144089
144056
  var REFRESH_KEY = Symbol.for("band.chat-session-summary.refresh");
144090
144057
  var g15 = globalThis;
144091
144058
  if (!g15[REFRESH_KEY]) g15[REFRESH_KEY] = /* @__PURE__ */ new Map();
@@ -144115,7 +144082,7 @@ async function ensureActiveSessionSummary(chatId, worktreePath) {
144115
144082
  });
144116
144083
  return getChat(chatId);
144117
144084
  } catch (err) {
144118
- log24.warn({ chatId, err }, "ensureActiveSessionSummary failed");
144085
+ log23.warn({ chatId, err }, "ensureActiveSessionSummary failed");
144119
144086
  return chat;
144120
144087
  }
144121
144088
  }
@@ -144152,7 +144119,7 @@ async function doRefresh(chatId, worktreePath) {
144152
144119
  lastModified: latest.lastModified
144153
144120
  });
144154
144121
  } catch (err) {
144155
- log24.warn({ chatId, err }, "active session refresh failed");
144122
+ log23.warn({ chatId, err }, "active session refresh failed");
144156
144123
  }
144157
144124
  }
144158
144125
 
@@ -144562,7 +144529,7 @@ function fuzzyScore(query, filePath) {
144562
144529
  // src/lib/terminal-config.ts
144563
144530
  init_src();
144564
144531
  init_zod();
144565
- var log25 = createLogger("terminal-config");
144532
+ var log24 = createLogger("terminal-config");
144566
144533
  var TerminalPaneConfigSchema = external_exports2.object({
144567
144534
  name: external_exports2.string().optional(),
144568
144535
  command: external_exports2.string().optional(),
@@ -144593,7 +144560,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
144593
144560
  if (!terminalBlock) return null;
144594
144561
  const result = WorkspaceTerminalConfigSchema.safeParse(terminalBlock);
144595
144562
  if (!result.success) {
144596
- log25.warn(
144563
+ log24.warn(
144597
144564
  "Invalid workspace.terminal config: %s",
144598
144565
  result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join("; ")
144599
144566
  );
@@ -144604,7 +144571,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
144604
144571
 
144605
144572
  // src/trpc/router.ts
144606
144573
  var execFileAsync = promisify(execFile5);
144607
- var log26 = createLogger("trpc");
144574
+ var log25 = createLogger("trpc");
144608
144575
  var t2 = initTRPC.context().create();
144609
144576
  var publicProcedure = t2.procedure;
144610
144577
  var projectsRouter = t2.router({
@@ -144837,6 +144804,17 @@ var workspacesRouter = t2.router({
144837
144804
  killWorkspaceServers(workspaceId);
144838
144805
  stopJobsForKey(workspaceId);
144839
144806
  deleteCronjobFile(workspaceId);
144807
+ try {
144808
+ const deletedTasks = deleteWorkspaceTasks(workspaceId);
144809
+ if (deletedTasks > 0) {
144810
+ log25.info(
144811
+ { workspaceId, count: deletedTasks },
144812
+ "deleted workspace tasks on removal"
144813
+ );
144814
+ }
144815
+ } catch (err) {
144816
+ log25.error({ workspaceId, err }, "failed to delete workspace tasks on removal");
144817
+ }
144840
144818
  emit({ kind: "remove", workspaceId });
144841
144819
  const projPath = proj.path;
144842
144820
  setImmediate(() => {
@@ -144853,7 +144831,7 @@ var workspacesRouter = t2.router({
144853
144831
  timeout: 6e4
144854
144832
  });
144855
144833
  } catch (err) {
144856
- log26.warn({ err, workspaceId }, "teardown script failed");
144834
+ log25.warn({ err, workspaceId }, "teardown script failed");
144857
144835
  }
144858
144836
  }
144859
144837
  try {
@@ -144871,7 +144849,7 @@ var workspacesRouter = t2.router({
144871
144849
  encoding: "utf-8"
144872
144850
  });
144873
144851
  } catch (err) {
144874
- log26.warn({ err, workspaceId }, "git worktree prune failed");
144852
+ log25.warn({ err, workspaceId }, "git worktree prune failed");
144875
144853
  }
144876
144854
  }
144877
144855
  try {
@@ -144883,7 +144861,7 @@ var workspacesRouter = t2.router({
144883
144861
  } catch {
144884
144862
  }
144885
144863
  })().catch((err) => {
144886
- log26.error({ err, workspaceId }, "background workspace cleanup failed");
144864
+ log25.error({ err, workspaceId }, "background workspace cleanup failed");
144887
144865
  });
144888
144866
  });
144889
144867
  return { ok: true };
@@ -145168,7 +145146,7 @@ var workspaceRouter = t2.router({
145168
145146
  );
145169
145147
  branches = output.trim().split("\n").map((b10) => b10.trim()).filter(Boolean);
145170
145148
  } catch (err) {
145171
- log26.error(
145149
+ log25.error(
145172
145150
  `listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
145173
145151
  );
145174
145152
  }
@@ -145822,35 +145800,81 @@ var workspaceRouter = t2.router({
145822
145800
  throw new Error("Workspace not found");
145823
145801
  }
145824
145802
  const cwd = workspace.worktree.path;
145825
- const args = ["grep", "-n", "--no-color", "-I"];
145826
- if (input.regex) {
145827
- args.push("-E");
145828
- } else {
145829
- args.push("-F");
145830
- }
145831
- if (!input.caseSensitive) args.push("-i");
145832
- if (input.wholeWord) args.push("-w");
145833
- args.push("--", input.query);
145834
- let output;
145835
- try {
145836
- output = await execGit(args, cwd);
145837
- } catch {
145838
- return { results: [] };
145839
- }
145840
- const lines = output.trim().split("\n").filter(Boolean);
145841
- const results = [];
145842
- for (const raw of lines) {
145843
- if (results.length >= input.limit) break;
145844
- const colonIdx1 = raw.indexOf(":");
145845
- if (colonIdx1 === -1) continue;
145846
- const colonIdx2 = raw.indexOf(":", colonIdx1 + 1);
145847
- if (colonIdx2 === -1) continue;
145848
- const file2 = raw.slice(0, colonIdx1);
145849
- const line2 = Number.parseInt(raw.slice(colonIdx1 + 1, colonIdx2), 10);
145850
- const content2 = raw.slice(colonIdx2 + 1);
145851
- results.push({ file: file2, line: line2, content: content2 });
145852
- }
145853
- return { results };
145803
+ const args = [];
145804
+ if (!input.caseSensitive) args.push("--ignore-case");
145805
+ if (input.wholeWord) args.push("--word-regexp");
145806
+ if (!input.regex) args.push("--fixed-strings");
145807
+ args.push("--json");
145808
+ args.push("--", input.query, "./");
145809
+ return await new Promise((resolvePromise, rejectPromise) => {
145810
+ const results = [];
145811
+ const child = spawn8(rgPath, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
145812
+ let stdoutBuf = "";
145813
+ let stderrBuf = "";
145814
+ let settled = false;
145815
+ let killed = false;
145816
+ const finish = (value) => {
145817
+ if (settled) return;
145818
+ settled = true;
145819
+ resolvePromise({ results: value });
145820
+ };
145821
+ const fail = (err) => {
145822
+ if (settled) return;
145823
+ settled = true;
145824
+ rejectPromise(err);
145825
+ };
145826
+ child.stdout.setEncoding("utf-8");
145827
+ child.stdout.on("data", (chunk) => {
145828
+ if (settled) return;
145829
+ stdoutBuf += chunk;
145830
+ while (true) {
145831
+ const nlIdx = stdoutBuf.indexOf("\n");
145832
+ if (nlIdx === -1) break;
145833
+ const line2 = stdoutBuf.slice(0, nlIdx);
145834
+ stdoutBuf = stdoutBuf.slice(nlIdx + 1);
145835
+ if (!line2) continue;
145836
+ let event;
145837
+ try {
145838
+ event = JSON.parse(line2);
145839
+ } catch {
145840
+ continue;
145841
+ }
145842
+ if (event.type !== "match") continue;
145843
+ const data = event.data;
145844
+ if (!data) continue;
145845
+ const rawFile = data.path?.text;
145846
+ const lineNumber = data.line_number;
145847
+ const rawContent = data.lines?.text;
145848
+ if (!rawFile || typeof lineNumber !== "number" || rawContent === void 0) {
145849
+ continue;
145850
+ }
145851
+ const file2 = rawFile.startsWith("./") ? rawFile.slice(2) : rawFile;
145852
+ const content2 = rawContent.endsWith("\n") ? rawContent.slice(0, -1) : rawContent;
145853
+ results.push({ file: file2, line: lineNumber, content: content2 });
145854
+ if (results.length >= input.limit) {
145855
+ killed = true;
145856
+ child.kill("SIGTERM");
145857
+ finish(results);
145858
+ return;
145859
+ }
145860
+ }
145861
+ });
145862
+ child.stderr.setEncoding("utf-8");
145863
+ child.stderr.on("data", (chunk) => {
145864
+ stderrBuf += chunk;
145865
+ });
145866
+ child.on("error", (err) => {
145867
+ fail(err);
145868
+ });
145869
+ child.on("close", (code) => {
145870
+ if (settled) return;
145871
+ if (code === 0 || code === 1 || killed) {
145872
+ finish(results);
145873
+ } else {
145874
+ fail(new Error(`ripgrep exited with code ${code}: ${stderrBuf.trim()}`));
145875
+ }
145876
+ });
145877
+ });
145854
145878
  }),
145855
145879
  switchAgent: publicProcedure.input(
145856
145880
  external_exports2.object({
@@ -145881,21 +145905,21 @@ var tunnelRouter = t2.router({
145881
145905
  return getTunnelStatus();
145882
145906
  }),
145883
145907
  start: publicProcedure.input(external_exports2.object({}).optional()).mutation(async () => {
145884
- log26.debug("tunnel.start called");
145908
+ log25.debug("tunnel.start called");
145885
145909
  const port2 = parseInt(process.env.BAND_PORT || "3456", 10);
145886
- log26.debug("tunnel.start: port=%d", port2);
145910
+ log25.debug("tunnel.start: port=%d", port2);
145887
145911
  try {
145888
145912
  await startTunnel({ port: port2 });
145889
145913
  } catch (err) {
145890
- log26.debug({ err }, "tunnel.start: startTunnel failed");
145914
+ log25.debug({ err }, "tunnel.start: startTunnel failed");
145891
145915
  return { ok: true, url: null };
145892
145916
  }
145893
145917
  const status = getTunnelStatus();
145894
- log26.debug({ status }, "tunnel.start: after startTunnel");
145918
+ log25.debug({ status }, "tunnel.start: after startTunnel");
145895
145919
  if (status.url) {
145896
145920
  return { ok: true, url: status.url };
145897
145921
  }
145898
- log26.debug("tunnel.start: no URL available");
145922
+ log25.debug("tunnel.start: no URL available");
145899
145923
  return { ok: true, url: null };
145900
145924
  }),
145901
145925
  stop: publicProcedure.mutation(async () => {
@@ -146221,15 +146245,15 @@ async function loadJsonlPage(opts) {
146221
146245
  }
146222
146246
  var servicesRouter = t2.router({
146223
146247
  health: publicProcedure.query(() => {
146224
- log26.debug("services.health called");
146248
+ log25.debug("services.health called");
146225
146249
  const tunnel = getTunnelStatus();
146226
- log26.debug({ tunnel }, "services.health: tunnel status");
146250
+ log25.debug({ tunnel }, "services.health: tunnel status");
146227
146251
  const result = {
146228
146252
  webserver: true,
146229
146253
  tunnel: tunnel.running,
146230
146254
  tunnel_url: tunnel.url
146231
146255
  };
146232
- log26.debug({ result }, "services.health result");
146256
+ log25.debug({ result }, "services.health result");
146233
146257
  return result;
146234
146258
  }),
146235
146259
  // Activity level controls how often the branch-status poller fires.
@@ -146623,7 +146647,7 @@ var chatsRouter = t2.router({
146623
146647
  summary = info?.summary;
146624
146648
  lastModified = info?.lastModified;
146625
146649
  } catch (err) {
146626
- log26.warn(
146650
+ log25.warn(
146627
146651
  { chatId: input.chatId, sessionId: input.sessionId, err },
146628
146652
  "setActiveSession: getSessionInfo failed"
146629
146653
  );
@@ -146743,7 +146767,7 @@ var browserHostRouter = t2.router({
146743
146767
  // can confirm in the server log that the bridge component actually
146744
146768
  // executed. Drop once the experiment is stable.
146745
146769
  ping: publicProcedure.input(external_exports2.object({ where: external_exports2.string() })).mutation(({ input }) => {
146746
- log26.info("browserHost.ping from %s", input.where);
146770
+ log25.info("browserHost.ping from %s", input.where);
146747
146771
  return { ok: true };
146748
146772
  }),
146749
146773
  ensureView: publicProcedure.subscription(async function* (opts) {
@@ -147303,6 +147327,7 @@ async function main() {
147303
147327
  runMigrations();
147304
147328
  loadChatsFromDb();
147305
147329
  cleanupStaleTasks();
147330
+ startTaskPruneScheduler();
147306
147331
  const resetCount = resetAgentStatuses();
147307
147332
  if (resetCount > 0) {
147308
147333
  console.log(`Reset ${resetCount} stale agent status(es) on startup`);
@@ -147553,6 +147578,7 @@ async function main() {
147553
147578
  const shutdown = async () => {
147554
147579
  stopBranchStatusPoller();
147555
147580
  stopCronjobScheduler();
147581
+ stopTaskPruneScheduler();
147556
147582
  killAllTerminals();
147557
147583
  killAllServers();
147558
147584
  await stopTunnel().catch(() => {