@band-app/server 0.14.0 → 0.16.2
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-CjLCp0Ep.js → DockviewTerminalContainer-D2lnsm6V.js} +2 -2
- package/dist/client/assets/TerminalPanel-SEbvgXv_.js +4 -0
- package/dist/client/assets/{_basePickBy-CQtQtDdV.js → _basePickBy-C-uqClKF.js} +1 -1
- package/dist/client/assets/{_baseUniq-D4iUo06T.js → _baseUniq-sN_xdSud.js} +1 -1
- package/dist/client/assets/{arc-Bk8y2eXC.js → arc-DOqEiCLs.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-nOygF9m2.js → architectureDiagram-VXUJARFQ-DqRs-Rmj.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-CZ4Nt28v.js → blockDiagram-VD42YOAC-Dxh5tO7I.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-C31ZTlu2.js → c4Diagram-YG6GDRKO-CykynX-A.js} +1 -1
- package/dist/client/assets/channel-DijZVjmy.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-GjIrL7gq.js → chunk-4BX2VUAB-BckEbEmg.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-Dd6rfkjS.js → chunk-55IACEB6-Ds9A0UL5.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-Dzfqlv3x.js → chunk-B4BG7PRW-BbdA9dFb.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-CP20GTKI.js → chunk-DI55MBZ5-C10prUQu.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BjMT67vC.js → chunk-FMBD7UC4-CMO5VhEI.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-DjTHrDYb.js → chunk-QN33PNHL-BrbSzW7G.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-DaZKkfet.js → chunk-QZHKN3VN-BjFQUCU6.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-C-s0f3Nv.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-DWG1ghIg.js → cose-bilkent-S5V4N54A-DbSjwZ4l.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-D5Xahd1k.js → dagre-6UL2VRFP-Q5hxi0O0.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-DB5Yj4_A.js → diagram-PSM6KHXK-D7kyAUq5.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-CaI4Qm9S.js → diagram-QEK2KX5R-B7mpl_Jj.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-Bc8uBUs8.js → diagram-S2PKOQOG-CcIvSvFS.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-BEdcnVfH.js → erDiagram-Q2GNP2WA-M2OHKSFi.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-CP1RMYLo.js → flowDiagram-NV44I4VS-Ot2zCa0t.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-DybSY1zy.js → ganttDiagram-JELNMOA3-Dtl6PI3C.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-B1zM9cMa.js → gitGraphDiagram-V2S2FVAM-DJCTwkyi.js} +1 -1
- package/dist/client/assets/{graph-CPZWfRvB.js → graph-DhvBAydB.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-Bugc5R-I.js → highlighted-body-B3W2YXNL-C6fHuUGl.js} +1 -1
- package/dist/client/assets/{index-BSZ6dtOY.js → index-26c50Xcq.js} +1 -1
- package/dist/client/assets/index-B1K9dSWl.js +1 -0
- package/dist/client/assets/{index-BydRuBb_.js → index-B7VmPIW6.js} +1 -1
- package/dist/client/assets/{index-vP2I9_aT.js → index-BBv9ZEF9.js} +1 -1
- package/dist/client/assets/{index-DEVawlAU.js → index-BDHBx5UL.js} +1 -1
- package/dist/client/assets/{index-CYD8Chzm.js → index-BUTfo7TS.js} +1 -1
- package/dist/client/assets/{index-D5BWxHiy.js → index-BYvWvSws.js} +1 -1
- package/dist/client/assets/{index-SP7EGmTJ.js → index-CDbyr_lc.js} +1 -1
- package/dist/client/assets/{index-X_vPvtM3.js → index-CHGnZzhm.js} +1 -1
- package/dist/client/assets/{index-D4U4UdW8.js → index-CKHhLCNz.js} +1 -1
- package/dist/client/assets/{index-BQkn45ME.js → index-CfsvL24Z.js} +1 -1
- package/dist/client/assets/{index-mOXvCPx7.js → index-CjXcgzNg.js} +1 -1
- package/dist/client/assets/{index-BSvAdzfH.js → index-CuNktTO3.js} +1 -1
- package/dist/client/assets/{index-Cm01-0la.js → index-DDe15mVl.js} +1 -1
- package/dist/client/assets/{index-Bu-ZuLPi.js → index-I4Tc5Cuc.js} +1 -1
- package/dist/client/assets/{index-CrF4PAiW.js → index-MZ-6_xYm.js} +1 -1
- package/dist/client/assets/{index-BGq7dGXw.js → index-SeTSJcqN.js} +1 -1
- package/dist/client/assets/{index-CijlrIEA.js → index-_yteHBmq.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-BCk158Sc.js → infoDiagram-HS3SLOUP-CbAjFJUe.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-Dmw405Jr.js → journeyDiagram-XKPGCS4Q-Bf_0viAE.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-DqNJB_Z3.js → kanban-definition-3W4ZIXB7-CB2ylbw7.js} +1 -1
- package/dist/client/assets/{layout-ODCofYfe.js → layout-Cp_4dcMO.js} +1 -1
- package/dist/client/assets/{linear-CHYpf9oZ.js → linear-D1KyszeO.js} +1 -1
- package/dist/client/assets/main-CBJTAZFq.css +1 -0
- package/dist/client/assets/{main-81Q8XW4n.js → main-Cl2c5yKs.js} +245 -245
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-DD4Ndh7U.js → mindmap-definition-VGOIOE7T-Cm_2Y7ZK.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-C9vB0eMW.js → pieDiagram-ADFJNKIX-C9PiUHN5.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-DKJimp3K.js → quadrantDiagram-AYHSOK5B-Cj0nbFw-.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-_AjYejyE.js → requirementDiagram-UZGBJVZJ-BVgceiyR.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-BN_ggjKc.js → sankeyDiagram-TZEHDZUN-D7dheggz.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-Ck-zlUdD.js → sequenceDiagram-WL72ISMW-DVDMYgkc.js} +1 -1
- package/dist/client/assets/{square-terminal-DVejknjY.js → square-terminal-C64ybmC7.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-Ccmp8_yK.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-Bm5sYZxz.js → timeline-definition-IT6M3QCI-Cs1CMQvF.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-C6oEKt2u.js → treemap-GDKQZRPO-DerMxDGL.js} +1 -1
- package/dist/client/assets/{useSessionListContext-l-QdtVht.js → useSessionListContext-BcM5_lz3.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId-BPktlGJd.js → workspace._workspaceId-C4dZT1kN.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.changes-DNu9WOV2.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._-BHhCSQ0w.js → workspace._workspaceId.code._-DRRjmZ4D.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.code.index-0y_GQ6sP.js → workspace._workspaceId.code.index-CQLsjESL.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.index-CtrlsI9z.js → workspace._workspaceId.index-CE3X4XHe.js} +1 -1
- package/dist/client/assets/{workspace._workspaceId.terminal-DsvwvNc_.js → workspace._workspaceId.terminal-0Iuu4wZI.js} +2 -2
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-ru_cdw1P.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-DVUKt_HJ.js → DockviewTerminalContainer-RbFw8Eo4.js} +3 -3
- package/dist/server/assets/{TerminalPanel-hEaDQqdo.js → TerminalPanel-BS0KF1ac.js} +52 -22
- package/dist/server/assets/{_basePickBy-Nag5vQgo.js → _basePickBy-Vtp-JFm9.js} +2 -2
- package/dist/server/assets/{_baseUniq-BcTT1Srn.js → _baseUniq-CRtvsDi1.js} +1 -1
- package/dist/server/assets/{_tanstack-start-manifest_v-D0rpEWOW.js → _tanstack-start-manifest_v-787sukfk.js} +1 -1
- package/dist/server/assets/{arc-CDj2zIqg.js → arc-ChWehBm_.js} +1 -1
- package/dist/server/assets/{architecture-7HQA4BMR-7A5zOnYc.js → architecture-7HQA4BMR-BiLezQsp.js} +6 -6
- package/dist/server/assets/{architectureDiagram-VXUJARFQ--uDzxMk3.js → architectureDiagram-VXUJARFQ-tjTQ4ZaT.js} +6 -6
- package/dist/server/assets/{blockDiagram-VD42YOAC-DAc1UHQ6.js → blockDiagram-VD42YOAC-C0oBPtSv.js} +6 -6
- package/dist/server/assets/{c4Diagram-YG6GDRKO-ByeFZAO1.js → c4Diagram-YG6GDRKO-nGE1cXwD.js} +2 -2
- package/dist/server/assets/{channel-B6u30R-7.js → channel-CqQOLgw9.js} +1 -1
- package/dist/server/assets/{chunk-4BX2VUAB-X_mApFBH.js → chunk-4BX2VUAB-DrJXJmx5.js} +1 -1
- package/dist/server/assets/{chunk-55IACEB6-DMO5XJKd.js → chunk-55IACEB6-CKxRFH9J.js} +1 -1
- package/dist/server/assets/{chunk-B4BG7PRW-Da7HlBM1.js → chunk-B4BG7PRW-BxyNZV2w.js} +4 -4
- package/dist/server/assets/{chunk-DI55MBZ5-DuioLWo-.js → chunk-DI55MBZ5-CajwqGPE.js} +3 -3
- package/dist/server/assets/{chunk-FMBD7UC4-BhKTk6rW.js → chunk-FMBD7UC4-D1CO-v-G.js} +1 -1
- package/dist/server/assets/{chunk-QN33PNHL-BgZXw9n5.js → chunk-QN33PNHL-D4KiZklP.js} +1 -1
- package/dist/server/assets/{chunk-QZHKN3VN-DHuwppPm.js → chunk-QZHKN3VN-CNElfh9C.js} +1 -1
- package/dist/server/assets/{chunk-TZMSLE5B-w8fhHHwn.js → chunk-TZMSLE5B-CHBqvPAr.js} +1 -1
- package/dist/server/assets/{classDiagram-v2-WZHVMYZB-BZf5qvSp.js → classDiagram-2ON5EDUG-D3C4Rk7Q.js} +5 -5
- package/dist/server/assets/{classDiagram-2ON5EDUG-BZf5qvSp.js → classDiagram-v2-WZHVMYZB-D3C4Rk7Q.js} +5 -5
- package/dist/server/assets/{clone-CjoEs-v-.js → clone-DsPS0_DH.js} +1 -1
- package/dist/server/assets/{cose-bilkent-S5V4N54A-BNk0NAbB.js → cose-bilkent-S5V4N54A-V_MYkZlm.js} +1 -1
- package/dist/server/assets/{dagre-6UL2VRFP-C0_F8CHc.js → dagre-6UL2VRFP-D_Mh5gNH.js} +6 -6
- package/dist/server/assets/{diagram-PSM6KHXK-LARMaMiS.js → diagram-PSM6KHXK-B9dGPsE9.js} +7 -7
- package/dist/server/assets/{diagram-QEK2KX5R-jKvozWzw.js → diagram-QEK2KX5R-BcfmavO-.js} +6 -6
- package/dist/server/assets/{diagram-S2PKOQOG-5a2K9q2r.js → diagram-S2PKOQOG-B8urPf9c.js} +6 -6
- package/dist/server/assets/{erDiagram-Q2GNP2WA-DPxBpQns.js → erDiagram-Q2GNP2WA-CzG0zKt-.js} +4 -4
- package/dist/server/assets/{flowDiagram-NV44I4VS-CX3XZT5Y.js → flowDiagram-NV44I4VS-Bk7aIalC.js} +5 -5
- package/dist/server/assets/{ganttDiagram-JELNMOA3-BmjiDolw.js → ganttDiagram-JELNMOA3-wmt8nm9q.js} +2 -2
- package/dist/server/assets/{gitGraph-G5XIXVHT-BxG8jjGU.js → gitGraph-G5XIXVHT-CmiFNHiv.js} +6 -6
- package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-ChLdCg6Z.js → gitGraphDiagram-V2S2FVAM-OV2DR1Ux.js} +7 -7
- package/dist/server/assets/{graph-Bx5JUzop.js → graph-ziMVg61H.js} +2 -2
- package/dist/server/assets/{highlighted-body-B3W2YXNL-DDkviWDm.js → highlighted-body-B3W2YXNL-DX00yTJM.js} +1 -1
- package/dist/server/assets/{index-BoT6zVKn.js → index-9M09S61v.js} +2 -2
- package/dist/server/assets/{index-OEnZTnkb.js → index-B5x9IUkQ.js} +2 -2
- package/dist/server/assets/{index-Bb41VJM3.js → index-BvBMEwhL.js} +4 -4
- package/dist/server/assets/{index-C4USpn2y.js → index-C-k9sCKq.js} +2 -2
- package/dist/server/assets/{index-BP-Fy_Ud.js → index-CKmyLecf.js} +2 -2
- package/dist/server/assets/{index-DO3wKBul.js → index-CXnsJrX8.js} +5 -5
- package/dist/server/assets/{index-Dp74K7A4.js → index-Ce2uXVrE.js} +2 -2
- package/dist/server/assets/{index-CDCloCld.js → index-CiWhFogO.js} +2 -2
- package/dist/server/assets/{index-Cuuby6oP.js → index-D5nqcxSY.js} +3 -3
- package/dist/server/assets/{index-BnAK5zRH.js → index-DLmI6-iR.js} +1 -1
- package/dist/server/assets/{index-DSGH2NU6.js → index-DNaA-OTp.js} +2 -2
- package/dist/server/assets/{index-DrrqcbHg.js → index-DPAkuW3l.js} +2 -2
- package/dist/server/assets/{index-CLsI0TMm.js → index-VtjR2oZj.js} +2 -2
- package/dist/server/assets/{index-DjhMY50H.js → index-ayG05uhc.js} +3 -3
- package/dist/server/assets/{index-DTkAyV2J.js → index-l8a7u6GS.js} +2 -2
- package/dist/server/assets/{index-Duvita0E.js → index-sKmEy2Z2.js} +5 -5
- package/dist/server/assets/{index-BKnmhk3u.js → index-sbo2EHgw.js} +2 -2
- package/dist/server/assets/{index-BBCpeEJl.js → index-xVhCXu45.js} +2 -2
- package/dist/server/assets/{info-VBDWY6EO-6bfVBBeD.js → info-VBDWY6EO-muqpsCRw.js} +6 -6
- package/dist/server/assets/{infoDiagram-HS3SLOUP-B1v9HmWX.js → infoDiagram-HS3SLOUP-D8EoxteQ.js} +5 -5
- package/dist/server/assets/{journeyDiagram-XKPGCS4Q-Cb26EUwI.js → journeyDiagram-XKPGCS4Q-BwZk-fnC.js} +4 -4
- package/dist/server/assets/{kanban-definition-3W4ZIXB7-Cv4GaETC.js → kanban-definition-3W4ZIXB7-DEfYos8T.js} +2 -2
- package/dist/server/assets/{layout-CQJCngSZ.js → layout-CKMmyz2h.js} +4 -4
- package/dist/server/assets/{linear-Civ7P345.js → linear-DXR7qYUB.js} +1 -1
- package/dist/server/assets/{mermaid-3ZIDBTTL-EBg4-fWO.js → mermaid-3ZIDBTTL-DxhML77C.js} +1 -1
- package/dist/server/assets/{mermaid-parser.core-2e_OlBPy.js → mermaid-parser.core-DBGA5y48.js} +11 -11
- package/dist/server/assets/{mindmap-definition-VGOIOE7T-uP_bqLZ-.js → mindmap-definition-VGOIOE7T-Bg8B0Ls9.js} +3 -3
- package/dist/server/assets/{packet-DYOGHKS2-C9RhEbus.js → packet-DYOGHKS2-CnH_YgfD.js} +6 -6
- package/dist/server/assets/{pie-VRWISCQL-DXIjmNyN.js → pie-VRWISCQL-iceCWNPC.js} +6 -6
- package/dist/server/assets/{pieDiagram-ADFJNKIX-C2Qp43pf.js → pieDiagram-ADFJNKIX-Bw3RR9nb.js} +7 -7
- package/dist/server/assets/{quadrantDiagram-AYHSOK5B-C9I9kDB1.js → quadrantDiagram-AYHSOK5B-CpLsW_Ir.js} +2 -2
- package/dist/server/assets/{radar-ZZBFDIW7-CEz6u4b9.js → radar-ZZBFDIW7-Bab4MCR4.js} +6 -6
- package/dist/server/assets/{requirementDiagram-UZGBJVZJ-DmCcKz-Y.js → requirementDiagram-UZGBJVZJ-DkGtaEnw.js} +3 -3
- package/dist/server/assets/{router-BlHVACji.js → router-yk-AJHab.js} +1927 -1027
- package/dist/server/assets/{sankeyDiagram-TZEHDZUN-DM2H1xi3.js → sankeyDiagram-TZEHDZUN-CtEV3_Bx.js} +1 -1
- package/dist/server/assets/{sequenceDiagram-WL72ISMW-DWDQKCiq.js → sequenceDiagram-WL72ISMW-BMW4qEme.js} +3 -3
- package/dist/server/assets/{square-terminal-CCwkUkGX.js → square-terminal-Bui9B6KN.js} +1 -1
- package/dist/server/assets/{stateDiagram-FKZM4ZOC-_4Khdh4I.js → stateDiagram-FKZM4ZOC-C7xazM8E.js} +8 -8
- package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-Cos-pE9j.js → stateDiagram-v2-4FDKWEC3-D_rYvDGP.js} +4 -4
- package/dist/server/assets/{timeline-definition-IT6M3QCI-DeLSZGNq.js → timeline-definition-IT6M3QCI-BaAlfxrc.js} +2 -2
- package/dist/server/assets/{treemap-GDKQZRPO-LKeqy604.js → treemap-GDKQZRPO-DlP1TABE.js} +6 -6
- package/dist/server/assets/{workspace._workspaceId-C0PMWq41.js → workspace._workspaceId-Be45P7LL.js} +2 -2
- package/dist/server/assets/{workspace._workspaceId.changes-CzyqOgM_.js → workspace._workspaceId.changes-EoyIscxQ.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.code._-QG2CLJod.js → workspace._workspaceId.code._-CcX7Gt0G.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.code.index-CVy3VzQK.js → workspace._workspaceId.code.index-CFbCDVph.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.index-LBt-0JYY.js → workspace._workspaceId.index-DmYHy6nH.js} +1 -1
- package/dist/server/assets/{workspace._workspaceId.terminal-jMK4pgOD.js → workspace._workspaceId.terminal-D_KPwmYr.js} +2 -2
- package/dist/server/assets/{xychartDiagram-PRI3JC2R-DHrKht9t.js → xychartDiagram-PRI3JC2R-Cq7t_yS-.js} +2 -2
- package/dist/server/server.js +2 -2
- package/dist/start-server.mjs +766 -467
- package/package.json +6 -5
- package/dist/client/assets/TerminalPanel-Cu7fEaGN.js +0 -4
- package/dist/client/assets/channel-BgmjEVPj.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-BKsagNLe.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-BKsagNLe.js +0 -1
- package/dist/client/assets/clone-CBcd3GIz.js +0 -1
- package/dist/client/assets/index-BKUORVg0.js +0 -1
- package/dist/client/assets/main-DYrDxnSM.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-Cgq8vGxD.js +0 -1
- package/dist/client/assets/workspace._workspaceId.code-DP6cBpn1.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,39 +120421,94 @@ 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
|
+
|
|
120449
|
+
// ../../packages/dashboard-core/src/lib/language-map.ts
|
|
120450
|
+
var SUPPORTED_LANGUAGES = [
|
|
120451
|
+
{ id: "plaintext", label: "Plain Text" },
|
|
120452
|
+
{ id: "bash", label: "Bash / Shell" },
|
|
120453
|
+
{ id: "c", label: "C" },
|
|
120454
|
+
{ id: "clojure", label: "Clojure" },
|
|
120455
|
+
{ id: "cpp", label: "C++" },
|
|
120456
|
+
{ id: "csharp", label: "C#" },
|
|
120457
|
+
{ id: "css", label: "CSS" },
|
|
120458
|
+
{ id: "dart", label: "Dart" },
|
|
120459
|
+
{ id: "diff", label: "Diff" },
|
|
120460
|
+
{ id: "dockerfile", label: "Dockerfile" },
|
|
120461
|
+
{ id: "elixir", label: "Elixir" },
|
|
120462
|
+
{ id: "erlang", label: "Erlang" },
|
|
120463
|
+
{ id: "go", label: "Go" },
|
|
120464
|
+
{ id: "graphql", label: "GraphQL" },
|
|
120465
|
+
{ id: "haskell", label: "Haskell" },
|
|
120466
|
+
{ id: "hcl", label: "HCL / Terraform" },
|
|
120467
|
+
{ id: "html", label: "HTML" },
|
|
120468
|
+
{ id: "ini", label: "INI" },
|
|
120469
|
+
{ id: "java", label: "Java" },
|
|
120470
|
+
{ id: "javascript", label: "JavaScript" },
|
|
120471
|
+
{ id: "json", label: "JSON" },
|
|
120472
|
+
{ id: "jsonc", label: "JSON with Comments" },
|
|
120473
|
+
{ id: "jsx", label: "JavaScript (JSX)" },
|
|
120474
|
+
{ id: "kotlin", label: "Kotlin" },
|
|
120475
|
+
{ id: "less", label: "Less" },
|
|
120476
|
+
{ id: "lua", label: "Lua" },
|
|
120477
|
+
{ id: "makefile", label: "Makefile" },
|
|
120478
|
+
{ id: "markdown", label: "Markdown" },
|
|
120479
|
+
{ id: "mdx", label: "MDX" },
|
|
120480
|
+
{ id: "php", label: "PHP" },
|
|
120481
|
+
{ id: "powershell", label: "PowerShell" },
|
|
120482
|
+
{ id: "python", label: "Python" },
|
|
120483
|
+
{ id: "r", label: "R" },
|
|
120484
|
+
{ id: "ruby", label: "Ruby" },
|
|
120485
|
+
{ id: "rust", label: "Rust" },
|
|
120486
|
+
{ id: "sass", label: "Sass" },
|
|
120487
|
+
{ id: "scala", label: "Scala" },
|
|
120488
|
+
{ id: "scss", label: "SCSS" },
|
|
120489
|
+
{ id: "sql", label: "SQL" },
|
|
120490
|
+
{ id: "svelte", label: "Svelte" },
|
|
120491
|
+
{ id: "swift", label: "Swift" },
|
|
120492
|
+
{ id: "toml", label: "TOML" },
|
|
120493
|
+
{ id: "typescript", label: "TypeScript" },
|
|
120494
|
+
{ id: "tsx", label: "TypeScript (TSX)" },
|
|
120495
|
+
{ id: "vue", label: "Vue" },
|
|
120496
|
+
{ id: "xml", label: "XML" },
|
|
120497
|
+
{ id: "yaml", label: "YAML" }
|
|
120498
|
+
];
|
|
120499
|
+
var LANGUAGE_LABEL_BY_ID = new Map(SUPPORTED_LANGUAGES.map((l) => [l.id, l.label]));
|
|
120500
|
+
|
|
120414
120501
|
// ../../packages/dashboard-core/src/components/ChangesFileTree.tsx
|
|
120415
|
-
var
|
|
120502
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
120416
120503
|
|
|
120417
120504
|
// ../../packages/dashboard-core/src/hooks/use-deferred-menu-action.ts
|
|
120418
|
-
var
|
|
120505
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
120419
120506
|
function useDeferredMenuAction() {
|
|
120420
|
-
const pendingRef = (0,
|
|
120421
|
-
const queue = (0,
|
|
120507
|
+
const pendingRef = (0, import_react28.useRef)(null);
|
|
120508
|
+
const queue = (0, import_react28.useCallback)((fn) => {
|
|
120422
120509
|
pendingRef.current = fn;
|
|
120423
120510
|
}, []);
|
|
120424
|
-
const flush = (0,
|
|
120511
|
+
const flush = (0, import_react28.useCallback)((e2) => {
|
|
120425
120512
|
e2.preventDefault();
|
|
120426
120513
|
const fn = pendingRef.current;
|
|
120427
120514
|
pendingRef.current = null;
|
|
@@ -120570,18 +120657,18 @@ function getFileIcon(filename) {
|
|
|
120570
120657
|
}
|
|
120571
120658
|
|
|
120572
120659
|
// ../../packages/dashboard-core/src/components/FileStatusBadge.tsx
|
|
120573
|
-
var
|
|
120660
|
+
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
|
|
120574
120661
|
|
|
120575
120662
|
// ../../packages/dashboard-core/src/components/ChangesFileTree.tsx
|
|
120576
|
-
var
|
|
120663
|
+
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
120577
120664
|
|
|
120578
120665
|
// ../../packages/dashboard-core/src/components/RevertFileDialog.tsx
|
|
120579
|
-
var
|
|
120666
|
+
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
120580
120667
|
|
|
120581
120668
|
// ../../packages/dashboard-core/src/components/SearchBar.tsx
|
|
120582
120669
|
var import_lucide_react7 = __toESM(require_lucide_react(), 1);
|
|
120583
|
-
var
|
|
120584
|
-
var
|
|
120670
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
120671
|
+
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
120585
120672
|
var DEFAULT_VISIBLE_OPTIONS = ["caseSensitive", "wholeWord", "regex"];
|
|
120586
120673
|
function ToggleButton({
|
|
120587
120674
|
active,
|
|
@@ -120589,7 +120676,7 @@ function ToggleButton({
|
|
|
120589
120676
|
title,
|
|
120590
120677
|
children
|
|
120591
120678
|
}) {
|
|
120592
|
-
return /* @__PURE__ */ (0,
|
|
120679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120593
120680
|
"button",
|
|
120594
120681
|
{
|
|
120595
120682
|
type: "button",
|
|
@@ -120600,7 +120687,7 @@ function ToggleButton({
|
|
|
120600
120687
|
}
|
|
120601
120688
|
);
|
|
120602
120689
|
}
|
|
120603
|
-
var SearchBar = (0,
|
|
120690
|
+
var SearchBar = (0, import_react30.forwardRef)(function SearchBar2({
|
|
120604
120691
|
query,
|
|
120605
120692
|
onQueryChange,
|
|
120606
120693
|
options: options2,
|
|
@@ -120616,27 +120703,27 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120616
120703
|
const showCase = visibleOptions.includes("caseSensitive");
|
|
120617
120704
|
const showWholeWord = visibleOptions.includes("wholeWord");
|
|
120618
120705
|
const showRegex = visibleOptions.includes("regex");
|
|
120619
|
-
const inputRef = (0,
|
|
120620
|
-
(0,
|
|
120706
|
+
const inputRef = (0, import_react30.useRef)(null);
|
|
120707
|
+
(0, import_react30.useImperativeHandle)(ref, () => ({
|
|
120621
120708
|
focus: () => inputRef.current?.focus(),
|
|
120622
120709
|
select: () => inputRef.current?.select()
|
|
120623
120710
|
}));
|
|
120624
|
-
const toggleCase = (0,
|
|
120711
|
+
const toggleCase = (0, import_react30.useCallback)(() => {
|
|
120625
120712
|
onOptionsChange({ ...options2, caseSensitive: !options2.caseSensitive });
|
|
120626
120713
|
}, [options2, onOptionsChange]);
|
|
120627
|
-
const toggleWholeWord = (0,
|
|
120714
|
+
const toggleWholeWord = (0, import_react30.useCallback)(() => {
|
|
120628
120715
|
onOptionsChange({ ...options2, wholeWord: !options2.wholeWord });
|
|
120629
120716
|
}, [options2, onOptionsChange]);
|
|
120630
|
-
const toggleRegex = (0,
|
|
120717
|
+
const toggleRegex = (0, import_react30.useCallback)(() => {
|
|
120631
120718
|
onOptionsChange({ ...options2, regex: !options2.regex });
|
|
120632
120719
|
}, [options2, onOptionsChange]);
|
|
120633
|
-
return /* @__PURE__ */ (0,
|
|
120720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
|
|
120634
120721
|
"div",
|
|
120635
120722
|
{
|
|
120636
120723
|
className: `flex shrink-0 items-center gap-1.5 border-b border-border bg-muted/30 px-3 py-1.5 ${className ?? ""}`,
|
|
120637
120724
|
children: [
|
|
120638
|
-
/* @__PURE__ */ (0,
|
|
120639
|
-
/* @__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)(
|
|
120640
120727
|
"input",
|
|
120641
120728
|
{
|
|
120642
120729
|
ref: inputRef,
|
|
@@ -120657,11 +120744,11 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120657
120744
|
}
|
|
120658
120745
|
}
|
|
120659
120746
|
),
|
|
120660
|
-
showCase && /* @__PURE__ */ (0,
|
|
120661
|
-
showWholeWord && /* @__PURE__ */ (0,
|
|
120662
|
-
showRegex && /* @__PURE__ */ (0,
|
|
120663
|
-
matchInfo && query && /* @__PURE__ */ (0,
|
|
120664
|
-
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)(
|
|
120665
120752
|
"button",
|
|
120666
120753
|
{
|
|
120667
120754
|
type: "button",
|
|
@@ -120669,10 +120756,10 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120669
120756
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
120670
120757
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
120671
120758
|
title: "Previous match (Shift+Enter)",
|
|
120672
|
-
children: /* @__PURE__ */ (0,
|
|
120759
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.ChevronUp, { className: "size-3.5" })
|
|
120673
120760
|
}
|
|
120674
120761
|
),
|
|
120675
|
-
onNext && /* @__PURE__ */ (0,
|
|
120762
|
+
onNext && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120676
120763
|
"button",
|
|
120677
120764
|
{
|
|
120678
120765
|
type: "button",
|
|
@@ -120680,17 +120767,17 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120680
120767
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
120681
120768
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
120682
120769
|
title: "Next match (Enter)",
|
|
120683
|
-
children: /* @__PURE__ */ (0,
|
|
120770
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.ChevronDown, { className: "size-3.5" })
|
|
120684
120771
|
}
|
|
120685
120772
|
),
|
|
120686
|
-
onClose && /* @__PURE__ */ (0,
|
|
120773
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
120687
120774
|
"button",
|
|
120688
120775
|
{
|
|
120689
120776
|
type: "button",
|
|
120690
120777
|
onClick: onClose,
|
|
120691
120778
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground",
|
|
120692
120779
|
title: "Close (Escape)",
|
|
120693
|
-
children: /* @__PURE__ */ (0,
|
|
120780
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_lucide_react7.X, { className: "size-3.5" })
|
|
120694
120781
|
}
|
|
120695
120782
|
)
|
|
120696
120783
|
]
|
|
@@ -120699,7 +120786,7 @@ var SearchBar = (0, import_react29.forwardRef)(function SearchBar2({
|
|
|
120699
120786
|
});
|
|
120700
120787
|
|
|
120701
120788
|
// ../../packages/dashboard-core/src/components/DiffView.tsx
|
|
120702
|
-
var
|
|
120789
|
+
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
|
|
120703
120790
|
var diffTheme = EditorView.theme({
|
|
120704
120791
|
".cm-insertedLine": { backgroundColor: "rgba(34, 197, 94, 0.1)" },
|
|
120705
120792
|
".cm-deletedLine": { backgroundColor: "rgba(239, 68, 68, 0.1)" },
|
|
@@ -120750,8 +120837,8 @@ var diffTheme = EditorView.theme({
|
|
|
120750
120837
|
|
|
120751
120838
|
// ../../packages/dashboard-core/src/components/FileBrowser.tsx
|
|
120752
120839
|
var import_lucide_react8 = __toESM(require_lucide_react(), 1);
|
|
120753
|
-
var
|
|
120754
|
-
var
|
|
120840
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
120841
|
+
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
120755
120842
|
var expandedStateCache = /* @__PURE__ */ new Map();
|
|
120756
120843
|
var dirContentsCache = /* @__PURE__ */ new Map();
|
|
120757
120844
|
function getCachedExpanded(wsId) {
|
|
@@ -120780,11 +120867,11 @@ function EntryNameInput({
|
|
|
120780
120867
|
onSubmit,
|
|
120781
120868
|
onCancel
|
|
120782
120869
|
}) {
|
|
120783
|
-
const [value, setValue] = (0,
|
|
120784
|
-
const [submitting, setSubmitting] = (0,
|
|
120785
|
-
const [error40, setError] = (0,
|
|
120786
|
-
const inputRef = (0,
|
|
120787
|
-
(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)(() => {
|
|
120788
120875
|
const el = inputRef.current;
|
|
120789
120876
|
if (!el) return;
|
|
120790
120877
|
el.focus();
|
|
@@ -120832,21 +120919,21 @@ function EntryNameInput({
|
|
|
120832
120919
|
}
|
|
120833
120920
|
};
|
|
120834
120921
|
const Icon = kind === "directory" ? import_lucide_react8.Folder : import_lucide_react8.File;
|
|
120835
|
-
return /* @__PURE__ */ (0,
|
|
120836
|
-
/* @__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)(
|
|
120837
120924
|
"div",
|
|
120838
120925
|
{
|
|
120839
120926
|
className: `flex items-center ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"}`,
|
|
120840
120927
|
style: { height },
|
|
120841
120928
|
children: [
|
|
120842
|
-
/* @__PURE__ */ (0,
|
|
120843
|
-
/* @__PURE__ */ (0,
|
|
120929
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "size-3.5 shrink-0" }),
|
|
120930
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120844
120931
|
Icon,
|
|
120845
120932
|
{
|
|
120846
120933
|
className: kind === "directory" ? "size-4 shrink-0 text-blue-600 dark:text-blue-400" : "size-4 shrink-0 text-muted-foreground"
|
|
120847
120934
|
}
|
|
120848
120935
|
),
|
|
120849
|
-
/* @__PURE__ */ (0,
|
|
120936
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120850
120937
|
"input",
|
|
120851
120938
|
{
|
|
120852
120939
|
ref: inputRef,
|
|
@@ -120883,7 +120970,7 @@ function EntryNameInput({
|
|
|
120883
120970
|
]
|
|
120884
120971
|
}
|
|
120885
120972
|
),
|
|
120886
|
-
error40 && /* @__PURE__ */ (0,
|
|
120973
|
+
error40 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120887
120974
|
"div",
|
|
120888
120975
|
{
|
|
120889
120976
|
className: "pointer-events-none text-xs text-destructive",
|
|
@@ -120950,7 +121037,7 @@ function TreeNode2({
|
|
|
120950
121037
|
onOpenFilePinned(entryPath);
|
|
120951
121038
|
}
|
|
120952
121039
|
};
|
|
120953
|
-
const button = /* @__PURE__ */ (0,
|
|
121040
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
120954
121041
|
"button",
|
|
120955
121042
|
{
|
|
120956
121043
|
ref: isSelected ? selectedRef : void 0,
|
|
@@ -120963,12 +121050,12 @@ function TreeNode2({
|
|
|
120963
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" : ""}`,
|
|
120964
121051
|
style: { paddingLeft: `${depth * indent + basePad}px` },
|
|
120965
121052
|
children: [
|
|
120966
|
-
isDir ? isExpanded ? /* @__PURE__ */ (0,
|
|
120967
|
-
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" }) : (() => {
|
|
120968
121055
|
const FileIcon = getFileIcon(entry.name);
|
|
120969
|
-
return /* @__PURE__ */ (0,
|
|
121056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" });
|
|
120970
121057
|
})(),
|
|
120971
|
-
/* @__PURE__ */ (0,
|
|
121058
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "min-w-0 flex-1 truncate", children: entry.name })
|
|
120972
121059
|
]
|
|
120973
121060
|
}
|
|
120974
121061
|
);
|
|
@@ -120990,7 +121077,7 @@ function TreeNode2({
|
|
|
120990
121077
|
// a padding div with `depth={0}` would double-apply `basePad`, shifting
|
|
120991
121078
|
// the input ~4px to the right and giving it visibly less horizontal
|
|
120992
121079
|
// room than the rest of the tree.
|
|
120993
|
-
/* @__PURE__ */ (0,
|
|
121080
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
120994
121081
|
EntryNameInput,
|
|
120995
121082
|
{
|
|
120996
121083
|
kind: isDir ? "directory" : "file",
|
|
@@ -121004,74 +121091,74 @@ function TreeNode2({
|
|
|
121004
121091
|
},
|
|
121005
121092
|
`rename-${entryPath}`
|
|
121006
121093
|
)
|
|
121007
|
-
) : /* @__PURE__ */ (0,
|
|
121094
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121008
121095
|
ContextMenu2,
|
|
121009
121096
|
{
|
|
121010
121097
|
onOpenChange: (open3) => {
|
|
121011
121098
|
if (open3) onSelectRow(entryPath, isDir ? "directory" : "file");
|
|
121012
121099
|
},
|
|
121013
121100
|
children: [
|
|
121014
|
-
/* @__PURE__ */ (0,
|
|
121015
|
-
/* @__PURE__ */ (0,
|
|
121016
|
-
isDir && /* @__PURE__ */ (0,
|
|
121017
|
-
/* @__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)(
|
|
121018
121105
|
ContextMenuItem2,
|
|
121019
121106
|
{
|
|
121020
121107
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "file")),
|
|
121021
121108
|
children: [
|
|
121022
|
-
/* @__PURE__ */ (0,
|
|
121109
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.File, { className: "size-4" }),
|
|
121023
121110
|
"New File"
|
|
121024
121111
|
]
|
|
121025
121112
|
}
|
|
121026
121113
|
),
|
|
121027
|
-
/* @__PURE__ */ (0,
|
|
121114
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121028
121115
|
ContextMenuItem2,
|
|
121029
121116
|
{
|
|
121030
121117
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "directory")),
|
|
121031
121118
|
children: [
|
|
121032
|
-
/* @__PURE__ */ (0,
|
|
121119
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.FolderPlus, { className: "size-4" }),
|
|
121033
121120
|
"New Folder"
|
|
121034
121121
|
]
|
|
121035
121122
|
}
|
|
121036
121123
|
),
|
|
121037
|
-
/* @__PURE__ */ (0,
|
|
121124
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ContextMenuSeparator2, {})
|
|
121038
121125
|
] }),
|
|
121039
|
-
canCut && /* @__PURE__ */ (0,
|
|
121126
|
+
canCut && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121040
121127
|
ContextMenuItem2,
|
|
121041
121128
|
{
|
|
121042
121129
|
onSelect: () => menu.queue(() => onCut(entryPath, isDir ? "directory" : "file")),
|
|
121043
121130
|
children: [
|
|
121044
|
-
/* @__PURE__ */ (0,
|
|
121131
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Scissors, { className: "size-4" }),
|
|
121045
121132
|
"Cut"
|
|
121046
121133
|
]
|
|
121047
121134
|
}
|
|
121048
121135
|
),
|
|
121049
|
-
canCopy && /* @__PURE__ */ (0,
|
|
121136
|
+
canCopy && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121050
121137
|
ContextMenuItem2,
|
|
121051
121138
|
{
|
|
121052
121139
|
onSelect: () => menu.queue(() => onCopy(entryPath, isDir ? "directory" : "file")),
|
|
121053
121140
|
children: [
|
|
121054
|
-
/* @__PURE__ */ (0,
|
|
121141
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Copy, { className: "size-4" }),
|
|
121055
121142
|
"Copy"
|
|
121056
121143
|
]
|
|
121057
121144
|
}
|
|
121058
121145
|
),
|
|
121059
|
-
isDir && canPaste && /* @__PURE__ */ (0,
|
|
121060
|
-
/* @__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" }),
|
|
121061
121148
|
"Paste"
|
|
121062
121149
|
] }),
|
|
121063
|
-
(canCut || canCopy || isDir && canPaste) && (canRename || canDelete) && /* @__PURE__ */ (0,
|
|
121064
|
-
canRename && /* @__PURE__ */ (0,
|
|
121065
|
-
/* @__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" }),
|
|
121066
121153
|
"Rename"
|
|
121067
121154
|
] }),
|
|
121068
|
-
canDelete && /* @__PURE__ */ (0,
|
|
121155
|
+
canDelete && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|
|
121069
121156
|
ContextMenuItem2,
|
|
121070
121157
|
{
|
|
121071
121158
|
variant: "destructive",
|
|
121072
121159
|
onSelect: () => menu.queue(() => onRequestDelete(entryPath, isDir ? "directory" : "file")),
|
|
121073
121160
|
children: [
|
|
121074
|
-
/* @__PURE__ */ (0,
|
|
121161
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_lucide_react8.Trash2, { className: "size-4" }),
|
|
121075
121162
|
"Delete"
|
|
121076
121163
|
]
|
|
121077
121164
|
}
|
|
@@ -121081,13 +121168,13 @@ function TreeNode2({
|
|
|
121081
121168
|
}
|
|
121082
121169
|
);
|
|
121083
121170
|
const showInlineInput = newEntry?.parentPath === entryPath;
|
|
121084
|
-
return /* @__PURE__ */ (0,
|
|
121171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121085
121172
|
row,
|
|
121086
121173
|
isExpanded && (() => {
|
|
121087
121174
|
const splitIdx = children?.findIndex((c2) => c2.type === "file") ?? -1;
|
|
121088
121175
|
const folderChildren = splitIdx === -1 ? children ?? [] : (children ?? []).slice(0, splitIdx);
|
|
121089
121176
|
const fileChildren = splitIdx === -1 ? [] : (children ?? []).slice(splitIdx);
|
|
121090
|
-
const renderChild = (child) => /* @__PURE__ */ (0,
|
|
121177
|
+
const renderChild = (child) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121091
121178
|
TreeNode2,
|
|
121092
121179
|
{
|
|
121093
121180
|
entry: child,
|
|
@@ -121124,7 +121211,7 @@ function TreeNode2({
|
|
|
121124
121211
|
},
|
|
121125
121212
|
child.name
|
|
121126
121213
|
);
|
|
121127
|
-
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0,
|
|
121214
|
+
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121128
121215
|
EntryNameInput,
|
|
121129
121216
|
{
|
|
121130
121217
|
kind: newEntry.kind,
|
|
@@ -121136,9 +121223,9 @@ function TreeNode2({
|
|
|
121136
121223
|
},
|
|
121137
121224
|
`new-${newEntry.kind}-${entryPath}`
|
|
121138
121225
|
) : null;
|
|
121139
|
-
return /* @__PURE__ */ (0,
|
|
121226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121140
121227
|
showInlineInput && newEntry.kind === "directory" && newEntryInput,
|
|
121141
|
-
isLoading && !children?.length && /* @__PURE__ */ (0,
|
|
121228
|
+
isLoading && !children?.length && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121142
121229
|
"div",
|
|
121143
121230
|
{
|
|
121144
121231
|
className: `flex items-center text-muted-foreground/70 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -121149,7 +121236,7 @@ function TreeNode2({
|
|
|
121149
121236
|
children: "Loading\u2026"
|
|
121150
121237
|
}
|
|
121151
121238
|
),
|
|
121152
|
-
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0,
|
|
121239
|
+
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121153
121240
|
"div",
|
|
121154
121241
|
{
|
|
121155
121242
|
className: `flex items-center italic text-muted-foreground/50 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -121167,7 +121254,7 @@ function TreeNode2({
|
|
|
121167
121254
|
})()
|
|
121168
121255
|
] });
|
|
121169
121256
|
}
|
|
121170
|
-
var FileBrowser = (0,
|
|
121257
|
+
var FileBrowser = (0, import_react32.forwardRef)(function FileBrowser2({
|
|
121171
121258
|
workspaceId,
|
|
121172
121259
|
onOpenFile,
|
|
121173
121260
|
onOpenFilePinned,
|
|
@@ -121177,23 +121264,23 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121177
121264
|
onPathDeleted
|
|
121178
121265
|
}, handleRef) {
|
|
121179
121266
|
const adapter = useAdapter();
|
|
121180
|
-
const [expandedPaths, setExpandedPaths] = (0,
|
|
121267
|
+
const [expandedPaths, setExpandedPaths] = (0, import_react32.useState)(
|
|
121181
121268
|
() => new Set(getCachedExpanded(workspaceId))
|
|
121182
121269
|
);
|
|
121183
|
-
const [dirContents, setDirContents] = (0,
|
|
121270
|
+
const [dirContents, setDirContents] = (0, import_react32.useState)(
|
|
121184
121271
|
() => new Map(getCachedContents(workspaceId))
|
|
121185
121272
|
);
|
|
121186
|
-
const [loadingPaths, setLoadingPaths] = (0,
|
|
121187
|
-
const [newEntry, setNewEntry] = (0,
|
|
121188
|
-
const [pendingDelete, setPendingDelete] = (0,
|
|
121189
|
-
const [deleteError, setDeleteError] = (0,
|
|
121190
|
-
const [deleteSubmitting, setDeleteSubmitting] = (0,
|
|
121191
|
-
const [renamingPath, setRenamingPath] = (0,
|
|
121192
|
-
const [clipboard, setClipboard] = (0,
|
|
121193
|
-
const [treeSelection, setTreeSelection] = (0,
|
|
121194
|
-
const selectedRef = (0,
|
|
121195
|
-
const prevWorkspaceRef = (0,
|
|
121196
|
-
(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)(() => {
|
|
121197
121284
|
if (prevWorkspaceRef.current !== workspaceId) {
|
|
121198
121285
|
prevWorkspaceRef.current = workspaceId;
|
|
121199
121286
|
setExpandedPaths(new Set(getCachedExpanded(workspaceId)));
|
|
@@ -121208,18 +121295,18 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121208
121295
|
setClipboard(null);
|
|
121209
121296
|
}
|
|
121210
121297
|
}, [workspaceId]);
|
|
121211
|
-
(0,
|
|
121298
|
+
(0, import_react32.useEffect)(() => {
|
|
121212
121299
|
if (selectedFile) {
|
|
121213
121300
|
setTreeSelection({ path: selectedFile, kind: "file" });
|
|
121214
121301
|
}
|
|
121215
121302
|
}, [selectedFile]);
|
|
121216
|
-
const handleSelectRow = (0,
|
|
121303
|
+
const handleSelectRow = (0, import_react32.useCallback)((path3, kind) => {
|
|
121217
121304
|
setTreeSelection({ path: path3, kind });
|
|
121218
121305
|
}, []);
|
|
121219
|
-
const clearTreeSelection = (0,
|
|
121306
|
+
const clearTreeSelection = (0, import_react32.useCallback)(() => {
|
|
121220
121307
|
setTreeSelection(null);
|
|
121221
121308
|
}, []);
|
|
121222
|
-
const fetchDir = (0,
|
|
121309
|
+
const fetchDir = (0, import_react32.useCallback)(
|
|
121223
121310
|
async (dirPath, opts) => {
|
|
121224
121311
|
if (!adapter.listWorkspaceFiles) return;
|
|
121225
121312
|
const cache = getCachedContents(workspaceId);
|
|
@@ -121243,10 +121330,10 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121243
121330
|
},
|
|
121244
121331
|
[adapter, workspaceId]
|
|
121245
121332
|
);
|
|
121246
|
-
(0,
|
|
121333
|
+
(0, import_react32.useEffect)(() => {
|
|
121247
121334
|
fetchDir("");
|
|
121248
121335
|
}, [fetchDir]);
|
|
121249
|
-
(0,
|
|
121336
|
+
(0, import_react32.useEffect)(() => {
|
|
121250
121337
|
if (!adapter.subscribeFileChanges) return;
|
|
121251
121338
|
const unsubscribe = adapter.subscribeFileChanges(workspaceId, (changedPath) => {
|
|
121252
121339
|
const cache = getCachedContents(workspaceId);
|
|
@@ -121255,8 +121342,8 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121255
121342
|
});
|
|
121256
121343
|
return unsubscribe;
|
|
121257
121344
|
}, [adapter, workspaceId, fetchDir]);
|
|
121258
|
-
const prevSelectedRef = (0,
|
|
121259
|
-
(0,
|
|
121345
|
+
const prevSelectedRef = (0, import_react32.useRef)(void 0);
|
|
121346
|
+
(0, import_react32.useEffect)(() => {
|
|
121260
121347
|
if (!selectedFile || selectedFile === prevSelectedRef.current) {
|
|
121261
121348
|
prevSelectedRef.current = selectedFile;
|
|
121262
121349
|
return;
|
|
@@ -121283,7 +121370,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121283
121370
|
fetchDir(dir);
|
|
121284
121371
|
}
|
|
121285
121372
|
}, [selectedFile, workspaceId, fetchDir]);
|
|
121286
|
-
(0,
|
|
121373
|
+
(0, import_react32.useEffect)(() => {
|
|
121287
121374
|
if (selectedFile && selectedRef.current) {
|
|
121288
121375
|
const timer = setTimeout(() => {
|
|
121289
121376
|
selectedRef.current?.scrollIntoView({ block: "nearest" });
|
|
@@ -121291,7 +121378,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121291
121378
|
return () => clearTimeout(timer);
|
|
121292
121379
|
}
|
|
121293
121380
|
}, [selectedFile, dirContents]);
|
|
121294
|
-
const toggleExpand = (0,
|
|
121381
|
+
const toggleExpand = (0, import_react32.useCallback)(
|
|
121295
121382
|
(dirPath) => {
|
|
121296
121383
|
setExpandedPaths((prev) => {
|
|
121297
121384
|
const next = new Set(prev);
|
|
@@ -121307,7 +121394,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121307
121394
|
},
|
|
121308
121395
|
[workspaceId, fetchDir]
|
|
121309
121396
|
);
|
|
121310
|
-
const ensureDirExpanded = (0,
|
|
121397
|
+
const ensureDirExpanded = (0, import_react32.useCallback)(
|
|
121311
121398
|
async (dirPath) => {
|
|
121312
121399
|
const cached2 = getCachedExpanded(workspaceId);
|
|
121313
121400
|
if (!cached2.has(dirPath)) {
|
|
@@ -121319,17 +121406,17 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121319
121406
|
},
|
|
121320
121407
|
[workspaceId, fetchDir]
|
|
121321
121408
|
);
|
|
121322
|
-
const requestNewEntry = (0,
|
|
121409
|
+
const requestNewEntry = (0, import_react32.useCallback)(
|
|
121323
121410
|
(parentPath, kind) => {
|
|
121324
121411
|
void ensureDirExpanded(parentPath);
|
|
121325
121412
|
setNewEntry({ parentPath, kind });
|
|
121326
121413
|
},
|
|
121327
121414
|
[ensureDirExpanded]
|
|
121328
121415
|
);
|
|
121329
|
-
const cancelNewEntry = (0,
|
|
121416
|
+
const cancelNewEntry = (0, import_react32.useCallback)(() => {
|
|
121330
121417
|
setNewEntry(null);
|
|
121331
121418
|
}, []);
|
|
121332
|
-
const submitNewEntry = (0,
|
|
121419
|
+
const submitNewEntry = (0, import_react32.useCallback)(
|
|
121333
121420
|
async (name24) => {
|
|
121334
121421
|
if (!newEntry) return;
|
|
121335
121422
|
const fullPath = newEntry.parentPath ? `${newEntry.parentPath}/${name24}` : name24;
|
|
@@ -121362,16 +121449,16 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121362
121449
|
[adapter, newEntry, fetchDir, onOpenFile, workspaceId]
|
|
121363
121450
|
);
|
|
121364
121451
|
const canDelete = Boolean(adapter.deleteWorkspacePath);
|
|
121365
|
-
const requestDelete = (0,
|
|
121452
|
+
const requestDelete = (0, import_react32.useCallback)((path3, kind) => {
|
|
121366
121453
|
setDeleteError(null);
|
|
121367
121454
|
setPendingDelete({ path: path3, kind });
|
|
121368
121455
|
}, []);
|
|
121369
|
-
const cancelDelete = (0,
|
|
121456
|
+
const cancelDelete = (0, import_react32.useCallback)(() => {
|
|
121370
121457
|
if (deleteSubmitting) return;
|
|
121371
121458
|
setPendingDelete(null);
|
|
121372
121459
|
setDeleteError(null);
|
|
121373
121460
|
}, [deleteSubmitting]);
|
|
121374
|
-
const confirmDelete = (0,
|
|
121461
|
+
const confirmDelete = (0, import_react32.useCallback)(async () => {
|
|
121375
121462
|
if (!pendingDelete || !adapter.deleteWorkspacePath) return;
|
|
121376
121463
|
setDeleteSubmitting(true);
|
|
121377
121464
|
setDeleteError(null);
|
|
@@ -121417,13 +121504,13 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121417
121504
|
}
|
|
121418
121505
|
}, [adapter, pendingDelete, fetchDir, workspaceId, onPathDeleted]);
|
|
121419
121506
|
const canRename = Boolean(adapter.renameWorkspacePath);
|
|
121420
|
-
const requestRename = (0,
|
|
121507
|
+
const requestRename = (0, import_react32.useCallback)((path3) => {
|
|
121421
121508
|
setRenamingPath(path3);
|
|
121422
121509
|
}, []);
|
|
121423
|
-
const cancelRename = (0,
|
|
121510
|
+
const cancelRename = (0, import_react32.useCallback)(() => {
|
|
121424
121511
|
setRenamingPath(null);
|
|
121425
121512
|
}, []);
|
|
121426
|
-
const submitRename = (0,
|
|
121513
|
+
const submitRename = (0, import_react32.useCallback)(
|
|
121427
121514
|
async (newName) => {
|
|
121428
121515
|
if (renamingPath == null || !adapter.renameWorkspacePath) return;
|
|
121429
121516
|
const oldPath = renamingPath;
|
|
@@ -121479,7 +121566,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121479
121566
|
},
|
|
121480
121567
|
[adapter, renamingPath, fetchDir, onPathRenamed, workspaceId]
|
|
121481
121568
|
);
|
|
121482
|
-
const resolveDefaultTarget = (0,
|
|
121569
|
+
const resolveDefaultTarget = (0, import_react32.useCallback)(() => {
|
|
121483
121570
|
if (treeSelection?.kind === "directory") return treeSelection.path;
|
|
121484
121571
|
if (treeSelection?.kind === "file") {
|
|
121485
121572
|
const idx = treeSelection.path.lastIndexOf("/");
|
|
@@ -121492,13 +121579,13 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121492
121579
|
const canPaste = Boolean(
|
|
121493
121580
|
clipboard && (clipboard.op === "copy" && adapter.copyWorkspacePath || clipboard.op === "cut" && adapter.renameWorkspacePath)
|
|
121494
121581
|
);
|
|
121495
|
-
const cutPath = (0,
|
|
121582
|
+
const cutPath = (0, import_react32.useCallback)((path3, kind) => {
|
|
121496
121583
|
setClipboard({ path: path3, kind, op: "cut" });
|
|
121497
121584
|
}, []);
|
|
121498
|
-
const copyPath = (0,
|
|
121585
|
+
const copyPath = (0, import_react32.useCallback)((path3, kind) => {
|
|
121499
121586
|
setClipboard({ path: path3, kind, op: "copy" });
|
|
121500
121587
|
}, []);
|
|
121501
|
-
const uniqueCopyName = (0,
|
|
121588
|
+
const uniqueCopyName = (0, import_react32.useCallback)(
|
|
121502
121589
|
(baseName, destFolder, kind) => {
|
|
121503
121590
|
const siblings = new Set(
|
|
121504
121591
|
(getCachedContents(workspaceId).get(destFolder) ?? []).map((e2) => e2.name)
|
|
@@ -121516,7 +121603,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121516
121603
|
},
|
|
121517
121604
|
[workspaceId]
|
|
121518
121605
|
);
|
|
121519
|
-
const pasteInto = (0,
|
|
121606
|
+
const pasteInto = (0, import_react32.useCallback)(
|
|
121520
121607
|
async (destFolder) => {
|
|
121521
121608
|
if (!clipboard) return;
|
|
121522
121609
|
const sourcePath = clipboard.path;
|
|
@@ -121580,7 +121667,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121580
121667
|
},
|
|
121581
121668
|
[adapter, clipboard, fetchDir, onPathRenamed, uniqueCopyName, workspaceId]
|
|
121582
121669
|
);
|
|
121583
|
-
(0,
|
|
121670
|
+
(0, import_react32.useImperativeHandle)(
|
|
121584
121671
|
handleRef,
|
|
121585
121672
|
() => ({
|
|
121586
121673
|
startNewFile(parentPath) {
|
|
@@ -121594,7 +121681,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121594
121681
|
);
|
|
121595
121682
|
const rootMenu = useDeferredMenuAction();
|
|
121596
121683
|
if (!adapter.listWorkspaceFiles) {
|
|
121597
|
-
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" });
|
|
121598
121685
|
}
|
|
121599
121686
|
const rootEntries = dirContents.get("") ?? [];
|
|
121600
121687
|
const rootLoading = loadingPaths.has("");
|
|
@@ -121631,20 +121718,20 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121631
121718
|
void pasteInto(resolveDefaultTarget());
|
|
121632
121719
|
}
|
|
121633
121720
|
};
|
|
121634
|
-
return /* @__PURE__ */ (0,
|
|
121635
|
-
/* @__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)(
|
|
121636
121723
|
ContextMenu2,
|
|
121637
121724
|
{
|
|
121638
121725
|
onOpenChange: (open3) => {
|
|
121639
121726
|
if (open3) clearTreeSelection();
|
|
121640
121727
|
},
|
|
121641
121728
|
children: [
|
|
121642
|
-
/* @__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: [
|
|
121643
121730
|
(() => {
|
|
121644
121731
|
const rootSplitIdx = rootEntries.findIndex((e2) => e2.type === "file");
|
|
121645
121732
|
const rootFolders = rootSplitIdx === -1 ? rootEntries : rootEntries.slice(0, rootSplitIdx);
|
|
121646
121733
|
const rootFiles = rootSplitIdx === -1 ? [] : rootEntries.slice(rootSplitIdx);
|
|
121647
|
-
const renderRow = (entry) => /* @__PURE__ */ (0,
|
|
121734
|
+
const renderRow = (entry) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121648
121735
|
TreeNode2,
|
|
121649
121736
|
{
|
|
121650
121737
|
entry,
|
|
@@ -121681,7 +121768,7 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121681
121768
|
},
|
|
121682
121769
|
entry.name
|
|
121683
121770
|
);
|
|
121684
|
-
const rootInput = showRootInput ? /* @__PURE__ */ (0,
|
|
121771
|
+
const rootInput = showRootInput ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121685
121772
|
EntryNameInput,
|
|
121686
121773
|
{
|
|
121687
121774
|
kind: newEntry.kind,
|
|
@@ -121693,30 +121780,30 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121693
121780
|
},
|
|
121694
121781
|
`new-${newEntry.kind}-root`
|
|
121695
121782
|
) : null;
|
|
121696
|
-
return /* @__PURE__ */ (0,
|
|
121783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
|
|
121697
121784
|
showRootInput && newEntry.kind === "directory" && rootInput,
|
|
121698
|
-
rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0,
|
|
121699
|
-
!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" }),
|
|
121700
121787
|
rootFolders.map(renderRow),
|
|
121701
121788
|
showRootInput && newEntry.kind === "file" && rootInput,
|
|
121702
121789
|
rootFiles.map(renderRow)
|
|
121703
121790
|
] });
|
|
121704
121791
|
})(),
|
|
121705
|
-
/* @__PURE__ */ (0,
|
|
121792
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "min-h-[40px] flex-1" })
|
|
121706
121793
|
] }) }),
|
|
121707
|
-
/* @__PURE__ */ (0,
|
|
121708
|
-
/* @__PURE__ */ (0,
|
|
121709
|
-
/* @__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" }),
|
|
121710
121797
|
"New File"
|
|
121711
121798
|
] }),
|
|
121712
|
-
/* @__PURE__ */ (0,
|
|
121713
|
-
/* @__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" }),
|
|
121714
121801
|
"New Folder"
|
|
121715
121802
|
] }),
|
|
121716
|
-
canPaste && /* @__PURE__ */ (0,
|
|
121717
|
-
/* @__PURE__ */ (0,
|
|
121718
|
-
/* @__PURE__ */ (0,
|
|
121719
|
-
/* @__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" }),
|
|
121720
121807
|
"Paste"
|
|
121721
121808
|
] })
|
|
121722
121809
|
] })
|
|
@@ -121724,42 +121811,42 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121724
121811
|
]
|
|
121725
121812
|
}
|
|
121726
121813
|
),
|
|
121727
|
-
/* @__PURE__ */ (0,
|
|
121814
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
121728
121815
|
Dialog2,
|
|
121729
121816
|
{
|
|
121730
121817
|
open: pendingDelete !== null,
|
|
121731
121818
|
onOpenChange: (open3) => {
|
|
121732
121819
|
if (!open3) cancelDelete();
|
|
121733
121820
|
},
|
|
121734
|
-
children: /* @__PURE__ */ (0,
|
|
121735
|
-
/* @__PURE__ */ (0,
|
|
121736
|
-
/* @__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: [
|
|
121737
121824
|
"Delete ",
|
|
121738
121825
|
pendingDelete?.kind === "directory" ? "folder" : "file"
|
|
121739
121826
|
] }),
|
|
121740
|
-
/* @__PURE__ */ (0,
|
|
121827
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(DialogDescription2, { children: [
|
|
121741
121828
|
"Are you sure you want to delete ",
|
|
121742
|
-
/* @__PURE__ */ (0,
|
|
121829
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("strong", { children: pendingDelete?.path }),
|
|
121743
121830
|
"?"
|
|
121744
121831
|
] })
|
|
121745
121832
|
] }),
|
|
121746
|
-
/* @__PURE__ */ (0,
|
|
121747
|
-
pendingDelete?.kind === "directory" && /* @__PURE__ */ (0,
|
|
121748
|
-
/* @__PURE__ */ (0,
|
|
121749
|
-
/* @__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." })
|
|
121750
121837
|
] }),
|
|
121751
|
-
pendingDelete?.kind === "file" && /* @__PURE__ */ (0,
|
|
121752
|
-
/* @__PURE__ */ (0,
|
|
121753
|
-
/* @__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." })
|
|
121754
121841
|
] }),
|
|
121755
|
-
deleteError && /* @__PURE__ */ (0,
|
|
121756
|
-
/* @__PURE__ */ (0,
|
|
121757
|
-
/* @__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 })
|
|
121758
121845
|
] })
|
|
121759
121846
|
] }),
|
|
121760
|
-
/* @__PURE__ */ (0,
|
|
121761
|
-
/* @__PURE__ */ (0,
|
|
121762
|
-
/* @__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)(
|
|
121763
121850
|
Button,
|
|
121764
121851
|
{
|
|
121765
121852
|
variant: "destructive",
|
|
@@ -121776,35 +121863,39 @@ var FileBrowser = (0, import_react31.forwardRef)(function FileBrowser2({
|
|
|
121776
121863
|
});
|
|
121777
121864
|
|
|
121778
121865
|
// ../../packages/dashboard-core/src/components/FileViewer.tsx
|
|
121779
|
-
var
|
|
121866
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
121780
121867
|
|
|
121781
121868
|
// ../../packages/dashboard-core/src/components/ImagePreview.tsx
|
|
121782
|
-
var
|
|
121783
|
-
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
121784
|
-
|
|
121785
|
-
// ../../packages/dashboard-core/src/components/PdfPreview.tsx
|
|
121869
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
121786
121870
|
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
121787
121871
|
|
|
121788
|
-
// ../../packages/dashboard-core/src/components/
|
|
121872
|
+
// ../../packages/dashboard-core/src/components/LanguagePickerDialog.tsx
|
|
121873
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
121789
121874
|
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
121790
121875
|
|
|
121791
|
-
// ../../packages/dashboard-core/src/components/
|
|
121792
|
-
var import_react34 = __toESM(require_react(), 1);
|
|
121876
|
+
// ../../packages/dashboard-core/src/components/PdfPreview.tsx
|
|
121793
121877
|
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
|
|
121794
121878
|
|
|
121795
|
-
// ../../packages/dashboard-core/src/components/
|
|
121796
|
-
var import_react35 = __toESM(require_react(), 1);
|
|
121879
|
+
// ../../packages/dashboard-core/src/components/FileViewer.tsx
|
|
121797
121880
|
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
121798
121881
|
|
|
121799
|
-
// ../../packages/dashboard-core/src/components/
|
|
121882
|
+
// ../../packages/dashboard-core/src/components/QuickOpenDialog.tsx
|
|
121800
121883
|
var import_react36 = __toESM(require_react(), 1);
|
|
121801
121884
|
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
|
|
121802
121885
|
|
|
121803
|
-
// ../../packages/dashboard-core/src/components/
|
|
121886
|
+
// ../../packages/dashboard-core/src/components/SearchFilesDialog.tsx
|
|
121887
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
121804
121888
|
var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
|
|
121805
121889
|
|
|
121890
|
+
// ../../packages/dashboard-core/src/components/WorkspacePickerDialog.tsx
|
|
121891
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
121892
|
+
var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
|
|
121893
|
+
|
|
121894
|
+
// ../../packages/dashboard-core/src/components/WorkspaceTabNav.tsx
|
|
121895
|
+
var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
|
|
121896
|
+
|
|
121806
121897
|
// ../../packages/dashboard-core/src/hooks/use-editor-history.ts
|
|
121807
|
-
var
|
|
121898
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
121808
121899
|
|
|
121809
121900
|
// ../../node_modules/.pnpm/marked@15.0.12/node_modules/marked/lib/marked.esm.js
|
|
121810
121901
|
function _getDefaults() {
|
|
@@ -125884,6 +125975,7 @@ function getTableAsAliasSQL(table) {
|
|
|
125884
125975
|
}
|
|
125885
125976
|
|
|
125886
125977
|
// src/lib/db/connection.ts
|
|
125978
|
+
init_src();
|
|
125887
125979
|
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
125888
125980
|
import { join as join10 } from "node:path";
|
|
125889
125981
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
@@ -131634,7 +131726,12 @@ var projects = sqliteTable("projects", {
|
|
|
131634
131726
|
path: text3("path").notNull(),
|
|
131635
131727
|
defaultBranch: text3("default_branch").notNull(),
|
|
131636
131728
|
label: text3("label"),
|
|
131637
|
-
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")
|
|
131638
131735
|
});
|
|
131639
131736
|
var worktrees = sqliteTable("worktrees", {
|
|
131640
131737
|
id: integer3("id").primaryKey({ autoIncrement: true }),
|
|
@@ -131700,6 +131797,7 @@ var browserHistory = sqliteTable(
|
|
|
131700
131797
|
);
|
|
131701
131798
|
|
|
131702
131799
|
// src/lib/db/connection.ts
|
|
131800
|
+
var log7 = createLogger("db");
|
|
131703
131801
|
var migrationsFolder = join10(import.meta.dirname, "migrations");
|
|
131704
131802
|
var _db = null;
|
|
131705
131803
|
var _sqlite = null;
|
|
@@ -131717,6 +131815,14 @@ function getDb() {
|
|
|
131717
131815
|
}
|
|
131718
131816
|
function closeDb() {
|
|
131719
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
|
+
}
|
|
131720
131826
|
_sqlite.close();
|
|
131721
131827
|
_sqlite = null;
|
|
131722
131828
|
_db = null;
|
|
@@ -131724,6 +131830,16 @@ function closeDb() {
|
|
|
131724
131830
|
}
|
|
131725
131831
|
|
|
131726
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
|
+
}
|
|
131727
131843
|
function bandHome() {
|
|
131728
131844
|
if (process.env.BAND_HOME) return process.env.BAND_HOME;
|
|
131729
131845
|
return join11(homedir6(), ".band");
|
|
@@ -131749,6 +131865,7 @@ function loadState() {
|
|
|
131749
131865
|
path: row.path,
|
|
131750
131866
|
defaultBranch: row.defaultBranch,
|
|
131751
131867
|
label: row.label ?? void 0,
|
|
131868
|
+
kind: row.kind ?? "git",
|
|
131752
131869
|
worktrees: wtByProject.get(row.name) ?? []
|
|
131753
131870
|
}))
|
|
131754
131871
|
};
|
|
@@ -131765,7 +131882,8 @@ function saveState(state2) {
|
|
|
131765
131882
|
path: project.path,
|
|
131766
131883
|
defaultBranch: project.defaultBranch,
|
|
131767
131884
|
label: project.label ?? null,
|
|
131768
|
-
sortOrder: i2
|
|
131885
|
+
sortOrder: i2,
|
|
131886
|
+
kind: project.kind
|
|
131769
131887
|
}).run();
|
|
131770
131888
|
for (const wt of project.worktrees) {
|
|
131771
131889
|
tx.insert(worktrees).values({
|
|
@@ -131924,7 +132042,7 @@ function deleteBranchStatus(workspaceId) {
|
|
|
131924
132042
|
}
|
|
131925
132043
|
|
|
131926
132044
|
// src/lib/agent-pool.ts
|
|
131927
|
-
var
|
|
132045
|
+
var log8 = createLogger("agent-pool");
|
|
131928
132046
|
var POOL_KEY = Symbol.for("band.agent-pool.v2");
|
|
131929
132047
|
var PENDING_KEY = Symbol.for("band.agent-pool.pending");
|
|
131930
132048
|
var g2 = globalThis;
|
|
@@ -131969,7 +132087,7 @@ function getAgent(chatId) {
|
|
|
131969
132087
|
return pool.get(chatId)?.agent;
|
|
131970
132088
|
}
|
|
131971
132089
|
function removeAgent(chatId) {
|
|
131972
|
-
|
|
132090
|
+
log8.info({ chatId }, "removing agent from pool");
|
|
131973
132091
|
return pool.delete(chatId);
|
|
131974
132092
|
}
|
|
131975
132093
|
async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
@@ -131977,7 +132095,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
|
131977
132095
|
if (existing) {
|
|
131978
132096
|
const requestedDefId = resolveAgentDefId(agentId);
|
|
131979
132097
|
if (existing.agentDefId !== requestedDefId) {
|
|
131980
|
-
|
|
132098
|
+
log8.info(
|
|
131981
132099
|
{ chatId, cached: existing.agentDefId, requested: requestedDefId },
|
|
131982
132100
|
"cached agent definition mismatch, replacing"
|
|
131983
132101
|
);
|
|
@@ -131991,7 +132109,7 @@ async function getOrCreateAgent(chatId, worktreePath, agentId) {
|
|
|
131991
132109
|
return inFlight.promise;
|
|
131992
132110
|
}
|
|
131993
132111
|
const config2 = getAgentConfig(worktreePath, agentId);
|
|
131994
|
-
|
|
132112
|
+
log8.info({ chatId, type: config2.type, defId, cwd: worktreePath }, "creating agent");
|
|
131995
132113
|
const promise2 = createCodingAgent(config2).then(
|
|
131996
132114
|
(agent) => {
|
|
131997
132115
|
pool.set(chatId, { agent, agentDefId: defId });
|
|
@@ -132054,6 +132172,18 @@ function listPanelStatesForWorkspace(workspaceId, panelType) {
|
|
|
132054
132172
|
const db2 = getDb();
|
|
132055
132173
|
return db2.select().from(panelStates).where(and(eq2(panelStates.workspaceId, workspaceId), eq2(panelStates.panelType, panelType))).all();
|
|
132056
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
|
+
}
|
|
132057
132187
|
|
|
132058
132188
|
// src/lib/dockview-layout-manager.ts
|
|
132059
132189
|
function isLeaf(node) {
|
|
@@ -132526,6 +132656,7 @@ function parseBatchedCIResponse(data, aliases, defaultBranches) {
|
|
|
132526
132656
|
}
|
|
132527
132657
|
|
|
132528
132658
|
// src/lib/sync-state.ts
|
|
132659
|
+
var PROJECT_SYNC_BATCH_SIZE = 8;
|
|
132529
132660
|
async function detectRemoteDefaultBranch(projectPath) {
|
|
132530
132661
|
try {
|
|
132531
132662
|
const ref = (await execGit(["symbolic-ref", "refs/remotes/origin/HEAD"], projectPath)).trim();
|
|
@@ -132550,35 +132681,50 @@ async function syncWorktrees() {
|
|
|
132550
132681
|
const state2 = loadState();
|
|
132551
132682
|
let changed = false;
|
|
132552
132683
|
for (const project of state2.projects) {
|
|
132553
|
-
|
|
132554
|
-
try {
|
|
132555
|
-
const gitWorktrees = await listWorktrees(project.path);
|
|
132556
|
-
const pinnedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt.pinned]));
|
|
132557
|
-
diskWorktrees = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({
|
|
132558
|
-
branch: wt.branch,
|
|
132559
|
-
path: wt.path,
|
|
132560
|
-
head: wt.head,
|
|
132561
|
-
pinned: pinnedByBranch.get(wt.branch) ?? false
|
|
132562
|
-
}));
|
|
132563
|
-
} catch {
|
|
132564
|
-
continue;
|
|
132565
|
-
}
|
|
132566
|
-
const existingSet = new Set(project.worktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132567
|
-
const diskSet = new Set(diskWorktrees.map((wt) => `${wt.branch}\0${wt.path}`));
|
|
132568
|
-
if (existingSet.size !== diskSet.size || Array.from(existingSet).some((key) => !diskSet.has(key))) {
|
|
132569
|
-
project.worktrees = diskWorktrees;
|
|
132684
|
+
if (reconcileKindForProject(project)) {
|
|
132570
132685
|
changed = true;
|
|
132571
132686
|
}
|
|
132572
|
-
|
|
132573
|
-
|
|
132574
|
-
|
|
132575
|
-
|
|
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;
|
|
132576
132694
|
}
|
|
132577
132695
|
}
|
|
132578
132696
|
if (changed) {
|
|
132579
132697
|
saveState(state2);
|
|
132580
132698
|
}
|
|
132581
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
|
+
}
|
|
132582
132728
|
|
|
132583
132729
|
// src/lib/branch-status-poller.ts
|
|
132584
132730
|
var INTERVALS = {
|
|
@@ -132597,6 +132743,7 @@ function getWorkspaces() {
|
|
|
132597
132743
|
const state2 = loadState();
|
|
132598
132744
|
const workspaces = [];
|
|
132599
132745
|
for (const project of state2.projects) {
|
|
132746
|
+
if (project.kind === "plain") continue;
|
|
132600
132747
|
for (const wt of project.worktrees) {
|
|
132601
132748
|
workspaces.push({
|
|
132602
132749
|
workspaceId: toWorkspaceId(project.name, wt.branch),
|
|
@@ -132840,12 +132987,12 @@ function getPollerActivity() {
|
|
|
132840
132987
|
import { spawn as spawn5 } from "node:child_process";
|
|
132841
132988
|
|
|
132842
132989
|
// src/lib/project-config.ts
|
|
132843
|
-
import { existsSync as
|
|
132990
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "node:fs";
|
|
132844
132991
|
import { join as join14 } from "node:path";
|
|
132845
132992
|
function loadProjectConfig(worktreePath, projectPath) {
|
|
132846
132993
|
for (const base2 of [worktreePath, projectPath]) {
|
|
132847
132994
|
const configPath = join14(base2, ".band", "config.json");
|
|
132848
|
-
if (
|
|
132995
|
+
if (existsSync5(configPath)) {
|
|
132849
132996
|
try {
|
|
132850
132997
|
return JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
132851
132998
|
} catch {
|
|
@@ -132964,7 +133111,7 @@ function subscribe(listener) {
|
|
|
132964
133111
|
}
|
|
132965
133112
|
|
|
132966
133113
|
// src/lib/chat-manager.ts
|
|
132967
|
-
var
|
|
133114
|
+
var log9 = createLogger("chat-manager");
|
|
132968
133115
|
var PANEL_TYPE = "chat";
|
|
132969
133116
|
var chatSessions = /* @__PURE__ */ new Map();
|
|
132970
133117
|
var workspaceChats = /* @__PURE__ */ new Map();
|
|
@@ -133035,7 +133182,7 @@ function createChat(workspaceId, options2) {
|
|
|
133035
133182
|
addToIndex(session);
|
|
133036
133183
|
addChatToLayout(workspaceId, session.id, { title: session.name });
|
|
133037
133184
|
emit({ kind: "chat-created", workspaceId, chatId: session.id });
|
|
133038
|
-
|
|
133185
|
+
log9.info({ chatId: session.id, workspaceId, agent: session.agent }, "chat pane created");
|
|
133039
133186
|
return session;
|
|
133040
133187
|
}
|
|
133041
133188
|
function getChat(chatId) {
|
|
@@ -133064,7 +133211,7 @@ function updateChat(chatId, updates) {
|
|
|
133064
133211
|
state: serializeState(session),
|
|
133065
133212
|
updatedAt: Date.now()
|
|
133066
133213
|
});
|
|
133067
|
-
|
|
133214
|
+
log9.info({ chatId, updates }, "chat pane updated");
|
|
133068
133215
|
return session;
|
|
133069
133216
|
}
|
|
133070
133217
|
function updateChatStatus(chatId, status) {
|
|
@@ -133116,7 +133263,7 @@ function removeChat(chatId) {
|
|
|
133116
133263
|
removeChatFromLayout(session.workspaceId, chatId);
|
|
133117
133264
|
removeFromIndex(chatId);
|
|
133118
133265
|
emit({ kind: "chat-removed", workspaceId: session.workspaceId, chatId });
|
|
133119
|
-
|
|
133266
|
+
log9.info({ chatId, workspaceId: session.workspaceId }, "chat pane removed");
|
|
133120
133267
|
return true;
|
|
133121
133268
|
}
|
|
133122
133269
|
function removeWorkspaceChats(workspaceId) {
|
|
@@ -133128,19 +133275,15 @@ function removeWorkspaceChats(workspaceId) {
|
|
|
133128
133275
|
}
|
|
133129
133276
|
deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE);
|
|
133130
133277
|
workspaceChats.delete(workspaceId);
|
|
133131
|
-
|
|
133278
|
+
log9.info({ workspaceId }, "all chat panes removed for workspace");
|
|
133132
133279
|
}
|
|
133133
133280
|
function loadChatsFromDb() {
|
|
133134
133281
|
_initialized = true;
|
|
133135
|
-
const rows = listPanelStates(PANEL_TYPE);
|
|
133136
133282
|
const now = Date.now();
|
|
133283
|
+
resetPanelStatesToIdle(PANEL_TYPE, now);
|
|
133284
|
+
const rows = listPanelStates(PANEL_TYPE);
|
|
133137
133285
|
for (const row of rows) {
|
|
133138
133286
|
const parsed = JSON.parse(row.state);
|
|
133139
|
-
parsed.status = "idle";
|
|
133140
|
-
updatePanelState(row.id, {
|
|
133141
|
-
state: JSON.stringify(parsed),
|
|
133142
|
-
updatedAt: now
|
|
133143
|
-
});
|
|
133144
133287
|
const session = {
|
|
133145
133288
|
id: row.id,
|
|
133146
133289
|
workspaceId: row.workspaceId,
|
|
@@ -133151,12 +133294,16 @@ function loadChatsFromDb() {
|
|
|
133151
133294
|
activeSessionId: parsed.activeSessionId ?? void 0,
|
|
133152
133295
|
activeSessionSummary: parsed.activeSessionSummary ?? void 0,
|
|
133153
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.
|
|
133154
133301
|
status: "idle"
|
|
133155
133302
|
};
|
|
133156
133303
|
addToIndex(session);
|
|
133157
133304
|
}
|
|
133158
133305
|
if (rows.length > 0) {
|
|
133159
|
-
|
|
133306
|
+
log9.info({ count: rows.length }, "loaded chat panes from database");
|
|
133160
133307
|
}
|
|
133161
133308
|
return rows.length;
|
|
133162
133309
|
}
|
|
@@ -133336,7 +133483,7 @@ function hasPendingInputForWorkspace(workspaceId) {
|
|
|
133336
133483
|
|
|
133337
133484
|
// src/lib/task-store.ts
|
|
133338
133485
|
init_src();
|
|
133339
|
-
var
|
|
133486
|
+
var log10 = createLogger("task-store");
|
|
133340
133487
|
function generateTaskId() {
|
|
133341
133488
|
return `tsk_${Date.now()}`;
|
|
133342
133489
|
}
|
|
@@ -133409,7 +133556,7 @@ function cleanupStaleTasks() {
|
|
|
133409
133556
|
const result = db2.update(tasks).set({ status: "failed", completedAt: now }).where(eq2(tasks.status, "running")).run();
|
|
133410
133557
|
const count3 = result.changes;
|
|
133411
133558
|
if (count3 > 0) {
|
|
133412
|
-
|
|
133559
|
+
log10.info({ count: count3 }, "cleaned up stale tasks on startup");
|
|
133413
133560
|
}
|
|
133414
133561
|
return count3;
|
|
133415
133562
|
}
|
|
@@ -133446,7 +133593,7 @@ function pruneOldTasks(retentionMs = TASK_RETENTION_MS) {
|
|
|
133446
133593
|
const cutoff = Date.now() - retentionMs;
|
|
133447
133594
|
const count3 = deleteTasksOlderThan(cutoff);
|
|
133448
133595
|
if (count3 > 0) {
|
|
133449
|
-
|
|
133596
|
+
log10.info({ count: count3, retentionMs }, "pruned tasks older than retention window");
|
|
133450
133597
|
}
|
|
133451
133598
|
return count3;
|
|
133452
133599
|
}
|
|
@@ -133457,13 +133604,13 @@ function startTaskPruneScheduler(options2 = {}) {
|
|
|
133457
133604
|
try {
|
|
133458
133605
|
pruneOldTasks(retentionMs);
|
|
133459
133606
|
} catch (err) {
|
|
133460
|
-
|
|
133607
|
+
log10.error({ err }, "initial task prune on boot failed");
|
|
133461
133608
|
}
|
|
133462
133609
|
const timer = setInterval(() => {
|
|
133463
133610
|
try {
|
|
133464
133611
|
pruneOldTasks(retentionMs);
|
|
133465
133612
|
} catch (err) {
|
|
133466
|
-
|
|
133613
|
+
log10.error({ err }, "scheduled task prune failed");
|
|
133467
133614
|
}
|
|
133468
133615
|
}, intervalMs);
|
|
133469
133616
|
timer.unref();
|
|
@@ -133550,7 +133697,7 @@ function resolveWorkspace(workspaceId) {
|
|
|
133550
133697
|
}
|
|
133551
133698
|
|
|
133552
133699
|
// src/lib/task-runner.ts
|
|
133553
|
-
var
|
|
133700
|
+
var log11 = createLogger("task-runner");
|
|
133554
133701
|
function listFiles(dir) {
|
|
133555
133702
|
try {
|
|
133556
133703
|
return new Set(readdirSync6(dir));
|
|
@@ -133609,7 +133756,7 @@ function persistTask(task) {
|
|
|
133609
133756
|
chatId: task.chatId
|
|
133610
133757
|
});
|
|
133611
133758
|
} catch (err) {
|
|
133612
|
-
|
|
133759
|
+
log11.warn({ err, taskId: task.taskRecordId }, "failed to persist task");
|
|
133613
133760
|
}
|
|
133614
133761
|
}
|
|
133615
133762
|
function broadcast(chatId, chunk) {
|
|
@@ -133633,7 +133780,7 @@ function broadcast(chatId, chunk) {
|
|
|
133633
133780
|
}
|
|
133634
133781
|
const subs = listeners2.get(chatId);
|
|
133635
133782
|
if (!subs || subs.size === 0) {
|
|
133636
|
-
|
|
133783
|
+
log11.warn({ chatId, chunkType: chunk.type }, "broadcast: no listeners");
|
|
133637
133784
|
return;
|
|
133638
133785
|
}
|
|
133639
133786
|
for (const listener of subs) {
|
|
@@ -133684,7 +133831,7 @@ function submitTask(options2) {
|
|
|
133684
133831
|
tasks2.set(chatId, task);
|
|
133685
133832
|
persistTask(task);
|
|
133686
133833
|
runTask(chatId, task).catch((err) => {
|
|
133687
|
-
|
|
133834
|
+
log11.error({ chatId, err }, "task execution failed");
|
|
133688
133835
|
if (task.status === "running") {
|
|
133689
133836
|
task.status = "failed";
|
|
133690
133837
|
task.completedAt = Date.now();
|
|
@@ -133718,7 +133865,7 @@ function abortTask(chatId) {
|
|
|
133718
133865
|
updateChatStatus(chatId, "idle");
|
|
133719
133866
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
133720
133867
|
emit({ kind: "update", status: updated });
|
|
133721
|
-
|
|
133868
|
+
log11.info({ chatId }, "task aborted by user");
|
|
133722
133869
|
return true;
|
|
133723
133870
|
}
|
|
133724
133871
|
function cancelTask(taskId) {
|
|
@@ -133738,7 +133885,7 @@ function cancelTask(taskId) {
|
|
|
133738
133885
|
updateChatStatus(chatId, "idle");
|
|
133739
133886
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
133740
133887
|
emit({ kind: "update", status: updated });
|
|
133741
|
-
|
|
133888
|
+
log11.info({ chatId, taskId }, "task cancelled (was running in-memory)");
|
|
133742
133889
|
return { cancelled: true, workspaceId: task.workspaceId };
|
|
133743
133890
|
}
|
|
133744
133891
|
}
|
|
@@ -133746,7 +133893,7 @@ function cancelTask(taskId) {
|
|
|
133746
133893
|
if (record2) {
|
|
133747
133894
|
const updated = upsertWorkspaceStatus(record2.workspaceId, { status: "waiting" });
|
|
133748
133895
|
emit({ kind: "update", status: updated });
|
|
133749
|
-
|
|
133896
|
+
log11.info({ taskId, workspaceId: record2.workspaceId }, "orphaned task cancelled");
|
|
133750
133897
|
return { cancelled: true, workspaceId: record2.workspaceId };
|
|
133751
133898
|
}
|
|
133752
133899
|
return { cancelled: false };
|
|
@@ -133766,7 +133913,7 @@ async function runTask(chatId, task) {
|
|
|
133766
133913
|
const taskAgentId = task.codingAgentId;
|
|
133767
133914
|
const resolvedAgentId = taskAgentId ?? chatSession?.agent;
|
|
133768
133915
|
const needsReplace = taskAgentId && taskAgentId !== chatSession?.agent;
|
|
133769
|
-
|
|
133916
|
+
log11.info(
|
|
133770
133917
|
{ chatId, taskAgentId, chatAgent: chatSession?.agent, resolvedAgentId, needsReplace },
|
|
133771
133918
|
"resolving agent for task"
|
|
133772
133919
|
);
|
|
@@ -133815,7 +133962,7 @@ async function runTask(chatId, task) {
|
|
|
133815
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.]`;
|
|
133816
133963
|
const effectivePrompt = task.sessionId ? task.agentPrompt : task.agentPrompt + fileSharingHint;
|
|
133817
133964
|
for await (const event of agent.runSession(effectivePrompt, task.sessionId, sessionOptions)) {
|
|
133818
|
-
|
|
133965
|
+
log11.info({ chatId, eventType: event.type }, "task event");
|
|
133819
133966
|
switch (event.type) {
|
|
133820
133967
|
case "session-start": {
|
|
133821
133968
|
task.sessionId = event.sessionId;
|
|
@@ -133996,7 +134143,7 @@ async function runTask(chatId, task) {
|
|
|
133996
134143
|
break;
|
|
133997
134144
|
}
|
|
133998
134145
|
case "session-id-resolved": {
|
|
133999
|
-
|
|
134146
|
+
log11.info(
|
|
134000
134147
|
{ chatId, previous: event.previousSessionId, resolved: event.resolvedSessionId },
|
|
134001
134148
|
"session ID resolved"
|
|
134002
134149
|
);
|
|
@@ -134091,7 +134238,7 @@ ${queued.text}`;
|
|
|
134091
134238
|
});
|
|
134092
134239
|
autoStarted = true;
|
|
134093
134240
|
} catch (err) {
|
|
134094
|
-
|
|
134241
|
+
log11.warn({ chatId, err }, "failed to auto-start queued task");
|
|
134095
134242
|
}
|
|
134096
134243
|
}
|
|
134097
134244
|
}
|
|
@@ -134191,7 +134338,7 @@ function getSessionEventsAfter(sessionId, afterEventId) {
|
|
|
134191
134338
|
}
|
|
134192
134339
|
|
|
134193
134340
|
// src/api/task-stream.ts
|
|
134194
|
-
var
|
|
134341
|
+
var log12 = createLogger("task-stream");
|
|
134195
134342
|
var INTERNAL_CHUNK_TYPES = /* @__PURE__ */ new Set(["user-message"]);
|
|
134196
134343
|
function toUIChunk(chunk) {
|
|
134197
134344
|
if (INTERNAL_CHUNK_TYPES.has(chunk.type)) return null;
|
|
@@ -134246,7 +134393,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
|
|
|
134246
134393
|
const buf = getSessionBuffer(task.sessionId);
|
|
134247
134394
|
if (buf && buf.events.length > 0) {
|
|
134248
134395
|
const taskStartEventId = task.firstEventId ?? Number.POSITIVE_INFINITY;
|
|
134249
|
-
|
|
134396
|
+
log12.info(
|
|
134250
134397
|
{
|
|
134251
134398
|
chatId,
|
|
134252
134399
|
sessionId: task.sessionId,
|
|
@@ -134270,7 +134417,7 @@ function streamTask(res, chatId, sessionId, afterEventId) {
|
|
|
134270
134417
|
}
|
|
134271
134418
|
}
|
|
134272
134419
|
if (queue.length === 0 && !caughtUp && (!task || task.status !== "running")) {
|
|
134273
|
-
|
|
134420
|
+
log12.warn(
|
|
134274
134421
|
{ chatId, taskStatus: task?.status, queueLen: queue.length },
|
|
134275
134422
|
"task-stream: no running task and no events \u2014 closing stream early"
|
|
134276
134423
|
);
|
|
@@ -134368,7 +134515,7 @@ ${prompt}`;
|
|
|
134368
134515
|
}
|
|
134369
134516
|
throw err;
|
|
134370
134517
|
}
|
|
134371
|
-
|
|
134518
|
+
log12.info({ chatId, workspaceId }, "task-stream: POST \u2014 task submitted, opening SSE stream");
|
|
134372
134519
|
streamTask(res, chatId, sessionId, void 0);
|
|
134373
134520
|
}
|
|
134374
134521
|
function handleGet(req, res, chatId) {
|
|
@@ -134382,13 +134529,13 @@ function handleGet(req, res, chatId) {
|
|
|
134382
134529
|
res.end();
|
|
134383
134530
|
return;
|
|
134384
134531
|
}
|
|
134385
|
-
|
|
134532
|
+
log12.info({ chatId, sessionId, afterEventId }, "task-stream: GET \u2014 reconnecting to active stream");
|
|
134386
134533
|
streamTask(res, chatId, sessionId ?? task.sessionId, afterEventId);
|
|
134387
134534
|
}
|
|
134388
134535
|
function handleTaskStream(req, res, chatId) {
|
|
134389
134536
|
if (req.method === "POST") {
|
|
134390
134537
|
handlePost(req, res, chatId).catch((err) => {
|
|
134391
|
-
|
|
134538
|
+
log12.error({ chatId, err }, "task-stream: POST handler error");
|
|
134392
134539
|
if (!res.headersSent) {
|
|
134393
134540
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
134394
134541
|
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
@@ -134433,7 +134580,7 @@ function removeBrowserFromLayout(workspaceId, browserId) {
|
|
|
134433
134580
|
}
|
|
134434
134581
|
|
|
134435
134582
|
// src/lib/browser-manager.ts
|
|
134436
|
-
var
|
|
134583
|
+
var log13 = createLogger("browser-manager");
|
|
134437
134584
|
var PANEL_TYPE2 = "browser";
|
|
134438
134585
|
var browserTabs = /* @__PURE__ */ new Map();
|
|
134439
134586
|
var workspaceBrowsers = /* @__PURE__ */ new Map();
|
|
@@ -134494,7 +134641,7 @@ function createBrowser(workspaceId, options2) {
|
|
|
134494
134641
|
title: tab.name,
|
|
134495
134642
|
initialUrl: tab.url || void 0
|
|
134496
134643
|
});
|
|
134497
|
-
|
|
134644
|
+
log13.info({ browserId: tab.id, workspaceId, url: tab.url }, "browser tab created");
|
|
134498
134645
|
return tab;
|
|
134499
134646
|
}
|
|
134500
134647
|
function getBrowser(browserId) {
|
|
@@ -134521,7 +134668,7 @@ function updateBrowser(browserId, updates) {
|
|
|
134521
134668
|
state: serializeState2(tab),
|
|
134522
134669
|
updatedAt: Date.now()
|
|
134523
134670
|
});
|
|
134524
|
-
|
|
134671
|
+
log13.info({ browserId, updates }, "browser tab updated");
|
|
134525
134672
|
return tab;
|
|
134526
134673
|
}
|
|
134527
134674
|
function updateBrowserUrl(browserId, url2) {
|
|
@@ -134538,7 +134685,7 @@ function removeBrowser(browserId) {
|
|
|
134538
134685
|
if (!tab) return false;
|
|
134539
134686
|
deletePanelState(browserId);
|
|
134540
134687
|
removeFromIndex2(browserId);
|
|
134541
|
-
|
|
134688
|
+
log13.info({ browserId, workspaceId: tab.workspaceId }, "browser tab removed");
|
|
134542
134689
|
return true;
|
|
134543
134690
|
}
|
|
134544
134691
|
function removeWorkspaceBrowsers(workspaceId) {
|
|
@@ -134549,19 +134696,15 @@ function removeWorkspaceBrowsers(workspaceId) {
|
|
|
134549
134696
|
}
|
|
134550
134697
|
deletePanelStatesForWorkspace(workspaceId, PANEL_TYPE2);
|
|
134551
134698
|
workspaceBrowsers.delete(workspaceId);
|
|
134552
|
-
|
|
134699
|
+
log13.info({ workspaceId }, "all browser tabs removed for workspace");
|
|
134553
134700
|
}
|
|
134554
134701
|
function loadBrowsersFromDb() {
|
|
134555
134702
|
_initialized2 = true;
|
|
134556
|
-
const rows = listPanelStates(PANEL_TYPE2);
|
|
134557
134703
|
const now = Date.now();
|
|
134704
|
+
resetPanelStatesToIdle(PANEL_TYPE2, now);
|
|
134705
|
+
const rows = listPanelStates(PANEL_TYPE2);
|
|
134558
134706
|
for (const row of rows) {
|
|
134559
134707
|
const parsed = JSON.parse(row.state);
|
|
134560
|
-
parsed.status = "idle";
|
|
134561
|
-
updatePanelState(row.id, {
|
|
134562
|
-
state: JSON.stringify(parsed),
|
|
134563
|
-
updatedAt: now
|
|
134564
|
-
});
|
|
134565
134708
|
const tab = {
|
|
134566
134709
|
id: row.id,
|
|
134567
134710
|
workspaceId: row.workspaceId,
|
|
@@ -134572,13 +134715,13 @@ function loadBrowsersFromDb() {
|
|
|
134572
134715
|
addToIndex2(tab);
|
|
134573
134716
|
}
|
|
134574
134717
|
if (rows.length > 0) {
|
|
134575
|
-
|
|
134718
|
+
log13.info({ count: rows.length }, "loaded browser tabs from database");
|
|
134576
134719
|
}
|
|
134577
134720
|
return rows.length;
|
|
134578
134721
|
}
|
|
134579
134722
|
|
|
134580
134723
|
// src/lib/browser-host.ts
|
|
134581
|
-
var
|
|
134724
|
+
var log14 = createLogger("browser-host");
|
|
134582
134725
|
var DESKTOP_CDP_HOST = "127.0.0.1";
|
|
134583
134726
|
var DESKTOP_CDP_PORT = 9223;
|
|
134584
134727
|
var globalAny = globalThis;
|
|
@@ -134629,7 +134772,7 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
134629
134772
|
reject: rejectFn,
|
|
134630
134773
|
timeoutId
|
|
134631
134774
|
});
|
|
134632
|
-
|
|
134775
|
+
log14.info(
|
|
134633
134776
|
"ensureCdpTargetId emitting ensureView for %s (url=%s, listeners=%d)",
|
|
134634
134777
|
bandTabId,
|
|
134635
134778
|
tab.url,
|
|
@@ -134643,13 +134786,13 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
134643
134786
|
url: tab.url
|
|
134644
134787
|
});
|
|
134645
134788
|
} catch (err) {
|
|
134646
|
-
|
|
134789
|
+
log14.warn("ensureView listener threw: %s", err instanceof Error ? err.message : err);
|
|
134647
134790
|
}
|
|
134648
134791
|
}
|
|
134649
134792
|
return promise2;
|
|
134650
134793
|
}
|
|
134651
134794
|
function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
134652
|
-
|
|
134795
|
+
log14.info("resolveTargetReady %s \u2192 %s", bandTabId, cdpTargetId);
|
|
134653
134796
|
targetIdByBandTabId.set(bandTabId, cdpTargetId);
|
|
134654
134797
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
134655
134798
|
if (pending2) {
|
|
@@ -134659,7 +134802,7 @@ function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
|
134659
134802
|
}
|
|
134660
134803
|
}
|
|
134661
134804
|
function markTargetDestroyed(bandTabId) {
|
|
134662
|
-
|
|
134805
|
+
log14.info("markTargetDestroyed %s", bandTabId);
|
|
134663
134806
|
targetIdByBandTabId.delete(bandTabId);
|
|
134664
134807
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
134665
134808
|
if (pending2) {
|
|
@@ -134670,10 +134813,10 @@ function markTargetDestroyed(bandTabId) {
|
|
|
134670
134813
|
}
|
|
134671
134814
|
function onEnsureView(listener) {
|
|
134672
134815
|
ensureListeners.add(listener);
|
|
134673
|
-
|
|
134816
|
+
log14.info("onEnsureView subscriber added (total=%d)", ensureListeners.size);
|
|
134674
134817
|
return () => {
|
|
134675
134818
|
ensureListeners.delete(listener);
|
|
134676
|
-
|
|
134819
|
+
log14.info("onEnsureView subscriber removed (total=%d)", ensureListeners.size);
|
|
134677
134820
|
if (ensureListeners.size === 0) {
|
|
134678
134821
|
for (const [bandTabId, pending2] of pendingEnsures) {
|
|
134679
134822
|
clearTimeout(pending2.timeoutId);
|
|
@@ -134690,7 +134833,7 @@ function isDesktopHostConnected() {
|
|
|
134690
134833
|
|
|
134691
134834
|
// src/lib/cdp-proxy.ts
|
|
134692
134835
|
init_src();
|
|
134693
|
-
var
|
|
134836
|
+
var log15 = createLogger("cdp-proxy");
|
|
134694
134837
|
async function handleCdpConnection(ws, req) {
|
|
134695
134838
|
const url2 = new URL(req.url ?? "", `http://${req.headers.host}`);
|
|
134696
134839
|
const bandTabId = url2.searchParams.get("bandTabId");
|
|
@@ -134713,17 +134856,17 @@ async function handleCdpConnection(ws, req) {
|
|
|
134713
134856
|
cdpTargetId = await ensureCdpTargetId(bandTabId);
|
|
134714
134857
|
} catch (err) {
|
|
134715
134858
|
const message = err instanceof Error ? err.message : String(err);
|
|
134716
|
-
|
|
134859
|
+
log15.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
|
|
134717
134860
|
if (ws.readyState === ws.OPEN) {
|
|
134718
134861
|
ws.close(4001, message.slice(0, 123));
|
|
134719
134862
|
}
|
|
134720
134863
|
return;
|
|
134721
134864
|
}
|
|
134722
134865
|
const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
|
|
134723
|
-
|
|
134866
|
+
log15.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
|
|
134724
134867
|
upstream = new wrapper_default(upstreamUrl);
|
|
134725
134868
|
upstream.on("open", () => {
|
|
134726
|
-
|
|
134869
|
+
log15.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
|
|
134727
134870
|
for (const msg of pending2) {
|
|
134728
134871
|
upstream?.send(msg);
|
|
134729
134872
|
}
|
|
@@ -134735,20 +134878,20 @@ async function handleCdpConnection(ws, req) {
|
|
|
134735
134878
|
}
|
|
134736
134879
|
});
|
|
134737
134880
|
upstream.on("error", (err) => {
|
|
134738
|
-
|
|
134881
|
+
log15.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
|
|
134739
134882
|
markTargetDestroyed(bandTabId);
|
|
134740
134883
|
if (ws.readyState === ws.OPEN) {
|
|
134741
134884
|
ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
|
|
134742
134885
|
}
|
|
134743
134886
|
});
|
|
134744
134887
|
upstream.on("close", (code) => {
|
|
134745
|
-
|
|
134888
|
+
log15.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
|
|
134746
134889
|
if (ws.readyState === ws.OPEN) {
|
|
134747
134890
|
ws.close(1e3, "Upstream closed");
|
|
134748
134891
|
}
|
|
134749
134892
|
});
|
|
134750
134893
|
ws.on("close", () => {
|
|
134751
|
-
|
|
134894
|
+
log15.debug("CDP client closed bandTabId=%s", bandTabId);
|
|
134752
134895
|
if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
|
|
134753
134896
|
try {
|
|
134754
134897
|
upstream.close();
|
|
@@ -134757,7 +134900,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
134757
134900
|
}
|
|
134758
134901
|
});
|
|
134759
134902
|
ws.on("error", (err) => {
|
|
134760
|
-
|
|
134903
|
+
log15.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
|
|
134761
134904
|
try {
|
|
134762
134905
|
upstream?.close();
|
|
134763
134906
|
} catch {
|
|
@@ -134767,7 +134910,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
134767
134910
|
|
|
134768
134911
|
// src/lib/cdp-targets.ts
|
|
134769
134912
|
init_src();
|
|
134770
|
-
var
|
|
134913
|
+
var log16 = createLogger("cdp-targets");
|
|
134771
134914
|
var CdpUnreachableError = class extends Error {
|
|
134772
134915
|
constructor(message) {
|
|
134773
134916
|
super(message);
|
|
@@ -134823,7 +134966,7 @@ async function captureSnapshot(bandTabId) {
|
|
|
134823
134966
|
});
|
|
134824
134967
|
ws.on("error", (err) => {
|
|
134825
134968
|
clearTimeout(timeout);
|
|
134826
|
-
|
|
134969
|
+
log16.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
|
|
134827
134970
|
markTargetDestroyed(bandTabId);
|
|
134828
134971
|
settle(new CdpUnreachableError(err.message));
|
|
134829
134972
|
});
|
|
@@ -135543,7 +135686,7 @@ function rowToDefinition(row) {
|
|
|
135543
135686
|
}
|
|
135544
135687
|
|
|
135545
135688
|
// src/lib/cronjob-scheduler.ts
|
|
135546
|
-
var
|
|
135689
|
+
var log17 = createLogger("cronjob-scheduler");
|
|
135547
135690
|
var SCHEDULER_KEY = Symbol.for("band.cronjob-scheduler");
|
|
135548
135691
|
var g14 = globalThis;
|
|
135549
135692
|
if (!g14[SCHEDULER_KEY]) {
|
|
@@ -135563,16 +135706,16 @@ function scheduleJob(job, fileKey) {
|
|
|
135563
135706
|
try {
|
|
135564
135707
|
const cronInstance = new E2(job.cronExpression, () => {
|
|
135565
135708
|
executeCronjob(job, fileKey).catch((err) => {
|
|
135566
|
-
|
|
135709
|
+
log17.error({ jobId: job.id, err }, "unhandled error in cronjob execution");
|
|
135567
135710
|
});
|
|
135568
135711
|
});
|
|
135569
135712
|
state.jobs.set(job.id, cronInstance);
|
|
135570
|
-
|
|
135713
|
+
log17.info(
|
|
135571
135714
|
{ jobId: job.id, name: job.name, cron: job.cronExpression, scope: job.scope },
|
|
135572
135715
|
"scheduled cronjob"
|
|
135573
135716
|
);
|
|
135574
135717
|
} catch (err) {
|
|
135575
|
-
|
|
135718
|
+
log17.error(
|
|
135576
135719
|
{ jobId: job.id, cronExpression: job.cronExpression, err },
|
|
135577
135720
|
"invalid cron expression, skipping job"
|
|
135578
135721
|
);
|
|
@@ -135586,24 +135729,24 @@ async function executeCronjob(job, fileKey) {
|
|
|
135586
135729
|
const appState = loadState();
|
|
135587
135730
|
const project = appState.projects.find((p6) => p6.name === fileKey);
|
|
135588
135731
|
if (!project) {
|
|
135589
|
-
|
|
135732
|
+
log17.warn({ jobId: job.id, fileKey }, "project not found for cronjob, skipping");
|
|
135590
135733
|
updateLastRun(job.id, "failed");
|
|
135591
135734
|
return;
|
|
135592
135735
|
}
|
|
135593
135736
|
workspaceId = toWorkspaceId(project.name, project.defaultBranch);
|
|
135594
135737
|
}
|
|
135595
|
-
|
|
135738
|
+
log17.info({ jobId: job.id, name: job.name, workspaceId }, "executing cronjob");
|
|
135596
135739
|
try {
|
|
135597
135740
|
const chat = getOrCreateDefaultChat(workspaceId);
|
|
135598
135741
|
submitTask({ workspaceId, chatId: chat.id, prompt: job.prompt });
|
|
135599
135742
|
updateLastRun(job.id, "completed");
|
|
135600
135743
|
} catch (err) {
|
|
135601
135744
|
if (err instanceof TaskConflictError) {
|
|
135602
|
-
|
|
135745
|
+
log17.info({ jobId: job.id, workspaceId }, "task already running, skipping cronjob execution");
|
|
135603
135746
|
updateLastRun(job.id, "skipped");
|
|
135604
135747
|
return;
|
|
135605
135748
|
}
|
|
135606
|
-
|
|
135749
|
+
log17.error({ jobId: job.id, err }, "cronjob execution failed");
|
|
135607
135750
|
updateLastRun(job.id, "failed");
|
|
135608
135751
|
}
|
|
135609
135752
|
}
|
|
@@ -135612,7 +135755,7 @@ function updateLastRun(jobId, status) {
|
|
|
135612
135755
|
const db2 = getDb();
|
|
135613
135756
|
db2.update(cronjobs).set({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString(), lastRunStatus: status }).where(eq2(cronjobs.id, jobId)).run();
|
|
135614
135757
|
} catch (err) {
|
|
135615
|
-
|
|
135758
|
+
log17.warn({ jobId, err }, "failed to update lastRun on cronjob");
|
|
135616
135759
|
}
|
|
135617
135760
|
}
|
|
135618
135761
|
function loadAndScheduleAll() {
|
|
@@ -135623,13 +135766,13 @@ function loadAndScheduleAll() {
|
|
|
135623
135766
|
for (const job of listAllCronjobs()) {
|
|
135624
135767
|
scheduleJob(job, job.fileKey);
|
|
135625
135768
|
}
|
|
135626
|
-
|
|
135769
|
+
log17.info({ count: state.jobs.size }, "loaded cronjob schedules");
|
|
135627
135770
|
}
|
|
135628
135771
|
function startCronjobScheduler() {
|
|
135629
135772
|
if (state.started) return;
|
|
135630
135773
|
state.started = true;
|
|
135631
135774
|
loadAndScheduleAll();
|
|
135632
|
-
|
|
135775
|
+
log17.info("cronjob scheduler started");
|
|
135633
135776
|
}
|
|
135634
135777
|
function stopCronjobScheduler() {
|
|
135635
135778
|
for (const [, cron] of state.jobs) {
|
|
@@ -135637,7 +135780,7 @@ function stopCronjobScheduler() {
|
|
|
135637
135780
|
}
|
|
135638
135781
|
state.jobs.clear();
|
|
135639
135782
|
state.started = false;
|
|
135640
|
-
|
|
135783
|
+
log17.info("cronjob scheduler stopped");
|
|
135641
135784
|
}
|
|
135642
135785
|
function reloadSchedules() {
|
|
135643
135786
|
if (!state.started) return;
|
|
@@ -135650,7 +135793,7 @@ function stopJobsForKey(key) {
|
|
|
135650
135793
|
if (cron) {
|
|
135651
135794
|
cron.stop();
|
|
135652
135795
|
state.jobs.delete(job.id);
|
|
135653
|
-
|
|
135796
|
+
log17.info({ jobId: job.id, key }, "stopped cronjob");
|
|
135654
135797
|
}
|
|
135655
135798
|
}
|
|
135656
135799
|
}
|
|
@@ -135716,7 +135859,7 @@ async function checkPrereqs() {
|
|
|
135716
135859
|
|
|
135717
135860
|
// src/lib/lsp-manager.ts
|
|
135718
135861
|
var __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
135719
|
-
var
|
|
135862
|
+
var log18 = createLogger("lsp");
|
|
135720
135863
|
var LANG_SERVER_CONFIG = {
|
|
135721
135864
|
typescript: { command: "typescript-language-server", args: ["--stdio"] }
|
|
135722
135865
|
};
|
|
@@ -135744,7 +135887,7 @@ async function getOrSpawnServer(workspaceId, lang) {
|
|
|
135744
135887
|
const workspaceBin = join17(cwd, "node_modules/.bin");
|
|
135745
135888
|
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
135746
135889
|
const combinedPath = [bundledBin, appBin, workspaceBin, resolvedPath].join(pathSep);
|
|
135747
|
-
|
|
135890
|
+
log18.debug("Spawning %s language server in %s for workspace %s", lang, cwd, workspaceId);
|
|
135748
135891
|
const child = spawn6(config2.command, config2.args, {
|
|
135749
135892
|
cwd,
|
|
135750
135893
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -135772,15 +135915,15 @@ async function getOrSpawnServer(workspaceId, lang) {
|
|
|
135772
135915
|
}
|
|
135773
135916
|
ids.add(serverId);
|
|
135774
135917
|
child.on("exit", (code) => {
|
|
135775
|
-
|
|
135918
|
+
log18.debug("Language server exited: %s (code %s)", serverId, String(code));
|
|
135776
135919
|
removeSession();
|
|
135777
135920
|
});
|
|
135778
135921
|
child.on("error", (err) => {
|
|
135779
|
-
|
|
135922
|
+
log18.error("Language server error: %s \u2014 %s", serverId, err.message);
|
|
135780
135923
|
removeSession();
|
|
135781
135924
|
});
|
|
135782
135925
|
child.stderr?.on("data", (chunk) => {
|
|
135783
|
-
|
|
135926
|
+
log18.debug("LSP stderr [%s]: %s", serverId, chunk.toString().trimEnd());
|
|
135784
135927
|
});
|
|
135785
135928
|
await new Promise((resolve8, reject) => {
|
|
135786
135929
|
child.once("spawn", resolve8);
|
|
@@ -135810,7 +135953,7 @@ function killAllServers() {
|
|
|
135810
135953
|
|
|
135811
135954
|
// src/lib/lsp-proxy.ts
|
|
135812
135955
|
init_src();
|
|
135813
|
-
var
|
|
135956
|
+
var log19 = createLogger("lsp-proxy");
|
|
135814
135957
|
function frameMessage(json4) {
|
|
135815
135958
|
const body = Buffer.from(json4, "utf-8");
|
|
135816
135959
|
const header = `Content-Length: ${body.byteLength}\r
|
|
@@ -135828,7 +135971,7 @@ function createFrameParser(onMessage) {
|
|
|
135828
135971
|
const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
|
|
135829
135972
|
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
135830
135973
|
if (!match) {
|
|
135831
|
-
|
|
135974
|
+
log19.warn("Malformed LSP header: %s", headerStr);
|
|
135832
135975
|
buffer = buffer.subarray(separatorIdx + 4);
|
|
135833
135976
|
continue;
|
|
135834
135977
|
}
|
|
@@ -135861,7 +136004,7 @@ async function handleLspConnection(ws, req) {
|
|
|
135861
136004
|
session = await getOrSpawnServer(workspaceId, lang);
|
|
135862
136005
|
} catch (err) {
|
|
135863
136006
|
const message = err instanceof Error ? err.message : String(err);
|
|
135864
|
-
|
|
136007
|
+
log19.error(
|
|
135865
136008
|
"Failed to spawn %s language server for workspace %s: %s",
|
|
135866
136009
|
lang,
|
|
135867
136010
|
workspaceId,
|
|
@@ -135875,12 +136018,12 @@ async function handleLspConnection(ws, req) {
|
|
|
135875
136018
|
ws.close(4002, "Language server stdio not available");
|
|
135876
136019
|
return;
|
|
135877
136020
|
}
|
|
135878
|
-
|
|
136021
|
+
log19.debug("LSP client connected: %s/%s", workspaceId, lang);
|
|
135879
136022
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
135880
136023
|
const retriedIds = /* @__PURE__ */ new Set();
|
|
135881
136024
|
const RETRY_DELAY_MS = 2e3;
|
|
135882
136025
|
const parseFrame = createFrameParser((json4) => {
|
|
135883
|
-
|
|
136026
|
+
log19.debug(
|
|
135884
136027
|
"LSP stdout [%s/%s]: %s",
|
|
135885
136028
|
workspaceId,
|
|
135886
136029
|
lang,
|
|
@@ -135892,7 +136035,7 @@ async function handleLspConnection(ws, req) {
|
|
|
135892
136035
|
const originalRequest = pendingRequests.get(msg.id);
|
|
135893
136036
|
retriedIds.add(msg.id);
|
|
135894
136037
|
pendingRequests.delete(msg.id);
|
|
135895
|
-
|
|
136038
|
+
log19.debug(
|
|
135896
136039
|
"LSP retrying request %d after 'No Project' error [%s/%s]",
|
|
135897
136040
|
msg.id,
|
|
135898
136041
|
workspaceId,
|
|
@@ -135914,14 +136057,14 @@ async function handleLspConnection(ws, req) {
|
|
|
135914
136057
|
const onStdoutData = (chunk) => parseFrame(chunk);
|
|
135915
136058
|
lspProcess.stdout.on("data", onStdoutData);
|
|
135916
136059
|
const onExit = (code) => {
|
|
135917
|
-
|
|
136060
|
+
log19.debug("LSP server exited (code %s), closing WebSocket", String(code));
|
|
135918
136061
|
if (ws.readyState === ws.OPEN) {
|
|
135919
136062
|
ws.close(1e3, "Language server exited");
|
|
135920
136063
|
}
|
|
135921
136064
|
};
|
|
135922
136065
|
lspProcess.on("exit", onExit);
|
|
135923
136066
|
function forwardToStdin(json4) {
|
|
135924
|
-
|
|
136067
|
+
log19.debug(
|
|
135925
136068
|
"LSP stdin [%s/%s]: %s",
|
|
135926
136069
|
workspaceId,
|
|
135927
136070
|
lang,
|
|
@@ -135948,7 +136091,7 @@ async function handleLspConnection(ws, req) {
|
|
|
135948
136091
|
ws.on("close", () => {
|
|
135949
136092
|
lspProcess.stdout?.off("data", onStdoutData);
|
|
135950
136093
|
lspProcess.off("exit", onExit);
|
|
135951
|
-
|
|
136094
|
+
log19.debug("LSP client disconnected: %s/%s (server kept alive)", workspaceId, lang);
|
|
135952
136095
|
});
|
|
135953
136096
|
}
|
|
135954
136097
|
|
|
@@ -136085,7 +136228,7 @@ function resolveCliPaths() {
|
|
|
136085
136228
|
// src/lib/cli-skills.ts
|
|
136086
136229
|
import { execFile as execFile4 } from "node:child_process";
|
|
136087
136230
|
import {
|
|
136088
|
-
existsSync as
|
|
136231
|
+
existsSync as existsSync6,
|
|
136089
136232
|
lstatSync as lstatSync3,
|
|
136090
136233
|
mkdirSync as mkdirSync5,
|
|
136091
136234
|
mkdtempSync,
|
|
@@ -136184,7 +136327,7 @@ async function installSkills(opts = {}) {
|
|
|
136184
136327
|
for (const name24 of BAND_SKILL_NAMES) {
|
|
136185
136328
|
const sourcePath = join19(stagingDir, name24, SKILL_FILE);
|
|
136186
136329
|
const destPath = join19(sharedDir, name24, SKILL_FILE);
|
|
136187
|
-
if (!
|
|
136330
|
+
if (!existsSync6(sourcePath)) {
|
|
136188
136331
|
opts.log?.warn("Generated skill missing from staging dir: %s (skipping)", sourcePath);
|
|
136189
136332
|
result.skipped.push(destPath);
|
|
136190
136333
|
continue;
|
|
@@ -136232,7 +136375,7 @@ async function installSkills(opts = {}) {
|
|
|
136232
136375
|
for (const name24 of BAND_SKILL_NAMES) {
|
|
136233
136376
|
const shared2 = join19(sharedDir, name24);
|
|
136234
136377
|
const link2 = join19(target.skillsDir, name24);
|
|
136235
|
-
if (!
|
|
136378
|
+
if (!existsSync6(shared2)) {
|
|
136236
136379
|
result.skipped.push(link2);
|
|
136237
136380
|
continue;
|
|
136238
136381
|
}
|
|
@@ -136444,40 +136587,65 @@ async function installHooks() {
|
|
|
136444
136587
|
}
|
|
136445
136588
|
|
|
136446
136589
|
// src/lib/setup.ts
|
|
136447
|
-
var
|
|
136590
|
+
var log20 = createLogger("setup");
|
|
136448
136591
|
var AGENT_CHECKS = [
|
|
136449
136592
|
{ id: "claude-code", type: "claude-code", label: "Claude Code", binary: "claude" },
|
|
136450
136593
|
{ id: "codex", type: "codex", label: "Codex", binary: "codex" },
|
|
136451
136594
|
{ id: "opencode", type: "opencode", label: "OpenCode", binary: "opencode" }
|
|
136452
136595
|
];
|
|
136453
136596
|
async function runFirstTimeSetup() {
|
|
136597
|
+
const projectSync = ensureProjectStateInSync();
|
|
136454
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() {
|
|
136455
136615
|
await ensureDefaultCodingAgents();
|
|
136456
136616
|
ensureNotificationDefaults();
|
|
136457
|
-
|
|
136458
|
-
|
|
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
|
+
}
|
|
136459
136627
|
}
|
|
136460
136628
|
async function ensureCliInstalled() {
|
|
136461
136629
|
let cliStatus;
|
|
136462
136630
|
try {
|
|
136463
136631
|
cliStatus = await checkCli();
|
|
136464
136632
|
} catch (err) {
|
|
136465
|
-
|
|
136633
|
+
log20.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
|
|
136466
136634
|
return;
|
|
136467
136635
|
}
|
|
136468
136636
|
if (cliStatus === "Installed") {
|
|
136469
136637
|
return;
|
|
136470
136638
|
}
|
|
136471
136639
|
if (cliStatus !== "NotInstalled") {
|
|
136472
|
-
|
|
136640
|
+
log20.warn("CLI not auto-installed (status: %s)", cliStatus);
|
|
136473
136641
|
return;
|
|
136474
136642
|
}
|
|
136475
|
-
|
|
136643
|
+
log20.info("Installing band CLI...");
|
|
136476
136644
|
try {
|
|
136477
136645
|
await installCli();
|
|
136478
|
-
|
|
136646
|
+
log20.info("CLI installed to /usr/local/bin/band");
|
|
136479
136647
|
} catch (err) {
|
|
136480
|
-
|
|
136648
|
+
log20.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
|
|
136481
136649
|
}
|
|
136482
136650
|
}
|
|
136483
136651
|
async function ensureDefaultCodingAgents() {
|
|
@@ -136486,17 +136654,17 @@ async function ensureDefaultCodingAgents() {
|
|
|
136486
136654
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
136487
136655
|
return;
|
|
136488
136656
|
}
|
|
136489
|
-
|
|
136657
|
+
log20.info("Detecting installed coding agents...");
|
|
136490
136658
|
const detected = [];
|
|
136491
136659
|
for (const check2 of AGENT_CHECKS) {
|
|
136492
136660
|
const path3 = await whichBinary(check2.binary);
|
|
136493
136661
|
if (path3) {
|
|
136494
|
-
|
|
136662
|
+
log20.info("Detected coding agent: %s (%s)", check2.id, path3);
|
|
136495
136663
|
detected.push({ id: check2.id, type: check2.type, label: check2.label });
|
|
136496
136664
|
}
|
|
136497
136665
|
}
|
|
136498
136666
|
if (detected.length === 0) {
|
|
136499
|
-
|
|
136667
|
+
log20.info("No coding agent CLIs detected on PATH");
|
|
136500
136668
|
return;
|
|
136501
136669
|
}
|
|
136502
136670
|
const current = loadSettings();
|
|
@@ -136505,7 +136673,7 @@ async function ensureDefaultCodingAgents() {
|
|
|
136505
136673
|
current.defaultCodingAgent = detected[0].id;
|
|
136506
136674
|
}
|
|
136507
136675
|
saveSettings(current);
|
|
136508
|
-
|
|
136676
|
+
log20.info("Enabled %d coding agent(s); default = %s", detected.length, current.defaultCodingAgent);
|
|
136509
136677
|
}
|
|
136510
136678
|
function ensureNotificationDefaults() {
|
|
136511
136679
|
const settings = loadSettings();
|
|
@@ -136517,7 +136685,7 @@ function ensureNotificationDefaults() {
|
|
|
136517
136685
|
...settings,
|
|
136518
136686
|
notifications: { ...notifications, soundOnNeedsAttention: true }
|
|
136519
136687
|
});
|
|
136520
|
-
|
|
136688
|
+
log20.info("Set default notifications.soundOnNeedsAttention = true");
|
|
136521
136689
|
}
|
|
136522
136690
|
async function ensureClaudeHooks() {
|
|
136523
136691
|
try {
|
|
@@ -136526,9 +136694,9 @@ async function ensureClaudeHooks() {
|
|
|
136526
136694
|
return;
|
|
136527
136695
|
}
|
|
136528
136696
|
await installHooks();
|
|
136529
|
-
|
|
136697
|
+
log20.info("Installed Claude Code hooks");
|
|
136530
136698
|
} catch (err) {
|
|
136531
|
-
|
|
136699
|
+
log20.warn(
|
|
136532
136700
|
"Failed to install Claude Code hooks: %s",
|
|
136533
136701
|
err instanceof Error ? err.message : String(err)
|
|
136534
136702
|
);
|
|
@@ -136536,11 +136704,11 @@ async function ensureClaudeHooks() {
|
|
|
136536
136704
|
}
|
|
136537
136705
|
async function ensureSkillsInstalled() {
|
|
136538
136706
|
try {
|
|
136539
|
-
const result = await installSkills({ log:
|
|
136707
|
+
const result = await installSkills({ log: log20 });
|
|
136540
136708
|
const wrote = result.written.length + result.updated.length;
|
|
136541
136709
|
const linkChange = result.linked.length;
|
|
136542
136710
|
if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
|
|
136543
|
-
|
|
136711
|
+
log20.info(
|
|
136544
136712
|
"Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
|
|
136545
136713
|
result.written.length,
|
|
136546
136714
|
result.updated.length,
|
|
@@ -136552,13 +136720,13 @@ async function ensureSkillsInstalled() {
|
|
|
136552
136720
|
);
|
|
136553
136721
|
}
|
|
136554
136722
|
} catch (err) {
|
|
136555
|
-
|
|
136723
|
+
log20.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
|
|
136556
136724
|
}
|
|
136557
136725
|
}
|
|
136558
136726
|
|
|
136559
136727
|
// src/lib/terminal-manager.ts
|
|
136560
136728
|
init_src();
|
|
136561
|
-
import { existsSync as
|
|
136729
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
136562
136730
|
import { join as join21 } from "node:path";
|
|
136563
136731
|
|
|
136564
136732
|
// src/lib/terminal-layout-manager.ts
|
|
@@ -136586,7 +136754,7 @@ function removeTerminalFromLayout(workspaceId, terminalId) {
|
|
|
136586
136754
|
}
|
|
136587
136755
|
|
|
136588
136756
|
// src/lib/terminal-manager.ts
|
|
136589
|
-
var
|
|
136757
|
+
var log21 = createLogger("terminal");
|
|
136590
136758
|
var MAX_SCROLLBACK_SIZE = 1e5;
|
|
136591
136759
|
var terminals = /* @__PURE__ */ new Map();
|
|
136592
136760
|
var workspaceTerminals = /* @__PURE__ */ new Map();
|
|
@@ -136617,20 +136785,20 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136617
136785
|
if (options2?.cwd) {
|
|
136618
136786
|
const resolved = join21(workspaceRoot, options2.cwd);
|
|
136619
136787
|
if (!resolved.startsWith(workspaceRoot)) {
|
|
136620
|
-
|
|
136621
|
-
} else if (
|
|
136788
|
+
log21.warn("Ignoring cwd %s \u2014 resolves outside workspace root %s", options2.cwd, workspaceRoot);
|
|
136789
|
+
} else if (existsSync7(resolved)) {
|
|
136622
136790
|
cwd = resolved;
|
|
136623
136791
|
} else {
|
|
136624
|
-
|
|
136792
|
+
log21.warn("Ignoring cwd %s \u2014 directory does not exist", options2.cwd);
|
|
136625
136793
|
}
|
|
136626
136794
|
}
|
|
136627
|
-
if (!
|
|
136795
|
+
if (!existsSync7(cwd)) {
|
|
136628
136796
|
throw new Error(`Workspace directory does not exist: ${cwd}`);
|
|
136629
136797
|
}
|
|
136630
|
-
if (!
|
|
136798
|
+
if (!existsSync7(shell)) {
|
|
136631
136799
|
throw new Error(`Shell not found: ${shell}`);
|
|
136632
136800
|
}
|
|
136633
|
-
|
|
136801
|
+
log21.debug(
|
|
136634
136802
|
"Spawning shell %s in %s for terminal %s (PATH=%s)",
|
|
136635
136803
|
shell,
|
|
136636
136804
|
cwd,
|
|
@@ -136649,7 +136817,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136649
136817
|
});
|
|
136650
136818
|
} catch (err) {
|
|
136651
136819
|
const msg = err instanceof Error ? err.message : String(err);
|
|
136652
|
-
|
|
136820
|
+
log21.error("pty.spawn failed: %s (shell=%s, cwd=%s)", msg, shell, cwd);
|
|
136653
136821
|
throw err;
|
|
136654
136822
|
}
|
|
136655
136823
|
const session = { pty: ptyProcess, scrollback: "", workspaceId };
|
|
@@ -136685,7 +136853,7 @@ async function spawnTerminal(workspaceId, terminalId, options2) {
|
|
|
136685
136853
|
}
|
|
136686
136854
|
});
|
|
136687
136855
|
ptyProcess.onExit(() => {
|
|
136688
|
-
|
|
136856
|
+
log21.debug("Terminal exited: %s (workspace %s)", terminalId, workspaceId);
|
|
136689
136857
|
terminals.delete(terminalId);
|
|
136690
136858
|
outputListeners.delete(terminalId);
|
|
136691
136859
|
const set2 = workspaceTerminals.get(workspaceId);
|
|
@@ -136793,13 +136961,36 @@ function killAllTerminals() {
|
|
|
136793
136961
|
|
|
136794
136962
|
// src/lib/terminal-ws.ts
|
|
136795
136963
|
init_src();
|
|
136796
|
-
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
|
+
}
|
|
136797
136988
|
async function handleTerminalConnection(ws, req) {
|
|
136798
136989
|
const url2 = new URL(req.url, `http://${req.headers.host}`);
|
|
136799
136990
|
const workspaceId = url2.searchParams.get("workspaceId");
|
|
136800
136991
|
const terminalId = url2.searchParams.get("terminalId");
|
|
136801
136992
|
if (!workspaceId || !terminalId) {
|
|
136802
|
-
ws
|
|
136993
|
+
safeClose(ws, 4e3, "Missing workspaceId or terminalId");
|
|
136803
136994
|
return;
|
|
136804
136995
|
}
|
|
136805
136996
|
const existing = getTerminalSession(terminalId);
|
|
@@ -136834,8 +137025,8 @@ async function handleTerminalConnection(ws, req) {
|
|
|
136834
137025
|
session = await spawnTerminal(workspaceId, terminalId, spawnOpts);
|
|
136835
137026
|
} catch (err) {
|
|
136836
137027
|
const msg = err instanceof Error ? err.message : String(err);
|
|
136837
|
-
|
|
136838
|
-
ws
|
|
137028
|
+
log22.error("Failed to spawn terminal %s for workspace %s: %s", terminalId, workspaceId, msg);
|
|
137029
|
+
safeClose(ws, 4001, msg);
|
|
136839
137030
|
return;
|
|
136840
137031
|
}
|
|
136841
137032
|
attachSession(ws, terminalId, workspaceId, session, true);
|
|
@@ -136848,7 +137039,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
136848
137039
|
});
|
|
136849
137040
|
}
|
|
136850
137041
|
function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
136851
|
-
|
|
137042
|
+
log22.debug(
|
|
136852
137043
|
"Terminal %s: %s (workspace %s)",
|
|
136853
137044
|
isNew ? "connected" : "reconnected",
|
|
136854
137045
|
terminalId,
|
|
@@ -136877,7 +137068,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
136877
137068
|
}, 3e3);
|
|
136878
137069
|
const exitDisposable = session.pty.onExit(({ exitCode }) => {
|
|
136879
137070
|
clearInterval(processInterval);
|
|
136880
|
-
|
|
137071
|
+
log22.debug("PTY exited with code %d for terminal %s", exitCode, terminalId);
|
|
136881
137072
|
if (ws.readyState === ws.OPEN) {
|
|
136882
137073
|
ws.close(1e3, "Terminal exited");
|
|
136883
137074
|
}
|
|
@@ -136889,7 +137080,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
136889
137080
|
clearInterval(processInterval);
|
|
136890
137081
|
dataDisposable.dispose();
|
|
136891
137082
|
exitDisposable.dispose();
|
|
136892
|
-
|
|
137083
|
+
log22.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
|
|
136893
137084
|
});
|
|
136894
137085
|
}
|
|
136895
137086
|
function handleMessage(ws, terminalId, session, message) {
|
|
@@ -136927,7 +137118,7 @@ function getToken() {
|
|
|
136927
137118
|
}
|
|
136928
137119
|
|
|
136929
137120
|
// src/lib/tunnel.ts
|
|
136930
|
-
var
|
|
137121
|
+
var log23 = createLogger("tunnel");
|
|
136931
137122
|
var tunnelProcess = null;
|
|
136932
137123
|
var tunnelUrl = null;
|
|
136933
137124
|
var startInProgress = null;
|
|
@@ -136941,7 +137132,7 @@ function appendToken(baseUrl, token) {
|
|
|
136941
137132
|
}
|
|
136942
137133
|
function spawnTunnel(options2, resolvedPath) {
|
|
136943
137134
|
const args = ["tunnel", "--config", "/dev/null", "--url", `http://localhost:${options2.port}`];
|
|
136944
|
-
|
|
137135
|
+
log23.debug("spawning cloudflared %s", args.join(" "));
|
|
136945
137136
|
return new Promise((resolve8, reject) => {
|
|
136946
137137
|
const child = spawn7("cloudflared", args, {
|
|
136947
137138
|
env: { ...process.env, PATH: resolvedPath },
|
|
@@ -136955,12 +137146,12 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
136955
137146
|
for (const line2 of text4.split("\n")) {
|
|
136956
137147
|
const trimmed = line2.trim();
|
|
136957
137148
|
if (!trimmed) continue;
|
|
136958
|
-
|
|
137149
|
+
log23.debug("output: %s", trimmed);
|
|
136959
137150
|
const url2 = extractUrl(trimmed);
|
|
136960
137151
|
if (url2) {
|
|
136961
137152
|
const token = getToken();
|
|
136962
137153
|
tunnelUrl = appendToken(url2, token);
|
|
136963
|
-
|
|
137154
|
+
log23.debug("detected URL: %s", tunnelUrl);
|
|
136964
137155
|
emit({ kind: "tunnel-url", url: tunnelUrl });
|
|
136965
137156
|
if (!settled) {
|
|
136966
137157
|
settled = true;
|
|
@@ -136975,7 +137166,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
136975
137166
|
handleOutput(data);
|
|
136976
137167
|
});
|
|
136977
137168
|
child.on("error", (err) => {
|
|
136978
|
-
|
|
137169
|
+
log23.debug("process error: %s", err.message);
|
|
136979
137170
|
tunnelProcess = null;
|
|
136980
137171
|
tunnelUrl = null;
|
|
136981
137172
|
emit({ kind: "tunnel-error", error: err.message });
|
|
@@ -136985,7 +137176,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
136985
137176
|
}
|
|
136986
137177
|
});
|
|
136987
137178
|
child.on("exit", (code) => {
|
|
136988
|
-
|
|
137179
|
+
log23.debug("process exited with code: %d", code ?? -1);
|
|
136989
137180
|
const wasRunning = tunnelProcess !== null && settled;
|
|
136990
137181
|
tunnelProcess = null;
|
|
136991
137182
|
tunnelUrl = null;
|
|
@@ -137007,7 +137198,7 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137007
137198
|
});
|
|
137008
137199
|
setTimeout(() => {
|
|
137009
137200
|
if (!settled) {
|
|
137010
|
-
|
|
137201
|
+
log23.debug("30s timeout reached, resolving without URL");
|
|
137011
137202
|
settled = true;
|
|
137012
137203
|
resolve8();
|
|
137013
137204
|
}
|
|
@@ -137016,12 +137207,12 @@ function spawnTunnel(options2, resolvedPath) {
|
|
|
137016
137207
|
}
|
|
137017
137208
|
async function startTunnel(options2) {
|
|
137018
137209
|
if (startInProgress) {
|
|
137019
|
-
|
|
137210
|
+
log23.debug("startTunnel: start already in progress, waiting...");
|
|
137020
137211
|
await startInProgress;
|
|
137021
137212
|
return;
|
|
137022
137213
|
}
|
|
137023
137214
|
if (tunnelProcess) {
|
|
137024
|
-
|
|
137215
|
+
log23.debug("startTunnel: already running, re-emitting URL");
|
|
137025
137216
|
if (tunnelUrl) {
|
|
137026
137217
|
emit({ kind: "tunnel-url", url: tunnelUrl });
|
|
137027
137218
|
}
|
|
@@ -143947,7 +144138,7 @@ function createContext8() {
|
|
|
143947
144138
|
// src/trpc/router.ts
|
|
143948
144139
|
import { execFile as execFile5, execFileSync as execFileSync2, spawn as spawn8 } from "node:child_process";
|
|
143949
144140
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
143950
|
-
import { existsSync as
|
|
144141
|
+
import { existsSync as existsSync9, constants as fsConstants, mkdirSync as mkdirSync7, unlinkSync as unlinkSync3 } from "node:fs";
|
|
143951
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";
|
|
143952
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";
|
|
143953
144144
|
import { promisify } from "node:util";
|
|
@@ -144052,7 +144243,7 @@ function clearHistory(workspaceId, range, now = Date.now()) {
|
|
|
144052
144243
|
|
|
144053
144244
|
// src/lib/chat-session-summary.ts
|
|
144054
144245
|
init_src();
|
|
144055
|
-
var
|
|
144246
|
+
var log24 = createLogger("chat-session-summary");
|
|
144056
144247
|
var REFRESH_KEY = Symbol.for("band.chat-session-summary.refresh");
|
|
144057
144248
|
var g15 = globalThis;
|
|
144058
144249
|
if (!g15[REFRESH_KEY]) g15[REFRESH_KEY] = /* @__PURE__ */ new Map();
|
|
@@ -144082,7 +144273,7 @@ async function ensureActiveSessionSummary(chatId, worktreePath) {
|
|
|
144082
144273
|
});
|
|
144083
144274
|
return getChat(chatId);
|
|
144084
144275
|
} catch (err) {
|
|
144085
|
-
|
|
144276
|
+
log24.warn({ chatId, err }, "ensureActiveSessionSummary failed");
|
|
144086
144277
|
return chat;
|
|
144087
144278
|
}
|
|
144088
144279
|
}
|
|
@@ -144119,7 +144310,7 @@ async function doRefresh(chatId, worktreePath) {
|
|
|
144119
144310
|
lastModified: latest.lastModified
|
|
144120
144311
|
});
|
|
144121
144312
|
} catch (err) {
|
|
144122
|
-
|
|
144313
|
+
log24.warn({ chatId, err }, "active session refresh failed");
|
|
144123
144314
|
}
|
|
144124
144315
|
}
|
|
144125
144316
|
|
|
@@ -144429,10 +144620,10 @@ function subscribeToFileChanges(workspaceId, listener) {
|
|
|
144429
144620
|
|
|
144430
144621
|
// src/lib/formatter.ts
|
|
144431
144622
|
init_src();
|
|
144432
|
-
import { existsSync as
|
|
144623
|
+
import { existsSync as existsSync8, realpathSync as realpathSync4 } from "node:fs";
|
|
144433
144624
|
import { basename, dirname as dirname6, isAbsolute, join as join22, resolve as resolvePath } from "node:path";
|
|
144434
144625
|
import prettier from "prettier";
|
|
144435
|
-
var
|
|
144626
|
+
var log25 = createLogger("formatter");
|
|
144436
144627
|
var FormatterError = class extends Error {
|
|
144437
144628
|
code;
|
|
144438
144629
|
detail;
|
|
@@ -144456,7 +144647,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
144456
144647
|
const ignorePath = resolvePath(worktreePath, ".prettierignore");
|
|
144457
144648
|
const info = await prettier.getFileInfo(absFile, {
|
|
144458
144649
|
resolveConfig: true,
|
|
144459
|
-
ignorePath:
|
|
144650
|
+
ignorePath: existsSync8(ignorePath) ? ignorePath : void 0
|
|
144460
144651
|
});
|
|
144461
144652
|
if (info.ignored) {
|
|
144462
144653
|
return {
|
|
@@ -144487,7 +144678,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
144487
144678
|
}
|
|
144488
144679
|
const changed = formatted !== content2;
|
|
144489
144680
|
if (changed) {
|
|
144490
|
-
|
|
144681
|
+
log25.info(
|
|
144491
144682
|
"Formatted %s with parser=%s (%d bytes in)",
|
|
144492
144683
|
absFile,
|
|
144493
144684
|
info.inferredParser,
|
|
@@ -144626,7 +144817,7 @@ function fuzzyScore(query, filePath) {
|
|
|
144626
144817
|
// src/lib/terminal-config.ts
|
|
144627
144818
|
init_src();
|
|
144628
144819
|
init_zod();
|
|
144629
|
-
var
|
|
144820
|
+
var log26 = createLogger("terminal-config");
|
|
144630
144821
|
var TerminalPaneConfigSchema = external_exports2.object({
|
|
144631
144822
|
name: external_exports2.string().optional(),
|
|
144632
144823
|
command: external_exports2.string().optional(),
|
|
@@ -144657,7 +144848,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
|
|
|
144657
144848
|
if (!terminalBlock) return null;
|
|
144658
144849
|
const result = WorkspaceTerminalConfigSchema.safeParse(terminalBlock);
|
|
144659
144850
|
if (!result.success) {
|
|
144660
|
-
|
|
144851
|
+
log26.warn(
|
|
144661
144852
|
"Invalid workspace.terminal config: %s",
|
|
144662
144853
|
result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join("; ")
|
|
144663
144854
|
);
|
|
@@ -144668,7 +144859,7 @@ function loadWorkspaceTerminalConfig(worktreePath, projectPath) {
|
|
|
144668
144859
|
|
|
144669
144860
|
// src/trpc/router.ts
|
|
144670
144861
|
var execFileAsync = promisify(execFile5);
|
|
144671
|
-
var
|
|
144862
|
+
var log27 = createLogger("trpc");
|
|
144672
144863
|
var t2 = initTRPC.context().create();
|
|
144673
144864
|
var publicProcedure = t2.procedure;
|
|
144674
144865
|
var projectsRouter = t2.router({
|
|
@@ -144677,26 +144868,32 @@ var projectsRouter = t2.router({
|
|
|
144677
144868
|
const settings = loadSettings();
|
|
144678
144869
|
const statuses = loadCurrentStatuses();
|
|
144679
144870
|
const statusMap = new Map(statuses.map((s6) => [s6.workspaceId, s6]));
|
|
144871
|
+
for (const project of state2.projects) {
|
|
144872
|
+
reconcileKindForProject(project);
|
|
144873
|
+
}
|
|
144680
144874
|
const projects2 = await Promise.all(
|
|
144681
144875
|
state2.projects.map(async (project) => {
|
|
144682
|
-
const trackedBranches = new Set(project.worktrees.map((wt) => wt.branch));
|
|
144683
|
-
const trackedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt]));
|
|
144684
144876
|
let worktrees2 = project.worktrees;
|
|
144685
|
-
|
|
144686
|
-
const
|
|
144687
|
-
|
|
144688
|
-
|
|
144689
|
-
|
|
144690
|
-
|
|
144691
|
-
|
|
144692
|
-
|
|
144693
|
-
|
|
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
|
+
}
|
|
144694
144890
|
}
|
|
144695
144891
|
return {
|
|
144696
144892
|
name: project.name,
|
|
144697
144893
|
path: project.path,
|
|
144698
144894
|
defaultBranch: project.defaultBranch,
|
|
144699
144895
|
label: project.label,
|
|
144896
|
+
kind: project.kind,
|
|
144700
144897
|
worktrees: worktrees2.map((wt) => {
|
|
144701
144898
|
const workspaceId = toWorkspaceId(project.name, wt.branch);
|
|
144702
144899
|
const status = statusMap.get(workspaceId);
|
|
@@ -144713,7 +144910,7 @@ var projectsRouter = t2.router({
|
|
|
144713
144910
|
}),
|
|
144714
144911
|
checkPath: publicProcedure.input(external_exports2.object({ path: external_exports2.string() })).query(({ input }) => {
|
|
144715
144912
|
const resolvedPath = resolve6(input.path);
|
|
144716
|
-
const isGitRepo =
|
|
144913
|
+
const isGitRepo = existsSync9(join23(resolvedPath, ".git"));
|
|
144717
144914
|
return { isGitRepo };
|
|
144718
144915
|
}),
|
|
144719
144916
|
gitInit: publicProcedure.input(external_exports2.object({ path: external_exports2.string() })).mutation(async ({ input }) => {
|
|
@@ -144735,37 +144932,84 @@ var projectsRouter = t2.router({
|
|
|
144735
144932
|
);
|
|
144736
144933
|
}
|
|
144737
144934
|
}
|
|
144935
|
+
const resolvedPath = resolve6(input.path);
|
|
144936
|
+
const kind = existsSync9(join23(resolvedPath, ".git")) ? "git" : "plain";
|
|
144738
144937
|
let defaultBranch = "main";
|
|
144739
|
-
try {
|
|
144740
|
-
const env = { ...process.env };
|
|
144741
|
-
if (env.PATH) {
|
|
144742
|
-
env.PATH = `/opt/homebrew/bin:/usr/local/bin:${env.PATH}`;
|
|
144743
|
-
}
|
|
144744
|
-
const output = execFileSync2("git", ["symbolic-ref", "--short", "HEAD"], {
|
|
144745
|
-
cwd: input.path,
|
|
144746
|
-
env,
|
|
144747
|
-
encoding: "utf-8"
|
|
144748
|
-
}).trim();
|
|
144749
|
-
if (output) defaultBranch = output;
|
|
144750
|
-
} catch {
|
|
144751
|
-
}
|
|
144752
144938
|
let worktrees2 = [];
|
|
144753
|
-
|
|
144754
|
-
|
|
144755
|
-
|
|
144756
|
-
|
|
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 }];
|
|
144757
144960
|
}
|
|
144758
144961
|
const project = {
|
|
144759
144962
|
name: name24,
|
|
144760
|
-
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,
|
|
144761
144969
|
defaultBranch,
|
|
144762
144970
|
worktrees: worktrees2,
|
|
144763
|
-
label: input.label ?? void 0
|
|
144971
|
+
label: input.label ?? void 0,
|
|
144972
|
+
kind
|
|
144764
144973
|
};
|
|
144765
144974
|
state2.projects.push(project);
|
|
144766
144975
|
saveState(state2);
|
|
144767
144976
|
return project;
|
|
144768
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
|
+
}),
|
|
144769
145013
|
remove: publicProcedure.input(external_exports2.object({ name: external_exports2.string() })).mutation(({ input }) => {
|
|
144770
145014
|
const state2 = loadState();
|
|
144771
145015
|
state2.projects = state2.projects.filter((p6) => p6.name !== input.name);
|
|
@@ -144817,6 +145061,12 @@ var workspacesRouter = t2.router({
|
|
|
144817
145061
|
if (!proj) {
|
|
144818
145062
|
throw new Error(`Project "${input.project}" not found`);
|
|
144819
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
|
+
}
|
|
144820
145070
|
const existing = proj.worktrees.find((wt) => wt.branch === input.branch);
|
|
144821
145071
|
if (existing) {
|
|
144822
145072
|
return { ok: true, path: existing.path };
|
|
@@ -144858,6 +145108,12 @@ var workspacesRouter = t2.router({
|
|
|
144858
145108
|
if (!proj) {
|
|
144859
145109
|
throw new Error(`Project "${input.project}" not found`);
|
|
144860
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
|
+
}
|
|
144861
145117
|
const { command, env: gitEnv } = gitCmd();
|
|
144862
145118
|
const output = execFileSync2(command, ["worktree", "list", "--porcelain"], {
|
|
144863
145119
|
cwd: proj.path,
|
|
@@ -144904,13 +145160,13 @@ var workspacesRouter = t2.router({
|
|
|
144904
145160
|
try {
|
|
144905
145161
|
const deletedTasks = deleteWorkspaceTasks(workspaceId);
|
|
144906
145162
|
if (deletedTasks > 0) {
|
|
144907
|
-
|
|
145163
|
+
log27.info(
|
|
144908
145164
|
{ workspaceId, count: deletedTasks },
|
|
144909
145165
|
"deleted workspace tasks on removal"
|
|
144910
145166
|
);
|
|
144911
145167
|
}
|
|
144912
145168
|
} catch (err) {
|
|
144913
|
-
|
|
145169
|
+
log27.error({ workspaceId, err }, "failed to delete workspace tasks on removal");
|
|
144914
145170
|
}
|
|
144915
145171
|
emit({ kind: "remove", workspaceId });
|
|
144916
145172
|
const projPath = proj.path;
|
|
@@ -144928,7 +145184,7 @@ var workspacesRouter = t2.router({
|
|
|
144928
145184
|
timeout: 6e4
|
|
144929
145185
|
});
|
|
144930
145186
|
} catch (err) {
|
|
144931
|
-
|
|
145187
|
+
log27.warn({ err, workspaceId }, "teardown script failed");
|
|
144932
145188
|
}
|
|
144933
145189
|
}
|
|
144934
145190
|
try {
|
|
@@ -144946,7 +145202,7 @@ var workspacesRouter = t2.router({
|
|
|
144946
145202
|
encoding: "utf-8"
|
|
144947
145203
|
});
|
|
144948
145204
|
} catch (err) {
|
|
144949
|
-
|
|
145205
|
+
log27.warn({ err, workspaceId }, "git worktree prune failed");
|
|
144950
145206
|
}
|
|
144951
145207
|
}
|
|
144952
145208
|
try {
|
|
@@ -144958,7 +145214,7 @@ var workspacesRouter = t2.router({
|
|
|
144958
145214
|
} catch {
|
|
144959
145215
|
}
|
|
144960
145216
|
})().catch((err) => {
|
|
144961
|
-
|
|
145217
|
+
log27.error({ err, workspaceId }, "background workspace cleanup failed");
|
|
144962
145218
|
});
|
|
144963
145219
|
});
|
|
144964
145220
|
return { ok: true };
|
|
@@ -144975,6 +145231,12 @@ var workspacesRouter = t2.router({
|
|
|
144975
145231
|
if (!proj) {
|
|
144976
145232
|
throw new Error(`Project "${input.project}" not found`);
|
|
144977
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
|
+
}
|
|
144978
145240
|
const wt = proj.worktrees.find((w2) => w2.branch === input.branch);
|
|
144979
145241
|
if (!wt) {
|
|
144980
145242
|
throw new Error(`Workspace "${input.branch}" not found`);
|
|
@@ -144989,6 +145251,12 @@ var workspacesRouter = t2.router({
|
|
|
144989
145251
|
if (!workspace) {
|
|
144990
145252
|
throw new Error("Workspace not found");
|
|
144991
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
|
+
}
|
|
144992
145260
|
const cwd = workspace.worktree.path;
|
|
144993
145261
|
try {
|
|
144994
145262
|
await execGit(["pull", "--rebase"], cwd);
|
|
@@ -145007,6 +145275,12 @@ var workspacesRouter = t2.router({
|
|
|
145007
145275
|
if (!workspace) {
|
|
145008
145276
|
throw new Error("Workspace not found");
|
|
145009
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
|
+
}
|
|
145010
145284
|
const cwd = workspace.worktree.path;
|
|
145011
145285
|
try {
|
|
145012
145286
|
await execGit(["push"], cwd);
|
|
@@ -145017,7 +145291,7 @@ var workspacesRouter = t2.router({
|
|
|
145017
145291
|
}),
|
|
145018
145292
|
runScript: publicProcedure.input(external_exports2.object({ path: external_exports2.string(), scriptType: external_exports2.string() })).mutation(({ input }) => {
|
|
145019
145293
|
const scriptPath = join23(input.path, ".band", input.scriptType);
|
|
145020
|
-
if (!
|
|
145294
|
+
if (!existsSync9(scriptPath)) {
|
|
145021
145295
|
throw new Error(`Script "${input.scriptType}" not found`);
|
|
145022
145296
|
}
|
|
145023
145297
|
return new Promise((resolve8, reject) => {
|
|
@@ -145103,6 +145377,7 @@ var LANG_MAP = {
|
|
|
145103
145377
|
};
|
|
145104
145378
|
var compareBranchSchema = external_exports2.string().min(1).regex(/^[^-]/, "branch name must not start with '-'").optional();
|
|
145105
145379
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
145380
|
+
var EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
145106
145381
|
async function resolveDiffContext(cwd, defaultBranch, diffMode, compareBranchInput) {
|
|
145107
145382
|
const compareBranch = diffMode === "uncommitted" ? defaultBranch : compareBranchInput ?? defaultBranch;
|
|
145108
145383
|
let headBranch;
|
|
@@ -145180,7 +145455,7 @@ var workspaceRouter = t2.router({
|
|
|
145180
145455
|
*
|
|
145181
145456
|
* Returns `{ skipped: true, reason }` when Prettier has no parser for
|
|
145182
145457
|
* the file's extension (or it's covered by `.prettierignore`). Editors
|
|
145183
|
-
* fire this off
|
|
145458
|
+
* fire this off Shift+Alt+F without checking the file type first, so a
|
|
145184
145459
|
* soft skip is the right outcome for unsupported files rather than a
|
|
145185
145460
|
* surfaced error.
|
|
145186
145461
|
*
|
|
@@ -145291,7 +145566,7 @@ var workspaceRouter = t2.router({
|
|
|
145291
145566
|
);
|
|
145292
145567
|
branches = output.trim().split("\n").map((b10) => b10.trim()).filter(Boolean);
|
|
145293
145568
|
} catch (err) {
|
|
145294
|
-
|
|
145569
|
+
log27.error(
|
|
145295
145570
|
`listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
|
|
145296
145571
|
);
|
|
145297
145572
|
}
|
|
@@ -145381,6 +145656,18 @@ var workspaceRouter = t2.router({
|
|
|
145381
145656
|
if (!workspace) {
|
|
145382
145657
|
throw new Error("Workspace not found");
|
|
145383
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
|
+
}
|
|
145384
145671
|
const cwd = workspace.worktree.path;
|
|
145385
145672
|
const defaultBranch = workspace.project.defaultBranch;
|
|
145386
145673
|
const { compareBranch, headBranch, mergeBase } = await resolveDiffContext(
|
|
@@ -145720,11 +146007,11 @@ var workspaceRouter = t2.router({
|
|
|
145720
146007
|
if (!target.startsWith(root) || target === root) {
|
|
145721
146008
|
throw new Error("Invalid path");
|
|
145722
146009
|
}
|
|
145723
|
-
if (
|
|
146010
|
+
if (existsSync9(target)) {
|
|
145724
146011
|
throw new Error("A file or directory already exists at this path");
|
|
145725
146012
|
}
|
|
145726
146013
|
const parent = dirname7(target);
|
|
145727
|
-
if (!
|
|
146014
|
+
if (!existsSync9(parent)) {
|
|
145728
146015
|
throw new Error("Parent directory does not exist");
|
|
145729
146016
|
}
|
|
145730
146017
|
const parentStat = await stat4(parent);
|
|
@@ -145749,11 +146036,11 @@ var workspaceRouter = t2.router({
|
|
|
145749
146036
|
if (!target.startsWith(root) || target === root) {
|
|
145750
146037
|
throw new Error("Invalid path");
|
|
145751
146038
|
}
|
|
145752
|
-
if (
|
|
146039
|
+
if (existsSync9(target)) {
|
|
145753
146040
|
throw new Error("A file or directory already exists at this path");
|
|
145754
146041
|
}
|
|
145755
146042
|
const parent = dirname7(target);
|
|
145756
|
-
if (!
|
|
146043
|
+
if (!existsSync9(parent)) {
|
|
145757
146044
|
throw new Error("Parent directory does not exist");
|
|
145758
146045
|
}
|
|
145759
146046
|
const parentStat = await stat4(parent);
|
|
@@ -145828,11 +146115,11 @@ var workspaceRouter = t2.router({
|
|
|
145828
146115
|
} catch {
|
|
145829
146116
|
throw new Error("Source path does not exist");
|
|
145830
146117
|
}
|
|
145831
|
-
if (
|
|
146118
|
+
if (existsSync9(toTarget)) {
|
|
145832
146119
|
throw new Error("A file or directory already exists at the destination");
|
|
145833
146120
|
}
|
|
145834
146121
|
const toParent = dirname7(toTarget);
|
|
145835
|
-
if (!
|
|
146122
|
+
if (!existsSync9(toParent)) {
|
|
145836
146123
|
throw new Error("Destination parent directory does not exist");
|
|
145837
146124
|
}
|
|
145838
146125
|
const toParentStat = await stat4(toParent);
|
|
@@ -145882,11 +146169,11 @@ var workspaceRouter = t2.router({
|
|
|
145882
146169
|
if (entryStat.isDirectory() && toTarget.startsWith(fromTarget + sep2)) {
|
|
145883
146170
|
throw new Error("Cannot copy a directory into itself");
|
|
145884
146171
|
}
|
|
145885
|
-
if (
|
|
146172
|
+
if (existsSync9(toTarget)) {
|
|
145886
146173
|
throw new Error("A file or directory already exists at the destination");
|
|
145887
146174
|
}
|
|
145888
146175
|
const toParent = dirname7(toTarget);
|
|
145889
|
-
if (!
|
|
146176
|
+
if (!existsSync9(toParent)) {
|
|
145890
146177
|
throw new Error("Destination parent directory does not exist");
|
|
145891
146178
|
}
|
|
145892
146179
|
const toParentStat = await stat4(toParent);
|
|
@@ -146139,21 +146426,21 @@ var tunnelRouter = t2.router({
|
|
|
146139
146426
|
return getTunnelStatus();
|
|
146140
146427
|
}),
|
|
146141
146428
|
start: publicProcedure.input(external_exports2.object({}).optional()).mutation(async () => {
|
|
146142
|
-
|
|
146429
|
+
log27.debug("tunnel.start called");
|
|
146143
146430
|
const port2 = parseInt(process.env.BAND_PORT || "3456", 10);
|
|
146144
|
-
|
|
146431
|
+
log27.debug("tunnel.start: port=%d", port2);
|
|
146145
146432
|
try {
|
|
146146
146433
|
await startTunnel({ port: port2 });
|
|
146147
146434
|
} catch (err) {
|
|
146148
|
-
|
|
146435
|
+
log27.debug({ err }, "tunnel.start: startTunnel failed");
|
|
146149
146436
|
return { ok: true, url: null };
|
|
146150
146437
|
}
|
|
146151
146438
|
const status = getTunnelStatus();
|
|
146152
|
-
|
|
146439
|
+
log27.debug({ status }, "tunnel.start: after startTunnel");
|
|
146153
146440
|
if (status.url) {
|
|
146154
146441
|
return { ok: true, url: status.url };
|
|
146155
146442
|
}
|
|
146156
|
-
|
|
146443
|
+
log27.debug("tunnel.start: no URL available");
|
|
146157
146444
|
return { ok: true, url: null };
|
|
146158
146445
|
}),
|
|
146159
146446
|
stop: publicProcedure.mutation(async () => {
|
|
@@ -146479,15 +146766,15 @@ async function loadJsonlPage(opts) {
|
|
|
146479
146766
|
}
|
|
146480
146767
|
var servicesRouter = t2.router({
|
|
146481
146768
|
health: publicProcedure.query(() => {
|
|
146482
|
-
|
|
146769
|
+
log27.debug("services.health called");
|
|
146483
146770
|
const tunnel = getTunnelStatus();
|
|
146484
|
-
|
|
146771
|
+
log27.debug({ tunnel }, "services.health: tunnel status");
|
|
146485
146772
|
const result = {
|
|
146486
146773
|
webserver: true,
|
|
146487
146774
|
tunnel: tunnel.running,
|
|
146488
146775
|
tunnel_url: tunnel.url
|
|
146489
146776
|
};
|
|
146490
|
-
|
|
146777
|
+
log27.debug({ result }, "services.health result");
|
|
146491
146778
|
return result;
|
|
146492
146779
|
}),
|
|
146493
146780
|
// Activity level controls how often the branch-status poller fires.
|
|
@@ -146881,7 +147168,7 @@ var chatsRouter = t2.router({
|
|
|
146881
147168
|
summary = info?.summary;
|
|
146882
147169
|
lastModified = info?.lastModified;
|
|
146883
147170
|
} catch (err) {
|
|
146884
|
-
|
|
147171
|
+
log27.warn(
|
|
146885
147172
|
{ chatId: input.chatId, sessionId: input.sessionId, err },
|
|
146886
147173
|
"setActiveSession: getSessionInfo failed"
|
|
146887
147174
|
);
|
|
@@ -147001,7 +147288,7 @@ var browserHostRouter = t2.router({
|
|
|
147001
147288
|
// can confirm in the server log that the bridge component actually
|
|
147002
147289
|
// executed. Drop once the experiment is stable.
|
|
147003
147290
|
ping: publicProcedure.input(external_exports2.object({ where: external_exports2.string() })).mutation(({ input }) => {
|
|
147004
|
-
|
|
147291
|
+
log27.info("browserHost.ping from %s", input.where);
|
|
147005
147292
|
return { ok: true };
|
|
147006
147293
|
}),
|
|
147007
147294
|
ensureView: publicProcedure.subscription(async function* (opts) {
|
|
@@ -147504,10 +147791,20 @@ var assets = build_default(clientDir, {
|
|
|
147504
147791
|
gzip: true,
|
|
147505
147792
|
etag: true
|
|
147506
147793
|
});
|
|
147507
|
-
var
|
|
147508
|
-
|
|
147509
|
-
|
|
147510
|
-
|
|
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
|
+
}
|
|
147511
147808
|
function serveStaticFile(res, root, subdir, rawFilename) {
|
|
147512
147809
|
const filename = basename3(decodeURIComponent(rawFilename));
|
|
147513
147810
|
if (!filename || filename.includes("..")) {
|
|
@@ -147561,6 +147858,7 @@ function serveWorkspaceFile(res, workspaceId, rawPath) {
|
|
|
147561
147858
|
async function main() {
|
|
147562
147859
|
runMigrations();
|
|
147563
147860
|
loadChatsFromDb();
|
|
147861
|
+
loadBrowsersFromDb();
|
|
147564
147862
|
cleanupStaleTasks();
|
|
147565
147863
|
startTaskPruneScheduler();
|
|
147566
147864
|
const resetCount = resetAgentStatuses();
|
|
@@ -147666,7 +147964,7 @@ async function main() {
|
|
|
147666
147964
|
"Cache-Control": "no-cache",
|
|
147667
147965
|
"Access-Control-Allow-Origin": "*"
|
|
147668
147966
|
});
|
|
147669
|
-
res.end(
|
|
147967
|
+
res.end(getOpenApiSpec());
|
|
147670
147968
|
return;
|
|
147671
147969
|
}
|
|
147672
147970
|
if (req.url === "/api/docs") {
|
|
@@ -147674,7 +147972,7 @@ async function main() {
|
|
|
147674
147972
|
"Content-Type": "text/html",
|
|
147675
147973
|
"Cache-Control": "no-cache"
|
|
147676
147974
|
});
|
|
147677
|
-
res.end(
|
|
147975
|
+
res.end(getCachedScalarHtml());
|
|
147678
147976
|
return;
|
|
147679
147977
|
}
|
|
147680
147978
|
if (req.url?.startsWith("/mcp")) {
|
|
@@ -147799,6 +148097,7 @@ async function main() {
|
|
|
147799
148097
|
});
|
|
147800
148098
|
httpServer.listen(port, "0.0.0.0", () => {
|
|
147801
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`);
|
|
147802
148101
|
const settings = loadSettings();
|
|
147803
148102
|
if (settings.autoStartTunnel) {
|
|
147804
148103
|
checkPrereqs().then((prereqs) => {
|