@band-app/server 0.15.0 → 0.16.3
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.
- package/dist/client/assets/{DockviewTerminalContainer-DJBIrF63.js → DockviewTerminalContainer-D2lnsm6V.js} +2 -2
- package/dist/client/assets/TerminalPanel-SEbvgXv_.js +4 -0
- package/dist/client/assets/{_basePickBy-Dc0lZvrW.js → _basePickBy-C-uqClKF.js} +1 -1
- package/dist/client/assets/{_baseUniq-Cf73kSyg.js → _baseUniq-sN_xdSud.js} +1 -1
- package/dist/client/assets/{arc-CwSM8pE7.js → arc-DOqEiCLs.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-CH39Gb3A.js → architectureDiagram-VXUJARFQ-DqRs-Rmj.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-DDxgl1uo.js → blockDiagram-VD42YOAC-Dxh5tO7I.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-BfEjKk-g.js → c4Diagram-YG6GDRKO-CykynX-A.js} +1 -1
- package/dist/client/assets/channel-DijZVjmy.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-m8XoXk_H.js → chunk-4BX2VUAB-BckEbEmg.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CtGE4lZU.js → chunk-55IACEB6-Ds9A0UL5.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-e8RHFxfZ.js → chunk-B4BG7PRW-BbdA9dFb.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-6OH7qKMA.js → chunk-DI55MBZ5-C10prUQu.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-OC-xaPXK.js → chunk-FMBD7UC4-CMO5VhEI.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-OAk8wo3f.js → chunk-QN33PNHL-BrbSzW7G.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BQaX9Wrw.js → chunk-QZHKN3VN-BjFQUCU6.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-BB9WpJAf.js → chunk-TZMSLE5B-B6ZDwm2_.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-DkjTgKpR.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-DkjTgKpR.js +1 -0
- package/dist/client/assets/clone-DTHwmURu.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-C9h_X8Kk.js → cose-bilkent-S5V4N54A-DbSjwZ4l.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-DqYC11ua.js → dagre-6UL2VRFP-Q5hxi0O0.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-CI1DRC6A.js → diagram-PSM6KHXK-D7kyAUq5.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-fCfXFf0Y.js → diagram-QEK2KX5R-B7mpl_Jj.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-ShkC9z2o.js → diagram-S2PKOQOG-CcIvSvFS.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-CaIQw3Ar.js → erDiagram-Q2GNP2WA-M2OHKSFi.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-CBTayrED.js → flowDiagram-NV44I4VS-Ot2zCa0t.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-BXX1Htdo.js → ganttDiagram-JELNMOA3-Dtl6PI3C.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-Dwzg4ngG.js → gitGraphDiagram-V2S2FVAM-DJCTwkyi.js} +1 -1
- package/dist/client/assets/{graph-CiXo3Prx.js → graph-DhvBAydB.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-7aLtgz8i.js → highlighted-body-B3W2YXNL-C6fHuUGl.js} +1 -1
- package/dist/client/assets/{index-Du9yJkB_.js → index-26c50Xcq.js} +1 -1
- package/dist/client/assets/index-B1K9dSWl.js +1 -0
- package/dist/client/assets/{index-C1zwysWn.js → index-B7VmPIW6.js} +1 -1
- package/dist/client/assets/{index-De1kIhJh.js → index-BBv9ZEF9.js} +1 -1
- package/dist/client/assets/{index-CVm5Qdu2.js → index-BDHBx5UL.js} +1 -1
- package/dist/client/assets/{index-BMWcJGJE.js → index-BUTfo7TS.js} +1 -1
- package/dist/client/assets/{index-Cg6YccFW.js → index-BYvWvSws.js} +1 -1
- package/dist/client/assets/{index-DmilV26W.js → index-CDbyr_lc.js} +1 -1
- package/dist/client/assets/{index-DQmzIoYb.js → index-CHGnZzhm.js} +1 -1
- package/dist/client/assets/{index-DRtcpY-M.js → index-CKHhLCNz.js} +1 -1
- package/dist/client/assets/{index-Gs7HImF7.js → index-CfsvL24Z.js} +1 -1
- package/dist/client/assets/{index-BCNUajNr.js → index-CjXcgzNg.js} +1 -1
- package/dist/client/assets/{index-DypgdPcb.js → index-CuNktTO3.js} +1 -1
- package/dist/client/assets/{index-CO6I2abN.js → index-DDe15mVl.js} +1 -1
- package/dist/client/assets/{index-CfYqVQ5p.js → index-I4Tc5Cuc.js} +1 -1
- package/dist/client/assets/{index-Di4toQJ5.js → index-MZ-6_xYm.js} +1 -1
- package/dist/client/assets/{index-DZu_2Bx_.js → index-SeTSJcqN.js} +1 -1
- package/dist/client/assets/{index-CR-ehys5.js → index-_yteHBmq.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-CWD1TyOW.js → infoDiagram-HS3SLOUP-CbAjFJUe.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-DhxNYqmd.js → journeyDiagram-XKPGCS4Q-Bf_0viAE.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-CnS4C6i0.js → kanban-definition-3W4ZIXB7-CB2ylbw7.js} +1 -1
- package/dist/client/assets/{layout-CSID7t17.js → layout-Cp_4dcMO.js} +1 -1
- package/dist/client/assets/{linear-DoyBnBXg.js → linear-D1KyszeO.js} +1 -1
- package/dist/client/assets/main-CBJTAZFq.css +1 -0
- package/dist/client/assets/{main-DqsO5O95.js → main-Cl2c5yKs.js} +236 -236
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-DInqVMnG.js → mindmap-definition-VGOIOE7T-Cm_2Y7ZK.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-9NXrhDdT.js → pieDiagram-ADFJNKIX-C9PiUHN5.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-C9V_pdwH.js → quadrantDiagram-AYHSOK5B-Cj0nbFw-.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-D7InXBsj.js → requirementDiagram-UZGBJVZJ-BVgceiyR.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-wucasjR9.js → sankeyDiagram-TZEHDZUN-D7dheggz.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-z8y3Dw_f.js → sequenceDiagram-WL72ISMW-DVDMYgkc.js} +1 -1
- package/dist/client/assets/{square-terminal-BGmf1D-6.js → square-terminal-C64ybmC7.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-UgwHItEV.js → stateDiagram-FKZM4ZOC-ClAcB9Xo.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BH91aEUE.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-BFRCSYLj.js → timeline-definition-IT6M3QCI-Cs1CMQvF.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-aQmWnuZQ.js → treemap-GDKQZRPO-DerMxDGL.js} +1 -1
- package/dist/client/assets/{useSessionListContext-HoR6j8FY.js → useSessionListContext-BcM5_lz3.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId-DGCQw9gi.js → workspace._workspaceId-C4dZT1kN.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.changes-DBE9NcLH.js → workspace._workspaceId.changes-BbnFHDel.js} +1 -1
- package/dist/client/assets/workspace._workspaceId.code-5MY9mEL9.js +1 -0
- package/dist/client/assets/{workspace._workspaceId.code._-CsnvG2rj.js → workspace._workspaceId.code._-DRRjmZ4D.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.code.index-BdfNmZpz.js → workspace._workspaceId.code.index-CQLsjESL.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.index-C7NyedGf.js → workspace._workspaceId.index-CE3X4XHe.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.terminal-C5ph2UWn.js → workspace._workspaceId.terminal-0Iuu4wZI.js} +2 -2
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-DElSdzdM.js → xychartDiagram-PRI3JC2R-BVo__gVD.js} +1 -1
- package/dist/migrations/20260518175010_wealthy_talon/migration.sql +1 -0
- package/dist/migrations/20260518175010_wealthy_talon/snapshot.json +856 -0
- package/dist/openapi.json +11356 -0
- package/dist/server/assets/{DockviewTerminalContainer-Btn06b30.js → DockviewTerminalContainer-RbFw8Eo4.js} +3 -3
- package/dist/server/assets/{TerminalPanel-DiuUhPK5.js → TerminalPanel-BS0KF1ac.js} +52 -22
- package/dist/server/assets/{_basePickBy-D5WFbUhD.js → _basePickBy-Vtp-JFm9.js} +2 -2
- package/dist/server/assets/{_baseUniq-DFZeWlPn.js → _baseUniq-CRtvsDi1.js} +1 -1
- package/dist/server/assets/{_tanstack-start-manifest_v-UCApGYfd.js → _tanstack-start-manifest_v-787sukfk.js} +1 -1
- package/dist/server/assets/{arc-B1QmYB3V.js → arc-ChWehBm_.js} +1 -1
- package/dist/server/assets/{architecture-7HQA4BMR-SXElPY6g.js → architecture-7HQA4BMR-BiLezQsp.js} +6 -6
- package/dist/server/assets/{architectureDiagram-VXUJARFQ-H4ZI6Opr.js → architectureDiagram-VXUJARFQ-tjTQ4ZaT.js} +6 -6
- package/dist/server/assets/{blockDiagram-VD42YOAC-UhTmqpkK.js → blockDiagram-VD42YOAC-C0oBPtSv.js} +6 -6
- package/dist/server/assets/{c4Diagram-YG6GDRKO-BcLh1QQl.js → c4Diagram-YG6GDRKO-nGE1cXwD.js} +2 -2
- package/dist/server/assets/{channel-DVtl256s.js → channel-CqQOLgw9.js} +1 -1
- package/dist/server/assets/{chunk-4BX2VUAB-BYUElNcW.js → chunk-4BX2VUAB-DrJXJmx5.js} +1 -1
- package/dist/server/assets/{chunk-55IACEB6-CQXVz3Ix.js → chunk-55IACEB6-CKxRFH9J.js} +1 -1
- package/dist/server/assets/{chunk-B4BG7PRW-xbFaXlOL.js → chunk-B4BG7PRW-BxyNZV2w.js} +4 -4
- package/dist/server/assets/{chunk-DI55MBZ5-BWUyQjGD.js → chunk-DI55MBZ5-CajwqGPE.js} +3 -3
- package/dist/server/assets/{chunk-FMBD7UC4-tuJ9minw.js → chunk-FMBD7UC4-D1CO-v-G.js} +1 -1
- package/dist/server/assets/{chunk-QN33PNHL-B9p522HA.js → chunk-QN33PNHL-D4KiZklP.js} +1 -1
- package/dist/server/assets/{chunk-QZHKN3VN-C6GPdMrh.js → chunk-QZHKN3VN-CNElfh9C.js} +1 -1
- package/dist/server/assets/{chunk-TZMSLE5B-6Ng3t3Od.js → chunk-TZMSLE5B-CHBqvPAr.js} +1 -1
- package/dist/server/assets/{classDiagram-v2-WZHVMYZB-BvOdRP7s.js → classDiagram-2ON5EDUG-D3C4Rk7Q.js} +5 -5
- package/dist/server/assets/{classDiagram-2ON5EDUG-BvOdRP7s.js → classDiagram-v2-WZHVMYZB-D3C4Rk7Q.js} +5 -5
- package/dist/server/assets/{clone-CuDKCzEN.js → clone-DsPS0_DH.js} +1 -1
- package/dist/server/assets/{cose-bilkent-S5V4N54A-BhU6LMhN.js → cose-bilkent-S5V4N54A-V_MYkZlm.js} +1 -1
- package/dist/server/assets/{dagre-6UL2VRFP-CH-VbyTI.js → dagre-6UL2VRFP-D_Mh5gNH.js} +6 -6
- package/dist/server/assets/{diagram-PSM6KHXK-BE0vVJdc.js → diagram-PSM6KHXK-B9dGPsE9.js} +7 -7
- package/dist/server/assets/{diagram-QEK2KX5R-rlYyF51_.js → diagram-QEK2KX5R-BcfmavO-.js} +6 -6
- package/dist/server/assets/{diagram-S2PKOQOG-CsrxbKjr.js → diagram-S2PKOQOG-B8urPf9c.js} +6 -6
- package/dist/server/assets/{erDiagram-Q2GNP2WA-DeBKeqCX.js → erDiagram-Q2GNP2WA-CzG0zKt-.js} +4 -4
- package/dist/server/assets/{flowDiagram-NV44I4VS-hg6b4dSR.js → flowDiagram-NV44I4VS-Bk7aIalC.js} +5 -5
- package/dist/server/assets/{ganttDiagram-JELNMOA3-oy5gzveG.js → ganttDiagram-JELNMOA3-wmt8nm9q.js} +2 -2
- package/dist/server/assets/{gitGraph-G5XIXVHT-DyKGpXFt.js → gitGraph-G5XIXVHT-CmiFNHiv.js} +6 -6
- package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-CN8rFh7o.js → gitGraphDiagram-V2S2FVAM-OV2DR1Ux.js} +7 -7
- package/dist/server/assets/{graph-CdsnxBHP.js → graph-ziMVg61H.js} +2 -2
- package/dist/server/assets/{highlighted-body-B3W2YXNL-D6ahbJdi.js → highlighted-body-B3W2YXNL-DX00yTJM.js} +1 -1
- package/dist/server/assets/{index-BJorH749.js → index-9M09S61v.js} +2 -2
- package/dist/server/assets/{index-Crgd09US.js → index-B5x9IUkQ.js} +2 -2
- package/dist/server/assets/{index-CaRM9svU.js → index-BvBMEwhL.js} +4 -4
- package/dist/server/assets/{index-D2P0pxCr.js → index-C-k9sCKq.js} +2 -2
- package/dist/server/assets/{index-BhJN38EV.js → index-CKmyLecf.js} +2 -2
- package/dist/server/assets/{index-DsLZMKNC.js → index-CXnsJrX8.js} +5 -5
- package/dist/server/assets/{index-CchdHjwq.js → index-Ce2uXVrE.js} +2 -2
- package/dist/server/assets/{index-BT8sxrq0.js → index-CiWhFogO.js} +2 -2
- package/dist/server/assets/{index-CsnrxvSd.js → index-D5nqcxSY.js} +3 -3
- package/dist/server/assets/{index-BzYp7sVL.js → index-DLmI6-iR.js} +1 -1
- package/dist/server/assets/{index-C9H7VUtp.js → index-DNaA-OTp.js} +2 -2
- package/dist/server/assets/{index-7k2BqwZv.js → index-DPAkuW3l.js} +2 -2
- package/dist/server/assets/{index-XaoY6ovr.js → index-VtjR2oZj.js} +2 -2
- package/dist/server/assets/{index-DBbuiN2t.js → index-ayG05uhc.js} +3 -3
- package/dist/server/assets/{index-B9hFfb3C.js → index-l8a7u6GS.js} +2 -2
- package/dist/server/assets/{index-Dp5TbN68.js → index-sKmEy2Z2.js} +5 -5
- package/dist/server/assets/{index-aOrOBCQS.js → index-sbo2EHgw.js} +2 -2
- package/dist/server/assets/{index-DIv5BUol.js → index-xVhCXu45.js} +2 -2
- package/dist/server/assets/{info-VBDWY6EO-HckNvgz-.js → info-VBDWY6EO-muqpsCRw.js} +6 -6
- package/dist/server/assets/{infoDiagram-HS3SLOUP-P_hugt8D.js → infoDiagram-HS3SLOUP-D8EoxteQ.js} +5 -5
- package/dist/server/assets/{journeyDiagram-XKPGCS4Q-lQfkL_-i.js → journeyDiagram-XKPGCS4Q-BwZk-fnC.js} +4 -4
- package/dist/server/assets/{kanban-definition-3W4ZIXB7-CFh-YdaO.js → kanban-definition-3W4ZIXB7-DEfYos8T.js} +2 -2
- package/dist/server/assets/{layout-Ce1d_Ibk.js → layout-CKMmyz2h.js} +4 -4
- package/dist/server/assets/{linear-CuiUQTrq.js → linear-DXR7qYUB.js} +1 -1
- package/dist/server/assets/{mermaid-3ZIDBTTL-C7xGj9Xg.js → mermaid-3ZIDBTTL-DxhML77C.js} +1 -1
- package/dist/server/assets/{mermaid-parser.core-BOlp9l_E.js → mermaid-parser.core-DBGA5y48.js} +11 -11
- package/dist/server/assets/{mindmap-definition-VGOIOE7T-Byc-qFo2.js → mindmap-definition-VGOIOE7T-Bg8B0Ls9.js} +3 -3
- package/dist/server/assets/{packet-DYOGHKS2-BiRLh9CC.js → packet-DYOGHKS2-CnH_YgfD.js} +6 -6
- package/dist/server/assets/{pie-VRWISCQL-hgf7Lgm4.js → pie-VRWISCQL-iceCWNPC.js} +6 -6
- package/dist/server/assets/{pieDiagram-ADFJNKIX-YXV3ET4_.js → pieDiagram-ADFJNKIX-Bw3RR9nb.js} +7 -7
- package/dist/server/assets/{quadrantDiagram-AYHSOK5B-r_peNHCA.js → quadrantDiagram-AYHSOK5B-CpLsW_Ir.js} +2 -2
- package/dist/server/assets/{radar-ZZBFDIW7-CGIDKJlK.js → radar-ZZBFDIW7-Bab4MCR4.js} +6 -6
- package/dist/server/assets/{requirementDiagram-UZGBJVZJ-aI3jQPLf.js → requirementDiagram-UZGBJVZJ-DkGtaEnw.js} +3 -3
- package/dist/server/assets/{router-BNIoB7QX.js → router-yk-AJHab.js} +1119 -880
- package/dist/server/assets/{sankeyDiagram-TZEHDZUN-B1Sb9Zvd.js → sankeyDiagram-TZEHDZUN-CtEV3_Bx.js} +1 -1
- package/dist/server/assets/{sequenceDiagram-WL72ISMW-DrJxigNy.js → sequenceDiagram-WL72ISMW-BMW4qEme.js} +3 -3
- package/dist/server/assets/{square-terminal-DWTC1p8r.js → square-terminal-Bui9B6KN.js} +1 -1
- package/dist/server/assets/{stateDiagram-FKZM4ZOC-Dnsp85zH.js → stateDiagram-FKZM4ZOC-C7xazM8E.js} +8 -8
- package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-C6x8SVRv.js → stateDiagram-v2-4FDKWEC3-D_rYvDGP.js} +4 -4
- package/dist/server/assets/{timeline-definition-IT6M3QCI-DSIrepaO.js → timeline-definition-IT6M3QCI-BaAlfxrc.js} +2 -2
- package/dist/server/assets/{treemap-GDKQZRPO-C9hefMmZ.js → treemap-GDKQZRPO-DlP1TABE.js} +6 -6
- package/dist/server/assets/{workspace._workspaceId-BY5hpCRH.js → workspace._workspaceId-Be45P7LL.js} +2 -2
- package/dist/server/assets/{workspace._workspaceId.changes-CiekaeTG.js → workspace._workspaceId.changes-EoyIscxQ.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.code._-Bi-RxK7c.js → workspace._workspaceId.code._-CcX7Gt0G.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.code.index-DRR8qo6z.js → workspace._workspaceId.code.index-CFbCDVph.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.index-BRFgw3FA.js → workspace._workspaceId.index-DmYHy6nH.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.terminal-BhyASMi7.js → workspace._workspaceId.terminal-D_KPwmYr.js} +2 -2
- package/dist/server/assets/{xychartDiagram-PRI3JC2R-0ftH7hFg.js → xychartDiagram-PRI3JC2R-Cq7t_yS-.js} +2 -2
- package/dist/server/server.js +2 -2
- package/dist/start-server.mjs +710 -467
- package/package.json +6 -5
- package/dist/client/assets/TerminalPanel-CJRwWyR3.js +0 -4
- package/dist/client/assets/channel-CXGOk1aw.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-CN-WyCFd.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-CN-WyCFd.js +0 -1
- package/dist/client/assets/clone-BLJrTeWA.js +0 -1
- package/dist/client/assets/index-eX1Ljh4a.js +0 -1
- package/dist/client/assets/main-DYrDxnSM.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-B0Y2fSqT.js +0 -1
- package/dist/client/assets/workspace._workspaceId.code-Cc2uBW1l.js +0 -1
package/dist/start-server.mjs
CHANGED
|
@@ -6501,11 +6501,11 @@ var require_tools = __commonJS({
|
|
|
6501
6501
|
}
|
|
6502
6502
|
}
|
|
6503
6503
|
}
|
|
6504
|
-
function buildFormatters(level, bindings,
|
|
6504
|
+
function buildFormatters(level, bindings, log28) {
|
|
6505
6505
|
return {
|
|
6506
6506
|
level,
|
|
6507
6507
|
bindings,
|
|
6508
|
-
log:
|
|
6508
|
+
log: log28
|
|
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:
|
|
6891
|
+
const { level, bindings: chindings, log: log28 } = options2.formatters;
|
|
6892
6892
|
instance[formattersSym] = buildFormatters(
|
|
6893
6893
|
level || formatters.level,
|
|
6894
6894
|
chindings || resetChildingsFormatter,
|
|
6895
|
-
|
|
6895
|
+
log28 || formatters.log
|
|
6896
6896
|
);
|
|
6897
6897
|
} else {
|
|
6898
6898
|
instance[formattersSym] = buildFormatters(
|
|
@@ -86574,11 +86574,11 @@ var require_core = __commonJS({
|
|
|
86574
86574
|
Ajv2.ValidationError = validation_error_1.default;
|
|
86575
86575
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
86576
86576
|
exports.default = Ajv2;
|
|
86577
|
-
function checkOptions(checkOpts, options2, msg,
|
|
86577
|
+
function checkOptions(checkOpts, options2, msg, log28 = "error") {
|
|
86578
86578
|
for (const key in checkOpts) {
|
|
86579
86579
|
const opt = key;
|
|
86580
86580
|
if (opt in options2)
|
|
86581
|
-
this.logger[
|
|
86581
|
+
this.logger[log28](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
86582
86582
|
}
|
|
86583
86583
|
}
|
|
86584
86584
|
function getSchEnv(keyRef) {
|
|
@@ -108374,7 +108374,7 @@ init_src();
|
|
|
108374
108374
|
|
|
108375
108375
|
// src/lib/state.ts
|
|
108376
108376
|
import { randomBytes } from "node:crypto";
|
|
108377
|
-
import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync } from "node:fs";
|
|
108377
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync } from "node:fs";
|
|
108378
108378
|
import { homedir as homedir6 } from "node:os";
|
|
108379
108379
|
import { dirname, join as join11 } from "node:path";
|
|
108380
108380
|
|
|
@@ -120182,12 +120182,15 @@ var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
|
|
|
120182
120182
|
var import_react19 = __toESM(require_react(), 1);
|
|
120183
120183
|
var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
|
|
120184
120184
|
|
|
120185
|
+
// ../../packages/dashboard-core/src/components/PromoteToGitDialog.tsx
|
|
120186
|
+
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
|
|
120187
|
+
|
|
120185
120188
|
// ../../packages/dashboard-core/src/components/WorkspaceCard.tsx
|
|
120186
120189
|
var import_lucide_react5 = __toESM(require_lucide_react(), 1);
|
|
120187
120190
|
var import_react20 = __toESM(require_react(), 1);
|
|
120188
120191
|
|
|
120189
120192
|
// ../../packages/dashboard-core/src/components/GitStatusIndicator.tsx
|
|
120190
|
-
var
|
|
120193
|
+
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
|
|
120191
120194
|
function GitStatusIndicator({ git }) {
|
|
120192
120195
|
const parts = [];
|
|
120193
120196
|
if (git.conflict) {
|
|
@@ -120219,27 +120222,27 @@ function GitStatusIndicator({ git }) {
|
|
|
120219
120222
|
});
|
|
120220
120223
|
}
|
|
120221
120224
|
if (parts.length === 0) return null;
|
|
120222
|
-
return /* @__PURE__ */ (0,
|
|
120223
|
-
/* @__PURE__ */ (0,
|
|
120224
|
-
/* @__PURE__ */ (0,
|
|
120225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(Tooltip2, { children: [
|
|
120226
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "inline-flex items-center gap-0.5 font-mono text-[11px] leading-none shrink-0 pr-0.5", children: parts.map((p6) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: p6.color, children: p6.text }, p6.text)) }) }),
|
|
120227
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(TooltipContent2, { children: parts.map((p6) => p6.tooltip).join(", ") })
|
|
120225
120228
|
] });
|
|
120226
120229
|
}
|
|
120227
120230
|
|
|
120228
120231
|
// ../../packages/dashboard-core/src/components/SetupStatusIndicator.tsx
|
|
120229
120232
|
var import_lucide_react4 = __toESM(require_lucide_react(), 1);
|
|
120230
|
-
var
|
|
120233
|
+
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
120231
120234
|
function SetupStatusIndicator({ setup }) {
|
|
120232
120235
|
if (!setup) return null;
|
|
120233
120236
|
if (setup.state === "running") {
|
|
120234
|
-
return /* @__PURE__ */ (0,
|
|
120235
|
-
/* @__PURE__ */ (0,
|
|
120236
|
-
/* @__PURE__ */ (0,
|
|
120237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Tooltip2, { children: [
|
|
120238
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react4.Loader, { className: "size-3.5 shrink-0 text-blue-600 dark:text-blue-400 animate-spin" }) }),
|
|
120239
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TooltipContent2, { side: "top", children: "Setting up workspace..." })
|
|
120237
120240
|
] });
|
|
120238
120241
|
}
|
|
120239
120242
|
if (setup.state === "failed") {
|
|
120240
|
-
return /* @__PURE__ */ (0,
|
|
120241
|
-
/* @__PURE__ */ (0,
|
|
120242
|
-
/* @__PURE__ */ (0,
|
|
120243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Tooltip2, { children: [
|
|
120244
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react4.CircleAlert, { className: "size-3.5 shrink-0 text-red-600 dark:text-red-400" }) }),
|
|
120245
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(TooltipContent2, { side: "top", children: [
|
|
120243
120246
|
"Setup failed",
|
|
120244
120247
|
setup.error ? `: ${setup.error}` : ""
|
|
120245
120248
|
] })
|
|
@@ -120249,11 +120252,32 @@ function SetupStatusIndicator({ setup }) {
|
|
|
120249
120252
|
}
|
|
120250
120253
|
|
|
120251
120254
|
// ../../packages/dashboard-core/src/components/WorkspaceCard.tsx
|
|
120252
|
-
var
|
|
120255
|
+
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
120256
|
+
var RECENT_ACTIVATION_WINDOW_MS = 300;
|
|
120257
|
+
var recentlyActivatedWorkspaceId = null;
|
|
120258
|
+
var recentlyActivatedTimer = null;
|
|
120259
|
+
function markRecentActivation(workspaceId) {
|
|
120260
|
+
recentlyActivatedWorkspaceId = workspaceId;
|
|
120261
|
+
if (recentlyActivatedTimer) clearTimeout(recentlyActivatedTimer);
|
|
120262
|
+
recentlyActivatedTimer = setTimeout(() => {
|
|
120263
|
+
recentlyActivatedWorkspaceId = null;
|
|
120264
|
+
recentlyActivatedTimer = null;
|
|
120265
|
+
}, RECENT_ACTIVATION_WINDOW_MS);
|
|
120266
|
+
}
|
|
120267
|
+
function consumeRecentActivation(workspaceId) {
|
|
120268
|
+
if (recentlyActivatedWorkspaceId !== workspaceId) return false;
|
|
120269
|
+
recentlyActivatedWorkspaceId = null;
|
|
120270
|
+
if (recentlyActivatedTimer) {
|
|
120271
|
+
clearTimeout(recentlyActivatedTimer);
|
|
120272
|
+
recentlyActivatedTimer = null;
|
|
120273
|
+
}
|
|
120274
|
+
return true;
|
|
120275
|
+
}
|
|
120253
120276
|
var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
120254
120277
|
worktree,
|
|
120255
120278
|
projectName,
|
|
120256
120279
|
defaultBranch,
|
|
120280
|
+
projectKind,
|
|
120257
120281
|
status,
|
|
120258
120282
|
branchStatus,
|
|
120259
120283
|
setupStatus,
|
|
@@ -120262,13 +120286,9 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120262
120286
|
showProjectName,
|
|
120263
120287
|
onTogglePinned
|
|
120264
120288
|
}) {
|
|
120289
|
+
const isPlain = projectKind === "plain";
|
|
120265
120290
|
const cardRef = (0, import_react20.useRef)(null);
|
|
120266
120291
|
const capabilities = useCapabilities();
|
|
120267
|
-
(0, import_react20.useEffect)(() => {
|
|
120268
|
-
if (isFocused) {
|
|
120269
|
-
cardRef.current?.scrollIntoView({ block: "nearest" });
|
|
120270
|
-
}
|
|
120271
|
-
}, [isFocused]);
|
|
120272
120292
|
const openWorkspace = useDashboardStore((s6) => s6.openWorkspace);
|
|
120273
120293
|
const clearNeedsAttention = useDashboardStore((s6) => s6.clearNeedsAttention);
|
|
120274
120294
|
const runScript = useDashboardStore((s6) => s6.runScript);
|
|
@@ -120279,8 +120299,14 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120279
120299
|
const workspaceId = toWorkspaceId(projectName, worktree.branch);
|
|
120280
120300
|
const isActive = useDashboardStore((s6) => s6.activeWorkspaceId === workspaceId);
|
|
120281
120301
|
const href = capabilities.getWorkspaceHref?.(workspaceId);
|
|
120302
|
+
(0, import_react20.useEffect)(() => {
|
|
120303
|
+
if (!isActive) return;
|
|
120304
|
+
if (consumeRecentActivation(workspaceId)) return;
|
|
120305
|
+
cardRef.current?.scrollIntoView({ block: "center" });
|
|
120306
|
+
}, [isActive, workspaceId]);
|
|
120282
120307
|
const handleClick = () => {
|
|
120283
120308
|
clearNeedsAttention(workspaceId);
|
|
120309
|
+
markRecentActivation(workspaceId);
|
|
120284
120310
|
if (href && capabilities.navigate) {
|
|
120285
120311
|
capabilities.navigate(href);
|
|
120286
120312
|
} else if (!href) {
|
|
@@ -120292,6 +120318,12 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120292
120318
|
ref: cardRef,
|
|
120293
120319
|
className,
|
|
120294
120320
|
tabIndex: 0,
|
|
120321
|
+
// Semantic markers — let tests, screen readers, and future styling
|
|
120322
|
+
// changes target the active card without depending on the Tailwind
|
|
120323
|
+
// class string. `aria-current="page"` is the standard ARIA pattern for
|
|
120324
|
+
// "currently-active link in a list of related links".
|
|
120325
|
+
"data-active": isActive || void 0,
|
|
120326
|
+
"aria-current": isActive ? "page" : void 0,
|
|
120295
120327
|
onClick: (e2) => {
|
|
120296
120328
|
e2.stopPropagation();
|
|
120297
120329
|
handleClick();
|
|
@@ -120320,12 +120352,12 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120320
120352
|
});
|
|
120321
120353
|
}
|
|
120322
120354
|
};
|
|
120323
|
-
return /* @__PURE__ */ (0,
|
|
120324
|
-
/* @__PURE__ */ (0,
|
|
120325
|
-
/* @__PURE__ */ (0,
|
|
120326
|
-
/* @__PURE__ */ (0,
|
|
120327
|
-
/* @__PURE__ */ (0,
|
|
120328
|
-
/* @__PURE__ */ (0,
|
|
120355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenu2, { children: [
|
|
120356
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ContextMenuTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { ...containerProps, children: [
|
|
120357
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Tooltip2, { children: [
|
|
120358
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-2 min-w-0 overflow-hidden", children: [
|
|
120359
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(AgentStatusIndicator, { agent: status?.agent, isActive }),
|
|
120360
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
120329
120361
|
"span",
|
|
120330
120362
|
{
|
|
120331
120363
|
className: `text-sm truncate ${isActive ? "font-semibold text-foreground" : "font-medium text-muted-foreground"}`,
|
|
@@ -120333,46 +120365,46 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120333
120365
|
}
|
|
120334
120366
|
)
|
|
120335
120367
|
] }) }),
|
|
120336
|
-
/* @__PURE__ */ (0,
|
|
120368
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipContent2, { side: "top", children: showProjectName ? worktree.path : worktree.branch })
|
|
120337
120369
|
] }),
|
|
120338
|
-
/* @__PURE__ */ (0,
|
|
120339
|
-
/* @__PURE__ */ (0,
|
|
120340
|
-
branchStatus && /* @__PURE__ */ (0,
|
|
120341
|
-
branchStatus && /* @__PURE__ */ (0,
|
|
120370
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "hidden @[10rem]:flex group-hover:flex items-center gap-2 shrink-0 ml-auto pl-2", children: [
|
|
120371
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(SetupStatusIndicator, { setup: setupStatus }),
|
|
120372
|
+
!isPlain && branchStatus && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(GitStatusIndicator, { git: branchStatus.git }),
|
|
120373
|
+
!isPlain && branchStatus && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(CIStatusIndicator, { ci: branchStatus.ci })
|
|
120342
120374
|
] })
|
|
120343
120375
|
] }) }),
|
|
120344
|
-
/* @__PURE__ */ (0,
|
|
120345
|
-
/* @__PURE__ */ (0,
|
|
120346
|
-
isPinned ? /* @__PURE__ */ (0,
|
|
120376
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuContent2, { children: [
|
|
120377
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => onTogglePinned(projectName, worktree.branch, isPinned), children: [
|
|
120378
|
+
isPinned ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.PinOff, {}) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.Pin, {}),
|
|
120347
120379
|
isPinned ? "Unpin workspace" : "Pin workspace"
|
|
120348
120380
|
] }),
|
|
120349
|
-
/* @__PURE__ */ (0,
|
|
120350
|
-
capabilities.copyPath && /* @__PURE__ */ (0,
|
|
120351
|
-
/* @__PURE__ */ (0,
|
|
120381
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ContextMenuSeparator2, {}),
|
|
120382
|
+
capabilities.copyPath && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => navigator.clipboard.writeText(worktree.path), children: [
|
|
120383
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.Clipboard, {}),
|
|
120352
120384
|
"Copy path"
|
|
120353
120385
|
] }),
|
|
120354
|
-
capabilities.revealInFinder && /* @__PURE__ */ (0,
|
|
120355
|
-
/* @__PURE__ */ (0,
|
|
120386
|
+
capabilities.revealInFinder && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => capabilities.revealInFinder(worktree.path), children: [
|
|
120387
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.FolderOpen, {}),
|
|
120356
120388
|
"Open in Finder"
|
|
120357
120389
|
] }),
|
|
120358
|
-
worktree.hasSetup && /* @__PURE__ */ (0,
|
|
120359
|
-
/* @__PURE__ */ (0,
|
|
120390
|
+
worktree.hasSetup && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => runScript(worktree.path, "setup"), children: [
|
|
120391
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.Play, {}),
|
|
120360
120392
|
"Run setup"
|
|
120361
120393
|
] }),
|
|
120362
|
-
worktree.hasTeardown && /* @__PURE__ */ (0,
|
|
120363
|
-
/* @__PURE__ */ (0,
|
|
120394
|
+
worktree.hasTeardown && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => runScript(worktree.path, "teardown"), children: [
|
|
120395
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.Square, {}),
|
|
120364
120396
|
"Run teardown"
|
|
120365
120397
|
] }),
|
|
120366
|
-
/* @__PURE__ */ (0,
|
|
120367
|
-
/* @__PURE__ */ (0,
|
|
120398
|
+
!isPlain && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => gitPull(projectName, worktree.branch), children: [
|
|
120399
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.ArrowDownToLine, {}),
|
|
120368
120400
|
"Git pull"
|
|
120369
120401
|
] }),
|
|
120370
|
-
/* @__PURE__ */ (0,
|
|
120371
|
-
/* @__PURE__ */ (0,
|
|
120402
|
+
!isPlain && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { onClick: () => gitPush(projectName, worktree.branch), children: [
|
|
120403
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.ArrowUpFromLine, {}),
|
|
120372
120404
|
"Git push"
|
|
120373
120405
|
] }),
|
|
120374
|
-
worktree.branch !== defaultBranch && /* @__PURE__ */ (0,
|
|
120375
|
-
/* @__PURE__ */ (0,
|
|
120406
|
+
!isPlain && worktree.branch !== defaultBranch && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(ContextMenuItem2, { variant: "destructive", onClick: handleDelete, children: [
|
|
120407
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react5.Trash2, {}),
|
|
120376
120408
|
"Delete workspace"
|
|
120377
120409
|
] })
|
|
120378
120410
|
] })
|
|
@@ -120380,7 +120412,7 @@ var WorkspaceCard = (0, import_react20.memo)(function WorkspaceCard2({
|
|
|
120380
120412
|
});
|
|
120381
120413
|
|
|
120382
120414
|
// ../../packages/dashboard-core/src/components/ProjectList.tsx
|
|
120383
|
-
var
|
|
120415
|
+
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
|
|
120384
120416
|
|
|
120385
120417
|
// ../../packages/dashboard-core/src/components/SettingsPage.tsx
|
|
120386
120418
|
var import_react23 = __toESM(require_react(), 1);
|
|
@@ -120389,28 +120421,31 @@ var import_react23 = __toESM(require_react(), 1);
|
|
|
120389
120421
|
var import_react22 = __toESM(require_react(), 1);
|
|
120390
120422
|
|
|
120391
120423
|
// ../../packages/dashboard-core/src/components/settings/SettingsRow.tsx
|
|
120392
|
-
var
|
|
120424
|
+
var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
|
|
120393
120425
|
|
|
120394
120426
|
// ../../packages/dashboard-core/src/components/settings/SettingsSection.tsx
|
|
120395
|
-
var
|
|
120427
|
+
var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
|
|
120396
120428
|
|
|
120397
120429
|
// ../../packages/dashboard-core/src/components/SettingsPage.tsx
|
|
120398
|
-
var
|
|
120430
|
+
var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
|
|
120399
120431
|
|
|
120400
120432
|
// ../../packages/dashboard-core/src/components/DashboardShell.tsx
|
|
120401
|
-
var
|
|
120433
|
+
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
|
|
120402
120434
|
var isElectron = typeof window !== "undefined" && "__BAND_DESKTOP__" in window;
|
|
120403
120435
|
|
|
120404
120436
|
// ../../packages/dashboard-core/src/components/DiffView.tsx
|
|
120405
120437
|
init_dist4();
|
|
120406
|
-
var
|
|
120438
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
120407
120439
|
|
|
120408
120440
|
// ../../packages/dashboard-core/src/hooks/use-diff-target.ts
|
|
120409
120441
|
var import_react25 = __toESM(require_react(), 1);
|
|
120410
120442
|
|
|
120411
|
-
// ../../packages/dashboard-core/src/hooks/use-
|
|
120443
|
+
// ../../packages/dashboard-core/src/hooks/use-project-kind.ts
|
|
120412
120444
|
var import_react26 = __toESM(require_react(), 1);
|
|
120413
120445
|
|
|
120446
|
+
// ../../packages/dashboard-core/src/hooks/use-search.ts
|
|
120447
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
120448
|
+
|
|
120414
120449
|
// ../../packages/dashboard-core/src/lib/language-map.ts
|
|
120415
120450
|
var SUPPORTED_LANGUAGES = [
|
|
120416
120451
|
{ id: "plaintext", label: "Plain Text" },
|
|
@@ -120464,16 +120499,16 @@ var SUPPORTED_LANGUAGES = [
|
|
|
120464
120499
|
var LANGUAGE_LABEL_BY_ID = new Map(SUPPORTED_LANGUAGES.map((l) => [l.id, l.label]));
|
|
120465
120500
|
|
|
120466
120501
|
// ../../packages/dashboard-core/src/components/ChangesFileTree.tsx
|
|
120467
|
-
var
|
|
120502
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
120468
120503
|
|
|
120469
120504
|
// ../../packages/dashboard-core/src/hooks/use-deferred-menu-action.ts
|
|
120470
|
-
var
|
|
120505
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
120471
120506
|
function useDeferredMenuAction() {
|
|
120472
|
-
const pendingRef = (0,
|
|
120473
|
-
const queue = (0,
|
|
120507
|
+
const pendingRef = (0, import_react28.useRef)(null);
|
|
120508
|
+
const queue = (0, import_react28.useCallback)((fn) => {
|
|
120474
120509
|
pendingRef.current = fn;
|
|
120475
120510
|
}, []);
|
|
120476
|
-
const flush = (0,
|
|
120511
|
+
const flush = (0, import_react28.useCallback)((e2) => {
|
|
120477
120512
|
e2.preventDefault();
|
|
120478
120513
|
const fn = pendingRef.current;
|
|
120479
120514
|
pendingRef.current = null;
|
|
@@ -120622,18 +120657,18 @@ function getFileIcon(filename) {
|
|
|
120622
120657
|
}
|
|
120623
120658
|
|
|
120624
120659
|
// ../../packages/dashboard-core/src/components/FileStatusBadge.tsx
|
|
120625
|
-
var
|
|
120660
|
+
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
|
|
120626
120661
|
|
|
120627
120662
|
// ../../packages/dashboard-core/src/components/ChangesFileTree.tsx
|
|
120628
|
-
var
|
|
120663
|
+
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
120629
120664
|
|
|
120630
120665
|
// ../../packages/dashboard-core/src/components/RevertFileDialog.tsx
|
|
120631
|
-
var
|
|
120666
|
+
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
120632
120667
|
|
|
120633
120668
|
// ../../packages/dashboard-core/src/components/SearchBar.tsx
|
|
120634
120669
|
var import_lucide_react7 = __toESM(require_lucide_react(), 1);
|
|
120635
|
-
var
|
|
120636
|
-
var
|
|
120670
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
120671
|
+
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
120637
120672
|
var DEFAULT_VISIBLE_OPTIONS = ["caseSensitive", "wholeWord", "regex"];
|
|
120638
120673
|
function ToggleButton({
|
|
120639
120674
|
active,
|
|
@@ -120641,7 +120676,7 @@ function ToggleButton({
|
|
|
120641
120676
|
title,
|
|
120642
120677
|
children
|
|
120643
120678
|
}) {
|
|
120644
|
-
return /* @__PURE__ */ (0,
|
|
120679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120645
120680
|
"button",
|
|
120646
120681
|
{
|
|
120647
120682
|
type: "button",
|
|
@@ -120652,7 +120687,7 @@ function ToggleButton({
|
|
|
120652
120687
|
}
|
|
120653
120688
|
);
|
|
120654
120689
|
}
|
|
120655
|
-
var SearchBar = (0,
|
|
120690
|
+
var SearchBar = (0, import_react30.forwardRef)(function SearchBar2({
|
|
120656
120691
|
query,
|
|
120657
120692
|
onQueryChange,
|
|
120658
120693
|
options: options2,
|
|
@@ -120668,27 +120703,27 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120668
120703
|
const showCase = visibleOptions.includes("caseSensitive");
|
|
120669
120704
|
const showWholeWord = visibleOptions.includes("wholeWord");
|
|
120670
120705
|
const showRegex = visibleOptions.includes("regex");
|
|
120671
|
-
const inputRef = (0,
|
|
120672
|
-
(0,
|
|
120706
|
+
const inputRef = (0, import_react30.useRef)(null);
|
|
120707
|
+
(0, import_react30.useImperativeHandle)(ref, () => ({
|
|
120673
120708
|
focus: () => inputRef.current?.focus(),
|
|
120674
120709
|
select: () => inputRef.current?.select()
|
|
120675
120710
|
}));
|
|
120676
|
-
const toggleCase = (0,
|
|
120711
|
+
const toggleCase = (0, import_react30.useCallback)(() => {
|
|
120677
120712
|
onOptionsChange({ ...options2, caseSensitive: !options2.caseSensitive });
|
|
120678
120713
|
}, [options2, onOptionsChange]);
|
|
120679
|
-
const toggleWholeWord = (0,
|
|
120714
|
+
const toggleWholeWord = (0, import_react30.useCallback)(() => {
|
|
120680
120715
|
onOptionsChange({ ...options2, wholeWord: !options2.wholeWord });
|
|
120681
120716
|
}, [options2, onOptionsChange]);
|
|
120682
|
-
const toggleRegex = (0,
|
|
120717
|
+
const toggleRegex = (0, import_react30.useCallback)(() => {
|
|
120683
120718
|
onOptionsChange({ ...options2, regex: !options2.regex });
|
|
120684
120719
|
}, [options2, onOptionsChange]);
|
|
120685
|
-
return /* @__PURE__ */ (0,
|
|
120720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
120686
120721
|
"div",
|
|
120687
120722
|
{
|
|
120688
120723
|
className: `flex shrink-0 items-center gap-1.5 border-b border-border bg-muted/30 px-3 py-1.5 ${className ?? ""}`,
|
|
120689
120724
|
children: [
|
|
120690
|
-
/* @__PURE__ */ (0,
|
|
120691
|
-
/* @__PURE__ */ (0,
|
|
120725
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.Search, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
120726
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120692
120727
|
"input",
|
|
120693
120728
|
{
|
|
120694
120729
|
ref: inputRef,
|
|
@@ -120709,11 +120744,11 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120709
120744
|
}
|
|
120710
120745
|
}
|
|
120711
120746
|
),
|
|
120712
|
-
showCase && /* @__PURE__ */ (0,
|
|
120713
|
-
showWholeWord && /* @__PURE__ */ (0,
|
|
120714
|
-
showRegex && /* @__PURE__ */ (0,
|
|
120715
|
-
matchInfo && query && /* @__PURE__ */ (0,
|
|
120716
|
-
onPrevious && /* @__PURE__ */ (0,
|
|
120747
|
+
showCase && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ToggleButton, { active: options2.caseSensitive, onClick: toggleCase, title: "Match Case", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.CaseSensitive, { className: "size-4" }) }),
|
|
120748
|
+
showWholeWord && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ToggleButton, { active: options2.wholeWord, onClick: toggleWholeWord, title: "Match Whole Word", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.WholeWord, { className: "size-4" }) }),
|
|
120749
|
+
showRegex && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ToggleButton, { active: options2.regex, onClick: toggleRegex, title: "Use Regular Expression", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.Regex, { className: "size-4" }) }),
|
|
120750
|
+
matchInfo && query && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: matchInfo.total > 0 ? `${matchInfo.current} of ${matchInfo.total}` : "No results" }),
|
|
120751
|
+
onPrevious && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120717
120752
|
"button",
|
|
120718
120753
|
{
|
|
120719
120754
|
type: "button",
|
|
@@ -120721,10 +120756,10 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120721
120756
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
120722
120757
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
120723
120758
|
title: "Previous match (Shift+Enter)",
|
|
120724
|
-
children: /* @__PURE__ */ (0,
|
|
120759
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.ChevronUp, { className: "size-3.5" })
|
|
120725
120760
|
}
|
|
120726
120761
|
),
|
|
120727
|
-
onNext && /* @__PURE__ */ (0,
|
|
120762
|
+
onNext && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120728
120763
|
"button",
|
|
120729
120764
|
{
|
|
120730
120765
|
type: "button",
|
|
@@ -120732,17 +120767,17 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120732
120767
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
120733
120768
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
120734
120769
|
title: "Next match (Enter)",
|
|
120735
|
-
children: /* @__PURE__ */ (0,
|
|
120770
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.ChevronDown, { className: "size-3.5" })
|
|
120736
120771
|
}
|
|
120737
120772
|
),
|
|
120738
|
-
onClose && /* @__PURE__ */ (0,
|
|
120773
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120739
120774
|
"button",
|
|
120740
120775
|
{
|
|
120741
120776
|
type: "button",
|
|
120742
120777
|
onClick: onClose,
|
|
120743
120778
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground",
|
|
120744
120779
|
title: "Close (Escape)",
|
|
120745
|
-
children: /* @__PURE__ */ (0,
|
|
120780
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.X, { className: "size-3.5" })
|
|
120746
120781
|
}
|
|
120747
120782
|
)
|
|
120748
120783
|
]
|
|
@@ -120751,7 +120786,7 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120751
120786
|
});
|
|
120752
120787
|
|
|
120753
120788
|
// ../../packages/dashboard-core/src/components/DiffView.tsx
|
|
120754
|
-
var
|
|
120789
|
+
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
|
|
120755
120790
|
var diffTheme = EditorView.theme({
|
|
120756
120791
|
".cm-insertedLine": { backgroundColor: "rgba(34, 197, 94, 0.1)" },
|
|
120757
120792
|
".cm-deletedLine": { backgroundColor: "rgba(239, 68, 68, 0.1)" },
|
|
@@ -120802,8 +120837,8 @@ var diffTheme = EditorView.theme({
|
|
|
120802
120837
|
|
|
120803
120838
|
// ../../packages/dashboard-core/src/components/FileBrowser.tsx
|
|
120804
120839
|
var import_lucide_react8 = __toESM(require_lucide_react(), 1);
|
|
120805
|
-
var
|
|
120806
|
-
var
|
|
120840
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
120841
|
+
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
120807
120842
|
var expandedStateCache = /* @__PURE__ */ new Map();
|
|
120808
120843
|
var dirContentsCache = /* @__PURE__ */ new Map();
|
|
120809
120844
|
function getCachedExpanded(wsId) {
|
|
@@ -120832,11 +120867,11 @@ function EntryNameInput({
|
|
|
120832
120867
|
onSubmit,
|
|
120833
120868
|
onCancel
|
|
120834
120869
|
}) {
|
|
120835
|
-
const [value, setValue] = (0,
|
|
120836
|
-
const [submitting, setSubmitting] = (0,
|
|
120837
|
-
const [error40, setError] = (0,
|
|
120838
|
-
const inputRef = (0,
|
|
120839
|
-
(0,
|
|
120870
|
+
const [value, setValue] = (0, import_react32.useState)(initialValue);
|
|
120871
|
+
const [submitting, setSubmitting] = (0, import_react32.useState)(false);
|
|
120872
|
+
const [error40, setError] = (0, import_react32.useState)(null);
|
|
120873
|
+
const inputRef = (0, import_react32.useRef)(null);
|
|
120874
|
+
(0, import_react32.useEffect)(() => {
|
|
120840
120875
|
const el = inputRef.current;
|
|
120841
120876
|
if (!el) return;
|
|
120842
120877
|
el.focus();
|
|
@@ -120884,21 +120919,21 @@ function EntryNameInput({
|
|
|
120884
120919
|
}
|
|
120885
120920
|
};
|
|
120886
120921
|
const Icon = kind === "directory" ? import_lucide_react8.Folder : import_lucide_react8.File;
|
|
120887
|
-
return /* @__PURE__ */ (0,
|
|
120888
|
-
/* @__PURE__ */ (0,
|
|
120922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex w-full flex-col", style: { paddingLeft: `${depth * indent + basePad}px` }, children: [
|
|
120923
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
120889
120924
|
"div",
|
|
120890
120925
|
{
|
|
120891
120926
|
className: `flex items-center ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"}`,
|
|
120892
120927
|
style: { height },
|
|
120893
120928
|
children: [
|
|
120894
|
-
/* @__PURE__ */ (0,
|
|
120895
|
-
/* @__PURE__ */ (0,
|
|
120929
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "size-3.5 shrink-0" }),
|
|
120930
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120896
120931
|
Icon,
|
|
120897
120932
|
{
|
|
120898
120933
|
className: kind === "directory" ? "size-4 shrink-0 text-blue-600 dark:text-blue-400" : "size-4 shrink-0 text-muted-foreground"
|
|
120899
120934
|
}
|
|
120900
120935
|
),
|
|
120901
|
-
/* @__PURE__ */ (0,
|
|
120936
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120902
120937
|
"input",
|
|
120903
120938
|
{
|
|
120904
120939
|
ref: inputRef,
|
|
@@ -120935,7 +120970,7 @@ function EntryNameInput({
|
|
|
120935
120970
|
]
|
|
120936
120971
|
}
|
|
120937
120972
|
),
|
|
120938
|
-
error40 && /* @__PURE__ */ (0,
|
|
120973
|
+
error40 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120939
120974
|
"div",
|
|
120940
120975
|
{
|
|
120941
120976
|
className: "pointer-events-none text-xs text-destructive",
|
|
@@ -121002,7 +121037,7 @@ function TreeNode2({
|
|
|
121002
121037
|
onOpenFilePinned(entryPath);
|
|
121003
121038
|
}
|
|
121004
121039
|
};
|
|
121005
|
-
const button = /* @__PURE__ */ (0,
|
|
121040
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121006
121041
|
"button",
|
|
121007
121042
|
{
|
|
121008
121043
|
ref: isSelected ? selectedRef : void 0,
|
|
@@ -121015,12 +121050,12 @@ function TreeNode2({
|
|
|
121015
121050
|
className: `flex w-full items-center text-left select-none hover:bg-accent/50 [-webkit-touch-callout:none] ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"} ${isSelected ? "bg-blue-500/30 text-foreground outline outline-1 -outline-offset-1 outline-blue-400/60 hover:bg-blue-500/30 dark:bg-blue-500/40 dark:outline-blue-400/70 dark:hover:bg-blue-500/40" : ""} ${isCut ? "opacity-50" : ""}`,
|
|
121016
121051
|
style: { paddingLeft: `${depth * indent + basePad}px` },
|
|
121017
121052
|
children: [
|
|
121018
|
-
isDir ? isExpanded ? /* @__PURE__ */ (0,
|
|
121019
|
-
isDir ? isExpanded ? /* @__PURE__ */ (0,
|
|
121053
|
+
isDir ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "size-3.5 shrink-0" }),
|
|
121054
|
+
isDir ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.FolderOpen, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Folder, { className: "size-4 shrink-0 text-blue-600 dark:text-blue-400" }) : (() => {
|
|
121020
121055
|
const FileIcon = getFileIcon(entry.name);
|
|
121021
|
-
return /* @__PURE__ */ (0,
|
|
121056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
|
|
121022
121057
|
})(),
|
|
121023
|
-
/* @__PURE__ */ (0,
|
|
121058
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "min-w-0 flex-1 truncate", children: entry.name })
|
|
121024
121059
|
]
|
|
121025
121060
|
}
|
|
121026
121061
|
);
|
|
@@ -121042,7 +121077,7 @@ function TreeNode2({
|
|
|
121042
121077
|
// a padding div with `depth={0}` would double-apply `basePad`, shifting
|
|
121043
121078
|
// the input ~4px to the right and giving it visibly less horizontal
|
|
121044
121079
|
// room than the rest of the tree.
|
|
121045
|
-
/* @__PURE__ */ (0,
|
|
121080
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121046
121081
|
EntryNameInput,
|
|
121047
121082
|
{
|
|
121048
121083
|
kind: isDir ? "directory" : "file",
|
|
@@ -121056,74 +121091,74 @@ function TreeNode2({
|
|
|
121056
121091
|
},
|
|
121057
121092
|
`rename-${entryPath}`
|
|
121058
121093
|
)
|
|
121059
|
-
) : /* @__PURE__ */ (0,
|
|
121094
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121060
121095
|
ContextMenu2,
|
|
121061
121096
|
{
|
|
121062
121097
|
onOpenChange: (open3) => {
|
|
121063
121098
|
if (open3) onSelectRow(entryPath, isDir ? "directory" : "file");
|
|
121064
121099
|
},
|
|
121065
121100
|
children: [
|
|
121066
|
-
/* @__PURE__ */ (0,
|
|
121067
|
-
/* @__PURE__ */ (0,
|
|
121068
|
-
isDir && /* @__PURE__ */ (0,
|
|
121069
|
-
/* @__PURE__ */ (0,
|
|
121101
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuTrigger2, { asChild: true, children: button }),
|
|
121102
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuContent2, { onCloseAutoFocus: menu.flush, children: [
|
|
121103
|
+
isDir && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121104
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121070
121105
|
ContextMenuItem2,
|
|
121071
121106
|
{
|
|
121072
121107
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "file")),
|
|
121073
121108
|
children: [
|
|
121074
|
-
/* @__PURE__ */ (0,
|
|
121109
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.File, { className: "size-4" }),
|
|
121075
121110
|
"New File"
|
|
121076
121111
|
]
|
|
121077
121112
|
}
|
|
121078
121113
|
),
|
|
121079
|
-
/* @__PURE__ */ (0,
|
|
121114
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121080
121115
|
ContextMenuItem2,
|
|
121081
121116
|
{
|
|
121082
121117
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "directory")),
|
|
121083
121118
|
children: [
|
|
121084
|
-
/* @__PURE__ */ (0,
|
|
121119
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.FolderPlus, { className: "size-4" }),
|
|
121085
121120
|
"New Folder"
|
|
121086
121121
|
]
|
|
121087
121122
|
}
|
|
121088
121123
|
),
|
|
121089
|
-
/* @__PURE__ */ (0,
|
|
121124
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuSeparator2, {})
|
|
121090
121125
|
] }),
|
|
121091
|
-
canCut && /* @__PURE__ */ (0,
|
|
121126
|
+
canCut && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121092
121127
|
ContextMenuItem2,
|
|
121093
121128
|
{
|
|
121094
121129
|
onSelect: () => menu.queue(() => onCut(entryPath, isDir ? "directory" : "file")),
|
|
121095
121130
|
children: [
|
|
121096
|
-
/* @__PURE__ */ (0,
|
|
121131
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Scissors, { className: "size-4" }),
|
|
121097
121132
|
"Cut"
|
|
121098
121133
|
]
|
|
121099
121134
|
}
|
|
121100
121135
|
),
|
|
121101
|
-
canCopy && /* @__PURE__ */ (0,
|
|
121136
|
+
canCopy && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121102
121137
|
ContextMenuItem2,
|
|
121103
121138
|
{
|
|
121104
121139
|
onSelect: () => menu.queue(() => onCopy(entryPath, isDir ? "directory" : "file")),
|
|
121105
121140
|
children: [
|
|
121106
|
-
/* @__PURE__ */ (0,
|
|
121141
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Copy, { className: "size-4" }),
|
|
121107
121142
|
"Copy"
|
|
121108
121143
|
]
|
|
121109
121144
|
}
|
|
121110
121145
|
),
|
|
121111
|
-
isDir && canPaste && /* @__PURE__ */ (0,
|
|
121112
|
-
/* @__PURE__ */ (0,
|
|
121146
|
+
isDir && canPaste && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuItem2, { onSelect: () => menu.queue(() => void onPaste(entryPath)), children: [
|
|
121147
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.ClipboardPaste, { className: "size-4" }),
|
|
121113
121148
|
"Paste"
|
|
121114
121149
|
] }),
|
|
121115
|
-
(canCut || canCopy || isDir && canPaste) && (canRename || canDelete) && /* @__PURE__ */ (0,
|
|
121116
|
-
canRename && /* @__PURE__ */ (0,
|
|
121117
|
-
/* @__PURE__ */ (0,
|
|
121150
|
+
(canCut || canCopy || isDir && canPaste) && (canRename || canDelete) && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuSeparator2, {}),
|
|
121151
|
+
canRename && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuItem2, { onSelect: () => menu.queue(() => onRequestRename(entryPath)), children: [
|
|
121152
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Pencil, { className: "size-4" }),
|
|
121118
121153
|
"Rename"
|
|
121119
121154
|
] }),
|
|
121120
|
-
canDelete && /* @__PURE__ */ (0,
|
|
121155
|
+
canDelete && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121121
121156
|
ContextMenuItem2,
|
|
121122
121157
|
{
|
|
121123
121158
|
variant: "destructive",
|
|
121124
121159
|
onSelect: () => menu.queue(() => onRequestDelete(entryPath, isDir ? "directory" : "file")),
|
|
121125
121160
|
children: [
|
|
121126
|
-
/* @__PURE__ */ (0,
|
|
121161
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Trash2, { className: "size-4" }),
|
|
121127
121162
|
"Delete"
|
|
121128
121163
|
]
|
|
121129
121164
|
}
|
|
@@ -121133,13 +121168,13 @@ function TreeNode2({
|
|
|
121133
121168
|
}
|
|
121134
121169
|
);
|
|
121135
121170
|
const showInlineInput = newEntry?.parentPath === entryPath;
|
|
121136
|
-
return /* @__PURE__ */ (0,
|
|
121171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121137
121172
|
row,
|
|
121138
121173
|
isExpanded && (() => {
|
|
121139
121174
|
const splitIdx = children?.findIndex((c2) => c2.type === "file") ?? -1;
|
|
121140
121175
|
const folderChildren = splitIdx === -1 ? children ?? [] : (children ?? []).slice(0, splitIdx);
|
|
121141
121176
|
const fileChildren = splitIdx === -1 ? [] : (children ?? []).slice(splitIdx);
|
|
121142
|
-
const renderChild = (child) => /* @__PURE__ */ (0,
|
|
121177
|
+
const renderChild = (child) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121143
121178
|
TreeNode2,
|
|
121144
121179
|
{
|
|
121145
121180
|
entry: child,
|
|
@@ -121176,7 +121211,7 @@ function TreeNode2({
|
|
|
121176
121211
|
},
|
|
121177
121212
|
child.name
|
|
121178
121213
|
);
|
|
121179
|
-
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0,
|
|
121214
|
+
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121180
121215
|
EntryNameInput,
|
|
121181
121216
|
{
|
|
121182
121217
|
kind: newEntry.kind,
|
|
@@ -121188,9 +121223,9 @@ function TreeNode2({
|
|
|
121188
121223
|
},
|
|
121189
121224
|
`new-${newEntry.kind}-${entryPath}`
|
|
121190
121225
|
) : null;
|
|
121191
|
-
return /* @__PURE__ */ (0,
|
|
121226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121192
121227
|
showInlineInput && newEntry.kind === "directory" && newEntryInput,
|
|
121193
|
-
isLoading && !children?.length && /* @__PURE__ */ (0,
|
|
121228
|
+
isLoading && !children?.length && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121194
121229
|
"div",
|
|
121195
121230
|
{
|
|
121196
121231
|
className: `flex items-center text-muted-foreground/70 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -121201,7 +121236,7 @@ function TreeNode2({
|
|
|
121201
121236
|
children: "Loading\u2026"
|
|
121202
121237
|
}
|
|
121203
121238
|
),
|
|
121204
|
-
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0,
|
|
121239
|
+
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121205
121240
|
"div",
|
|
121206
121241
|
{
|
|
121207
121242
|
className: `flex items-center italic text-muted-foreground/50 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -121219,7 +121254,7 @@ function TreeNode2({
|
|
|
121219
121254
|
})()
|
|
121220
121255
|
] });
|
|
121221
121256
|
}
|
|
121222
|
-
var FileBrowser = (0,
|
|
121257
|
+
var FileBrowser = (0, import_react32.forwardRef)(function FileBrowser2({
|
|
121223
121258
|
workspaceId,
|
|
121224
121259
|
onOpenFile,
|
|
121225
121260
|
onOpenFilePinned,
|
|
@@ -121229,23 +121264,23 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121229
121264
|
onPathDeleted
|
|
121230
121265
|
}, handleRef) {
|
|
121231
121266
|
const adapter = useAdapter();
|
|
121232
|
-
const [expandedPaths, setExpandedPaths] = (0,
|
|
121267
|
+
const [expandedPaths, setExpandedPaths] = (0, import_react32.useState)(
|
|
121233
121268
|
() => new Set(getCachedExpanded(workspaceId))
|
|
121234
121269
|
);
|
|
121235
|
-
const [dirContents, setDirContents] = (0,
|
|
121270
|
+
const [dirContents, setDirContents] = (0, import_react32.useState)(
|
|
121236
121271
|
() => new Map(getCachedContents(workspaceId))
|
|
121237
121272
|
);
|
|
121238
|
-
const [loadingPaths, setLoadingPaths] = (0,
|
|
121239
|
-
const [newEntry, setNewEntry] = (0,
|
|
121240
|
-
const [pendingDelete, setPendingDelete] = (0,
|
|
121241
|
-
const [deleteError, setDeleteError] = (0,
|
|
121242
|
-
const [deleteSubmitting, setDeleteSubmitting] = (0,
|
|
121243
|
-
const [renamingPath, setRenamingPath] = (0,
|
|
121244
|
-
const [clipboard, setClipboard] = (0,
|
|
121245
|
-
const [treeSelection, setTreeSelection] = (0,
|
|
121246
|
-
const selectedRef = (0,
|
|
121247
|
-
const prevWorkspaceRef = (0,
|
|
121248
|
-
(0,
|
|
121273
|
+
const [loadingPaths, setLoadingPaths] = (0, import_react32.useState)(/* @__PURE__ */ new Set());
|
|
121274
|
+
const [newEntry, setNewEntry] = (0, import_react32.useState)(null);
|
|
121275
|
+
const [pendingDelete, setPendingDelete] = (0, import_react32.useState)(null);
|
|
121276
|
+
const [deleteError, setDeleteError] = (0, import_react32.useState)(null);
|
|
121277
|
+
const [deleteSubmitting, setDeleteSubmitting] = (0, import_react32.useState)(false);
|
|
121278
|
+
const [renamingPath, setRenamingPath] = (0, import_react32.useState)(null);
|
|
121279
|
+
const [clipboard, setClipboard] = (0, import_react32.useState)(null);
|
|
121280
|
+
const [treeSelection, setTreeSelection] = (0, import_react32.useState)(() => selectedFile ? { path: selectedFile, kind: "file" } : null);
|
|
121281
|
+
const selectedRef = (0, import_react32.useRef)(null);
|
|
121282
|
+
const prevWorkspaceRef = (0, import_react32.useRef)(workspaceId);
|
|
121283
|
+
(0, import_react32.useEffect)(() => {
|
|
121249
121284
|
if (prevWorkspaceRef.current !== workspaceId) {
|
|
121250
121285
|
prevWorkspaceRef.current = workspaceId;
|
|
121251
121286
|
setExpandedPaths(new Set(getCachedExpanded(workspaceId)));
|
|
@@ -121260,18 +121295,18 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121260
121295
|
setClipboard(null);
|
|
121261
121296
|
}
|
|
121262
121297
|
}, [workspaceId]);
|
|
121263
|
-
(0,
|
|
121298
|
+
(0, import_react32.useEffect)(() => {
|
|
121264
121299
|
if (selectedFile) {
|
|
121265
121300
|
setTreeSelection({ path: selectedFile, kind: "file" });
|
|
121266
121301
|
}
|
|
121267
121302
|
}, [selectedFile]);
|
|
121268
|
-
const handleSelectRow = (0,
|
|
121303
|
+
const handleSelectRow = (0, import_react32.useCallback)((path3, kind) => {
|
|
121269
121304
|
setTreeSelection({ path: path3, kind });
|
|
121270
121305
|
}, []);
|
|
121271
|
-
const clearTreeSelection = (0,
|
|
121306
|
+
const clearTreeSelection = (0, import_react32.useCallback)(() => {
|
|
121272
121307
|
setTreeSelection(null);
|
|
121273
121308
|
}, []);
|
|
121274
|
-
const fetchDir = (0,
|
|
121309
|
+
const fetchDir = (0, import_react32.useCallback)(
|
|
121275
121310
|
async (dirPath, opts) => {
|
|
121276
121311
|
if (!adapter.listWorkspaceFiles) return;
|
|
121277
121312
|
const cache = getCachedContents(workspaceId);
|
|
@@ -121295,10 +121330,10 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121295
121330
|
},
|
|
121296
121331
|
[adapter, workspaceId]
|
|
121297
121332
|
);
|
|
121298
|
-
(0,
|
|
121333
|
+
(0, import_react32.useEffect)(() => {
|
|
121299
121334
|
fetchDir("");
|
|
121300
121335
|
}, [fetchDir]);
|
|
121301
|
-
(0,
|
|
121336
|
+
(0, import_react32.useEffect)(() => {
|
|
121302
121337
|
if (!adapter.subscribeFileChanges) return;
|
|
121303
121338
|
const unsubscribe = adapter.subscribeFileChanges(workspaceId, (changedPath) => {
|
|
121304
121339
|
const cache = getCachedContents(workspaceId);
|
|
@@ -121307,8 +121342,8 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121307
121342
|
});
|
|
121308
121343
|
return unsubscribe;
|
|
121309
121344
|
}, [adapter, workspaceId, fetchDir]);
|
|
121310
|
-
const prevSelectedRef = (0,
|
|
121311
|
-
(0,
|
|
121345
|
+
const prevSelectedRef = (0, import_react32.useRef)(void 0);
|
|
121346
|
+
(0, import_react32.useEffect)(() => {
|
|
121312
121347
|
if (!selectedFile || selectedFile === prevSelectedRef.current) {
|
|
121313
121348
|
prevSelectedRef.current = selectedFile;
|
|
121314
121349
|
return;
|
|
@@ -121335,7 +121370,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121335
121370
|
fetchDir(dir);
|
|
121336
121371
|
}
|
|
121337
121372
|
}, [selectedFile, workspaceId, fetchDir]);
|
|
121338
|
-
(0,
|
|
121373
|
+
(0, import_react32.useEffect)(() => {
|
|
121339
121374
|
if (selectedFile && selectedRef.current) {
|
|
121340
121375
|
const timer = setTimeout(() => {
|
|
121341
121376
|
selectedRef.current?.scrollIntoView({ block: "nearest" });
|
|
@@ -121343,7 +121378,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121343
121378
|
return () => clearTimeout(timer);
|
|
121344
121379
|
}
|
|
121345
121380
|
}, [selectedFile, dirContents]);
|
|
121346
|
-
const toggleExpand = (0,
|
|
121381
|
+
const toggleExpand = (0, import_react32.useCallback)(
|
|
121347
121382
|
(dirPath) => {
|
|
121348
121383
|
setExpandedPaths((prev) => {
|
|
121349
121384
|
const next = new Set(prev);
|
|
@@ -121359,7 +121394,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121359
121394
|
},
|
|
121360
121395
|
[workspaceId, fetchDir]
|
|
121361
121396
|
);
|
|
121362
|
-
const ensureDirExpanded = (0,
|
|
121397
|
+
const ensureDirExpanded = (0, import_react32.useCallback)(
|
|
121363
121398
|
async (dirPath) => {
|
|
121364
121399
|
const cached2 = getCachedExpanded(workspaceId);
|
|
121365
121400
|
if (!cached2.has(dirPath)) {
|
|
@@ -121371,17 +121406,17 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121371
121406
|
},
|
|
121372
121407
|
[workspaceId, fetchDir]
|
|
121373
121408
|
);
|
|
121374
|
-
const requestNewEntry = (0,
|
|
121409
|
+
const requestNewEntry = (0, import_react32.useCallback)(
|
|
121375
121410
|
(parentPath, kind) => {
|
|
121376
121411
|
void ensureDirExpanded(parentPath);
|
|
121377
121412
|
setNewEntry({ parentPath, kind });
|
|
121378
121413
|
},
|
|
121379
121414
|
[ensureDirExpanded]
|
|
121380
121415
|
);
|
|
121381
|
-
const cancelNewEntry = (0,
|
|
121416
|
+
const cancelNewEntry = (0, import_react32.useCallback)(() => {
|
|
121382
121417
|
setNewEntry(null);
|
|
121383
121418
|
}, []);
|
|
121384
|
-
const submitNewEntry = (0,
|
|
121419
|
+
const submitNewEntry = (0, import_react32.useCallback)(
|
|
121385
121420
|
async (name24) => {
|
|
121386
121421
|
if (!newEntry) return;
|
|
121387
121422
|
const fullPath = newEntry.parentPath ? `${newEntry.parentPath}/${name24}` : name24;
|
|
@@ -121414,16 +121449,16 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121414
121449
|
[adapter, newEntry, fetchDir, onOpenFile, workspaceId]
|
|
121415
121450
|
);
|
|
121416
121451
|
const canDelete = Boolean(adapter.deleteWorkspacePath);
|
|
121417
|
-
const requestDelete = (0,
|
|
121452
|
+
const requestDelete = (0, import_react32.useCallback)((path3, kind) => {
|
|
121418
121453
|
setDeleteError(null);
|
|
121419
121454
|
setPendingDelete({ path: path3, kind });
|
|
121420
121455
|
}, []);
|
|
121421
|
-
const cancelDelete = (0,
|
|
121456
|
+
const cancelDelete = (0, import_react32.useCallback)(() => {
|
|
121422
121457
|
if (deleteSubmitting) return;
|
|
121423
121458
|
setPendingDelete(null);
|
|
121424
121459
|
setDeleteError(null);
|
|
121425
121460
|
}, [deleteSubmitting]);
|
|
121426
|
-
const confirmDelete = (0,
|
|
121461
|
+
const confirmDelete = (0, import_react32.useCallback)(async () => {
|
|
121427
121462
|
if (!pendingDelete || !adapter.deleteWorkspacePath) return;
|
|
121428
121463
|
setDeleteSubmitting(true);
|
|
121429
121464
|
setDeleteError(null);
|
|
@@ -121469,13 +121504,13 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121469
121504
|
}
|
|
121470
121505
|
}, [adapter, pendingDelete, fetchDir, workspaceId, onPathDeleted]);
|
|
121471
121506
|
const canRename = Boolean(adapter.renameWorkspacePath);
|
|
121472
|
-
const requestRename = (0,
|
|
121507
|
+
const requestRename = (0, import_react32.useCallback)((path3) => {
|
|
121473
121508
|
setRenamingPath(path3);
|
|
121474
121509
|
}, []);
|
|
121475
|
-
const cancelRename = (0,
|
|
121510
|
+
const cancelRename = (0, import_react32.useCallback)(() => {
|
|
121476
121511
|
setRenamingPath(null);
|
|
121477
121512
|
}, []);
|
|
121478
|
-
const submitRename = (0,
|
|
121513
|
+
const submitRename = (0, import_react32.useCallback)(
|
|
121479
121514
|
async (newName) => {
|
|
121480
121515
|
if (renamingPath == null || !adapter.renameWorkspacePath) return;
|
|
121481
121516
|
const oldPath = renamingPath;
|
|
@@ -121531,7 +121566,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121531
121566
|
},
|
|
121532
121567
|
[adapter, renamingPath, fetchDir, onPathRenamed, workspaceId]
|
|
121533
121568
|
);
|
|
121534
|
-
const resolveDefaultTarget = (0,
|
|
121569
|
+
const resolveDefaultTarget = (0, import_react32.useCallback)(() => {
|
|
121535
121570
|
if (treeSelection?.kind === "directory") return treeSelection.path;
|
|
121536
121571
|
if (treeSelection?.kind === "file") {
|
|
121537
121572
|
const idx = treeSelection.path.lastIndexOf("/");
|
|
@@ -121544,13 +121579,13 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121544
121579
|
const canPaste = Boolean(
|
|
121545
121580
|
clipboard && (clipboard.op === "copy" && adapter.copyWorkspacePath || clipboard.op === "cut" && adapter.renameWorkspacePath)
|
|
121546
121581
|
);
|
|
121547
|
-
const cutPath = (0,
|
|
121582
|
+
const cutPath = (0, import_react32.useCallback)((path3, kind) => {
|
|
121548
121583
|
setClipboard({ path: path3, kind, op: "cut" });
|
|
121549
121584
|
}, []);
|
|
121550
|
-
const copyPath = (0,
|
|
121585
|
+
const copyPath = (0, import_react32.useCallback)((path3, kind) => {
|
|
121551
121586
|
setClipboard({ path: path3, kind, op: "copy" });
|
|
121552
121587
|
}, []);
|
|
121553
|
-
const uniqueCopyName = (0,
|
|
121588
|
+
const uniqueCopyName = (0, import_react32.useCallback)(
|
|
121554
121589
|
(baseName, destFolder, kind) => {
|
|
121555
121590
|
const siblings = new Set(
|
|
121556
121591
|
(getCachedContents(workspaceId).get(destFolder) ?? []).map((e2) => e2.name)
|
|
@@ -121568,7 +121603,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121568
121603
|
},
|
|
121569
121604
|
[workspaceId]
|
|
121570
121605
|
);
|
|
121571
|
-
const pasteInto = (0,
|
|
121606
|
+
const pasteInto = (0, import_react32.useCallback)(
|
|
121572
121607
|
async (destFolder) => {
|
|
121573
121608
|
if (!clipboard) return;
|
|
121574
121609
|
const sourcePath = clipboard.path;
|
|
@@ -121632,7 +121667,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121632
121667
|
},
|
|
121633
121668
|
[adapter, clipboard, fetchDir, onPathRenamed, uniqueCopyName, workspaceId]
|
|
121634
121669
|
);
|
|
121635
|
-
(0,
|
|
121670
|
+
(0, import_react32.useImperativeHandle)(
|
|
121636
121671
|
handleRef,
|
|
121637
121672
|
() => ({
|
|
121638
121673
|
startNewFile(parentPath) {
|
|
@@ -121646,7 +121681,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121646
121681
|
);
|
|
121647
121682
|
const rootMenu = useDeferredMenuAction();
|
|
121648
121683
|
if (!adapter.listWorkspaceFiles) {
|
|
121649
|
-
return /* @__PURE__ */ (0,
|
|
121684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "File browsing not supported" });
|
|
121650
121685
|
}
|
|
121651
121686
|
const rootEntries = dirContents.get("") ?? [];
|
|
121652
121687
|
const rootLoading = loadingPaths.has("");
|
|
@@ -121683,20 +121718,20 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121683
121718
|
void pasteInto(resolveDefaultTarget());
|
|
121684
121719
|
}
|
|
121685
121720
|
};
|
|
121686
|
-
return /* @__PURE__ */ (0,
|
|
121687
|
-
/* @__PURE__ */ (0,
|
|
121721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex h-full flex-col overflow-hidden", onKeyDown: handleKeyDown, children: [
|
|
121722
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121688
121723
|
ContextMenu2,
|
|
121689
121724
|
{
|
|
121690
121725
|
onOpenChange: (open3) => {
|
|
121691
121726
|
if (open3) clearTreeSelection();
|
|
121692
121727
|
},
|
|
121693
121728
|
children: [
|
|
121694
|
-
/* @__PURE__ */ (0,
|
|
121729
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "min-h-0 flex-1 overflow-y-auto py-1 pl-px", children: [
|
|
121695
121730
|
(() => {
|
|
121696
121731
|
const rootSplitIdx = rootEntries.findIndex((e2) => e2.type === "file");
|
|
121697
121732
|
const rootFolders = rootSplitIdx === -1 ? rootEntries : rootEntries.slice(0, rootSplitIdx);
|
|
121698
121733
|
const rootFiles = rootSplitIdx === -1 ? [] : rootEntries.slice(rootSplitIdx);
|
|
121699
|
-
const renderRow = (entry) => /* @__PURE__ */ (0,
|
|
121734
|
+
const renderRow = (entry) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121700
121735
|
TreeNode2,
|
|
121701
121736
|
{
|
|
121702
121737
|
entry,
|
|
@@ -121733,7 +121768,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121733
121768
|
},
|
|
121734
121769
|
entry.name
|
|
121735
121770
|
);
|
|
121736
|
-
const rootInput = showRootInput ? /* @__PURE__ */ (0,
|
|
121771
|
+
const rootInput = showRootInput ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121737
121772
|
EntryNameInput,
|
|
121738
121773
|
{
|
|
121739
121774
|
kind: newEntry.kind,
|
|
@@ -121745,30 +121780,30 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121745
121780
|
},
|
|
121746
121781
|
`new-${newEntry.kind}-root`
|
|
121747
121782
|
) : null;
|
|
121748
|
-
return /* @__PURE__ */ (0,
|
|
121783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121749
121784
|
showRootInput && newEntry.kind === "directory" && rootInput,
|
|
121750
|
-
rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0,
|
|
121751
|
-
!rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0,
|
|
121785
|
+
rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Loading\u2026" }),
|
|
121786
|
+
!rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Empty directory" }),
|
|
121752
121787
|
rootFolders.map(renderRow),
|
|
121753
121788
|
showRootInput && newEntry.kind === "file" && rootInput,
|
|
121754
121789
|
rootFiles.map(renderRow)
|
|
121755
121790
|
] });
|
|
121756
121791
|
})(),
|
|
121757
|
-
/* @__PURE__ */ (0,
|
|
121792
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "min-h-[40px] flex-1" })
|
|
121758
121793
|
] }) }),
|
|
121759
|
-
/* @__PURE__ */ (0,
|
|
121760
|
-
/* @__PURE__ */ (0,
|
|
121761
|
-
/* @__PURE__ */ (0,
|
|
121794
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuContent2, { onCloseAutoFocus: rootMenu.flush, children: [
|
|
121795
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "file")), children: [
|
|
121796
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.File, { className: "size-4" }),
|
|
121762
121797
|
"New File"
|
|
121763
121798
|
] }),
|
|
121764
|
-
/* @__PURE__ */ (0,
|
|
121765
|
-
/* @__PURE__ */ (0,
|
|
121799
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "directory")), children: [
|
|
121800
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.FolderPlus, { className: "size-4" }),
|
|
121766
121801
|
"New Folder"
|
|
121767
121802
|
] }),
|
|
121768
|
-
canPaste && /* @__PURE__ */ (0,
|
|
121769
|
-
/* @__PURE__ */ (0,
|
|
121770
|
-
/* @__PURE__ */ (0,
|
|
121771
|
-
/* @__PURE__ */ (0,
|
|
121803
|
+
canPaste && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121804
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuSeparator2, {}),
|
|
121805
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => void pasteInto("")), children: [
|
|
121806
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.ClipboardPaste, { className: "size-4" }),
|
|
121772
121807
|
"Paste"
|
|
121773
121808
|
] })
|
|
121774
121809
|
] })
|
|
@@ -121776,42 +121811,42 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121776
121811
|
]
|
|
121777
121812
|
}
|
|
121778
121813
|
),
|
|
121779
|
-
/* @__PURE__ */ (0,
|
|
121814
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121780
121815
|
Dialog2,
|
|
121781
121816
|
{
|
|
121782
121817
|
open: pendingDelete !== null,
|
|
121783
121818
|
onOpenChange: (open3) => {
|
|
121784
121819
|
if (!open3) cancelDelete();
|
|
121785
121820
|
},
|
|
121786
|
-
children: /* @__PURE__ */ (0,
|
|
121787
|
-
/* @__PURE__ */ (0,
|
|
121788
|
-
/* @__PURE__ */ (0,
|
|
121821
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogContent2, { className: "sm:max-w-[425px]", onClick: (e2) => e2.stopPropagation(), children: [
|
|
121822
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogHeader, { children: [
|
|
121823
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogTitle2, { children: [
|
|
121789
121824
|
"Delete ",
|
|
121790
121825
|
pendingDelete?.kind === "directory" ? "folder" : "file"
|
|
121791
121826
|
] }),
|
|
121792
|
-
/* @__PURE__ */ (0,
|
|
121827
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogDescription2, { children: [
|
|
121793
121828
|
"Are you sure you want to delete ",
|
|
121794
|
-
/* @__PURE__ */ (0,
|
|
121829
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("strong", { children: pendingDelete?.path }),
|
|
121795
121830
|
"?"
|
|
121796
121831
|
] })
|
|
121797
121832
|
] }),
|
|
121798
|
-
/* @__PURE__ */ (0,
|
|
121799
|
-
pendingDelete?.kind === "directory" && /* @__PURE__ */ (0,
|
|
121800
|
-
/* @__PURE__ */ (0,
|
|
121801
|
-
/* @__PURE__ */ (0,
|
|
121833
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex flex-col gap-2 text-sm", children: [
|
|
121834
|
+
pendingDelete?.kind === "directory" && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
|
|
121835
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.AlertTriangle, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
|
|
121836
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "The folder and all of its contents will be deleted from disk. This cannot be undone." })
|
|
121802
121837
|
] }),
|
|
121803
|
-
pendingDelete?.kind === "file" && /* @__PURE__ */ (0,
|
|
121804
|
-
/* @__PURE__ */ (0,
|
|
121805
|
-
/* @__PURE__ */ (0,
|
|
121838
|
+
pendingDelete?.kind === "file" && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
|
|
121839
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.AlertTriangle, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
|
|
121840
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "The file will be deleted from disk. This cannot be undone." })
|
|
121806
121841
|
] }),
|
|
121807
|
-
deleteError && /* @__PURE__ */ (0,
|
|
121808
|
-
/* @__PURE__ */ (0,
|
|
121809
|
-
/* @__PURE__ */ (0,
|
|
121842
|
+
deleteError && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 p-3 text-destructive", children: [
|
|
121843
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.AlertTriangle, { className: "size-4 shrink-0 mt-0.5" }),
|
|
121844
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: deleteError })
|
|
121810
121845
|
] })
|
|
121811
121846
|
] }),
|
|
121812
|
-
/* @__PURE__ */ (0,
|
|
121813
|
-
/* @__PURE__ */ (0,
|
|
121814
|
-
/* @__PURE__ */ (0,
|
|
121847
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogFooter, { children: [
|
|
121848
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Button, { variant: "ghost", onClick: cancelDelete, disabled: deleteSubmitting, children: "Cancel" }),
|
|
121849
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121815
121850
|
Button,
|
|
121816
121851
|
{
|
|
121817
121852
|
variant: "destructive",
|
|
@@ -121828,39 +121863,39 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121828
121863
|
});
|
|
121829
121864
|
|
|
121830
121865
|
// ../../packages/dashboard-core/src/components/FileViewer.tsx
|
|
121831
|
-
var
|
|
121866
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
121832
121867
|
|
|
121833
121868
|
// ../../packages/dashboard-core/src/components/ImagePreview.tsx
|
|
121834
|
-
var import_react32 = __toESM(require_react(), 1);
|
|
121835
|
-
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
121836
|
-
|
|
121837
|
-
// ../../packages/dashboard-core/src/components/LanguagePickerDialog.tsx
|
|
121838
121869
|
var import_react33 = __toESM(require_react(), 1);
|
|
121839
121870
|
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
121840
121871
|
|
|
121841
|
-
// ../../packages/dashboard-core/src/components/
|
|
121872
|
+
// ../../packages/dashboard-core/src/components/LanguagePickerDialog.tsx
|
|
121873
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
121842
121874
|
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
121843
121875
|
|
|
121844
|
-
// ../../packages/dashboard-core/src/components/
|
|
121876
|
+
// ../../packages/dashboard-core/src/components/PdfPreview.tsx
|
|
121845
121877
|
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
|
|
121846
121878
|
|
|
121847
|
-
// ../../packages/dashboard-core/src/components/
|
|
121848
|
-
var import_react35 = __toESM(require_react(), 1);
|
|
121879
|
+
// ../../packages/dashboard-core/src/components/FileViewer.tsx
|
|
121849
121880
|
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
121850
121881
|
|
|
121851
|
-
// ../../packages/dashboard-core/src/components/
|
|
121882
|
+
// ../../packages/dashboard-core/src/components/QuickOpenDialog.tsx
|
|
121852
121883
|
var import_react36 = __toESM(require_react(), 1);
|
|
121853
121884
|
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
|
|
121854
121885
|
|
|
121855
|
-
// ../../packages/dashboard-core/src/components/
|
|
121886
|
+
// ../../packages/dashboard-core/src/components/SearchFilesDialog.tsx
|
|
121856
121887
|
var import_react37 = __toESM(require_react(), 1);
|
|
121857
121888
|
var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
|
|
121858
121889
|
|
|
121859
|
-
// ../../packages/dashboard-core/src/components/
|
|
121890
|
+
// ../../packages/dashboard-core/src/components/WorkspacePickerDialog.tsx
|
|
121891
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
121860
121892
|
var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
|
|
121861
121893
|
|
|
121894
|
+
// ../../packages/dashboard-core/src/components/WorkspaceTabNav.tsx
|
|
121895
|
+
var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
|
|
121896
|
+
|
|
121862
121897
|
// ../../packages/dashboard-core/src/hooks/use-editor-history.ts
|
|
121863
|
-
var
|
|
121898
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
121864
121899
|
|
|
121865
121900
|
// ../../node_modules/.pnpm/marked@15.0.12/node_modules/marked/lib/marked.esm.js
|
|
121866
121901
|
function _getDefaults() {
|
|
@@ -125940,6 +125975,7 @@ function getTableAsAliasSQL(table) {
|
|
|
125940
125975
|
}
|
|
125941
125976
|
|
|
125942
125977
|
// src/lib/db/connection.ts
|
|
125978
|
+
init_src();
|
|
125943
125979
|
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
125944
125980
|
import { join as join10 } from "node:path";
|
|
125945
125981
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
@@ -131690,7 +131726,12 @@ var projects = sqliteTable("projects", {
|
|
|
131690
131726
|
path: text3("path").notNull(),
|
|
131691
131727
|
defaultBranch: text3("default_branch").notNull(),
|
|
131692
131728
|
label: text3("label"),
|
|
131693
|
-
sortOrder: integer3("sort_order").notNull()
|
|
131729
|
+
sortOrder: integer3("sort_order").notNull(),
|
|
131730
|
+
// Discriminates between git-backed projects (worktree-per-workspace,
|
|
131731
|
+
// branches, PR/CI features) and plain folders (single implicit workspace,
|
|
131732
|
+
// no isolation, git features disabled). Defaults to "git" so existing
|
|
131733
|
+
// rows keep their behavior unchanged after migration.
|
|
131734
|
+
kind: text3("kind", { enum: ["git", "plain"] }).notNull().default("git")
|
|
131694
131735
|
});
|
|
131695
131736
|
var worktrees = sqliteTable("worktrees", {
|
|
131696
131737
|
id: integer3("id").primaryKey({ autoIncrement: true }),
|
|
@@ -131756,6 +131797,7 @@ var browserHistory = sqliteTable(
|
|
|
131756
131797
|
);
|
|
131757
131798
|
|
|
131758
131799
|
// src/lib/db/connection.ts
|
|
131800
|
+
var log7 = createLogger("db");
|
|
131759
131801
|
var migrationsFolder = join10(import.meta.dirname, "migrations");
|
|
131760
131802
|
var _db = null;
|
|
131761
131803
|
var _sqlite = null;
|
|
@@ -131773,6 +131815,14 @@ function getDb() {
|
|
|
131773
131815
|
}
|
|
131774
131816
|
function closeDb() {
|
|
131775
131817
|
if (_sqlite) {
|
|
131818
|
+
try {
|
|
131819
|
+
_sqlite.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
131820
|
+
} catch (err) {
|
|
131821
|
+
log7.warn(
|
|
131822
|
+
"WAL checkpoint failed on close (best-effort): %s",
|
|
131823
|
+
err instanceof Error ? err.message : String(err)
|
|
131824
|
+
);
|
|
131825
|
+
}
|
|
131776
131826
|
_sqlite.close();
|
|
131777
131827
|
_sqlite = null;
|
|
131778
131828
|
_db = null;
|
|
@@ -131780,6 +131830,16 @@ function closeDb() {
|
|
|
131780
131830
|
}
|
|
131781
131831
|
|
|
131782
131832
|
// src/lib/state.ts
|
|
131833
|
+
function reconcileKindForProject(project) {
|
|
131834
|
+
if (!existsSync4(project.path)) return false;
|
|
131835
|
+
const detectedKind = existsSync4(join11(project.path, ".git")) ? "git" : "plain";
|
|
131836
|
+
if (detectedKind === project.kind) return false;
|
|
131837
|
+
project.kind = detectedKind;
|
|
131838
|
+
if (detectedKind === "plain") {
|
|
131839
|
+
project.worktrees = [{ branch: "main", path: project.path, pinned: false }];
|
|
131840
|
+
}
|
|
131841
|
+
return true;
|
|
131842
|
+
}
|
|
131783
131843
|
function bandHome() {
|
|
131784
131844
|
if (process.env.BAND_HOME) return process.env.BAND_HOME;
|
|
131785
131845
|
return join11(homedir6(), ".band");
|
|
@@ -131805,6 +131865,7 @@ function loadState() {
|
|
|
131805
131865
|
path: row.path,
|
|
131806
131866
|
defaultBranch: row.defaultBranch,
|
|
131807
131867
|
label: row.label ?? void 0,
|
|
131868
|
+
kind: row.kind ?? "git",
|
|
131808
131869
|
worktrees: wtByProject.get(row.name) ?? []
|
|
131809
131870
|
}))
|
|
131810
131871
|
};
|
|
@@ -131821,7 +131882,8 @@ function saveState(state2) {
|
|
|
131821
131882
|
path: project.path,
|
|
131822
131883
|
defaultBranch: project.defaultBranch,
|
|
131823
131884
|
label: project.label ?? null,
|
|
131824
|
-
sortOrder: i2
|
|
131885
|
+
sortOrder: i2,
|
|
131886
|
+
kind: project.kind
|
|
131825
131887
|
}).run();
|
|
131826
131888
|
for (const wt of project.worktrees) {
|
|
131827
131889
|
tx.insert(worktrees).values({
|
|
@@ -131980,7 +132042,7 @@ function deleteBranchStatus(workspaceId) {
|
|
|
131980
132042
|
}
|
|
131981
132043
|
|
|
131982
132044
|
// src/lib/agent-pool.ts
|
|
131983
|
-
var
|
|
132045
|
+
var log8 = createLogger("agent-pool");
|
|
131984
132046
|
var POOL_KEY = Symbol.for("band.agent-pool.v2");
|
|
131985
132047
|
var PENDING_KEY = Symbol.for("band.agent-pool.pending");
|
|
131986
132048
|
var g2 = globalThis;
|
|
@@ -132025,7 +132087,7 @@ function getAgent(chatId) {
|
|
|
132025
132087
|
return pool.get(chatId)?.agent;
|
|
132026
132088
|
}
|
|
132027
132089
|
function removeAgent(chatId) {
|
|
132028
|
-
|
|
132090
|
+
log8.info({ chatId }, "removing agent from pool");
|
|
132029
132091
|
return pool.delete(chatId);
|
|
132030
132092
|
}
|
|
132031
132093
|
async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
@@ -132033,7 +132095,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
|
132033
132095
|
if (existing) {
|
|
132034
132096
|
const requestedDefId = resolveAgentDefId(agentId);
|
|
132035
132097
|
if (existing.agentDefId !== requestedDefId) {
|
|
132036
|
-
|
|
132098
|
+
log8.info(
|
|
132037
132099
|
{ chatId, cached: existing.agentDefId, requested: requestedDefId },
|
|
132038
132100
|
"cached agent definition mismatch, replacing"
|
|
132039
132101
|
);
|
|
@@ -132047,7 +132109,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
|
132047
132109
|
return inFlight.promise;
|
|
132048
132110
|
}
|
|
132049
132111
|
const config2 = getAgentConfig(worktreePath, agentId);
|
|
132050
|
-
|
|
132112
|
+
log8.info({ chatId, type: config2.type, defId, cwd: worktreePath }, "creating agent");
|
|
132051
132113
|
const promise2 = createCodingAgent(config2).then(
|
|
132052
132114
|
(agent) => {
|
|
132053
132115
|
pool.set(chatId, { agent, agentDefId: defId });
|
|
@@ -132110,6 +132172,18 @@ function listPanelStatesForWorkspace(workspaceId, panelType) {
|
|
|
132110
132172
|
const db2 = getDb();
|
|
132111
132173
|
return db2.select().from(panelStates).where(and(eq2(panelStates.workspaceId, workspaceId), eq2(panelStates.panelType, panelType))).all();
|
|
132112
132174
|
}
|
|
132175
|
+
function resetPanelStatesToIdle(panelType, updatedAt) {
|
|
132176
|
+
const db2 = getDb();
|
|
132177
|
+
db2.update(panelStates).set({
|
|
132178
|
+
state: sql`json_set(${panelStates.state}, '$.status', 'idle')`,
|
|
132179
|
+
updatedAt
|
|
132180
|
+
}).where(
|
|
132181
|
+
and(
|
|
132182
|
+
eq2(panelStates.panelType, panelType),
|
|
132183
|
+
sql`json_extract(${panelStates.state}, '$.status') IS NOT 'idle'`
|
|
132184
|
+
)
|
|
132185
|
+
).run();
|
|
132186
|
+
}
|
|
132113
132187
|
|
|
132114
132188
|
// src/lib/dockview-layout-manager.ts
|
|
132115
132189
|
function isLeaf(node) {
|
|
@@ -132582,6 +132656,7 @@ function parseBatchedCIResponse(data, aliases, defaultBranches) {
|
|
|
132582
132656
|
}
|
|
132583
132657
|
|
|
132584
132658
|
// src/lib/sync-state.ts
|
|
132659
|
+
var PROJECT_SYNC_BATCH_SIZE = 8;
|
|
132585
132660
|
async function detectRemoteDefaultBranch(projectPath) {
|
|
132586
132661
|
try {
|
|
132587
132662
|
const ref = (await execGit(["symbolic-ref", "refs/remotes/origin/HEAD"], projectPath)).trim();
|
|
@@ -132606,35 +132681,50 @@ async function syncWorktrees() {
|
|
|
132606
132681
|
const state2 = loadState();
|
|
132607
132682
|
let changed = false;
|
|
132608
132683
|
for (const project of state2.projects) {
|
|
132609
|
-
|
|
132610
|
-
try {
|
|
132611
|
-
const gitWorktrees = await listWorktrees(project.path);
|
|
132612
|
-
const pinnedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt.pinned]));
|
|
132613
|
-
diskWorktrees = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({
|
|
132614
|
-
branch: wt.branch,
|
|
132615
|
-
path: wt.path,
|
|
132616
|
-
head: wt.head,
|
|
132617
|
-
pinned: pinnedByBranch.get(wt.branch) ?? false
|
|
132618
|
-
}));
|
|
132619
|
-
} catch {
|
|
132620
|
-
continue;
|
|
132621
|
-
}
|
|
132622
|
-
const existingSet = new Set(project.worktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132623
|
-
const diskSet = new Set(diskWorktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132624
|
-
if (existingSet.size !== diskSet.size || Array.from(existingSet).some((key) => !diskSet.has(key))) {
|
|
132625
|
-
project.worktrees = diskWorktrees;
|
|
132684
|
+
if (reconcileKindForProject(project)) {
|
|
132626
132685
|
changed = true;
|
|
132627
132686
|
}
|
|
132628
|
-
|
|
132629
|
-
|
|
132630
|
-
|
|
132631
|
-
|
|
132687
|
+
}
|
|
132688
|
+
const gitProjects = state2.projects.filter((p6) => p6.kind !== "plain");
|
|
132689
|
+
for (let i2 = 0; i2 < gitProjects.length; i2 += PROJECT_SYNC_BATCH_SIZE) {
|
|
132690
|
+
const batch = gitProjects.slice(i2, i2 + PROJECT_SYNC_BATCH_SIZE);
|
|
132691
|
+
const results = await Promise.all(batch.map(reconcileOneProject));
|
|
132692
|
+
for (const mutated of results) {
|
|
132693
|
+
if (mutated) changed = true;
|
|
132632
132694
|
}
|
|
132633
132695
|
}
|
|
132634
132696
|
if (changed) {
|
|
132635
132697
|
saveState(state2);
|
|
132636
132698
|
}
|
|
132637
132699
|
}
|
|
132700
|
+
async function reconcileOneProject(project) {
|
|
132701
|
+
let mutated = false;
|
|
132702
|
+
let diskWorktrees;
|
|
132703
|
+
try {
|
|
132704
|
+
const gitWorktrees = await listWorktrees(project.path);
|
|
132705
|
+
const pinnedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt.pinned]));
|
|
132706
|
+
diskWorktrees = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({
|
|
132707
|
+
branch: wt.branch,
|
|
132708
|
+
path: wt.path,
|
|
132709
|
+
head: wt.head,
|
|
132710
|
+
pinned: pinnedByBranch.get(wt.branch) ?? false
|
|
132711
|
+
}));
|
|
132712
|
+
} catch {
|
|
132713
|
+
return false;
|
|
132714
|
+
}
|
|
132715
|
+
const existingSet = new Set(project.worktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132716
|
+
const diskSet = new Set(diskWorktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132717
|
+
if (existingSet.size !== diskSet.size || Array.from(existingSet).some((key) => !diskSet.has(key))) {
|
|
132718
|
+
project.worktrees = diskWorktrees;
|
|
132719
|
+
mutated = true;
|
|
132720
|
+
}
|
|
132721
|
+
const remoteBranch = await detectRemoteDefaultBranch(project.path);
|
|
132722
|
+
if (remoteBranch && remoteBranch !== project.defaultBranch) {
|
|
132723
|
+
project.defaultBranch = remoteBranch;
|
|
132724
|
+
mutated = true;
|
|
132725
|
+
}
|
|
132726
|
+
return mutated;
|
|
132727
|
+
}
|
|
132638
132728
|
|
|
132639
132729
|
// src/lib/branch-status-poller.ts
|
|
132640
132730
|
var INTERVALS = {
|
|
@@ -132653,6 +132743,7 @@ function getWorkspaces() {
|
|
|
132653
132743
|
const state2 = loadState();
|
|
132654
132744
|
const workspaces = [];
|
|
132655
132745
|
for (const project of state2.projects) {
|
|
132746
|
+
if (project.kind === "plain") continue;
|
|
132656
132747
|
for (const wt of project.worktrees) {
|
|
132657
132748
|
workspaces.push({
|
|
132658
132749
|
workspaceId: toWorkspaceId(project.name, wt.branch),
|
|
@@ -132896,12 +132987,12 @@ function getPollerActivity() {
|
|
|
132896
132987
|
import { spawn as spawn5 } from "node:child_process";
|
|
132897
132988
|
|
|
132898
132989
|
// src/lib/project-config.ts
|
|
132899
|
-
import { existsSync as
|
|
132990
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "node:fs";
|
|
132900
132991
|
import { join as join14 } from "node:path";
|
|
132901
132992
|
function loadProjectConfig(worktreePath, projectPath) {
|
|
132902
132993
|
for (const base2 of [worktreePath, projectPath]) {
|
|
132903
132994
|
const configPath = join14(base2, ".band", "config.json");
|
|
132904
|
-
if (
|
|
132995
|
+
if (existsSync5(configPath)) {
|
|
132905
132996
|
try {
|
|
132906
132997
|
return JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
132907
132998
|
} catch {
|
|
@@ -133020,7 +133111,7 @@ function subscribe(listener) {
|
|
|
133020
133111
|
}
|
|
133021
133112
|
|
|
133022
133113
|
// src/lib/chat-manager.ts
|
|
133023
|
-
var
|
|
133114
|
+
var log9 = createLogger("chat-manager");
|
|
133024
133115
|
var PANEL_TYPE = "chat";
|
|
133025
133116
|
var chatSessions = /* @__PURE__ */ new Map();
|
|
133026
133117
|
var workspaceChats = /* @__PURE__ */ new Map();
|
|
@@ -133091,7 +133182,7 @@ function createChat(workspaceId, options2) {
|
|
|
133091
133182
|
addToIndex(session);
|
|
133092
133183
|
addChatToLayout(workspaceId, session.id, { title: session.name });
|
|
133093
133184
|
emit({ kind: "chat-created", workspaceId, chatId: session.id });
|
|
133094
|
-
|
|
133185
|
+
log9.info({ chatId: session.id, workspaceId, agent: session.agent }, "chat pane created");
|
|
133095
133186
|
return session;
|
|
133096
133187
|
}
|
|
133097
133188
|
function getChat(chatId) {
|
|
@@ -133120,7 +133211,7 @@ function updateChat(chatId, updates) {
|
|
|
133120
133211
|
state: serializeState(session),
|
|
133121
133212
|
updatedAt: Date.now()
|
|
133122
133213
|
});
|
|
133123
|
-
|
|
133214
|
+
log9.info({ chatId, updates }, "chat pane updated");
|
|
133124
133215
|
return session;
|
|
133125
133216
|
}
|
|
133126
133217
|
function updateChatStatus(chatId, status) {
|
|
@@ -133172,7 +133263,7 @@ function removeChat(chatId) {
|
|
|
133172
133263
|
removeChatFromLayout(session.workspaceId, chatId);
|
|
133173
133264
|
removeFromIndex(chatId);
|
|
133174
133265
|
emit({ kind: "chat-removed", workspaceId: session.workspaceId, chatId });
|
|
133175
|
-
|
|
133266
|
+
log9.info({ chatId, workspaceId: session.workspaceId }, "chat pane removed");
|
|
133176
133267
|
return true;
|
|
133177
133268
|
}
|
|
133178
133269
|
function removeWorkspaceChats(workspaceId) {
|
|
@@ -133184,19 +133275,15 @@ function removeWorkspaceChats(workspaceId) {
|
|
|
133184
133275
|
}
|
|
133185
133276
|
deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE);
|
|
133186
133277
|
workspaceChats.delete(workspaceId);
|
|
133187
|
-
|
|
133278
|
+
log9.info({ workspaceId }, "all chat panes removed for workspace");
|
|
133188
133279
|
}
|
|
133189
133280
|
function loadChatsFromDb() {
|
|
133190
133281
|
_initialized = true;
|
|
133191
|
-
const rows = listPanelStates(PANEL_TYPE);
|
|
133192
133282
|
const now = Date.now();
|
|
133283
|
+
resetPanelStatesToIdle(PANEL_TYPE, now);
|
|
133284
|
+
const rows = listPanelStates(PANEL_TYPE);
|
|
133193
133285
|
for (const row of rows) {
|
|
133194
133286
|
const parsed = JSON.parse(row.state);
|
|
133195
|
-
parsed.status = "idle";
|
|
133196
|
-
updatePanelState(row.id, {
|
|
133197
|
-
state: JSON.stringify(parsed),
|
|
133198
|
-
updatedAt: now
|
|
133199
|
-
});
|
|
133200
133287
|
const session = {
|
|
133201
133288
|
id: row.id,
|
|
133202
133289
|
workspaceId: row.workspaceId,
|
|
@@ -133207,12 +133294,16 @@ function loadChatsFromDb() {
|
|
|
133207
133294
|
activeSessionId: parsed.activeSessionId ?? void 0,
|
|
133208
133295
|
activeSessionSummary: parsed.activeSessionSummary ?? void 0,
|
|
133209
133296
|
activeSessionLastModified: parsed.activeSessionLastModified ?? void 0,
|
|
133297
|
+
// Force idle on the in-memory copy: even if the bulk UPDATE skipped
|
|
133298
|
+
// this row because it was already "idle" on disk, or — in some odd
|
|
133299
|
+
// race — wrote between the UPDATE and the SELECT, we never want to
|
|
133300
|
+
// hand the rest of the server a session in a non-idle state on boot.
|
|
133210
133301
|
status: "idle"
|
|
133211
133302
|
};
|
|
133212
133303
|
addToIndex(session);
|
|
133213
133304
|
}
|
|
133214
133305
|
if (rows.length > 0) {
|
|
133215
|
-
|
|
133306
|
+
log9.info({ count: rows.length }, "loaded chat panes from database");
|
|
133216
133307
|
}
|
|
133217
133308
|
return rows.length;
|
|
133218
133309
|
}
|
|
@@ -133392,7 +133483,7 @@ function hasPendingInputForWorkspace(workspaceId) {
|
|
|
133392
133483
|
|
|
133393
133484
|
// src/lib/task-store.ts
|
|
133394
133485
|
init_src();
|
|
133395
|
-
var
|
|
133486
|
+
var log10 = createLogger("task-store");
|
|
133396
133487
|
function generateTaskId() {
|
|
133397
133488
|
return `tsk_${Date.now()}`;
|
|
133398
133489
|
}
|
|
@@ -133465,7 +133556,7 @@ function cleanupStaleTasks() {
|
|
|
133465
133556
|
const result = db2.update(tasks).set({ status: "failed", completedAt: now }).where(eq2(tasks.status, "running")).run();
|
|
133466
133557
|
const count3 = result.changes;
|
|
133467
133558
|
if (count3 > 0) {
|
|
133468
|
-
|
|
133559
|
+
log10.info({ count: count3 }, "cleaned up stale tasks on startup");
|
|
133469
133560
|
}
|
|
133470
133561
|
return count3;
|
|
133471
133562
|
}
|
|
@@ -133502,7 +133593,7 @@ function pruneOldTasks(retentionMs = TASK_RETENTION_MS) {
|
|
|
133502
133593
|
const cutoff = Date.now() - retentionMs;
|
|
133503
133594
|
const count3 = deleteTasksOlderThan(cutoff);
|
|
133504
133595
|
if (count3 > 0) {
|
|
133505
|
-
|
|
133596
|
+
log10.info({ count: count3, retentionMs }, "pruned tasks older than retention window");
|
|
133506
133597
|
}
|
|
133507
133598
|
return count3;
|
|
133508
133599
|
}
|
|
@@ -133513,13 +133604,13 @@ function startTaskPruneScheduler(options2 = {}) {
|
|
|
133513
133604
|
try {
|
|
133514
133605
|
pruneOldTasks(retentionMs);
|
|
133515
133606
|
} catch (err) {
|
|
133516
|
-
|
|
133607
|
+
log10.error({ err }, "initial task prune on boot failed");
|
|
133517
133608
|
}
|
|
133518
133609
|
const timer = setInterval(() => {
|
|
133519
133610
|
try {
|
|
133520
133611
|
pruneOldTasks(retentionMs);
|
|
133521
133612
|
} catch (err) {
|
|
133522
|
-
|
|
133613
|
+
log10.error({ err }, "scheduled task prune failed");
|
|
133523
133614
|
}
|
|
133524
133615
|
}, intervalMs);
|
|
133525
133616
|
timer.unref();
|
|
@@ -133606,7 +133697,7 @@ function resolveWorkspace(workspaceId) {
|
|
|
133606
133697
|
}
|
|
133607
133698
|
|
|
133608
133699
|
// src/lib/task-runner.ts
|
|
133609
|
-
var
|
|
133700
|
+
var log11 = createLogger("task-runner");
|
|
133610
133701
|
function listFiles(dir) {
|
|
133611
133702
|
try {
|
|
133612
133703
|
return new Set(readdirSync6(dir));
|
|
@@ -133665,7 +133756,7 @@ function persistTask(task) {
|
|
|
133665
133756
|
chatId: task.chatId
|
|
133666
133757
|
});
|
|
133667
133758
|
} catch (err) {
|
|
133668
|
-
|
|
133759
|
+
log11.warn({ err, taskId: task.taskRecordId }, "failed to persist task");
|
|
133669
133760
|
}
|
|
133670
133761
|
}
|
|
133671
133762
|
function broadcast(chatId, chunk) {
|
|
@@ -133689,7 +133780,7 @@ function broadcast(chatId, chunk) {
|
|
|
133689
133780
|
}
|
|
133690
133781
|
const subs = listeners2.get(chatId);
|
|
133691
133782
|
if (!subs || subs.size === 0) {
|
|
133692
|
-
|
|
133783
|
+
log11.warn({ chatId, chunkType: chunk.type }, "broadcast: no listeners");
|
|
133693
133784
|
return;
|
|
133694
133785
|
}
|
|
133695
133786
|
for (const listener of subs) {
|
|
@@ -133740,7 +133831,7 @@ function submitTask(options2) {
|
|
|
133740
133831
|
tasks2.set(chatId, task);
|
|
133741
133832
|
persistTask(task);
|
|
133742
133833
|
runTask(chatId, task).catch((err) => {
|
|
133743
|
-
|
|
133834
|
+
log11.error({ chatId, err }, "task execution failed");
|
|
133744
133835
|
if (task.status === "running") {
|
|
133745
133836
|
task.status = "failed";
|
|
133746
133837
|
task.completedAt = Date.now();
|
|
@@ -133774,7 +133865,7 @@ function abortTask(chatId) {
|
|
|
133774
133865
|
updateChatStatus(chatId, "idle");
|
|
133775
133866
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
133776
133867
|
emit({ kind: "update", status: updated });
|
|
133777
|
-
|
|
133868
|
+
log11.info({ chatId }, "task aborted by user");
|
|
133778
133869
|
return true;
|
|
133779
133870
|
}
|
|
133780
133871
|
function cancelTask(taskId) {
|
|
@@ -133794,7 +133885,7 @@ function cancelTask(taskId) {
|
|
|
133794
133885
|
updateChatStatus(chatId, "idle");
|
|
133795
133886
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
133796
133887
|
emit({ kind: "update", status: updated });
|
|
133797
|
-
|
|
133888
|
+
log11.info({ chatId, taskId }, "task cancelled (was running in-memory)");
|
|
133798
133889
|
return { cancelled: true, workspaceId: task.workspaceId };
|
|
133799
133890
|
}
|
|
133800
133891
|
}
|
|
@@ -133802,7 +133893,7 @@ function cancelTask(taskId) {
|
|
|
133802
133893
|
if (record2) {
|
|
133803
133894
|
const updated = upsertWorkspaceStatus(record2.workspaceId, { status: "waiting" });
|
|
133804
133895
|
emit({ kind: "update", status: updated });
|
|
133805
|
-
|
|
133896
|
+
log11.info({ taskId, workspaceId: record2.workspaceId }, "orphaned task cancelled");
|
|
133806
133897
|
return { cancelled: true, workspaceId: record2.workspaceId };
|
|
133807
133898
|
}
|
|
133808
133899
|
return { cancelled: false };
|
|
@@ -133822,7 +133913,7 @@ async function runTask(chatId, task) {
|
|
|
133822
133913
|
const taskAgentId = task.codingAgentId;
|
|
133823
133914
|
const resolvedAgentId = taskAgentId ?? chatSession?.agent;
|
|
133824
133915
|
const needsReplace = taskAgentId && taskAgentId !== chatSession?.agent;
|
|
133825
|
-
|
|
133916
|
+
log11.info(
|
|
133826
133917
|
{ chatId, taskAgentId, chatAgent: chatSession?.agent, resolvedAgentId, needsReplace },
|
|
133827
133918
|
"resolving agent for task"
|
|
133828
133919
|
);
|
|
@@ -133871,7 +133962,7 @@ async function runTask(chatId, task) {
|
|
|
133871
133962
|
[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.]`;
|
|
133872
133963
|
const effectivePrompt = task.sessionId ? task.agentPrompt : task.agentPrompt + fileSharingHint;
|
|
133873
133964
|
for await (const event of agent.runSession(effectivePrompt, task.sessionId, sessionOptions)) {
|
|
133874
|
-
|
|
133965
|
+
log11.info({ chatId, eventType: event.type }, "task event");
|
|
133875
133966
|
switch (event.type) {
|
|
133876
133967
|
case "session-start": {
|
|
133877
133968
|
task.sessionId = event.sessionId;
|
|
@@ -134052,7 +134143,7 @@ async function runTask(chatId, task) {
|
|
|
134052
134143
|
break;
|
|
134053
134144
|
}
|
|
134054
134145
|
case "session-id-resolved": {
|
|
134055
|
-
|
|
134146
|
+
log11.info(
|
|
134056
134147
|
{ chatId, previous: event.previousSessionId, resolved: event.resolvedSessionId },
|
|
134057
134148
|
"session ID resolved"
|
|
134058
134149
|
);
|
|
@@ -134147,7 +134238,7 @@ ${queued.text}`;
|
|
|
134147
134238
|
});
|
|
134148
134239
|
autoStarted = true;
|
|
134149
134240
|
} catch (err) {
|
|
134150
|
-
|
|
134241
|
+
log11.warn({ chatId, err }, "failed to auto-start queued task");
|
|
134151
134242
|
}
|
|
134152
134243
|
}
|
|
134153
134244
|
}
|
|
@@ -134247,7 +134338,7 @@ function getSessionEventsAfter(sessionId, afterEventId) {
|
|
|
134247
134338
|
}
|
|
134248
134339
|
|
|
134249
134340
|
// src/api/task-stream.ts
|
|
134250
|
-
var
|
|
134341
|
+
var log12 = createLogger("task-stream");
|
|
134251
134342
|
var INTERNAL_CHUNK_TYPES = /* @__PURE__ */ new Set(["user-message"]);
|
|
134252
134343
|
function toUIChunk(chunk) {
|
|
134253
134344
|
if (INTERNAL_CHUNK_TYPES.has(chunk.type)) return null;
|
|
@@ -134302,7 +134393,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
|
|
|
134302
134393
|
const buf = getSessionBuffer(task.sessionId);
|
|
134303
134394
|
if (buf && buf.events.length > 0) {
|
|
134304
134395
|
const taskStartEventId = task.firstEventId ?? Number.POSITIVE_INFINITY;
|
|
134305
|
-
|
|
134396
|
+
log12.info(
|
|
134306
134397
|
{
|
|
134307
134398
|
chatId,
|
|
134308
134399
|
sessionId: task.sessionId,
|
|
@@ -134326,7 +134417,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
|
|
|
134326
134417
|
}
|
|
134327
134418
|
}
|
|
134328
134419
|
if (queue.length === 0 && !caughtUp && (!task || task.status !== "running")) {
|
|
134329
|
-
|
|
134420
|
+
log12.warn(
|
|
134330
134421
|
{ chatId, taskStatus: task?.status, queueLen: queue.length },
|
|
134331
134422
|
"task-stream: no running task and no events \u2014 closing stream early"
|
|
134332
134423
|
);
|
|
@@ -134424,7 +134515,7 @@ ${prompt}`;
|
|
|
134424
134515
|
}
|
|
134425
134516
|
throw err;
|
|
134426
134517
|
}
|
|
134427
|
-
|
|
134518
|
+
log12.info({ chatId, workspaceId }, "task-stream: POST \u2014 task submitted, opening SSE stream");
|
|
134428
134519
|
streamTask(res, chatId, sessionId, void 0);
|
|
134429
134520
|
}
|
|
134430
134521
|
function handleGet(req, res, chatId) {
|
|
@@ -134438,13 +134529,13 @@ function handleGet(req, res, chatId) {
|
|
|
134438
134529
|
res.end();
|
|
134439
134530
|
return;
|
|
134440
134531
|
}
|
|
134441
|
-
|
|
134532
|
+
log12.info({ chatId, sessionId, afterEventId }, "task-stream: GET \u2014 reconnecting to active stream");
|
|
134442
134533
|
streamTask(res, chatId, sessionId ?? task.sessionId, afterEventId);
|
|
134443
134534
|
}
|
|
134444
134535
|
function handleTaskStream(req, res, chatId) {
|
|
134445
134536
|
if (req.method === "POST") {
|
|
134446
134537
|
handlePost(req, res, chatId).catch((err) => {
|
|
134447
|
-
|
|
134538
|
+
log12.error({ chatId, err }, "task-stream: POST handler error");
|
|
134448
134539
|
if (!res.headersSent) {
|
|
134449
134540
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
134450
134541
|
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
@@ -134489,7 +134580,7 @@ function removeBrowserFromLayout(workspaceId, browserId) {
|
|
|
134489
134580
|
}
|
|
134490
134581
|
|
|
134491
134582
|
// src/lib/browser-manager.ts
|
|
134492
|
-
var
|
|
134583
|
+
var log13 = createLogger("browser-manager");
|
|
134493
134584
|
var PANEL_TYPE2 = "browser";
|
|
134494
134585
|
var browserTabs = /* @__PURE__ */ new Map();
|
|
134495
134586
|
var workspaceBrowsers = /* @__PURE__ */ new Map();
|
|
@@ -134550,7 +134641,7 @@ function createBrowser(workspaceId, options2) {
|
|
|
134550
134641
|
title: tab.name,
|
|
134551
134642
|
initialUrl: tab.url || void 0
|
|
134552
134643
|
});
|
|
134553
|
-
|
|
134644
|
+
log13.info({ browserId: tab.id, workspaceId, url: tab.url }, "browser tab created");
|
|
134554
134645
|
return tab;
|
|
134555
134646
|
}
|
|
134556
134647
|
function getBrowser(browserId) {
|
|
@@ -134577,7 +134668,7 @@ function updateBrowser(browserId, updates) {
|
|
|
134577
134668
|
state: serializeState2(tab),
|
|
134578
134669
|
updatedAt: Date.now()
|
|
134579
134670
|
});
|
|
134580
|
-
|
|
134671
|
+
log13.info({ browserId, updates }, "browser tab updated");
|
|
134581
134672
|
return tab;
|
|
134582
134673
|
}
|
|
134583
134674
|
function updateBrowserUrl(browserId, url2) {
|
|
@@ -134594,7 +134685,7 @@ function removeBrowser(browserId) {
|
|
|
134594
134685
|
if (!tab) return false;
|
|
134595
134686
|
deletePanelState(browserId);
|
|
134596
134687
|
removeFromIndex2(browserId);
|
|
134597
|
-
|
|
134688
|
+
log13.info({ browserId, workspaceId: tab.workspaceId }, "browser tab removed");
|
|
134598
134689
|
return true;
|
|
134599
134690
|
}
|
|
134600
134691
|
function removeWorkspaceBrowsers(workspaceId) {
|
|
@@ -134605,19 +134696,15 @@ function removeWorkspaceBrowsers(workspaceId) {
|
|
|
134605
134696
|
}
|
|
134606
134697
|
deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE2);
|
|
134607
134698
|
workspaceBrowsers.delete(workspaceId);
|
|
134608
|
-
|
|
134699
|
+
log13.info({ workspaceId }, "all browser tabs removed for workspace");
|
|
134609
134700
|
}
|
|
134610
134701
|
function loadBrowsersFromDb() {
|
|
134611
134702
|
_initialized2 = true;
|
|
134612
|
-
const rows = listPanelStates(PANEL_TYPE2);
|
|
134613
134703
|
const now = Date.now();
|
|
134704
|
+
resetPanelStatesToIdle(PANEL_TYPE2, now);
|
|
134705
|
+
const rows = listPanelStates(PANEL_TYPE2);
|
|
134614
134706
|
for (const row of rows) {
|
|
134615
134707
|
const parsed = JSON.parse(row.state);
|
|
134616
|
-
parsed.status = "idle";
|
|
134617
|
-
updatePanelState(row.id, {
|
|
134618
|
-
state: JSON.stringify(parsed),
|
|
134619
|
-
updatedAt: now
|
|
134620
|
-
});
|
|
134621
134708
|
const tab = {
|
|
134622
134709
|
id: row.id,
|
|
134623
134710
|
workspaceId: row.workspaceId,
|
|
@@ -134628,13 +134715,13 @@ function loadBrowsersFromDb() {
|
|
|
134628
134715
|
addToIndex2(tab);
|
|
134629
134716
|
}
|
|
134630
134717
|
if (rows.length > 0) {
|
|
134631
|
-
|
|
134718
|
+
log13.info({ count: rows.length }, "loaded browser tabs from database");
|
|
134632
134719
|
}
|
|
134633
134720
|
return rows.length;
|
|
134634
134721
|
}
|
|
134635
134722
|
|
|
134636
134723
|
// src/lib/browser-host.ts
|
|
134637
|
-
var
|
|
134724
|
+
var log14 = createLogger("browser-host");
|
|
134638
134725
|
var DESKTOP_CDP_HOST = "127.0.0.1";
|
|
134639
134726
|
var DESKTOP_CDP_PORT = 9223;
|
|
134640
134727
|
var globalAny = globalThis;
|
|
@@ -134685,7 +134772,7 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
134685
134772
|
reject: rejectFn,
|
|
134686
134773
|
timeoutId
|
|
134687
134774
|
});
|
|
134688
|
-
|
|
134775
|
+
log14.info(
|
|
134689
134776
|
"ensureCdpTargetId emitting ensureView for %s (url=%s, listeners=%d)",
|
|
134690
134777
|
bandTabId,
|
|
134691
134778
|
tab.url,
|
|
@@ -134699,13 +134786,13 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
134699
134786
|
url: tab.url
|
|
134700
134787
|
});
|
|
134701
134788
|
} catch (err) {
|
|
134702
|
-
|
|
134789
|
+
log14.warn("ensureView listener threw: %s", err instanceof Error ? err.message : err);
|
|
134703
134790
|
}
|
|
134704
134791
|
}
|
|
134705
134792
|
return promise2;
|
|
134706
134793
|
}
|
|
134707
134794
|
function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
134708
|
-
|
|
134795
|
+
log14.info("resolveTargetReady %s \u2192 %s", bandTabId, cdpTargetId);
|
|
134709
134796
|
targetIdByBandTabId.set(bandTabId, cdpTargetId);
|
|
134710
134797
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
134711
134798
|
if (pending2) {
|
|
@@ -134715,7 +134802,7 @@ function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
|
134715
134802
|
}
|
|
134716
134803
|
}
|
|
134717
134804
|
function markTargetDestroyed(bandTabId) {
|
|
134718
|
-
|
|
134805
|
+
log14.info("markTargetDestroyed %s", bandTabId);
|
|
134719
134806
|
targetIdByBandTabId.delete(bandTabId);
|
|
134720
134807
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
134721
134808
|
if (pending2) {
|
|
@@ -134726,10 +134813,10 @@ function markTargetDestroyed(bandTabId) {
|
|
|
134726
134813
|
}
|
|
134727
134814
|
function onEnsureView(listener) {
|
|
134728
134815
|
ensureListeners.add(listener);
|
|
134729
|
-
|
|
134816
|
+
log14.info("onEnsureView subscriber added (total=%d)", ensureListeners.size);
|
|
134730
134817
|
return () => {
|
|
134731
134818
|
ensureListeners.delete(listener);
|
|
134732
|
-
|
|
134819
|
+
log14.info("onEnsureView subscriber removed (total=%d)", ensureListeners.size);
|
|
134733
134820
|
if (ensureListeners.size === 0) {
|
|
134734
134821
|
for (const [bandTabId, pending2] of pendingEnsures) {
|
|
134735
134822
|
clearTimeout(pending2.timeoutId);
|
|
@@ -134746,7 +134833,7 @@ function isDesktopHostConnected() {
|
|
|
134746
134833
|
|
|
134747
134834
|
// src/lib/cdp-proxy.ts
|
|
134748
134835
|
init_src();
|
|
134749
|
-
var
|
|
134836
|
+
var log15 = createLogger("cdp-proxy");
|
|
134750
134837
|
async function handleCdpConnection(ws, req) {
|
|
134751
134838
|
const url2 = new URL(req.url ?? "", `http://${req.headers.host}`);
|
|
134752
134839
|
const bandTabId = url2.searchParams.get("bandTabId");
|
|
@@ -134769,17 +134856,17 @@ async function handleCdpConnection(ws, req) {
|
|
|
134769
134856
|
cdpTargetId = await ensureCdpTargetId(bandTabId);
|
|
134770
134857
|
} catch (err) {
|
|
134771
134858
|
const message = err instanceof Error ? err.message : String(err);
|
|
134772
|
-
|
|
134859
|
+
log15.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
|
|
134773
134860
|
if (ws.readyState === ws.OPEN) {
|
|
134774
134861
|
ws.close(4001, message.slice(0, 123));
|
|
134775
134862
|
}
|
|
134776
134863
|
return;
|
|
134777
134864
|
}
|
|
134778
134865
|
const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
|
|
134779
|
-
|
|
134866
|
+
log15.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
|
|
134780
134867
|
upstream = new wrapper_default(upstreamUrl);
|
|
134781
134868
|
upstream.on("open", () => {
|
|
134782
|
-
|
|
134869
|
+
log15.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
|
|
134783
134870
|
for (const msg of pending2) {
|
|
134784
134871
|
upstream?.send(msg);
|
|
134785
134872
|
}
|
|
@@ -134791,20 +134878,20 @@ async function handleCdpConnection(ws, req) {
|
|
|
134791
134878
|
}
|
|
134792
134879
|
});
|
|
134793
134880
|
upstream.on("error", (err) => {
|
|
134794
|
-
|
|
134881
|
+
log15.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
|
|
134795
134882
|
markTargetDestroyed(bandTabId);
|
|
134796
134883
|
if (ws.readyState === ws.OPEN) {
|
|
134797
134884
|
ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
|
|
134798
134885
|
}
|
|
134799
134886
|
});
|
|
134800
134887
|
upstream.on("close", (code) => {
|
|
134801
|
-
|
|
134888
|
+
log15.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
|
|
134802
134889
|
if (ws.readyState === ws.OPEN) {
|
|
134803
134890
|
ws.close(1e3, "Upstream closed");
|
|
134804
134891
|
}
|
|
134805
134892
|
});
|
|
134806
134893
|
ws.on("close", () => {
|
|
134807
|
-
|
|
134894
|
+
log15.debug("CDP client closed bandTabId=%s", bandTabId);
|
|
134808
134895
|
if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
|
|
134809
134896
|
try {
|
|
134810
134897
|
upstream.close();
|
|
@@ -134813,7 +134900,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
134813
134900
|
}
|
|
134814
134901
|
});
|
|
134815
134902
|
ws.on("error", (err) => {
|
|
134816
|
-
|
|
134903
|
+
log15.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
|
|
134817
134904
|
try {
|
|
134818
134905
|
upstream?.close();
|
|
134819
134906
|
} catch {
|
|
@@ -134823,7 +134910,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
134823
134910
|
|
|
134824
134911
|
// src/lib/cdp-targets.ts
|
|
134825
134912
|
init_src();
|
|
134826
|
-
var
|
|
134913
|
+
var log16 = createLogger("cdp-targets");
|
|
134827
134914
|
var CdpUnreachableError = class extends Error {
|
|
134828
134915
|
constructor(message) {
|
|
134829
134916
|
super(message);
|
|
@@ -134879,7 +134966,7 @@ async function captureSnapshot(bandTabId) {
|
|
|
134879
134966
|
});
|
|
134880
134967
|
ws.on("error", (err) => {
|
|
134881
134968
|
clearTimeout(timeout);
|
|
134882
|
-
|
|
134969
|
+
log16.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
|
|
134883
134970
|
markTargetDestroyed(bandTabId);
|
|
134884
134971
|
settle(new CdpUnreachableError(err.message));
|
|
134885
134972
|
});
|
|
@@ -135599,7 +135686,7 @@ function rowToDefinition(row) {
|
|
|
135599
135686
|
}
|
|
135600
135687
|
|
|
135601
135688
|
// src/lib/cronjob-scheduler.ts
|
|
135602
|
-
var
|
|
135689
|
+
var log17 = createLogger("cronjob-scheduler");
|
|
135603
135690
|
var SCHEDULER_KEY = Symbol.for("band.cronjob-scheduler");
|
|
135604
135691
|
var g14 = globalThis;
|
|
135605
135692
|
if (!g14[SCHEDULER_KEY]) {
|
|
@@ -135619,16 +135706,16 @@ function scheduleJob(job, fileKey) {
|
|
|
135619
135706
|
try {
|
|
135620
135707
|
const cronInstance = new E2(job.cronExpression, () => {
|
|
135621
135708
|
executeCronjob(job, fileKey).catch((err) => {
|
|
135622
|
-
|
|
135709
|
+
log17.error({ jobId: job.id, err }, "unhandled error in cronjob execution");
|
|
135623
135710
|
});
|
|
135624
135711
|
});
|
|
135625
135712
|
state.jobs.set(job.id, cronInstance);
|
|
135626
|
-
|
|
135713
|
+
log17.info(
|
|
135627
135714
|
{ jobId: job.id, name: job.name, cron: job.cronExpression, scope: job.scope },
|
|
135628
135715
|
"scheduled cronjob"
|
|
135629
135716
|
);
|
|
135630
135717
|
} catch (err) {
|
|
135631
|
-
|
|
135718
|
+
log17.error(
|
|
135632
135719
|
{ jobId: job.id, cronExpression: job.cronExpression, err },
|
|
135633
135720
|
"invalid cron expression, skipping job"
|
|
135634
135721
|
);
|
|
@@ -135642,24 +135729,24 @@ async function executeCronjob(job, fileKey) {
|
|
|
135642
135729
|
const appState = loadState();
|
|
135643
135730
|
const project = appState.projects.find((p6) => p6.name === fileKey);
|
|
135644
135731
|
if (!project) {
|
|
135645
|
-
|
|
135732
|
+
log17.warn({ jobId: job.id, fileKey }, "project not found for cronjob, skipping");
|
|
135646
135733
|
updateLastRun(job.id, "failed");
|
|
135647
135734
|
return;
|
|
135648
135735
|
}
|
|
135649
135736
|
workspaceId = toWorkspaceId(project.name, project.defaultBranch);
|
|
135650
135737
|
}
|
|
135651
|
-
|
|
135738
|
+
log17.info({ jobId: job.id, name: job.name, workspaceId }, "executing cronjob");
|
|
135652
135739
|
try {
|
|
135653
135740
|
const chat = getOrCreateDefaultChat(workspaceId);
|
|
135654
135741
|
submitTask({ workspaceId, chatId: chat.id, prompt: job.prompt });
|
|
135655
135742
|
updateLastRun(job.id, "completed");
|
|
135656
135743
|
} catch (err) {
|
|
135657
135744
|
if (err instanceof TaskConflictError) {
|
|
135658
|
-
|
|
135745
|
+
log17.info({ jobId: job.id, workspaceId }, "task already running, skipping cronjob execution");
|
|
135659
135746
|
updateLastRun(job.id, "skipped");
|
|
135660
135747
|
return;
|
|
135661
135748
|
}
|
|
135662
|
-
|
|
135749
|
+
log17.error({ jobId: job.id, err }, "cronjob execution failed");
|
|
135663
135750
|
updateLastRun(job.id, "failed");
|
|
135664
135751
|
}
|
|
135665
135752
|
}
|
|
@@ -135668,7 +135755,7 @@ function updateLastRun(jobId, status) {
|
|
|
135668
135755
|
const db2 = getDb();
|
|
135669
135756
|
db2.update(cronjobs).set({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString(), lastRunStatus: status }).where(eq2(cronjobs.id, jobId)).run();
|
|
135670
135757
|
} catch (err) {
|
|
135671
|
-
|
|
135758
|
+
log17.warn({ jobId, err }, "failed to update lastRun on cronjob");
|
|
135672
135759
|
}
|
|
135673
135760
|
}
|
|
135674
135761
|
function loadAndScheduleAll() {
|
|
@@ -135679,13 +135766,13 @@ function loadAndScheduleAll() {
|
|
|
135679
135766
|
for (const job of listAllCronjobs()) {
|
|
135680
135767
|
scheduleJob(job, job.fileKey);
|
|
135681
135768
|
}
|
|
135682
|
-
|
|
135769
|
+
log17.info({ count: state.jobs.size }, "loaded cronjob schedules");
|
|
135683
135770
|
}
|
|
135684
135771
|
function startCronjobScheduler() {
|
|
135685
135772
|
if (state.started) return;
|
|
135686
135773
|
state.started = true;
|
|
135687
135774
|
loadAndScheduleAll();
|
|
135688
|
-
|
|
135775
|
+
log17.info("cronjob scheduler started");
|
|
135689
135776
|
}
|
|
135690
135777
|
function stopCronjobScheduler() {
|
|
135691
135778
|
for (const [, cron] of state.jobs) {
|
|
@@ -135693,7 +135780,7 @@ function stopCronjobScheduler() {
|
|
|
135693
135780
|
}
|
|
135694
135781
|
state.jobs.clear();
|
|
135695
135782
|
state.started = false;
|
|
135696
|
-
|
|
135783
|
+
log17.info("cronjob scheduler stopped");
|
|
135697
135784
|
}
|
|
135698
135785
|
function reloadSchedules() {
|
|
135699
135786
|
if (!state.started) return;
|
|
@@ -135706,7 +135793,7 @@ function stopJobsForKey(key) {
|
|
|
135706
135793
|
if (cron) {
|
|
135707
135794
|
cron.stop();
|
|
135708
135795
|
state.jobs.delete(job.id);
|
|
135709
|
-
|
|
135796
|
+
log17.info({ jobId: job.id, key }, "stopped cronjob");
|
|
135710
135797
|
}
|
|
135711
135798
|
}
|
|
135712
135799
|
}
|
|
@@ -135772,7 +135859,7 @@ async function checkPrereqs() {
|
|
|
135772
135859
|
|
|
135773
135860
|
// src/lib/lsp-manager.ts
|
|
135774
135861
|
var __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
135775
|
-
var
|
|
135862
|
+
var log18 = createLogger("lsp");
|
|
135776
135863
|
var LANG_SERVER_CONFIG = {
|
|
135777
135864
|
typescript: { command: "typescript-language-server", args: ["--stdio"] }
|
|
135778
135865
|
};
|
|
@@ -135800,7 +135887,7 @@ async function getOrSpawnServer(workspaceId, lang) {
|
|
|
135800
135887
|
const workspaceBin = join17(cwd, "node_modules/.bin");
|
|
135801
135888
|
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
135802
135889
|
const combinedPath = [bundledBin, appBin, workspaceBin, resolvedPath].join(pathSep);
|
|
135803
|
-
|
|
135890
|
+
log18.debug("Spawning %s language server in %s for workspace %s", lang, cwd, workspaceId);
|
|
135804
135891
|
const child = spawn6(config2.command, config2.args, {
|
|
135805
135892
|
cwd,
|
|
135806
135893
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -135828,15 +135915,15 @@ async function getOrSpawnServer(workspaceId, lang) {
|
|
|
135828
135915
|
}
|
|
135829
135916
|
ids.add(serverId);
|
|
135830
135917
|
child.on("exit", (code) => {
|
|
135831
|
-
|
|
135918
|
+
log18.debug("Language server exited: %s (code %s)", serverId, String(code));
|
|
135832
135919
|
removeSession();
|
|
135833
135920
|
});
|
|
135834
135921
|
child.on("error", (err) => {
|
|
135835
|
-
|
|
135922
|
+
log18.error("Language server error: %s \u2014 %s", serverId, err.message);
|
|
135836
135923
|
removeSession();
|
|
135837
135924
|
});
|
|
135838
135925
|
child.stderr?.on("data", (chunk) => {
|
|
135839
|
-
|
|
135926
|
+
log18.debug("LSP stderr [%s]: %s", serverId, chunk.toString().trimEnd());
|
|
135840
135927
|
});
|
|
135841
135928
|
await new Promise((resolve8, reject) => {
|
|
135842
135929
|
child.once("spawn", resolve8);
|
|
@@ -135866,7 +135953,7 @@ function killAllServers() {
|
|
|
135866
135953
|
|
|
135867
135954
|
// src/lib/lsp-proxy.ts
|
|
135868
135955
|
init_src();
|
|
135869
|
-
var
|
|
135956
|
+
var log19 = createLogger("lsp-proxy");
|
|
135870
135957
|
function frameMessage(json4) {
|
|
135871
135958
|
const body = Buffer.from(json4, "utf-8");
|
|
135872
135959
|
const header = `Content-Length: ${body.byteLength}\r
|
|
@@ -135884,7 +135971,7 @@ function createFrameParser(onMessage) {
|
|
|
135884
135971
|
const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
|
|
135885
135972
|
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
135886
135973
|
if (!match) {
|
|
135887
|
-
|
|
135974
|
+
log19.warn("Malformed LSP header: %s", headerStr);
|
|
135888
135975
|
buffer = buffer.subarray(separatorIdx + 4);
|
|
135889
135976
|
continue;
|
|
135890
135977
|
}
|
|
@@ -135917,7 +136004,7 @@ async function handleLspConnection(ws, req) {
|
|
|
135917
136004
|
session = await getOrSpawnServer(workspaceId, lang);
|
|
135918
136005
|
} catch (err) {
|
|
135919
136006
|
const message = err instanceof Error ? err.message : String(err);
|
|
135920
|
-
|
|
136007
|
+
log19.error(
|
|
135921
136008
|
"Failed to spawn %s language server for workspace %s: %s",
|
|
135922
136009
|
lang,
|
|
135923
136010
|
workspaceId,
|
|
@@ -135931,12 +136018,12 @@ async function handleLspConnection(ws, req) {
|
|
|
135931
136018
|
ws.close(4002, "Language server stdio not available");
|
|
135932
136019
|
return;
|
|
135933
136020
|
}
|
|
135934
|
-
|
|
136021
|
+
log19.debug("LSP client connected: %s/%s", workspaceId, lang);
|
|
135935
136022
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
135936
136023
|
const retriedIds = /* @__PURE__ */ new Set();
|
|
135937
136024
|
const RETRY_DELAY_MS = 2e3;
|
|
135938
136025
|
const parseFrame = createFrameParser((json4) => {
|
|
135939
|
-
|
|
136026
|
+
log19.debug(
|
|
135940
136027
|
"LSP stdout [%s/%s]: %s",
|
|
135941
136028
|
workspaceId,
|
|
135942
136029
|
lang,
|
|
@@ -135948,7 +136035,7 @@ async function handleLspConnection(ws, req) {
|
|
|
135948
136035
|
const originalRequest = pendingRequests.get(msg.id);
|
|
135949
136036
|
retriedIds.add(msg.id);
|
|
135950
136037
|
pendingRequests.delete(msg.id);
|
|
135951
|
-
|
|
136038
|
+
log19.debug(
|
|
135952
136039
|
"LSP retrying request %d after 'No Project' error [%s/%s]",
|
|
135953
136040
|
msg.id,
|
|
135954
136041
|
workspaceId,
|
|
@@ -135970,14 +136057,14 @@ async function handleLspConnection(ws, req) {
|
|
|
135970
136057
|
const onStdoutData = (chunk) => parseFrame(chunk);
|
|
135971
136058
|
lspProcess.stdout.on("data", onStdoutData);
|
|
135972
136059
|
const onExit = (code) => {
|
|
135973
|
-
|
|
136060
|
+
log19.debug("LSP server exited (code %s), closing WebSocket", String(code));
|
|
135974
136061
|
if (ws.readyState === ws.OPEN) {
|
|
135975
136062
|
ws.close(1e3, "Language server exited");
|
|
135976
136063
|
}
|
|
135977
136064
|
};
|
|
135978
136065
|
lspProcess.on("exit", onExit);
|
|
135979
136066
|
function forwardToStdin(json4) {
|
|
135980
|
-
|
|
136067
|
+
log19.debug(
|
|
135981
136068
|
"LSP stdin [%s/%s]: %s",
|
|
135982
136069
|
workspaceId,
|
|
135983
136070
|
lang,
|
|
@@ -136004,7 +136091,7 @@ async function handleLspConnection(ws, req) {
|
|
|
136004
136091
|
ws.on("close", () => {
|
|
136005
136092
|
lspProcess.stdout?.off("data", onStdoutData);
|
|
136006
136093
|
lspProcess.off("exit", onExit);
|
|
136007
|
-
|
|
136094
|
+
log19.debug("LSP client disconnected: %s/%s (server kept alive)", workspaceId, lang);
|
|
136008
136095
|
});
|
|
136009
136096
|
}
|
|
136010
136097
|
|
|
@@ -136141,7 +136228,7 @@ function resolveCliPaths() {
|
|
|
136141
136228
|
// src/lib/cli-skills.ts
|
|
136142
136229
|
import { execFile as execFile4 } from "node:child_process";
|
|
136143
136230
|
import {
|
|
136144
|
-
existsSync as
|
|
136231
|
+
existsSync as existsSync6,
|
|
136145
136232
|
lstatSync as lstatSync3,
|
|
136146
136233
|
mkdirSync as mkdirSync5,
|
|
136147
136234
|
mkdtempSync,
|
|
@@ -136240,7 +136327,7 @@ async function installSkills(opts = {}) {
|
|
|
136240
136327
|
for (const name24 of BAND_SKILL_NAMES) {
|
|
136241
136328
|
const sourcePath = join19(stagingDir, name24, SKILL_FILE);
|
|
136242
136329
|
const destPath = join19(sharedDir, name24, SKILL_FILE);
|
|
136243
|
-
if (!
|
|
136330
|
+
if (!existsSync6(sourcePath)) {
|
|
136244
136331
|
opts.log?.warn("Generated skill missing from staging dir: %s (skipping)", sourcePath);
|
|
136245
136332
|
result.skipped.push(destPath);
|
|
136246
136333
|
continue;
|
|
@@ -136288,7 +136375,7 @@ async function installSkills(opts = {}) {
|
|
|
136288
136375
|
for (const name24 of BAND_SKILL_NAMES) {
|
|
136289
136376
|
const shared2 = join19(sharedDir, name24);
|
|
136290
136377
|
const link2 = join19(target.skillsDir, name24);
|
|
136291
|
-
if (!
|
|
136378
|
+
if (!existsSync6(shared2)) {
|
|
136292
136379
|
result.skipped.push(link2);
|
|
136293
136380
|
continue;
|
|
136294
136381
|
}
|
|
@@ -136500,40 +136587,65 @@ async function installHooks() {
|
|
|
136500
136587
|
}
|
|
136501
136588
|
|
|
136502
136589
|
// src/lib/setup.ts
|
|
136503
|
-
var
|
|
136590
|
+
var log20 = createLogger("setup");
|
|
136504
136591
|
var AGENT_CHECKS = [
|
|
136505
136592
|
{ id: "claude-code", type: "claude-code", label: "Claude Code", binary: "claude" },
|
|
136506
136593
|
{ id: "codex", type: "codex", label: "Codex", binary: "codex" },
|
|
136507
136594
|
{ id: "opencode", type: "opencode", label: "OpenCode", binary: "opencode" }
|
|
136508
136595
|
];
|
|
136509
136596
|
async function runFirstTimeSetup() {
|
|
136597
|
+
const projectSync = ensureProjectStateInSync();
|
|
136510
136598
|
await ensureCliInstalled();
|
|
136599
|
+
const results = await Promise.allSettled([
|
|
136600
|
+
projectSync,
|
|
136601
|
+
ensureSettingsDefaults(),
|
|
136602
|
+
ensureClaudeHooks(),
|
|
136603
|
+
ensureSkillsInstalled()
|
|
136604
|
+
]);
|
|
136605
|
+
for (const r6 of results) {
|
|
136606
|
+
if (r6.status === "rejected") {
|
|
136607
|
+
log20.warn(
|
|
136608
|
+
"Setup step failed: %s",
|
|
136609
|
+
r6.reason instanceof Error ? r6.reason.message : String(r6.reason)
|
|
136610
|
+
);
|
|
136611
|
+
}
|
|
136612
|
+
}
|
|
136613
|
+
}
|
|
136614
|
+
async function ensureSettingsDefaults() {
|
|
136511
136615
|
await ensureDefaultCodingAgents();
|
|
136512
136616
|
ensureNotificationDefaults();
|
|
136513
|
-
|
|
136514
|
-
|
|
136617
|
+
}
|
|
136618
|
+
async function ensureProjectStateInSync() {
|
|
136619
|
+
try {
|
|
136620
|
+
await syncWorktrees();
|
|
136621
|
+
} catch (err) {
|
|
136622
|
+
log20.warn(
|
|
136623
|
+
"Failed to sync project state at boot: %s",
|
|
136624
|
+
err instanceof Error ? err.message : String(err)
|
|
136625
|
+
);
|
|
136626
|
+
}
|
|
136515
136627
|
}
|
|
136516
136628
|
async function ensureCliInstalled() {
|
|
136517
136629
|
let cliStatus;
|
|
136518
136630
|
try {
|
|
136519
136631
|
cliStatus = await checkCli();
|
|
136520
136632
|
} catch (err) {
|
|
136521
|
-
|
|
136633
|
+
log20.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
|
|
136522
136634
|
return;
|
|
136523
136635
|
}
|
|
136524
136636
|
if (cliStatus === "Installed") {
|
|
136525
136637
|
return;
|
|
136526
136638
|
}
|
|
136527
136639
|
if (cliStatus !== "NotInstalled") {
|
|
136528
|
-
|
|
136640
|
+
log20.warn("CLI not auto-installed (status: %s)", cliStatus);
|
|
136529
136641
|
return;
|
|
136530
136642
|
}
|
|
136531
|
-
|
|
136643
|
+
log20.info("Installing band CLI...");
|
|
136532
136644
|
try {
|
|
136533
136645
|
await installCli();
|
|
136534
|
-
|
|
136646
|
+
log20.info("CLI installed to /usr/local/bin/band");
|
|
136535
136647
|
} catch (err) {
|
|
136536
|
-
|
|
136648
|
+
log20.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
|
|
136537
136649
|
}
|
|
136538
136650
|
}
|
|
136539
136651
|
async function ensureDefaultCodingAgents() {
|
|
@@ -136542,17 +136654,17 @@ async function ensureDefaultCodingAgents() {
|
|
|
136542
136654
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
136543
136655
|
return;
|
|
136544
136656
|
}
|
|
136545
|
-
|
|
136657
|
+
log20.info("Detecting installed coding agents...");
|
|
136546
136658
|
const detected = [];
|
|
136547
136659
|
for (const check2 of AGENT_CHECKS) {
|
|
136548
136660
|
const path3 = await whichBinary(check2.binary);
|
|
136549
136661
|
if (path3) {
|
|
136550
|
-
|
|
136662
|
+
log20.info("Detected coding agent: %s (%s)", check2.id, path3);
|
|
136551
136663
|
detected.push({ id: check2.id, type: check2.type, label: check2.label });
|
|
136552
136664
|
}
|
|
136553
136665
|
}
|
|
136554
136666
|
if (detected.length === 0) {
|
|
136555
|
-
|
|
136667
|
+
log20.info("No coding agent CLIs detected on PATH");
|
|
136556
136668
|
return;
|
|
136557
136669
|
}
|
|
136558
136670
|
const current = loadSettings();
|
|
@@ -136561,7 +136673,7 @@ async function ensureDefaultCodingAgents() {
|
|
|
136561
136673
|
current.defaultCodingAgent = detected[0].id;
|
|
136562
136674
|
}
|
|
136563
136675
|
saveSettings(current);
|
|
136564
|
-
|
|
136676
|
+
log20.info("Enabled %d coding agent(s); default = %s", detected.length, current.defaultCodingAgent);
|
|
136565
136677
|
}
|
|
136566
136678
|
function ensureNotificationDefaults() {
|
|
136567
136679
|
const settings = loadSettings();
|
|
@@ -136573,7 +136685,7 @@ function ensureNotificationDefaults() {
|
|
|
136573
136685
|
...settings,
|
|
136574
136686
|
notifications: { ...notifications, soundOnNeedsAttention: true }
|
|
136575
136687
|
});
|
|
136576
|
-
|
|
136688
|
+
log20.info("Set default notifications.soundOnNeedsAttention = true");
|
|
136577
136689
|
}
|
|
136578
136690
|
async function ensureClaudeHooks() {
|
|
136579
136691
|
try {
|
|
@@ -136582,9 +136694,9 @@ async function ensureClaudeHooks() {
|
|
|
136582
136694
|
return;
|
|
136583
136695
|
}
|
|
136584
136696
|
await installHooks();
|
|
136585
|
-
|
|
136697
|
+
log20.info("Installed Claude Code hooks");
|
|
136586
136698
|
} catch (err) {
|
|
136587
|
-
|
|
136699
|
+
log20.warn(
|
|
136588
136700
|
"Failed to install Claude Code hooks: %s",
|
|
136589
136701
|
err instanceof Error ? err.message : String(err)
|
|
136590
136702
|
);
|
|
@@ -136592,11 +136704,11 @@ async function ensureClaudeHooks() {
|
|
|
136592
136704
|
}
|
|
136593
136705
|
async function ensureSkillsInstalled() {
|
|
136594
136706
|
try {
|
|
136595
|
-
const result = await installSkills({ log:
|
|
136707
|
+
const result = await installSkills({ log: log20 });
|
|
136596
136708
|
const wrote = result.written.length + result.updated.length;
|
|
136597
136709
|
const linkChange = result.linked.length;
|
|
136598
136710
|
if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
|
|
136599
|
-
|
|
136711
|
+
log20.info(
|
|
136600
136712
|
"Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
|
|
136601
136713
|
result.written.length,
|
|
136602
136714
|
result.updated.length,
|
|
@@ -136608,13 +136720,13 @@ async function ensureSkillsInstalled() {
|
|
|
136608
136720
|
);
|
|
136609
136721
|
}
|
|
136610
136722
|
} catch (err) {
|
|
136611
|
-
|
|
136723
|
+
log20.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
|
|
136612
136724
|
}
|
|
136613
136725
|
}
|
|
136614
136726
|
|
|
136615
136727
|
// src/lib/terminal-manager.ts
|
|
136616
136728
|
init_src();
|
|
136617
|
-
import { existsSync as
|
|
136729
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
136618
136730
|
import { join as join21 } from "node:path";
|
|
136619
136731
|
|
|
136620
136732
|
// src/lib/terminal-layout-manager.ts
|
|
@@ -136642,7 +136754,7 @@ function removeTerminalFromLayout(workspaceId, terminalId) {
|
|
|
136642
136754
|
}
|
|
136643
136755
|
|
|
136644
136756
|
// src/lib/terminal-manager.ts
|
|
136645
|
-
var
|
|
136757
|
+
var log21 = createLogger("terminal");
|
|
136646
136758
|
var MAX_SCROLLBACK_SIZE = 1e5;
|
|
136647
136759
|
var terminals = /* @__PURE__ */ new Map();
|
|
136648
136760
|
var workspaceTerminals = /* @__PURE__ */ new Map();
|
|
@@ -136673,20 +136785,20 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136673
136785
|
if (options2?.cwd) {
|
|
136674
136786
|
const resolved = join21(workspaceRoot, options2.cwd);
|
|
136675
136787
|
if (!resolved.startsWith(workspaceRoot)) {
|
|
136676
|
-
|
|
136677
|
-
} else if (
|
|
136788
|
+
log21.warn("Ignoring cwd %s \u2014 resolves outside workspace root %s", options2.cwd, workspaceRoot);
|
|
136789
|
+
} else if (existsSync7(resolved)) {
|
|
136678
136790
|
cwd = resolved;
|
|
136679
136791
|
} else {
|
|
136680
|
-
|
|
136792
|
+
log21.warn("Ignoring cwd %s \u2014 directory does not exist", options2.cwd);
|
|
136681
136793
|
}
|
|
136682
136794
|
}
|
|
136683
|
-
if (!
|
|
136795
|
+
if (!existsSync7(cwd)) {
|
|
136684
136796
|
throw new Error(`Workspace directory does not exist: ${cwd}`);
|
|
136685
136797
|
}
|
|
136686
|
-
if (!
|
|
136798
|
+
if (!existsSync7(shell)) {
|
|
136687
136799
|
throw new Error(`Shell not found: ${shell}`);
|
|
136688
136800
|
}
|
|
136689
|
-
|
|
136801
|
+
log21.debug(
|
|
136690
136802
|
"Spawning shell %s in %s for terminal %s (PATH=%s)",
|
|
136691
136803
|
shell,
|
|
136692
136804
|
cwd,
|
|
@@ -136705,7 +136817,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136705
136817
|
});
|
|
136706
136818
|
} catch (err) {
|
|
136707
136819
|
const msg = err instanceof Error ? err.message : String(err);
|
|
136708
|
-
|
|
136820
|
+
log21.error("pty.spawn failed: %s (shell=%s, cwd=%s)", msg, shell, cwd);
|
|
136709
136821
|
throw err;
|
|
136710
136822
|
}
|
|
136711
136823
|
const session = { pty: ptyProcess, scrollback: "", workspaceId };
|
|
@@ -136741,7 +136853,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136741
136853
|
}
|
|
136742
136854
|
});
|
|
136743
136855
|
ptyProcess.onExit(() => {
|
|
136744
|
-
|
|
136856
|
+
log21.debug("Terminal exited: %s (workspace %s)", terminalId, workspaceId);
|
|
136745
136857
|
terminals.delete(terminalId);
|
|
136746
136858
|
outputListeners.delete(terminalId);
|
|
136747
136859
|
const set2 = workspaceTerminals.get(workspaceId);
|
|
@@ -136849,13 +136961,36 @@ function killAllTerminals() {
|
|
|
136849
136961
|
|
|
136850
136962
|
// src/lib/terminal-ws.ts
|
|
136851
136963
|
init_src();
|
|
136852
|
-
var
|
|
136964
|
+
var log22 = createLogger("terminal-ws");
|
|
136965
|
+
var MAX_CLOSE_REASON_BYTES = 123;
|
|
136966
|
+
function clampCloseReason(reason) {
|
|
136967
|
+
const enc = new TextEncoder();
|
|
136968
|
+
const bytes = enc.encode(reason);
|
|
136969
|
+
if (bytes.byteLength <= MAX_CLOSE_REASON_BYTES) return reason;
|
|
136970
|
+
const dec2 = new TextDecoder("utf-8", { fatal: true });
|
|
136971
|
+
for (let end = MAX_CLOSE_REASON_BYTES; end > 0; end--) {
|
|
136972
|
+
try {
|
|
136973
|
+
return dec2.decode(bytes.subarray(0, end));
|
|
136974
|
+
} catch {
|
|
136975
|
+
}
|
|
136976
|
+
}
|
|
136977
|
+
return "";
|
|
136978
|
+
}
|
|
136979
|
+
function safeClose(ws, code, reason) {
|
|
136980
|
+
if (ws.readyState === ws.OPEN) {
|
|
136981
|
+
try {
|
|
136982
|
+
ws.send(JSON.stringify({ type: "error", message: reason }));
|
|
136983
|
+
} catch {
|
|
136984
|
+
}
|
|
136985
|
+
}
|
|
136986
|
+
ws.close(code, clampCloseReason(reason));
|
|
136987
|
+
}
|
|
136853
136988
|
async function handleTerminalConnection(ws, req) {
|
|
136854
136989
|
const url2 = new URL(req.url, `http://${req.headers.host}`);
|
|
136855
136990
|
const workspaceId = url2.searchParams.get("workspaceId");
|
|
136856
136991
|
const terminalId = url2.searchParams.get("terminalId");
|
|
136857
136992
|
if (!workspaceId || !terminalId) {
|
|
136858
|
-
ws
|
|
136993
|
+
safeClose(ws, 4e3, "Missing workspaceId or terminalId");
|
|
136859
136994
|
return;
|
|
136860
136995
|
}
|
|
136861
136996
|
const existing = getTerminalSession(terminalId);
|
|
@@ -136890,8 +137025,8 @@ async function handleTerminalConnection(ws, req) {
|
|
|
136890
137025
|
session = await spawnTerminal(workspaceId, terminalId, spawnOpts);
|
|
136891
137026
|
} catch (err) {
|
|
136892
137027
|
const msg = err instanceof Error ? err.message : String(err);
|
|
136893
|
-
|
|
136894
|
-
ws
|
|
137028
|
+
log22.error("Failed to spawn terminal %s for workspace %s: %s", terminalId, workspaceId, msg);
|
|
137029
|
+
safeClose(ws, 4001, msg);
|
|
136895
137030
|
return;
|
|
136896
137031
|
}
|
|
136897
137032
|
attachSession(ws, terminalId, workspaceId, session, true);
|
|
@@ -136904,7 +137039,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
136904
137039
|
});
|
|
136905
137040
|
}
|
|
136906
137041
|
function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
136907
|
-
|
|
137042
|
+
log22.debug(
|
|
136908
137043
|
"Terminal %s: %s (workspace %s)",
|
|
136909
137044
|
isNew ? "connected" : "reconnected",
|
|
136910
137045
|
terminalId,
|
|
@@ -136933,7 +137068,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
136933
137068
|
}, 3e3);
|
|
136934
137069
|
const exitDisposable = session.pty.onExit(({ exitCode }) => {
|
|
136935
137070
|
clearInterval(processInterval);
|
|
136936
|
-
|
|
137071
|
+
log22.debug("PTY exited with code %d for terminal %s", exitCode, terminalId);
|
|
136937
137072
|
if (ws.readyState === ws.OPEN) {
|
|
136938
137073
|
ws.close(1e3, "Terminal exited");
|
|
136939
137074
|
}
|
|
@@ -136945,7 +137080,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
136945
137080
|
clearInterval(processInterval);
|
|
136946
137081
|
dataDisposable.dispose();
|
|
136947
137082
|
exitDisposable.dispose();
|
|
136948
|
-
|
|
137083
|
+
log22.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
|
|
136949
137084
|
});
|
|
136950
137085
|
}
|
|
136951
137086
|
function handleMessage(ws, terminalId, session, message) {
|
|
@@ -136983,7 +137118,7 @@ function getToken() {
|
|
|
136983
137118
|
}
|
|
136984
137119
|
|
|
136985
137120
|
// src/lib/tunnel.ts
|
|
136986
|
-
var
|
|
137121
|
+
var log23 = createLogger("tunnel");
|
|
136987
137122
|
var tunnelProcess = null;
|
|
136988
137123
|
var tunnelUrl = null;
|
|
136989
137124
|
var startInProgress = null;
|
|
@@ -136997,7 +137132,7 @@ function appendToken(baseUrl, token) {
|
|
|
136997
137132
|
}
|
|
136998
137133
|
function spawnTunnel(options2, resolvedPath) {
|
|
136999
137134
|
const args = ["tunnel", "--config", "/dev/null", "--url", `http://localhost:${options2.port}`];
|
|
137000
|
-
|
|
137135
|
+
log23.debug("spawning cloudflared %s", args.join(" "));
|
|
137001
137136
|
return new Promise((resolve8, reject) => {
|
|
137002
137137
|
const child = spawn7("cloudflared", args, {
|
|
137003
137138
|
env: { ...process.env, PATH: resolvedPath },
|
|
@@ -137011,12 +137146,12 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137011
137146
|
for (const line2 of text4.split("\n")) {
|
|
137012
137147
|
const trimmed = line2.trim();
|
|
137013
137148
|
if (!trimmed) continue;
|
|
137014
|
-
|
|
137149
|
+
log23.debug("output: %s", trimmed);
|
|
137015
137150
|
const url2 = extractUrl(trimmed);
|
|
137016
137151
|
if (url2) {
|
|
137017
137152
|
const token = getToken();
|
|
137018
137153
|
tunnelUrl = appendToken(url2, token);
|
|
137019
|
-
|
|
137154
|
+
log23.debug("detected URL: %s", tunnelUrl);
|
|
137020
137155
|
emit({ kind: "tunnel-url", url: tunnelUrl });
|
|
137021
137156
|
if (!settled) {
|
|
137022
137157
|
settled = true;
|
|
@@ -137031,7 +137166,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137031
137166
|
handleOutput(data);
|
|
137032
137167
|
});
|
|
137033
137168
|
child.on("error", (err) => {
|
|
137034
|
-
|
|
137169
|
+
log23.debug("process error: %s", err.message);
|
|
137035
137170
|
tunnelProcess = null;
|
|
137036
137171
|
tunnelUrl = null;
|
|
137037
137172
|
emit({ kind: "tunnel-error", error: err.message });
|
|
@@ -137041,7 +137176,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137041
137176
|
}
|
|
137042
137177
|
});
|
|
137043
137178
|
child.on("exit", (code) => {
|
|
137044
|
-
|
|
137179
|
+
log23.debug("process exited with code: %d", code ?? -1);
|
|
137045
137180
|
const wasRunning = tunnelProcess !== null && settled;
|
|
137046
137181
|
tunnelProcess = null;
|
|
137047
137182
|
tunnelUrl = null;
|
|
@@ -137063,7 +137198,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137063
137198
|
});
|
|
137064
137199
|
setTimeout(() => {
|
|
137065
137200
|
if (!settled) {
|
|
137066
|
-
|
|
137201
|
+
log23.debug("30s timeout reached, resolving without URL");
|
|
137067
137202
|
settled = true;
|
|
137068
137203
|
resolve8();
|
|
137069
137204
|
}
|
|
@@ -137072,12 +137207,12 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137072
137207
|
}
|
|
137073
137208
|
async function startTunnel(options2) {
|
|
137074
137209
|
if (startInProgress) {
|
|
137075
|
-
|
|
137210
|
+
log23.debug("startTunnel: start already in progress, waiting...");
|
|
137076
137211
|
await startInProgress;
|
|
137077
137212
|
return;
|
|
137078
137213
|
}
|
|
137079
137214
|
if (tunnelProcess) {
|
|
137080
|
-
|
|
137215
|
+
log23.debug("startTunnel: already running, re-emitting URL");
|
|
137081
137216
|
if (tunnelUrl) {
|
|
137082
137217
|
emit({ kind: "tunnel-url", url: tunnelUrl });
|
|
137083
137218
|
}
|
|
@@ -144003,7 +144138,7 @@ function createContext8() {
|
|
|
144003
144138
|
// src/trpc/router.ts
|
|
144004
144139
|
import { execFile as execFile5, execFileSync as execFileSync2, spawn as spawn8 } from "node:child_process";
|
|
144005
144140
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
144006
|
-
import { existsSync as
|
|
144141
|
+
import { existsSync as existsSync9, constants as fsConstants, mkdirSync as mkdirSync7, unlinkSync as unlinkSync3 } from "node:fs";
|
|
144007
144142
|
import { cp, mkdir as mkdir2, open as open2, readdir as readdir2, readFile as readFile2, rename, rm, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
|
|
144008
144143
|
import { basename as basename2, dirname as dirname7, extname as extname2, isAbsolute as isAbsolute2, join as join23, resolve as resolve6, sep as sep2 } from "node:path";
|
|
144009
144144
|
import { promisify } from "node:util";
|
|
@@ -144108,7 +144243,7 @@ function clearHistory(workspaceId, range, now = Date.now()) {
|
|
|
144108
144243
|
|
|
144109
144244
|
// src/lib/chat-session-summary.ts
|
|
144110
144245
|
init_src();
|
|
144111
|
-
var
|
|
144246
|
+
var log24 = createLogger("chat-session-summary");
|
|
144112
144247
|
var REFRESH_KEY = Symbol.for("band.chat-session-summary.refresh");
|
|
144113
144248
|
var g15 = globalThis;
|
|
144114
144249
|
if (!g15[REFRESH_KEY]) g15[REFRESH_KEY] = /* @__PURE__ */ new Map();
|
|
@@ -144138,7 +144273,7 @@ async function ensureActiveSessionSummary(chatId, worktreePath) {
|
|
|
144138
144273
|
});
|
|
144139
144274
|
return getChat(chatId);
|
|
144140
144275
|
} catch (err) {
|
|
144141
|
-
|
|
144276
|
+
log24.warn({ chatId, err }, "ensureActiveSessionSummary failed");
|
|
144142
144277
|
return chat;
|
|
144143
144278
|
}
|
|
144144
144279
|
}
|
|
@@ -144175,7 +144310,7 @@ async function doRefresh(chatId, worktreePath) {
|
|
|
144175
144310
|
lastModified: latest.lastModified
|
|
144176
144311
|
});
|
|
144177
144312
|
} catch (err) {
|
|
144178
|
-
|
|
144313
|
+
log24.warn({ chatId, err }, "active session refresh failed");
|
|
144179
144314
|
}
|
|
144180
144315
|
}
|
|
144181
144316
|
|
|
@@ -144485,10 +144620,10 @@ function subscribeToFileChanges(workspaceId, listener) {
|
|
|
144485
144620
|
|
|
144486
144621
|
// src/lib/formatter.ts
|
|
144487
144622
|
init_src();
|
|
144488
|
-
import { existsSync as
|
|
144623
|
+
import { existsSync as existsSync8, realpathSync as realpathSync4 } from "node:fs";
|
|
144489
144624
|
import { basename, dirname as dirname6, isAbsolute, join as join22, resolve as resolvePath } from "node:path";
|
|
144490
144625
|
import prettier from "prettier";
|
|
144491
|
-
var
|
|
144626
|
+
var log25 = createLogger("formatter");
|
|
144492
144627
|
var FormatterError = class extends Error {
|
|
144493
144628
|
code;
|
|
144494
144629
|
detail;
|
|
@@ -144512,7 +144647,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
144512
144647
|
const ignorePath = resolvePath(worktreePath, ".prettierignore");
|
|
144513
144648
|
const info = await prettier.getFileInfo(absFile, {
|
|
144514
144649
|
resolveConfig: true,
|
|
144515
|
-
ignorePath:
|
|
144650
|
+
ignorePath: existsSync8(ignorePath) ? ignorePath : void 0
|
|
144516
144651
|
});
|
|
144517
144652
|
if (info.ignored) {
|
|
144518
144653
|
return {
|
|
@@ -144543,7 +144678,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
144543
144678
|
}
|
|
144544
144679
|
const changed = formatted !== content2;
|
|
144545
144680
|
if (changed) {
|
|
144546
|
-
|
|
144681
|
+
log25.info(
|
|
144547
144682
|
"Formatted %s with parser=%s (%d bytes in)",
|
|
144548
144683
|
absFile,
|
|
144549
144684
|
info.inferredParser,
|
|
@@ -144682,7 +144817,7 @@ function fuzzyScore(query, filePath) {
|
|
|
144682
144817
|
// src/lib/terminal-config.ts
|
|
144683
144818
|
init_src();
|
|
144684
144819
|
init_zod();
|
|
144685
|
-
var
|
|
144820
|
+
var log26 = createLogger("terminal-config");
|
|
144686
144821
|
var TerminalPaneConfigSchema = external_exports2.object({
|
|
144687
144822
|
name: external_exports2.string().optional(),
|
|
144688
144823
|
command: external_exports2.string().optional(),
|
|
@@ -144713,7 +144848,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
|
|
|
144713
144848
|
if (!terminalBlock) return null;
|
|
144714
144849
|
const result = WorkspaceTerminalConfigSchema.safeParse(terminalBlock);
|
|
144715
144850
|
if (!result.success) {
|
|
144716
|
-
|
|
144851
|
+
log26.warn(
|
|
144717
144852
|
"Invalid workspace.terminal config: %s",
|
|
144718
144853
|
result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join("; ")
|
|
144719
144854
|
);
|
|
@@ -144724,7 +144859,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
|
|
|
144724
144859
|
|
|
144725
144860
|
// src/trpc/router.ts
|
|
144726
144861
|
var execFileAsync = promisify(execFile5);
|
|
144727
|
-
var
|
|
144862
|
+
var log27 = createLogger("trpc");
|
|
144728
144863
|
var t2 = initTRPC.context().create();
|
|
144729
144864
|
var publicProcedure = t2.procedure;
|
|
144730
144865
|
var projectsRouter = t2.router({
|
|
@@ -144733,26 +144868,32 @@ var projectsRouter = t2.router({
|
|
|
144733
144868
|
const settings = loadSettings();
|
|
144734
144869
|
const statuses = loadCurrentStatuses();
|
|
144735
144870
|
const statusMap = new Map(statuses.map((s6) => [s6.workspaceId, s6]));
|
|
144871
|
+
for (const project of state2.projects) {
|
|
144872
|
+
reconcileKindForProject(project);
|
|
144873
|
+
}
|
|
144736
144874
|
const projects2 = await Promise.all(
|
|
144737
144875
|
state2.projects.map(async (project) => {
|
|
144738
|
-
const trackedBranches = new Set(project.worktrees.map((wt) => wt.branch));
|
|
144739
|
-
const trackedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt]));
|
|
144740
144876
|
let worktrees2 = project.worktrees;
|
|
144741
|
-
|
|
144742
|
-
const
|
|
144743
|
-
|
|
144744
|
-
|
|
144745
|
-
|
|
144746
|
-
|
|
144747
|
-
|
|
144748
|
-
|
|
144749
|
-
|
|
144877
|
+
if (project.kind === "git") {
|
|
144878
|
+
const trackedBranches = new Set(project.worktrees.map((wt) => wt.branch));
|
|
144879
|
+
const trackedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt]));
|
|
144880
|
+
try {
|
|
144881
|
+
const gitWorktrees = await listWorktrees(project.path);
|
|
144882
|
+
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare && trackedBranches.has(wt.branch)).map((wt) => ({
|
|
144883
|
+
branch: wt.branch,
|
|
144884
|
+
path: wt.path,
|
|
144885
|
+
head: wt.head,
|
|
144886
|
+
pinned: trackedByBranch.get(wt.branch)?.pinned ?? false
|
|
144887
|
+
}));
|
|
144888
|
+
} catch {
|
|
144889
|
+
}
|
|
144750
144890
|
}
|
|
144751
144891
|
return {
|
|
144752
144892
|
name: project.name,
|
|
144753
144893
|
path: project.path,
|
|
144754
144894
|
defaultBranch: project.defaultBranch,
|
|
144755
144895
|
label: project.label,
|
|
144896
|
+
kind: project.kind,
|
|
144756
144897
|
worktrees: worktrees2.map((wt) => {
|
|
144757
144898
|
const workspaceId = toWorkspaceId(project.name, wt.branch);
|
|
144758
144899
|
const status = statusMap.get(workspaceId);
|
|
@@ -144769,7 +144910,7 @@ var projectsRouter = t2.router({
|
|
|
144769
144910
|
}),
|
|
144770
144911
|
checkPath: publicProcedure.input(external_exports2.object({ path: external_exports2.string() })).query(({ input }) => {
|
|
144771
144912
|
const resolvedPath = resolve6(input.path);
|
|
144772
|
-
const isGitRepo =
|
|
144913
|
+
const isGitRepo = existsSync9(join23(resolvedPath, ".git"));
|
|
144773
144914
|
return { isGitRepo };
|
|
144774
144915
|
}),
|
|
144775
144916
|
gitInit: publicProcedure.input(external_exports2.object({ path: external_exports2.string() })).mutation(async ({ input }) => {
|
|
@@ -144791,37 +144932,84 @@ var projectsRouter = t2.router({
|
|
|
144791
144932
|
);
|
|
144792
144933
|
}
|
|
144793
144934
|
}
|
|
144935
|
+
const resolvedPath = resolve6(input.path);
|
|
144936
|
+
const kind = existsSync9(join23(resolvedPath, ".git")) ? "git" : "plain";
|
|
144794
144937
|
let defaultBranch = "main";
|
|
144795
|
-
try {
|
|
144796
|
-
const env = { ...process.env };
|
|
144797
|
-
if (env.PATH) {
|
|
144798
|
-
env.PATH = `/opt/homebrew/bin:/usr/local/bin:${env.PATH}`;
|
|
144799
|
-
}
|
|
144800
|
-
const output = execFileSync2("git", ["symbolic-ref", "--short", "HEAD"], {
|
|
144801
|
-
cwd: input.path,
|
|
144802
|
-
env,
|
|
144803
|
-
encoding: "utf-8"
|
|
144804
|
-
}).trim();
|
|
144805
|
-
if (output) defaultBranch = output;
|
|
144806
|
-
} catch {
|
|
144807
|
-
}
|
|
144808
144938
|
let worktrees2 = [];
|
|
144809
|
-
|
|
144810
|
-
|
|
144811
|
-
|
|
144812
|
-
|
|
144939
|
+
if (kind === "git") {
|
|
144940
|
+
try {
|
|
144941
|
+
const env = { ...process.env };
|
|
144942
|
+
if (env.PATH) {
|
|
144943
|
+
env.PATH = `/opt/homebrew/bin:/usr/local/bin:${env.PATH}`;
|
|
144944
|
+
}
|
|
144945
|
+
const output = execFileSync2("git", ["symbolic-ref", "--short", "HEAD"], {
|
|
144946
|
+
cwd: resolvedPath,
|
|
144947
|
+
env,
|
|
144948
|
+
encoding: "utf-8"
|
|
144949
|
+
}).trim();
|
|
144950
|
+
if (output) defaultBranch = output;
|
|
144951
|
+
} catch {
|
|
144952
|
+
}
|
|
144953
|
+
try {
|
|
144954
|
+
const gitWorktrees = await listWorktrees(resolvedPath);
|
|
144955
|
+
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({ branch: wt.branch, path: wt.path, head: wt.head, pinned: false }));
|
|
144956
|
+
} catch {
|
|
144957
|
+
}
|
|
144958
|
+
} else {
|
|
144959
|
+
worktrees2 = [{ branch: "main", path: resolvedPath, pinned: false }];
|
|
144813
144960
|
}
|
|
144814
144961
|
const project = {
|
|
144815
144962
|
name: name24,
|
|
144816
|
-
path
|
|
144963
|
+
// Store the canonical path so downstream consumers
|
|
144964
|
+
// (cronjob-scheduler, branch-status-poller, etc.) and the
|
|
144965
|
+
// self-heal loop in projects.list can compare against
|
|
144966
|
+
// `existsSync(project.path)` without false negatives from
|
|
144967
|
+
// unnormalized input.
|
|
144968
|
+
path: resolvedPath,
|
|
144817
144969
|
defaultBranch,
|
|
144818
144970
|
worktrees: worktrees2,
|
|
144819
|
-
label: input.label ?? void 0
|
|
144971
|
+
label: input.label ?? void 0,
|
|
144972
|
+
kind
|
|
144820
144973
|
};
|
|
144821
144974
|
state2.projects.push(project);
|
|
144822
144975
|
saveState(state2);
|
|
144823
144976
|
return project;
|
|
144824
144977
|
}),
|
|
144978
|
+
/**
|
|
144979
|
+
* Run `git init` inside a plain project and flip its kind to "git".
|
|
144980
|
+
* The "promote to git" escape hatch from #427: lets a user start with a
|
|
144981
|
+
* plain folder and later opt into branches/PRs without re-adding the
|
|
144982
|
+
* project. After promotion, the existing implicit workspace becomes the
|
|
144983
|
+
* project's default-branch worktree (its path is already the project
|
|
144984
|
+
* path, which matches git's convention for the main worktree).
|
|
144985
|
+
*/
|
|
144986
|
+
promoteToGit: publicProcedure.input(external_exports2.object({ name: external_exports2.string() })).mutation(async ({ input }) => {
|
|
144987
|
+
const state2 = loadState();
|
|
144988
|
+
const project = state2.projects.find((p6) => p6.name === input.name);
|
|
144989
|
+
if (!project) {
|
|
144990
|
+
throw new TRPCError({
|
|
144991
|
+
code: "NOT_FOUND",
|
|
144992
|
+
message: `Project "${input.name}" not found`
|
|
144993
|
+
});
|
|
144994
|
+
}
|
|
144995
|
+
if (project.kind === "git") {
|
|
144996
|
+
throw new TRPCError({
|
|
144997
|
+
code: "BAD_REQUEST",
|
|
144998
|
+
message: `Project "${input.name}" is already a git project`
|
|
144999
|
+
});
|
|
145000
|
+
}
|
|
145001
|
+
if (!existsSync9(project.path)) {
|
|
145002
|
+
throw new TRPCError({
|
|
145003
|
+
code: "NOT_FOUND",
|
|
145004
|
+
message: `Project path "${project.path}" no longer exists. Remove the project and re-add it.`
|
|
145005
|
+
});
|
|
145006
|
+
}
|
|
145007
|
+
await execGit(["init", "-b", "main"], project.path);
|
|
145008
|
+
project.kind = "git";
|
|
145009
|
+
project.defaultBranch = "main";
|
|
145010
|
+
saveState(state2);
|
|
145011
|
+
return { ok: true, kind: project.kind, defaultBranch: project.defaultBranch };
|
|
145012
|
+
}),
|
|
144825
145013
|
remove: publicProcedure.input(external_exports2.object({ name: external_exports2.string() })).mutation(({ input }) => {
|
|
144826
145014
|
const state2 = loadState();
|
|
144827
145015
|
state2.projects = state2.projects.filter((p6) => p6.name !== input.name);
|
|
@@ -144873,6 +145061,12 @@ var workspacesRouter = t2.router({
|
|
|
144873
145061
|
if (!proj) {
|
|
144874
145062
|
throw new Error(`Project "${input.project}" not found`);
|
|
144875
145063
|
}
|
|
145064
|
+
if (proj.kind === "plain") {
|
|
145065
|
+
throw new TRPCError({
|
|
145066
|
+
code: "BAD_REQUEST",
|
|
145067
|
+
message: `Project "${input.project}" is a plain (non-git) folder and cannot have additional workspaces. Promote it to git (right-click the project \u2192 "Promote to git") to enable branches.`
|
|
145068
|
+
});
|
|
145069
|
+
}
|
|
144876
145070
|
const existing = proj.worktrees.find((wt) => wt.branch === input.branch);
|
|
144877
145071
|
if (existing) {
|
|
144878
145072
|
return { ok: true, path: existing.path };
|
|
@@ -144914,6 +145108,12 @@ var workspacesRouter = t2.router({
|
|
|
144914
145108
|
if (!proj) {
|
|
144915
145109
|
throw new Error(`Project "${input.project}" not found`);
|
|
144916
145110
|
}
|
|
145111
|
+
if (proj.kind === "plain") {
|
|
145112
|
+
throw new TRPCError({
|
|
145113
|
+
code: "BAD_REQUEST",
|
|
145114
|
+
message: `Project "${input.project}" is a plain (non-git) project. Remove the project instead of the workspace.`
|
|
145115
|
+
});
|
|
145116
|
+
}
|
|
144917
145117
|
const { command, env: gitEnv } = gitCmd();
|
|
144918
145118
|
const output = execFileSync2(command, ["worktree", "list", "--porcelain"], {
|
|
144919
145119
|
cwd: proj.path,
|
|
@@ -144960,13 +145160,13 @@ var workspacesRouter = t2.router({
|
|
|
144960
145160
|
try {
|
|
144961
145161
|
const deletedTasks = deleteWorkspaceTasks(workspaceId);
|
|
144962
145162
|
if (deletedTasks > 0) {
|
|
144963
|
-
|
|
145163
|
+
log27.info(
|
|
144964
145164
|
{ workspaceId, count: deletedTasks },
|
|
144965
145165
|
"deleted workspace tasks on removal"
|
|
144966
145166
|
);
|
|
144967
145167
|
}
|
|
144968
145168
|
} catch (err) {
|
|
144969
|
-
|
|
145169
|
+
log27.error({ workspaceId, err }, "failed to delete workspace tasks on removal");
|
|
144970
145170
|
}
|
|
144971
145171
|
emit({ kind: "remove", workspaceId });
|
|
144972
145172
|
const projPath = proj.path;
|
|
@@ -144984,7 +145184,7 @@ var workspacesRouter = t2.router({
|
|
|
144984
145184
|
timeout: 6e4
|
|
144985
145185
|
});
|
|
144986
145186
|
} catch (err) {
|
|
144987
|
-
|
|
145187
|
+
log27.warn({ err, workspaceId }, "teardown script failed");
|
|
144988
145188
|
}
|
|
144989
145189
|
}
|
|
144990
145190
|
try {
|
|
@@ -145002,7 +145202,7 @@ var workspacesRouter = t2.router({
|
|
|
145002
145202
|
encoding: "utf-8"
|
|
145003
145203
|
});
|
|
145004
145204
|
} catch (err) {
|
|
145005
|
-
|
|
145205
|
+
log27.warn({ err, workspaceId }, "git worktree prune failed");
|
|
145006
145206
|
}
|
|
145007
145207
|
}
|
|
145008
145208
|
try {
|
|
@@ -145014,7 +145214,7 @@ var workspacesRouter = t2.router({
|
|
|
145014
145214
|
} catch {
|
|
145015
145215
|
}
|
|
145016
145216
|
})().catch((err) => {
|
|
145017
|
-
|
|
145217
|
+
log27.error({ err, workspaceId }, "background workspace cleanup failed");
|
|
145018
145218
|
});
|
|
145019
145219
|
});
|
|
145020
145220
|
return { ok: true };
|
|
@@ -145031,6 +145231,12 @@ var workspacesRouter = t2.router({
|
|
|
145031
145231
|
if (!proj) {
|
|
145032
145232
|
throw new Error(`Project "${input.project}" not found`);
|
|
145033
145233
|
}
|
|
145234
|
+
if (proj.kind === "plain") {
|
|
145235
|
+
throw new TRPCError({
|
|
145236
|
+
code: "BAD_REQUEST",
|
|
145237
|
+
message: `Project "${input.project}" is a plain (non-git) project. Pinning is not available.`
|
|
145238
|
+
});
|
|
145239
|
+
}
|
|
145034
145240
|
const wt = proj.worktrees.find((w2) => w2.branch === input.branch);
|
|
145035
145241
|
if (!wt) {
|
|
145036
145242
|
throw new Error(`Workspace "${input.branch}" not found`);
|
|
@@ -145045,6 +145251,12 @@ var workspacesRouter = t2.router({
|
|
|
145045
145251
|
if (!workspace) {
|
|
145046
145252
|
throw new Error("Workspace not found");
|
|
145047
145253
|
}
|
|
145254
|
+
if (workspace.project.kind === "plain") {
|
|
145255
|
+
throw new TRPCError({
|
|
145256
|
+
code: "BAD_REQUEST",
|
|
145257
|
+
message: `Project "${input.project}" is a plain (non-git) project. Git pull is not available.`
|
|
145258
|
+
});
|
|
145259
|
+
}
|
|
145048
145260
|
const cwd = workspace.worktree.path;
|
|
145049
145261
|
try {
|
|
145050
145262
|
await execGit(["pull", "--rebase"], cwd);
|
|
@@ -145063,6 +145275,12 @@ var workspacesRouter = t2.router({
|
|
|
145063
145275
|
if (!workspace) {
|
|
145064
145276
|
throw new Error("Workspace not found");
|
|
145065
145277
|
}
|
|
145278
|
+
if (workspace.project.kind === "plain") {
|
|
145279
|
+
throw new TRPCError({
|
|
145280
|
+
code: "BAD_REQUEST",
|
|
145281
|
+
message: `Project "${input.project}" is a plain (non-git) project. Git push is not available.`
|
|
145282
|
+
});
|
|
145283
|
+
}
|
|
145066
145284
|
const cwd = workspace.worktree.path;
|
|
145067
145285
|
try {
|
|
145068
145286
|
await execGit(["push"], cwd);
|
|
@@ -145073,7 +145291,7 @@ var workspacesRouter = t2.router({
|
|
|
145073
145291
|
}),
|
|
145074
145292
|
runScript: publicProcedure.input(external_exports2.object({ path: external_exports2.string(), scriptType: external_exports2.string() })).mutation(({ input }) => {
|
|
145075
145293
|
const scriptPath = join23(input.path, ".band", input.scriptType);
|
|
145076
|
-
if (!
|
|
145294
|
+
if (!existsSync9(scriptPath)) {
|
|
145077
145295
|
throw new Error(`Script "${input.scriptType}" not found`);
|
|
145078
145296
|
}
|
|
145079
145297
|
return new Promise((resolve8, reject) => {
|
|
@@ -145159,6 +145377,7 @@ var LANG_MAP = {
|
|
|
145159
145377
|
};
|
|
145160
145378
|
var compareBranchSchema = external_exports2.string().min(1).regex(/^[^-]/, "branch name must not start with '-'").optional();
|
|
145161
145379
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
145380
|
+
var EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
145162
145381
|
async function resolveDiffContext(cwd, defaultBranch, diffMode, compareBranchInput) {
|
|
145163
145382
|
const compareBranch = diffMode === "uncommitted" ? defaultBranch : compareBranchInput ?? defaultBranch;
|
|
145164
145383
|
let headBranch;
|
|
@@ -145236,7 +145455,7 @@ var workspaceRouter = t2.router({
|
|
|
145236
145455
|
*
|
|
145237
145456
|
* Returns `{ skipped: true, reason }` when Prettier has no parser for
|
|
145238
145457
|
* the file's extension (or it's covered by `.prettierignore`). Editors
|
|
145239
|
-
* fire this off
|
|
145458
|
+
* fire this off Shift+Alt+F without checking the file type first, so a
|
|
145240
145459
|
* soft skip is the right outcome for unsupported files rather than a
|
|
145241
145460
|
* surfaced error.
|
|
145242
145461
|
*
|
|
@@ -145347,7 +145566,7 @@ var workspaceRouter = t2.router({
|
|
|
145347
145566
|
);
|
|
145348
145567
|
branches = output.trim().split("\n").map((b10) => b10.trim()).filter(Boolean);
|
|
145349
145568
|
} catch (err) {
|
|
145350
|
-
|
|
145569
|
+
log27.error(
|
|
145351
145570
|
`listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
|
|
145352
145571
|
);
|
|
145353
145572
|
}
|
|
@@ -145437,6 +145656,18 @@ var workspaceRouter = t2.router({
|
|
|
145437
145656
|
if (!workspace) {
|
|
145438
145657
|
throw new Error("Workspace not found");
|
|
145439
145658
|
}
|
|
145659
|
+
const hasGit = existsSync9(join23(workspace.worktree.path, ".git"));
|
|
145660
|
+
if (workspace.project.kind === "plain" || !hasGit) {
|
|
145661
|
+
const defaultBranch2 = workspace.project.defaultBranch;
|
|
145662
|
+
return {
|
|
145663
|
+
stats: { filesChanged: 0, insertions: 0, deletions: 0 },
|
|
145664
|
+
compareBranch: defaultBranch2,
|
|
145665
|
+
defaultBranch: defaultBranch2,
|
|
145666
|
+
headBranch: defaultBranch2,
|
|
145667
|
+
fileStatuses: {},
|
|
145668
|
+
mergeBase: EMPTY_TREE_SHA
|
|
145669
|
+
};
|
|
145670
|
+
}
|
|
145440
145671
|
const cwd = workspace.worktree.path;
|
|
145441
145672
|
const defaultBranch = workspace.project.defaultBranch;
|
|
145442
145673
|
const { compareBranch, headBranch, mergeBase } = await resolveDiffContext(
|
|
@@ -145776,11 +146007,11 @@ var workspaceRouter = t2.router({
|
|
|
145776
146007
|
if (!target.startsWith(root) || target === root) {
|
|
145777
146008
|
throw new Error("Invalid path");
|
|
145778
146009
|
}
|
|
145779
|
-
if (
|
|
146010
|
+
if (existsSync9(target)) {
|
|
145780
146011
|
throw new Error("A file or directory already exists at this path");
|
|
145781
146012
|
}
|
|
145782
146013
|
const parent = dirname7(target);
|
|
145783
|
-
if (!
|
|
146014
|
+
if (!existsSync9(parent)) {
|
|
145784
146015
|
throw new Error("Parent directory does not exist");
|
|
145785
146016
|
}
|
|
145786
146017
|
const parentStat = await stat4(parent);
|
|
@@ -145805,11 +146036,11 @@ var workspaceRouter = t2.router({
|
|
|
145805
146036
|
if (!target.startsWith(root) || target === root) {
|
|
145806
146037
|
throw new Error("Invalid path");
|
|
145807
146038
|
}
|
|
145808
|
-
if (
|
|
146039
|
+
if (existsSync9(target)) {
|
|
145809
146040
|
throw new Error("A file or directory already exists at this path");
|
|
145810
146041
|
}
|
|
145811
146042
|
const parent = dirname7(target);
|
|
145812
|
-
if (!
|
|
146043
|
+
if (!existsSync9(parent)) {
|
|
145813
146044
|
throw new Error("Parent directory does not exist");
|
|
145814
146045
|
}
|
|
145815
146046
|
const parentStat = await stat4(parent);
|
|
@@ -145884,11 +146115,11 @@ var workspaceRouter = t2.router({
|
|
|
145884
146115
|
} catch {
|
|
145885
146116
|
throw new Error("Source path does not exist");
|
|
145886
146117
|
}
|
|
145887
|
-
if (
|
|
146118
|
+
if (existsSync9(toTarget)) {
|
|
145888
146119
|
throw new Error("A file or directory already exists at the destination");
|
|
145889
146120
|
}
|
|
145890
146121
|
const toParent = dirname7(toTarget);
|
|
145891
|
-
if (!
|
|
146122
|
+
if (!existsSync9(toParent)) {
|
|
145892
146123
|
throw new Error("Destination parent directory does not exist");
|
|
145893
146124
|
}
|
|
145894
146125
|
const toParentStat = await stat4(toParent);
|
|
@@ -145938,11 +146169,11 @@ var workspaceRouter = t2.router({
|
|
|
145938
146169
|
if (entryStat.isDirectory() && toTarget.startsWith(fromTarget + sep2)) {
|
|
145939
146170
|
throw new Error("Cannot copy a directory into itself");
|
|
145940
146171
|
}
|
|
145941
|
-
if (
|
|
146172
|
+
if (existsSync9(toTarget)) {
|
|
145942
146173
|
throw new Error("A file or directory already exists at the destination");
|
|
145943
146174
|
}
|
|
145944
146175
|
const toParent = dirname7(toTarget);
|
|
145945
|
-
if (!
|
|
146176
|
+
if (!existsSync9(toParent)) {
|
|
145946
146177
|
throw new Error("Destination parent directory does not exist");
|
|
145947
146178
|
}
|
|
145948
146179
|
const toParentStat = await stat4(toParent);
|
|
@@ -146195,21 +146426,21 @@ var tunnelRouter = t2.router({
|
|
|
146195
146426
|
return getTunnelStatus();
|
|
146196
146427
|
}),
|
|
146197
146428
|
start: publicProcedure.input(external_exports2.object({}).optional()).mutation(async () => {
|
|
146198
|
-
|
|
146429
|
+
log27.debug("tunnel.start called");
|
|
146199
146430
|
const port2 = parseInt(process.env.BAND_PORT || "3456", 10);
|
|
146200
|
-
|
|
146431
|
+
log27.debug("tunnel.start: port=%d", port2);
|
|
146201
146432
|
try {
|
|
146202
146433
|
await startTunnel({ port: port2 });
|
|
146203
146434
|
} catch (err) {
|
|
146204
|
-
|
|
146435
|
+
log27.debug({ err }, "tunnel.start: startTunnel failed");
|
|
146205
146436
|
return { ok: true, url: null };
|
|
146206
146437
|
}
|
|
146207
146438
|
const status = getTunnelStatus();
|
|
146208
|
-
|
|
146439
|
+
log27.debug({ status }, "tunnel.start: after startTunnel");
|
|
146209
146440
|
if (status.url) {
|
|
146210
146441
|
return { ok: true, url: status.url };
|
|
146211
146442
|
}
|
|
146212
|
-
|
|
146443
|
+
log27.debug("tunnel.start: no URL available");
|
|
146213
146444
|
return { ok: true, url: null };
|
|
146214
146445
|
}),
|
|
146215
146446
|
stop: publicProcedure.mutation(async () => {
|
|
@@ -146535,15 +146766,15 @@ async function loadJsonlPage(opts) {
|
|
|
146535
146766
|
}
|
|
146536
146767
|
var servicesRouter = t2.router({
|
|
146537
146768
|
health: publicProcedure.query(() => {
|
|
146538
|
-
|
|
146769
|
+
log27.debug("services.health called");
|
|
146539
146770
|
const tunnel = getTunnelStatus();
|
|
146540
|
-
|
|
146771
|
+
log27.debug({ tunnel }, "services.health: tunnel status");
|
|
146541
146772
|
const result = {
|
|
146542
146773
|
webserver: true,
|
|
146543
146774
|
tunnel: tunnel.running,
|
|
146544
146775
|
tunnel_url: tunnel.url
|
|
146545
146776
|
};
|
|
146546
|
-
|
|
146777
|
+
log27.debug({ result }, "services.health result");
|
|
146547
146778
|
return result;
|
|
146548
146779
|
}),
|
|
146549
146780
|
// Activity level controls how often the branch-status poller fires.
|
|
@@ -146937,7 +147168,7 @@ var chatsRouter = t2.router({
|
|
|
146937
147168
|
summary = info?.summary;
|
|
146938
147169
|
lastModified = info?.lastModified;
|
|
146939
147170
|
} catch (err) {
|
|
146940
|
-
|
|
147171
|
+
log27.warn(
|
|
146941
147172
|
{ chatId: input.chatId, sessionId: input.sessionId, err },
|
|
146942
147173
|
"setActiveSession: getSessionInfo failed"
|
|
146943
147174
|
);
|
|
@@ -147057,7 +147288,7 @@ var browserHostRouter = t2.router({
|
|
|
147057
147288
|
// can confirm in the server log that the bridge component actually
|
|
147058
147289
|
// executed. Drop once the experiment is stable.
|
|
147059
147290
|
ping: publicProcedure.input(external_exports2.object({ where: external_exports2.string() })).mutation(({ input }) => {
|
|
147060
|
-
|
|
147291
|
+
log27.info("browserHost.ping from %s", input.where);
|
|
147061
147292
|
return { ok: true };
|
|
147062
147293
|
}),
|
|
147063
147294
|
ensureView: publicProcedure.subscription(async function* (opts) {
|
|
@@ -147560,10 +147791,20 @@ var assets = build_default(clientDir, {
|
|
|
147560
147791
|
gzip: true,
|
|
147561
147792
|
etag: true
|
|
147562
147793
|
});
|
|
147563
|
-
var
|
|
147564
|
-
|
|
147565
|
-
|
|
147566
|
-
|
|
147794
|
+
var _openApiSpec = null;
|
|
147795
|
+
function getOpenApiSpec() {
|
|
147796
|
+
if (_openApiSpec !== null) return _openApiSpec;
|
|
147797
|
+
const openApiDoc = JSON.parse(readFileSync9(join24(import.meta.dirname, "openapi.json"), "utf-8"));
|
|
147798
|
+
openApiDoc.servers = [{ url: "/trpc" }];
|
|
147799
|
+
_openApiSpec = JSON.stringify(openApiDoc, null, 2);
|
|
147800
|
+
return _openApiSpec;
|
|
147801
|
+
}
|
|
147802
|
+
var _scalarHtml = null;
|
|
147803
|
+
function getCachedScalarHtml() {
|
|
147804
|
+
if (_scalarHtml !== null) return _scalarHtml;
|
|
147805
|
+
_scalarHtml = getScalarHtml("/api/openapi.json");
|
|
147806
|
+
return _scalarHtml;
|
|
147807
|
+
}
|
|
147567
147808
|
function serveStaticFile(res, root, subdir, rawFilename) {
|
|
147568
147809
|
const filename = basename3(decodeURIComponent(rawFilename));
|
|
147569
147810
|
if (!filename || filename.includes("..")) {
|
|
@@ -147617,6 +147858,7 @@ function serveWorkspaceFile(res, workspaceId, rawPath) {
|
|
|
147617
147858
|
async function main() {
|
|
147618
147859
|
runMigrations();
|
|
147619
147860
|
loadChatsFromDb();
|
|
147861
|
+
loadBrowsersFromDb();
|
|
147620
147862
|
cleanupStaleTasks();
|
|
147621
147863
|
startTaskPruneScheduler();
|
|
147622
147864
|
const resetCount = resetAgentStatuses();
|
|
@@ -147722,7 +147964,7 @@ async function main() {
|
|
|
147722
147964
|
"Cache-Control": "no-cache",
|
|
147723
147965
|
"Access-Control-Allow-Origin": "*"
|
|
147724
147966
|
});
|
|
147725
|
-
res.end(
|
|
147967
|
+
res.end(getOpenApiSpec());
|
|
147726
147968
|
return;
|
|
147727
147969
|
}
|
|
147728
147970
|
if (req.url === "/api/docs") {
|
|
@@ -147730,7 +147972,7 @@ async function main() {
|
|
|
147730
147972
|
"Content-Type": "text/html",
|
|
147731
147973
|
"Cache-Control": "no-cache"
|
|
147732
147974
|
});
|
|
147733
|
-
res.end(
|
|
147975
|
+
res.end(getCachedScalarHtml());
|
|
147734
147976
|
return;
|
|
147735
147977
|
}
|
|
147736
147978
|
if (req.url?.startsWith("/mcp")) {
|
|
@@ -147855,6 +148097,7 @@ async function main() {
|
|
|
147855
148097
|
});
|
|
147856
148098
|
httpServer.listen(port, "0.0.0.0", () => {
|
|
147857
148099
|
console.log(`Web server listening on http://0.0.0.0:${port}`);
|
|
148100
|
+
console.log(`Web server boot took ${(process.uptime() * 1e3).toFixed(0)} ms`);
|
|
147858
148101
|
const settings = loadSettings();
|
|
147859
148102
|
if (settings.autoStartTunnel) {
|
|
147860
148103
|
checkPrereqs().then((prereqs) => {
|