@band-app/server 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/DockviewBrowserContainer-Bh7ygcym.js +5 -0
- package/dist/client/assets/DockviewTerminalContainer-BA10dl2w.js +2 -0
- package/dist/client/assets/{TerminalPanel-C4ZPrnFP.js → TerminalPanel-C40mohhY.js} +3 -3
- package/dist/client/assets/{_basePickBy-iyhrrxG-.js → _basePickBy-BoN5C7c3.js} +1 -1
- package/dist/client/assets/{_baseUniq-B1WwbMDv.js → _baseUniq-hs8Z8eGG.js} +1 -1
- package/dist/client/assets/{arc-DjqQ6qnK.js → arc-DStHWz7g.js} +1 -1
- package/dist/client/assets/{architectureDiagram-VXUJARFQ-C03XQiLa.js → architectureDiagram-VXUJARFQ-BmuwLrzR.js} +1 -1
- package/dist/client/assets/{blockDiagram-VD42YOAC-Zzrf5xcb.js → blockDiagram-VD42YOAC-CpfEplz4.js} +1 -1
- package/dist/client/assets/{c4Diagram-YG6GDRKO-BYA4DXcg.js → c4Diagram-YG6GDRKO-DFNXKd12.js} +1 -1
- package/dist/client/assets/channel-cGiKwLh2.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-CPD6ENUL.js → chunk-4BX2VUAB-BhKLwyZj.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CrLS-6CW.js → chunk-55IACEB6--1nGJwoJ.js} +1 -1
- package/dist/client/assets/{chunk-B4BG7PRW-CgpQP0mz.js → chunk-B4BG7PRW-DfW_4HED.js} +1 -1
- package/dist/client/assets/{chunk-DI55MBZ5-IOlh3km5.js → chunk-DI55MBZ5-BBLPj3y_.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DFsVS8Jr.js → chunk-FMBD7UC4-22_QzB6-.js} +1 -1
- package/dist/client/assets/{chunk-QN33PNHL-CmVDL9Gh.js → chunk-QN33PNHL-BsNBNA8p.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-B_Cnx6JN.js → chunk-QZHKN3VN-t5QozrKy.js} +1 -1
- package/dist/client/assets/{chunk-TZMSLE5B-DQbyM2Dh.js → chunk-TZMSLE5B-DTbuaeiD.js} +1 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-aEV-2-qP.js +1 -0
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-aEV-2-qP.js +1 -0
- package/dist/client/assets/clone-CArWpwXp.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-CTHDgB6u.js → cose-bilkent-S5V4N54A-HZO5t4GF.js} +1 -1
- package/dist/client/assets/{dagre-6UL2VRFP-UZkfCyUE.js → dagre-6UL2VRFP-DnOsaGGD.js} +1 -1
- package/dist/client/assets/{diagram-PSM6KHXK-DAlkSZ2c.js → diagram-PSM6KHXK-tirWXx7b.js} +1 -1
- package/dist/client/assets/{diagram-QEK2KX5R-CazlpGGg.js → diagram-QEK2KX5R-Cjtr8l3E.js} +1 -1
- package/dist/client/assets/{diagram-S2PKOQOG-COwMJUec.js → diagram-S2PKOQOG-CuNpvzLc.js} +1 -1
- package/dist/client/assets/{erDiagram-Q2GNP2WA-CXZvqia8.js → erDiagram-Q2GNP2WA-D2Rb5UvQ.js} +1 -1
- package/dist/client/assets/{flowDiagram-NV44I4VS-DA3lEpzG.js → flowDiagram-NV44I4VS-BSQxdSDJ.js} +1 -1
- package/dist/client/assets/{ganttDiagram-JELNMOA3-BWRgS4MP.js → ganttDiagram-JELNMOA3-Cj0PWn4F.js} +3 -3
- package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-7FizCSrq.js → gitGraphDiagram-V2S2FVAM-DMoH-grQ.js} +1 -1
- package/dist/client/assets/{graph-4L_GoTFH.js → graph-B7ABrrXm.js} +1 -1
- package/dist/client/assets/{highlighted-body-B3W2YXNL-ydRS8Ic9.js → highlighted-body-B3W2YXNL-DCQslkUR.js} +1 -1
- package/dist/client/assets/{index-BgKMJy37.js → index-8PaDaRYT.js} +1 -1
- package/dist/client/assets/{index-Bq6PEMRy.js → index-9FCRbBun.js} +1 -1
- package/dist/client/assets/{index-DJqbRWRD.js → index-B22f7bFn.js} +1 -1
- package/dist/client/assets/{index-Bs4eGT35.js → index-BCA8lija.js} +1 -1
- package/dist/client/assets/{index-BaTM0g6E.js → index-BG3Ltnuv.js} +1 -1
- package/dist/client/assets/index-BQhRobL8.js +1 -0
- package/dist/client/assets/{index-Cp1FqGEW.js → index-BaT5I2xy.js} +1 -1
- package/dist/client/assets/{index-Csd34_1g.js → index-BsEwdsSv.js} +1 -1
- package/dist/client/assets/{index-B8VQmYG-.js → index-C99EKoUY.js} +1 -1
- package/dist/client/assets/{index-D2ogHyak.js → index-CBLjtUwT.js} +1 -1
- package/dist/client/assets/{index-C6FACjGj.js → index-COql1I_y.js} +1 -1
- package/dist/client/assets/{index-Cl0dKOpc.js → index-D9SknX6B.js} +1 -1
- package/dist/client/assets/{index-CPC-pCRk.js → index-DWj9bxNA.js} +1 -1
- package/dist/client/assets/{index--PCwWsYS.js → index-DWqvtyLc.js} +1 -1
- package/dist/client/assets/{index-DScY4DVi.js → index-DaWbWCgj.js} +1 -1
- package/dist/client/assets/{index-qf4lR_zM.js → index-Diyv48F3.js} +1 -1
- package/dist/client/assets/{index-SJ6t3qme.js → index-DjFlwM8l.js} +1 -1
- package/dist/client/assets/{index-DTonRA2E.js → index-Myu-_U8q.js} +1 -1
- package/dist/client/assets/{infoDiagram-HS3SLOUP-CB9FyKi7.js → infoDiagram-HS3SLOUP-C_wVpnnp.js} +1 -1
- package/dist/client/assets/{journeyDiagram-XKPGCS4Q-C_bPulxt.js → journeyDiagram-XKPGCS4Q-DcF--XQH.js} +1 -1
- package/dist/client/assets/{kanban-definition-3W4ZIXB7-CGLwqWR-.js → kanban-definition-3W4ZIXB7-BA1w8rep.js} +1 -1
- package/dist/client/assets/{layout-XjqfGmSW.js → layout-DVMDYrln.js} +1 -1
- package/dist/client/assets/{main-FwGkrDro.js → main-B6t1j7Kr.js} +231 -231
- package/dist/client/assets/main-i-GTiqUd.css +1 -0
- package/dist/client/assets/{mindmap-definition-VGOIOE7T-DRNRxvpy.js → mindmap-definition-VGOIOE7T-C1vA0wr2.js} +1 -1
- package/dist/client/assets/{pieDiagram-ADFJNKIX-Co4AML3R.js → pieDiagram-ADFJNKIX-Q71p26az.js} +2 -2
- package/dist/client/assets/{quadrantDiagram-AYHSOK5B-DjuSOXov.js → quadrantDiagram-AYHSOK5B-Bxcd0mzk.js} +1 -1
- package/dist/client/assets/{requirementDiagram-UZGBJVZJ-Cl5py0JI.js → requirementDiagram-UZGBJVZJ-DWqCIKiG.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-TZEHDZUN-BNJImcEG.js → sankeyDiagram-TZEHDZUN-D9rSnLVX.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-WL72ISMW-Bd3PTcpW.js → sequenceDiagram-WL72ISMW-Co2Jz6Fl.js} +1 -1
- package/dist/client/assets/{square-terminal-CiX1sbUO.js → square-terminal-C3zI_mkt.js} +1 -1
- package/dist/client/assets/{stateDiagram-FKZM4ZOC-DXdFd6-L.js → stateDiagram-FKZM4ZOC-CXLDkeLY.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-R8LzGctw.js +1 -0
- package/dist/client/assets/{timeline-definition-IT6M3QCI-8CA5Ftj2.js → timeline-definition-IT6M3QCI-BXxZZYsm.js} +1 -1
- package/dist/client/assets/{treemap-GDKQZRPO-GQ5N0K_o.js → treemap-GDKQZRPO-BgMoU0kM.js} +1 -1
- package/dist/client/assets/workspace._workspaceId-Bww_ZNFK.js +2 -0
- package/dist/client/assets/{workspace._workspaceId-D0sPlrId.js → workspace._workspaceId-C_KGLGyB.js} +1 -1
- package/dist/client/assets/{xychartDiagram-PRI3JC2R-DzcmFrfB.js → xychartDiagram-PRI3JC2R-BQxVaOKh.js} +1 -1
- package/dist/migrations/20260703151516_add_worktree_name/migration.sql +2 -0
- package/dist/migrations/20260703151516_add_worktree_name/snapshot.json +1167 -0
- package/dist/openapi.json +184 -16
- package/dist/server/assets/{DockviewBrowserContainer-DvltiWxV.js → DockviewBrowserContainer-C6QVux14.js} +16 -3
- package/dist/server/assets/{DockviewTerminalContainer-YGo8Zbx1.js → DockviewTerminalContainer-OevWE65L.js} +29 -6
- package/dist/server/assets/{TerminalPanel-Bd0_i38P.js → TerminalPanel-BhOjwcFW.js} +3 -2
- package/dist/server/assets/{_basePickBy-BBas4T8q.js → _basePickBy-DVK5KtlH.js} +2 -2
- package/dist/server/assets/{_baseUniq-Bb-AXRqu.js → _baseUniq-DSFYYhGd.js} +1 -1
- package/dist/server/assets/_tanstack-start-manifest_v-C_7Mj4aJ.js +4 -0
- package/dist/server/assets/{arc-CNbGanI8.js → arc-BpwEbxUR.js} +1 -1
- package/dist/server/assets/{architecture-7HQA4BMR-BBpvCcgY.js → architecture-7HQA4BMR-CNyHLOO7.js} +6 -6
- package/dist/server/assets/{architectureDiagram-VXUJARFQ-CSgRy1oF.js → architectureDiagram-VXUJARFQ-DVUpIskI.js} +6 -6
- package/dist/server/assets/{blockDiagram-VD42YOAC-BZ551zIx.js → blockDiagram-VD42YOAC-CRv2pc0L.js} +6 -6
- package/dist/server/assets/{c4Diagram-YG6GDRKO-BpFPiRxu.js → c4Diagram-YG6GDRKO-CBv74bWb.js} +2 -2
- package/dist/server/assets/{channel-BakvXn0q.js → channel-C_c7u4ky.js} +1 -1
- package/dist/server/assets/{chunk-4BX2VUAB-iq_ixzMT.js → chunk-4BX2VUAB-85OXnz_P.js} +1 -1
- package/dist/server/assets/{chunk-55IACEB6-BTsLLiUt.js → chunk-55IACEB6-Cl8taExZ.js} +1 -1
- package/dist/server/assets/{chunk-B4BG7PRW-rFWSSos9.js → chunk-B4BG7PRW-C7W_R9n6.js} +4 -4
- package/dist/server/assets/{chunk-DI55MBZ5-C6HYpEOk.js → chunk-DI55MBZ5-CTi30KuT.js} +3 -3
- package/dist/server/assets/{chunk-FMBD7UC4-CWm7G-kI.js → chunk-FMBD7UC4-CsuoPD3I.js} +1 -1
- package/dist/server/assets/{chunk-QN33PNHL-C-sH07qa.js → chunk-QN33PNHL-BHHMj_a1.js} +1 -1
- package/dist/server/assets/{chunk-QZHKN3VN-DBYpRTmd.js → chunk-QZHKN3VN-DwwXlOCl.js} +1 -1
- package/dist/server/assets/{chunk-TZMSLE5B-D374mW8S.js → chunk-TZMSLE5B-ECyN9wrL.js} +1 -1
- package/dist/server/assets/{classDiagram-v2-WZHVMYZB-DV-SD-4W.js → classDiagram-2ON5EDUG-qbF8ds74.js} +5 -5
- package/dist/server/assets/{classDiagram-2ON5EDUG-DV-SD-4W.js → classDiagram-v2-WZHVMYZB-qbF8ds74.js} +5 -5
- package/dist/server/assets/{clone-DVtsQqal.js → clone-BCajbdd5.js} +1 -1
- package/dist/server/assets/{cose-bilkent-S5V4N54A-XbCluv3z.js → cose-bilkent-S5V4N54A-D5-w_t4l.js} +1 -1
- package/dist/server/assets/{dagre-6UL2VRFP-CuR4BisU.js → dagre-6UL2VRFP-CCIdAwdB.js} +6 -6
- package/dist/server/assets/{diagram-PSM6KHXK-CV_nySOq.js → diagram-PSM6KHXK-CWGITxy9.js} +7 -7
- package/dist/server/assets/{diagram-QEK2KX5R-Noar7MQT.js → diagram-QEK2KX5R-B07zrGgY.js} +6 -6
- package/dist/server/assets/{diagram-S2PKOQOG-B2BacNFz.js → diagram-S2PKOQOG-XGIpbjo1.js} +6 -6
- package/dist/server/assets/{erDiagram-Q2GNP2WA-B5Os4Fa-.js → erDiagram-Q2GNP2WA-DYHtO3j9.js} +4 -4
- package/dist/server/assets/{flowDiagram-NV44I4VS-DjQR68un.js → flowDiagram-NV44I4VS-Cs7hS9X4.js} +5 -5
- package/dist/server/assets/{ganttDiagram-JELNMOA3-B5uPZ6pu.js → ganttDiagram-JELNMOA3-BhLp8xvm.js} +1 -1
- package/dist/server/assets/{gitGraph-G5XIXVHT-6ZMiJWQT.js → gitGraph-G5XIXVHT-B46gW1OX.js} +6 -6
- package/dist/server/assets/{gitGraphDiagram-V2S2FVAM-DDF08l5z.js → gitGraphDiagram-V2S2FVAM-CZHNGOm0.js} +7 -7
- package/dist/server/assets/{graph-bRh_VJvO.js → graph-4bVECaJM.js} +2 -2
- package/dist/server/assets/{highlighted-body-B3W2YXNL-BI_Gmrii.js → highlighted-body-B3W2YXNL-DSf8s2aV.js} +1 -1
- package/dist/server/assets/{index-Bdft7sx8.js → index-14dCbIAi.js} +5 -5
- package/dist/server/assets/{index-Dyd5DTki.js → index-1OK7lyTa.js} +2 -2
- package/dist/server/assets/{index-y2Y1JSaD.js → index-8EiXP0Bf.js} +2 -2
- package/dist/server/assets/{index-BlZ00-BN.js → index-B72BPMJQ.js} +3 -3
- package/dist/server/assets/{index-K_Bo1J5h.js → index-BLv-1MtR.js} +5 -5
- package/dist/server/assets/{index-auM21h5r.js → index-BRzkEVRG.js} +1 -1
- package/dist/server/assets/{index-BKTDd3Bk.js → index-C7lRWZi8.js} +4 -4
- package/dist/server/assets/{index-VS9oMvxO.js → index-CDG7KvBY.js} +2 -2
- package/dist/server/assets/{index-C-y9iHQ0.js → index-CHvqm6Lz.js} +5 -5
- package/dist/server/assets/{index-CWdeYFNF.js → index-CKPuU6Za.js} +2 -2
- package/dist/server/assets/{index-RnzJqolD.js → index-CWr-Kh5M.js} +2 -2
- package/dist/server/assets/{index-D2pPyR7I.js → index-D2uLA4oe.js} +2 -2
- package/dist/server/assets/{index-DDZbXJFy.js → index-DAq8fRkd.js} +2 -2
- package/dist/server/assets/{index-5xKUZpsF.js → index-Dz2mzfvS.js} +2 -2
- package/dist/server/assets/{index-6TVwGkMb.js → index-Tq3ajWxh.js} +2 -2
- package/dist/server/assets/{index-DpTDX5JD.js → index-U3tOcUUV.js} +2 -2
- package/dist/server/assets/{index-CTIw5jsP.js → index-pFRKwTv2.js} +2 -2
- package/dist/server/assets/{index-CUQ92e7X.js → index-rT9xGtRW.js} +3 -3
- package/dist/server/assets/{info-VBDWY6EO-JLouBLo5.js → info-VBDWY6EO-DrELfFR0.js} +6 -6
- package/dist/server/assets/{infoDiagram-HS3SLOUP-zmvy_WJR.js → infoDiagram-HS3SLOUP-D40Crb-p.js} +5 -5
- package/dist/server/assets/{journeyDiagram-XKPGCS4Q-DyzviNdt.js → journeyDiagram-XKPGCS4Q-dtlVBwV2.js} +4 -4
- package/dist/server/assets/{kanban-definition-3W4ZIXB7-DOBL7QMj.js → kanban-definition-3W4ZIXB7-72vgA7Jl.js} +2 -2
- package/dist/server/assets/{layout-B_Ylwhz8.js → layout-DJ0Eul-X.js} +4 -4
- package/dist/server/assets/{mermaid-3ZIDBTTL-D1krx3WU.js → mermaid-3ZIDBTTL-DGEHf_at.js} +1 -1
- package/dist/server/assets/{mermaid-parser.core-B3d8rAVm.js → mermaid-parser.core-C1UfVEF8.js} +11 -11
- package/dist/server/assets/{mindmap-definition-VGOIOE7T-Kacyqp9Z.js → mindmap-definition-VGOIOE7T-DYfEp2uH.js} +3 -3
- package/dist/server/assets/{packet-DYOGHKS2-Bl6AuzeP.js → packet-DYOGHKS2-IHYchS32.js} +6 -6
- package/dist/server/assets/{pie-VRWISCQL-DTulKqSB.js → pie-VRWISCQL-R6SvOU4g.js} +6 -6
- package/dist/server/assets/{pieDiagram-ADFJNKIX-EBslGQgI.js → pieDiagram-ADFJNKIX-EgffZsud.js} +7 -7
- package/dist/server/assets/{quadrantDiagram-AYHSOK5B-BKSWYe6P.js → quadrantDiagram-AYHSOK5B-n2oJWllV.js} +1 -1
- package/dist/server/assets/{radar-ZZBFDIW7-C5ulLYDn.js → radar-ZZBFDIW7-BX2ya_Na.js} +6 -6
- package/dist/server/assets/{requirementDiagram-UZGBJVZJ-B7nRcnKx.js → requirementDiagram-UZGBJVZJ-CzCXruFj.js} +3 -3
- package/dist/server/assets/{router-hdCv0b-L.js → router-BC8bCsa3.js} +1100 -725
- package/dist/server/assets/{sankeyDiagram-TZEHDZUN-Dq6Q_X6w.js → sankeyDiagram-TZEHDZUN-C0GqwqSS.js} +1 -1
- package/dist/server/assets/{sequenceDiagram-WL72ISMW-CDfofz-s.js → sequenceDiagram-WL72ISMW-BfX0R0LP.js} +3 -3
- package/dist/server/assets/{square-terminal-D7R89vxW.js → square-terminal-BWcJU95Z.js} +1 -1
- package/dist/server/assets/{stateDiagram-FKZM4ZOC-BQdH_sw5.js → stateDiagram-FKZM4ZOC-QowlLVwh.js} +8 -8
- package/dist/server/assets/{stateDiagram-v2-4FDKWEC3-BTwyLH9n.js → stateDiagram-v2-4FDKWEC3-DVHzQlOF.js} +4 -4
- package/dist/server/assets/{timeline-definition-IT6M3QCI-BLfNWXx-.js → timeline-definition-IT6M3QCI-DUoaC7rz.js} +2 -2
- package/dist/server/assets/{treemap-GDKQZRPO-DYGhrk03.js → treemap-GDKQZRPO-B5KIzomx.js} +6 -6
- package/dist/server/assets/{workspace._workspaceId-C9ijioXa.js → workspace._workspaceId-DRK2dblR.js} +101 -11
- package/dist/server/assets/{workspace._workspaceId-BrMajMrS.js → workspace._workspaceId-hnIpuUNX.js} +1 -1
- package/dist/server/assets/{xychartDiagram-PRI3JC2R-CTiLODEl.js → xychartDiagram-PRI3JC2R-aNxYxejD.js} +1 -1
- package/dist/server/server.js +2 -2
- package/dist/start-server.mjs +736 -512
- package/package.json +4 -4
- package/dist/client/assets/DockviewBrowserContainer-AeGrBvbe.js +0 -5
- package/dist/client/assets/DockviewTerminalContainer-CEcmk81d.js +0 -2
- package/dist/client/assets/channel-ByfqtAS4.js +0 -1
- package/dist/client/assets/classDiagram-2ON5EDUG-CmzSv5tz.js +0 -1
- package/dist/client/assets/classDiagram-v2-WZHVMYZB-CmzSv5tz.js +0 -1
- package/dist/client/assets/clone-D6Np9jJP.js +0 -1
- package/dist/client/assets/index-p4yr3DW9.js +0 -1
- package/dist/client/assets/main-CBlP-xQr.css +0 -1
- package/dist/client/assets/stateDiagram-v2-4FDKWEC3-kbB9WbNB.js +0 -1
- package/dist/client/assets/workspace._workspaceId-C_iuy4p6.js +0 -2
- package/dist/server/assets/_tanstack-start-manifest_v-DJ7xH6AI.js +0 -4
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, log47) {
|
|
6505
6505
|
return {
|
|
6506
6506
|
level,
|
|
6507
6507
|
bindings,
|
|
6508
|
-
log:
|
|
6508
|
+
log: log47
|
|
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: log47 } = options2.formatters;
|
|
6892
6892
|
instance[formattersSym] = buildFormatters(
|
|
6893
6893
|
level || formatters.level,
|
|
6894
6894
|
chindings || resetChildingsFormatter,
|
|
6895
|
-
|
|
6895
|
+
log47 || formatters.log
|
|
6896
6896
|
);
|
|
6897
6897
|
} else {
|
|
6898
6898
|
instance[formattersSym] = buildFormatters(
|
|
@@ -30213,7 +30213,7 @@ var init_claude_code = __esm({
|
|
|
30213
30213
|
}
|
|
30214
30214
|
}
|
|
30215
30215
|
async listSessions(dir) {
|
|
30216
|
-
log2.
|
|
30216
|
+
log2.debug({ dir }, "listSessions");
|
|
30217
30217
|
const sessions = await c7$({ dir });
|
|
30218
30218
|
const filtered = sessions.filter((s6) => s6.cwd === dir);
|
|
30219
30219
|
const lastPrompts = await Promise.all(
|
|
@@ -32358,7 +32358,7 @@ var init_codex = __esm({
|
|
|
32358
32358
|
};
|
|
32359
32359
|
}
|
|
32360
32360
|
async listSessions(dir) {
|
|
32361
|
-
log4.
|
|
32361
|
+
log4.debug({ dir }, "listSessions");
|
|
32362
32362
|
const sessions = await readCodexSessions();
|
|
32363
32363
|
return sessions.filter((s6) => s6.cwd === dir).sort((a6, b10) => b10.lastModified - a6.lastModified);
|
|
32364
32364
|
}
|
|
@@ -33244,7 +33244,7 @@ var init_opencode = __esm({
|
|
|
33244
33244
|
}
|
|
33245
33245
|
async listSessions(dir) {
|
|
33246
33246
|
const sessions = await fetchOpenCodeSessions(this.executablePath, dir);
|
|
33247
|
-
log6.
|
|
33247
|
+
log6.debug({ dir, count: sessions.length }, "listSessions");
|
|
33248
33248
|
return sessions.map((s6) => ({
|
|
33249
33249
|
sessionId: s6.id,
|
|
33250
33250
|
summary: s6.title || "Untitled session",
|
|
@@ -87212,11 +87212,11 @@ var require_core = __commonJS({
|
|
|
87212
87212
|
Ajv2.ValidationError = validation_error_1.default;
|
|
87213
87213
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
87214
87214
|
exports.default = Ajv2;
|
|
87215
|
-
function checkOptions(checkOpts, options2, msg,
|
|
87215
|
+
function checkOptions(checkOpts, options2, msg, log47 = "error") {
|
|
87216
87216
|
for (const key in checkOpts) {
|
|
87217
87217
|
const opt = key;
|
|
87218
87218
|
if (opt in options2)
|
|
87219
|
-
this.logger[
|
|
87219
|
+
this.logger[log47](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
87220
87220
|
}
|
|
87221
87221
|
}
|
|
87222
87222
|
function getSchEnv(keyRef) {
|
|
@@ -101797,6 +101797,16 @@ var projects = sqliteTable("projects", {
|
|
|
101797
101797
|
var worktrees = sqliteTable("worktrees", {
|
|
101798
101798
|
id: integer2("id").primaryKey({ autoIncrement: true }),
|
|
101799
101799
|
projectName: text2("project_name").notNull().references(() => projects.name, { onDelete: "cascade" }),
|
|
101800
|
+
// Immutable workspace identity, set once at creation to the (slugified)
|
|
101801
|
+
// branch name. The workspace id is derived from this (`toWorkspaceId`),
|
|
101802
|
+
// NOT from `branch` — so switching the git branch inside the worktree
|
|
101803
|
+
// doesn't change the id (and everything keyed by it) or the projects-list
|
|
101804
|
+
// label. Sync updates `branch` to track git; it never touches `name`.
|
|
101805
|
+
// Backfilled to `branch` for pre-existing rows by the migration.
|
|
101806
|
+
name: text2("name").notNull(),
|
|
101807
|
+
// Live git branch checked out in the worktree. Reconciled against git by
|
|
101808
|
+
// `syncWorktrees` and used as the target of git operations. Distinct from
|
|
101809
|
+
// `name` above once the branch is switched.
|
|
101800
101810
|
branch: text2("branch").notNull(),
|
|
101801
101811
|
path: text2("path").notNull(),
|
|
101802
101812
|
head: text2("head"),
|
|
@@ -102529,16 +102539,89 @@ function listenerCount() {
|
|
|
102529
102539
|
// src/server/infra/setup/setup-runner.ts
|
|
102530
102540
|
import { spawn as spawn5 } from "node:child_process";
|
|
102531
102541
|
|
|
102542
|
+
// src/server/infra/process/path.ts
|
|
102543
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
102544
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
102545
|
+
import { delimiter } from "node:path";
|
|
102546
|
+
function defaultShell() {
|
|
102547
|
+
if (process.env.SHELL) return process.env.SHELL;
|
|
102548
|
+
if (process.platform === "win32") return process.env.ComSpec || "cmd.exe";
|
|
102549
|
+
for (const candidate of ["/bin/zsh", "/bin/bash", "/bin/sh"]) {
|
|
102550
|
+
if (existsSync4(candidate)) return candidate;
|
|
102551
|
+
}
|
|
102552
|
+
return "/bin/sh";
|
|
102553
|
+
}
|
|
102554
|
+
var cachedBinDirs = null;
|
|
102555
|
+
function extraBinDirs() {
|
|
102556
|
+
if (cachedBinDirs) return cachedBinDirs;
|
|
102557
|
+
if (process.platform === "darwin") {
|
|
102558
|
+
cachedBinDirs = ["/opt/homebrew/bin", "/usr/local/bin"];
|
|
102559
|
+
} else if (process.platform === "linux") {
|
|
102560
|
+
const dirs = [];
|
|
102561
|
+
const linuxbrew = "/home/linuxbrew/.linuxbrew/bin";
|
|
102562
|
+
if (existsSync4(linuxbrew)) dirs.push(linuxbrew);
|
|
102563
|
+
dirs.push("/usr/local/bin");
|
|
102564
|
+
cachedBinDirs = dirs;
|
|
102565
|
+
} else {
|
|
102566
|
+
cachedBinDirs = [];
|
|
102567
|
+
}
|
|
102568
|
+
return cachedBinDirs;
|
|
102569
|
+
}
|
|
102570
|
+
function prependBinDirs(path3) {
|
|
102571
|
+
return [...extraBinDirs(), ...path3 ? [path3] : []].join(delimiter);
|
|
102572
|
+
}
|
|
102573
|
+
var cachedShellPath = null;
|
|
102574
|
+
async function shellPath() {
|
|
102575
|
+
if (cachedShellPath) return cachedShellPath;
|
|
102576
|
+
const shell = defaultShell();
|
|
102577
|
+
try {
|
|
102578
|
+
const result = await new Promise((resolve12, reject) => {
|
|
102579
|
+
execFile3(shell, ["-li", "-c", "echo $PATH"], { timeout: 5e3 }, (err, stdout) => {
|
|
102580
|
+
if (err) {
|
|
102581
|
+
reject(err);
|
|
102582
|
+
return;
|
|
102583
|
+
}
|
|
102584
|
+
resolve12(stdout.trim());
|
|
102585
|
+
});
|
|
102586
|
+
});
|
|
102587
|
+
if (result) {
|
|
102588
|
+
cachedShellPath = result;
|
|
102589
|
+
return result;
|
|
102590
|
+
}
|
|
102591
|
+
} catch {
|
|
102592
|
+
}
|
|
102593
|
+
const fallback = prependBinDirs(process.env.PATH);
|
|
102594
|
+
cachedShellPath = fallback;
|
|
102595
|
+
return fallback;
|
|
102596
|
+
}
|
|
102597
|
+
async function whichBinary(name3) {
|
|
102598
|
+
const resolvedPath = await shellPath();
|
|
102599
|
+
try {
|
|
102600
|
+
const result = await new Promise((resolve12, reject) => {
|
|
102601
|
+
execFile3("which", [name3], { env: { ...process.env, PATH: resolvedPath } }, (err, stdout) => {
|
|
102602
|
+
if (err) {
|
|
102603
|
+
reject(err);
|
|
102604
|
+
return;
|
|
102605
|
+
}
|
|
102606
|
+
resolve12(stdout.trim());
|
|
102607
|
+
});
|
|
102608
|
+
});
|
|
102609
|
+
return result || null;
|
|
102610
|
+
} catch {
|
|
102611
|
+
return null;
|
|
102612
|
+
}
|
|
102613
|
+
}
|
|
102614
|
+
|
|
102532
102615
|
// src/server/infra/setup/project-config.ts
|
|
102533
102616
|
init_src();
|
|
102534
102617
|
init_zod();
|
|
102535
|
-
import { existsSync as
|
|
102618
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "node:fs";
|
|
102536
102619
|
import { join as join14 } from "node:path";
|
|
102537
102620
|
var log10 = createLogger("project-config");
|
|
102538
102621
|
function loadProjectConfig(worktreePath, projectPath) {
|
|
102539
102622
|
for (const base2 of [worktreePath, projectPath]) {
|
|
102540
102623
|
const configPath = join14(base2, ".band", "config.json");
|
|
102541
|
-
if (
|
|
102624
|
+
if (existsSync5(configPath)) {
|
|
102542
102625
|
try {
|
|
102543
102626
|
return JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
102544
102627
|
} catch {
|
|
@@ -102550,7 +102633,7 @@ function loadProjectConfig(worktreePath, projectPath) {
|
|
|
102550
102633
|
var CopyFilesSchema = external_exports.array(external_exports.string()).optional();
|
|
102551
102634
|
function getCopyFiles(projectPath) {
|
|
102552
102635
|
const configPath = join14(projectPath, ".band", "config.json");
|
|
102553
|
-
if (!
|
|
102636
|
+
if (!existsSync5(configPath)) return null;
|
|
102554
102637
|
let raw;
|
|
102555
102638
|
try {
|
|
102556
102639
|
raw = JSON.parse(readFileSync6(configPath, "utf-8"));
|
|
@@ -102589,7 +102672,7 @@ function runSetup(workspaceId, worktreePath, projectPath, onComplete) {
|
|
|
102589
102672
|
cwd: worktreePath,
|
|
102590
102673
|
env: {
|
|
102591
102674
|
...parentEnv,
|
|
102592
|
-
PATH:
|
|
102675
|
+
PATH: prependBinDirs(process.env.PATH)
|
|
102593
102676
|
},
|
|
102594
102677
|
stdio: ["ignore", "pipe", "pipe"]
|
|
102595
102678
|
});
|
|
@@ -111512,11 +111595,27 @@ function DialogOverlay2({
|
|
|
111512
111595
|
}
|
|
111513
111596
|
);
|
|
111514
111597
|
}
|
|
111598
|
+
var DIALOG_CONTENT_VARIANTS = {
|
|
111599
|
+
default: "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
|
|
111600
|
+
"bottom-sheet": [
|
|
111601
|
+
// Shared
|
|
111602
|
+
"fixed z-50 flex flex-col bg-background shadow-lg duration-200 outline-none",
|
|
111603
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
111604
|
+
// Mobile (< lg): bottom drawer
|
|
111605
|
+
"inset-x-0 bottom-0 w-full max-w-none rounded-t-2xl border border-b-0 p-6",
|
|
111606
|
+
"max-h-[calc(100dvh-env(safe-area-inset-top)-1.5rem)]",
|
|
111607
|
+
"max-lg:data-[state=open]:slide-in-from-bottom max-lg:data-[state=closed]:slide-out-to-bottom",
|
|
111608
|
+
// Desktop (lg+): revert to the centred modal
|
|
111609
|
+
"lg:inset-auto lg:top-[50%] lg:left-[50%] lg:bottom-auto lg:w-full lg:max-w-lg lg:max-h-[85vh] lg:translate-x-[-50%] lg:translate-y-[-50%] lg:rounded-lg lg:border-b",
|
|
111610
|
+
"lg:data-[state=open]:zoom-in-95 lg:data-[state=closed]:zoom-out-95"
|
|
111611
|
+
].join(" ")
|
|
111612
|
+
};
|
|
111515
111613
|
function DialogContent2({
|
|
111516
111614
|
className,
|
|
111517
111615
|
overlayClassName,
|
|
111518
111616
|
children,
|
|
111519
111617
|
showCloseButton = true,
|
|
111618
|
+
variant = "default",
|
|
111520
111619
|
...props
|
|
111521
111620
|
}) {
|
|
111522
111621
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DialogPortal2, { "data-slot": "dialog-portal", children: [
|
|
@@ -111525,10 +111624,8 @@ function DialogContent2({
|
|
|
111525
111624
|
dist_exports2.Content,
|
|
111526
111625
|
{
|
|
111527
111626
|
"data-slot": "dialog-content",
|
|
111528
|
-
|
|
111529
|
-
|
|
111530
|
-
className
|
|
111531
|
-
),
|
|
111627
|
+
"data-variant": variant,
|
|
111628
|
+
className: cn(DIALOG_CONTENT_VARIANTS[variant], className),
|
|
111532
111629
|
...props,
|
|
111533
111630
|
children: [
|
|
111534
111631
|
children,
|
|
@@ -111698,19 +111795,22 @@ var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
|
|
|
111698
111795
|
// ../../packages/ui/src/components/select.tsx
|
|
111699
111796
|
var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
|
|
111700
111797
|
|
|
111701
|
-
// ../../packages/ui/src/components/
|
|
111798
|
+
// ../../packages/ui/src/components/sheet.tsx
|
|
111702
111799
|
var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
|
|
111703
111800
|
|
|
111704
|
-
// ../../packages/ui/src/components/
|
|
111801
|
+
// ../../packages/ui/src/components/spinner.tsx
|
|
111705
111802
|
var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
|
|
111706
111803
|
|
|
111707
|
-
// ../../packages/ui/src/components/
|
|
111804
|
+
// ../../packages/ui/src/components/switch.tsx
|
|
111708
111805
|
var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
|
|
111806
|
+
|
|
111807
|
+
// ../../packages/ui/src/components/tooltip.tsx
|
|
111808
|
+
var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
|
|
111709
111809
|
function Tooltip2({ ...props }) {
|
|
111710
|
-
return /* @__PURE__ */ (0,
|
|
111810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(dist_exports8.Root, { "data-slot": "tooltip", ...props });
|
|
111711
111811
|
}
|
|
111712
111812
|
function TooltipTrigger2({ ...props }) {
|
|
111713
|
-
return /* @__PURE__ */ (0,
|
|
111813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(dist_exports8.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
111714
111814
|
}
|
|
111715
111815
|
function TooltipContent2({
|
|
111716
111816
|
className,
|
|
@@ -111718,7 +111818,7 @@ function TooltipContent2({
|
|
|
111718
111818
|
children,
|
|
111719
111819
|
...props
|
|
111720
111820
|
}) {
|
|
111721
|
-
return /* @__PURE__ */ (0,
|
|
111821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(dist_exports8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
111722
111822
|
dist_exports8.Content,
|
|
111723
111823
|
{
|
|
111724
111824
|
"data-slot": "tooltip-content",
|
|
@@ -111730,7 +111830,7 @@ function TooltipContent2({
|
|
|
111730
111830
|
...props,
|
|
111731
111831
|
children: [
|
|
111732
111832
|
children,
|
|
111733
|
-
/* @__PURE__ */ (0,
|
|
111833
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(dist_exports8.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })
|
|
111734
111834
|
]
|
|
111735
111835
|
}
|
|
111736
111836
|
) });
|
|
@@ -113873,7 +113973,7 @@ var QueryClient = class {
|
|
|
113873
113973
|
|
|
113874
113974
|
// ../../node_modules/.pnpm/@tanstack+react-query@5.90.21_react@19.2.4/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js
|
|
113875
113975
|
var React31 = __toESM(require_react(), 1);
|
|
113876
|
-
var
|
|
113976
|
+
var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
|
|
113877
113977
|
var QueryClientContext = React31.createContext(
|
|
113878
113978
|
void 0
|
|
113879
113979
|
);
|
|
@@ -113953,7 +114053,7 @@ function useRawDashboardStore() {
|
|
|
113953
114053
|
}
|
|
113954
114054
|
|
|
113955
114055
|
// src/dashboard/context.tsx
|
|
113956
|
-
var
|
|
114056
|
+
var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
|
|
113957
114057
|
var DashboardContext = (0, import_react5.createContext)(null);
|
|
113958
114058
|
function useAdapter() {
|
|
113959
114059
|
const ctx = (0, import_react5.useContext)(DashboardContext);
|
|
@@ -113979,15 +114079,18 @@ function useRemoveWorkspace() {
|
|
|
113979
114079
|
const openWorkspace = useDashboardStore((s6) => s6.openWorkspace);
|
|
113980
114080
|
const store2 = useRawDashboardStore();
|
|
113981
114081
|
return useMutation({
|
|
113982
|
-
mutationFn: ({ project,
|
|
113983
|
-
onSuccess: (_data, { project,
|
|
114082
|
+
mutationFn: ({ project, name: name3 }) => adapter.removeWorkspace(project, name3),
|
|
114083
|
+
onSuccess: (_data, { project, name: name3 }) => {
|
|
113984
114084
|
queryClient2.invalidateQueries({ queryKey: queryKeys.projects });
|
|
113985
|
-
const deletedWorkspaceId = toWorkspaceId(project,
|
|
114085
|
+
const deletedWorkspaceId = toWorkspaceId(project, name3);
|
|
113986
114086
|
if (store2.getState().activeWorkspaceId === deletedWorkspaceId) {
|
|
113987
114087
|
const projects2 = queryClient2.getQueryData(queryKeys.projects);
|
|
113988
114088
|
const projectInfo = projects2?.find((p6) => p6.name === project);
|
|
113989
114089
|
if (projectInfo) {
|
|
113990
|
-
|
|
114090
|
+
const mainWt = projectInfo.worktrees.find(
|
|
114091
|
+
(wt) => wt.name === projectInfo.defaultBranch || wt.branch === projectInfo.defaultBranch
|
|
114092
|
+
);
|
|
114093
|
+
openWorkspace(toWorkspaceId(project, mainWt?.name ?? projectInfo.defaultBranch));
|
|
113991
114094
|
}
|
|
113992
114095
|
}
|
|
113993
114096
|
},
|
|
@@ -113998,14 +114101,14 @@ function useRemoveWorkspace() {
|
|
|
113998
114101
|
}
|
|
113999
114102
|
|
|
114000
114103
|
// src/dashboard/components/AddProjectDialog.tsx
|
|
114001
|
-
var
|
|
114104
|
+
var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
|
|
114002
114105
|
|
|
114003
114106
|
// src/dashboard/components/AgentStatusIndicator.tsx
|
|
114004
114107
|
var import_lucide_react2 = __toESM(require_lucide_react(), 1);
|
|
114005
|
-
var
|
|
114108
|
+
var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
|
|
114006
114109
|
function AgentStatusIndicator({ agent, isActive }) {
|
|
114007
114110
|
if (!agent || agent.status !== "working" && agent.status !== "needs_attention") {
|
|
114008
|
-
return /* @__PURE__ */ (0,
|
|
114111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
114009
114112
|
import_lucide_react2.GitBranch,
|
|
114010
114113
|
{
|
|
114011
114114
|
className: `size-3 shrink-0 ${isActive ? "text-primary" : "text-muted-foreground"}`
|
|
@@ -114016,18 +114119,18 @@ function AgentStatusIndicator({ agent, isActive }) {
|
|
|
114016
114119
|
const color = isWorking ? "bg-status-working" : "bg-status-needs-attention";
|
|
114017
114120
|
const tooltip = isWorking ? "Agent running..." : "Needs your attention";
|
|
114018
114121
|
const animation = isWorking ? "" : "animate-status-pulse";
|
|
114019
|
-
return /* @__PURE__ */ (0,
|
|
114020
|
-
/* @__PURE__ */ (0,
|
|
114021
|
-
/* @__PURE__ */ (0,
|
|
114122
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Tooltip2, { children: [
|
|
114123
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: `inline-block size-2 shrink-0 rounded-full ${color} ${animation}` }) }),
|
|
114124
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TooltipContent2, { side: "top", children: tooltip })
|
|
114022
114125
|
] });
|
|
114023
114126
|
}
|
|
114024
114127
|
|
|
114025
114128
|
// src/dashboard/components/agent-icons.tsx
|
|
114026
|
-
var
|
|
114129
|
+
var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
|
|
114027
114130
|
|
|
114028
114131
|
// src/dashboard/components/CIStatusIndicator.tsx
|
|
114029
114132
|
var import_lucide_react3 = __toESM(require_lucide_react(), 1);
|
|
114030
|
-
var
|
|
114133
|
+
var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
|
|
114031
114134
|
function CIStatusIndicator({ ci }) {
|
|
114032
114135
|
const capabilities = useCapabilities();
|
|
114033
114136
|
const handleOpenUrl = (url, e2) => {
|
|
@@ -114037,63 +114140,63 @@ function CIStatusIndicator({ ci }) {
|
|
|
114037
114140
|
const clickable = !!ci.url && !!capabilities.openUrl;
|
|
114038
114141
|
const cursorClass = clickable ? "cursor-pointer" : "";
|
|
114039
114142
|
if (ci.state === "merged") {
|
|
114040
|
-
return /* @__PURE__ */ (0,
|
|
114041
|
-
/* @__PURE__ */ (0,
|
|
114143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Tooltip2, { children: [
|
|
114144
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
114042
114145
|
import_lucide_react3.GitMerge,
|
|
114043
114146
|
{
|
|
114044
114147
|
className: `size-3.5 shrink-0 text-violet-600 dark:text-violet-400 ${cursorClass}`,
|
|
114045
114148
|
onClick: (e2) => handleOpenUrl(ci.url, e2)
|
|
114046
114149
|
}
|
|
114047
114150
|
) }),
|
|
114048
|
-
/* @__PURE__ */ (0,
|
|
114151
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipContent2, { children: "Merged" })
|
|
114049
114152
|
] });
|
|
114050
114153
|
}
|
|
114051
114154
|
if (ci.state === "success") {
|
|
114052
|
-
return /* @__PURE__ */ (0,
|
|
114053
|
-
/* @__PURE__ */ (0,
|
|
114155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Tooltip2, { children: [
|
|
114156
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
114054
114157
|
import_lucide_react3.CircleCheck,
|
|
114055
114158
|
{
|
|
114056
114159
|
className: `size-3.5 shrink-0 text-green-600 dark:text-green-400 ${cursorClass}`,
|
|
114057
114160
|
onClick: (e2) => handleOpenUrl(ci.url, e2)
|
|
114058
114161
|
}
|
|
114059
114162
|
) }),
|
|
114060
|
-
/* @__PURE__ */ (0,
|
|
114163
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipContent2, { children: "CI passed" })
|
|
114061
114164
|
] });
|
|
114062
114165
|
}
|
|
114063
114166
|
if (ci.state === "failure") {
|
|
114064
|
-
return /* @__PURE__ */ (0,
|
|
114065
|
-
/* @__PURE__ */ (0,
|
|
114167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Tooltip2, { children: [
|
|
114168
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
114066
114169
|
import_lucide_react3.CircleAlert,
|
|
114067
114170
|
{
|
|
114068
114171
|
className: `size-3.5 shrink-0 text-red-600 dark:text-red-400 ${cursorClass}`,
|
|
114069
114172
|
onClick: (e2) => handleOpenUrl(ci.url, e2)
|
|
114070
114173
|
}
|
|
114071
114174
|
) }),
|
|
114072
|
-
/* @__PURE__ */ (0,
|
|
114175
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipContent2, { children: "CI failed" })
|
|
114073
114176
|
] });
|
|
114074
114177
|
}
|
|
114075
114178
|
if (ci.state === "running" || ci.state === "pending") {
|
|
114076
|
-
return /* @__PURE__ */ (0,
|
|
114077
|
-
/* @__PURE__ */ (0,
|
|
114179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Tooltip2, { children: [
|
|
114180
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
114078
114181
|
import_lucide_react3.Loader,
|
|
114079
114182
|
{
|
|
114080
114183
|
className: `size-3.5 shrink-0 text-yellow-600 dark:text-yellow-400 animate-spin ${cursorClass}`,
|
|
114081
114184
|
onClick: (e2) => handleOpenUrl(ci.url, e2)
|
|
114082
114185
|
}
|
|
114083
114186
|
) }),
|
|
114084
|
-
/* @__PURE__ */ (0,
|
|
114187
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipContent2, { children: ci.state === "running" ? "CI running" : "CI pending" })
|
|
114085
114188
|
] });
|
|
114086
114189
|
}
|
|
114087
114190
|
if (ci.state === "cancelled") {
|
|
114088
|
-
return /* @__PURE__ */ (0,
|
|
114089
|
-
/* @__PURE__ */ (0,
|
|
114191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Tooltip2, { children: [
|
|
114192
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
114090
114193
|
import_lucide_react3.Ban,
|
|
114091
114194
|
{
|
|
114092
114195
|
className: `size-3.5 shrink-0 text-gray-600 dark:text-gray-400 ${cursorClass}`,
|
|
114093
114196
|
onClick: (e2) => handleOpenUrl(ci.url, e2)
|
|
114094
114197
|
}
|
|
114095
114198
|
) }),
|
|
114096
|
-
/* @__PURE__ */ (0,
|
|
114199
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TooltipContent2, { children: "CI cancelled" })
|
|
114097
114200
|
] });
|
|
114098
114201
|
}
|
|
114099
114202
|
return null;
|
|
@@ -114442,19 +114545,19 @@ function legacyCopy(text3) {
|
|
|
114442
114545
|
var setSelectionTooltip = StateEffect.define();
|
|
114443
114546
|
|
|
114444
114547
|
// src/dashboard/components/CodeMirrorEditor.tsx
|
|
114445
|
-
var
|
|
114548
|
+
var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
|
|
114446
114549
|
|
|
114447
114550
|
// src/dashboard/components/CodeMirrorViewer.tsx
|
|
114448
114551
|
var import_react9 = __toESM(require_react(), 1);
|
|
114449
|
-
var
|
|
114552
|
+
var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
|
|
114450
114553
|
|
|
114451
114554
|
// src/dashboard/components/CommandPaletteDialog.tsx
|
|
114452
114555
|
var import_react10 = __toESM(require_react(), 1);
|
|
114453
|
-
var
|
|
114556
|
+
var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
|
|
114454
114557
|
|
|
114455
114558
|
// src/dashboard/components/CommitDialog.tsx
|
|
114456
114559
|
var import_react11 = __toESM(require_react(), 1);
|
|
114457
|
-
var
|
|
114560
|
+
var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
|
|
114458
114561
|
|
|
114459
114562
|
// src/dashboard/components/DashboardShell.tsx
|
|
114460
114563
|
var import_react25 = __toESM(require_react(), 1);
|
|
@@ -114493,7 +114596,7 @@ var import_react22 = __toESM(require_react(), 1);
|
|
|
114493
114596
|
var import_react19 = __toESM(require_react(), 1);
|
|
114494
114597
|
|
|
114495
114598
|
// src/dashboard/components/DeleteWorkspaceDialog.tsx
|
|
114496
|
-
var
|
|
114599
|
+
var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
|
|
114497
114600
|
|
|
114498
114601
|
// src/dashboard/components/NewWorkspaceForm.tsx
|
|
114499
114602
|
var import_react20 = __toESM(require_react(), 1);
|
|
@@ -114504,17 +114607,17 @@ function slugifyBranchName(input) {
|
|
|
114504
114607
|
}
|
|
114505
114608
|
|
|
114506
114609
|
// src/dashboard/components/NewWorkspaceForm.tsx
|
|
114507
|
-
var
|
|
114610
|
+
var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
|
|
114508
114611
|
|
|
114509
114612
|
// src/dashboard/components/PromoteToGitDialog.tsx
|
|
114510
|
-
var
|
|
114613
|
+
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
|
|
114511
114614
|
|
|
114512
114615
|
// src/dashboard/components/WorkspaceCard.tsx
|
|
114513
114616
|
var import_lucide_react5 = __toESM(require_lucide_react(), 1);
|
|
114514
114617
|
var import_react21 = __toESM(require_react(), 1);
|
|
114515
114618
|
|
|
114516
114619
|
// src/dashboard/components/GitStatusIndicator.tsx
|
|
114517
|
-
var
|
|
114620
|
+
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
114518
114621
|
function GitStatusIndicator({ git }) {
|
|
114519
114622
|
const parts = [];
|
|
114520
114623
|
if (git.conflict) {
|
|
@@ -114546,27 +114649,27 @@ function GitStatusIndicator({ git }) {
|
|
|
114546
114649
|
});
|
|
114547
114650
|
}
|
|
114548
114651
|
if (parts.length === 0) return null;
|
|
114549
|
-
return /* @__PURE__ */ (0,
|
|
114550
|
-
/* @__PURE__ */ (0,
|
|
114551
|
-
/* @__PURE__ */ (0,
|
|
114652
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Tooltip2, { children: [
|
|
114653
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime56.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_runtime56.jsx)("span", { className: p6.color, children: p6.text }, p6.text)) }) }),
|
|
114654
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TooltipContent2, { children: parts.map((p6) => p6.tooltip).join(", ") })
|
|
114552
114655
|
] });
|
|
114553
114656
|
}
|
|
114554
114657
|
|
|
114555
114658
|
// src/dashboard/components/SetupStatusIndicator.tsx
|
|
114556
114659
|
var import_lucide_react4 = __toESM(require_lucide_react(), 1);
|
|
114557
|
-
var
|
|
114660
|
+
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
114558
114661
|
function SetupStatusIndicator({ setup }) {
|
|
114559
114662
|
if (!setup) return null;
|
|
114560
114663
|
if (setup.state === "running") {
|
|
114561
|
-
return /* @__PURE__ */ (0,
|
|
114562
|
-
/* @__PURE__ */ (0,
|
|
114563
|
-
/* @__PURE__ */ (0,
|
|
114664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Tooltip2, { children: [
|
|
114665
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react4.Loader, { className: "size-3.5 shrink-0 text-blue-600 dark:text-blue-400 animate-spin" }) }),
|
|
114666
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipContent2, { side: "top", children: "Setting up workspace..." })
|
|
114564
114667
|
] });
|
|
114565
114668
|
}
|
|
114566
114669
|
if (setup.state === "failed") {
|
|
114567
|
-
return /* @__PURE__ */ (0,
|
|
114568
|
-
/* @__PURE__ */ (0,
|
|
114569
|
-
/* @__PURE__ */ (0,
|
|
114670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Tooltip2, { children: [
|
|
114671
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react4.CircleAlert, { className: "size-3.5 shrink-0 text-red-600 dark:text-red-400" }) }),
|
|
114672
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(TooltipContent2, { side: "top", children: [
|
|
114570
114673
|
"Setup failed",
|
|
114571
114674
|
setup.error ? `: ${setup.error}` : ""
|
|
114572
114675
|
] })
|
|
@@ -114576,7 +114679,7 @@ function SetupStatusIndicator({ setup }) {
|
|
|
114576
114679
|
}
|
|
114577
114680
|
|
|
114578
114681
|
// src/dashboard/components/WorkspaceCard.tsx
|
|
114579
|
-
var
|
|
114682
|
+
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
|
|
114580
114683
|
var RECENT_ACTIVATION_WINDOW_MS = 300;
|
|
114581
114684
|
var recentlyActivatedWorkspaceId = null;
|
|
114582
114685
|
var recentlyActivatedTimer = null;
|
|
@@ -114620,7 +114723,7 @@ var WorkspaceCard = (0, import_react21.memo)(function WorkspaceCard2({
|
|
|
114620
114723
|
const gitPush = useDashboardStore((s6) => s6.gitPush);
|
|
114621
114724
|
const removeWorkspaceMutation = useRemoveWorkspace();
|
|
114622
114725
|
const isPinned = worktree.pinned;
|
|
114623
|
-
const workspaceId = toWorkspaceId(projectName, worktree.
|
|
114726
|
+
const workspaceId = toWorkspaceId(projectName, worktree.name);
|
|
114624
114727
|
const isActive = useDashboardStore((s6) => s6.activeWorkspaceId === workspaceId);
|
|
114625
114728
|
const href = capabilities.getWorkspaceHref?.(workspaceId);
|
|
114626
114729
|
(0, import_react21.useEffect)(() => {
|
|
@@ -114637,7 +114740,7 @@ var WorkspaceCard = (0, import_react21.memo)(function WorkspaceCard2({
|
|
|
114637
114740
|
openWorkspace(workspaceId);
|
|
114638
114741
|
}
|
|
114639
114742
|
};
|
|
114640
|
-
const className = `@container group flex flex-row items-center justify-between pl-3 pr-2 py-1 min-h-9 min-w-0 overflow-hidden cursor-pointer select-none touch-manipulation transition-colors hover:bg-accent/50 [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:py-2 ${isActive ? "
|
|
114743
|
+
const className = `@container group flex flex-row items-center justify-between rounded-md pl-3 pr-2 py-1 min-h-9 min-w-0 overflow-hidden cursor-pointer select-none touch-manipulation transition-colors hover:bg-accent/50 [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:py-2 ${isActive ? "bg-primary/15 hover:bg-primary/15" : isFocused ? "bg-accent" : ""} ${href ? "no-underline text-inherit" : ""}`;
|
|
114641
114744
|
const containerProps = {
|
|
114642
114745
|
ref: cardRef,
|
|
114643
114746
|
className,
|
|
@@ -114670,70 +114773,70 @@ var WorkspaceCard = (0, import_react21.memo)(function WorkspaceCard2({
|
|
|
114670
114773
|
const hasUnpushedCommits = (branchStatus?.git.ahead ?? 0) > 0;
|
|
114671
114774
|
const handleDelete = () => {
|
|
114672
114775
|
if (!hasUnmergedPR && !isDirty2 && !hasUnpushedCommits) {
|
|
114673
|
-
removeWorkspaceMutation.mutate({ project: projectName,
|
|
114776
|
+
removeWorkspaceMutation.mutate({ project: projectName, name: worktree.name });
|
|
114674
114777
|
} else {
|
|
114675
114778
|
onShowDeleteDialog({
|
|
114676
114779
|
projectName,
|
|
114677
|
-
|
|
114780
|
+
name: worktree.name,
|
|
114678
114781
|
isUnmerged: hasUnmergedPR,
|
|
114679
114782
|
isDirty: isDirty2,
|
|
114680
114783
|
hasUnpushedCommits
|
|
114681
114784
|
});
|
|
114682
114785
|
}
|
|
114683
114786
|
};
|
|
114684
|
-
return /* @__PURE__ */ (0,
|
|
114685
|
-
/* @__PURE__ */ (0,
|
|
114686
|
-
/* @__PURE__ */ (0,
|
|
114687
|
-
/* @__PURE__ */ (0,
|
|
114688
|
-
/* @__PURE__ */ (0,
|
|
114689
|
-
/* @__PURE__ */ (0,
|
|
114787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenu2, { children: [
|
|
114788
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ContextMenuTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { ...containerProps, children: [
|
|
114789
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Tooltip2, { delayDuration: 800, children: [
|
|
114790
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex items-center gap-2 min-w-0 overflow-hidden", children: [
|
|
114791
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(AgentStatusIndicator, { agent: status?.agent, isActive }),
|
|
114792
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
114690
114793
|
"span",
|
|
114691
114794
|
{
|
|
114692
114795
|
className: `text-sm truncate ${isActive ? "font-bold text-foreground" : "font-medium text-muted-foreground"}`,
|
|
114693
|
-
children: showProjectName ? `${projectName}/${worktree.
|
|
114796
|
+
children: showProjectName ? `${projectName}/${worktree.name}` : worktree.name
|
|
114694
114797
|
}
|
|
114695
114798
|
)
|
|
114696
114799
|
] }) }),
|
|
114697
|
-
/* @__PURE__ */ (0,
|
|
114800
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(TooltipContent2, { side: "right", children: `${projectName}/${worktree.name}` })
|
|
114698
114801
|
] }),
|
|
114699
|
-
/* @__PURE__ */ (0,
|
|
114700
|
-
/* @__PURE__ */ (0,
|
|
114701
|
-
!isPlain && branchStatus && /* @__PURE__ */ (0,
|
|
114702
|
-
!isPlain && branchStatus && /* @__PURE__ */ (0,
|
|
114802
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "hidden @[10rem]:flex group-hover:flex items-center gap-2 shrink-0 ml-auto pl-2", children: [
|
|
114803
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(SetupStatusIndicator, { setup: setupStatus }),
|
|
114804
|
+
!isPlain && branchStatus && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(GitStatusIndicator, { git: branchStatus.git }),
|
|
114805
|
+
!isPlain && branchStatus && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(CIStatusIndicator, { ci: branchStatus.ci })
|
|
114703
114806
|
] })
|
|
114704
114807
|
] }) }),
|
|
114705
|
-
/* @__PURE__ */ (0,
|
|
114706
|
-
/* @__PURE__ */ (0,
|
|
114707
|
-
isPinned ? /* @__PURE__ */ (0,
|
|
114808
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuContent2, { children: [
|
|
114809
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => onTogglePinned(projectName, worktree.name, isPinned), children: [
|
|
114810
|
+
isPinned ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.PinOff, {}) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.Pin, {}),
|
|
114708
114811
|
isPinned ? "Unpin workspace" : "Pin workspace"
|
|
114709
114812
|
] }),
|
|
114710
|
-
/* @__PURE__ */ (0,
|
|
114711
|
-
capabilities.copyPath && /* @__PURE__ */ (0,
|
|
114712
|
-
/* @__PURE__ */ (0,
|
|
114813
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(ContextMenuSeparator2, {}),
|
|
114814
|
+
capabilities.copyPath && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => navigator.clipboard.writeText(worktree.path), children: [
|
|
114815
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.Clipboard, {}),
|
|
114713
114816
|
"Copy path"
|
|
114714
114817
|
] }),
|
|
114715
|
-
capabilities.revealInFinder && /* @__PURE__ */ (0,
|
|
114716
|
-
/* @__PURE__ */ (0,
|
|
114818
|
+
capabilities.revealInFinder && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => capabilities.revealInFinder(worktree.path), children: [
|
|
114819
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.FolderOpen, {}),
|
|
114717
114820
|
"Open in Finder"
|
|
114718
114821
|
] }),
|
|
114719
|
-
worktree.hasSetup && /* @__PURE__ */ (0,
|
|
114720
|
-
/* @__PURE__ */ (0,
|
|
114822
|
+
worktree.hasSetup && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => runScript(worktree.path, "setup"), children: [
|
|
114823
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.Play, {}),
|
|
114721
114824
|
"Run setup"
|
|
114722
114825
|
] }),
|
|
114723
|
-
worktree.hasTeardown && /* @__PURE__ */ (0,
|
|
114724
|
-
/* @__PURE__ */ (0,
|
|
114826
|
+
worktree.hasTeardown && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => runScript(worktree.path, "teardown"), children: [
|
|
114827
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.Square, {}),
|
|
114725
114828
|
"Run teardown"
|
|
114726
114829
|
] }),
|
|
114727
|
-
!isPlain && /* @__PURE__ */ (0,
|
|
114728
|
-
/* @__PURE__ */ (0,
|
|
114830
|
+
!isPlain && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => gitPull(projectName, worktree.name), children: [
|
|
114831
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.ArrowDownToLine, {}),
|
|
114729
114832
|
"Git pull"
|
|
114730
114833
|
] }),
|
|
114731
|
-
!isPlain && /* @__PURE__ */ (0,
|
|
114732
|
-
/* @__PURE__ */ (0,
|
|
114834
|
+
!isPlain && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { onClick: () => gitPush(projectName, worktree.name), children: [
|
|
114835
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.ArrowUpFromLine, {}),
|
|
114733
114836
|
"Git push"
|
|
114734
114837
|
] }),
|
|
114735
|
-
!isPlain && worktree.
|
|
114736
|
-
/* @__PURE__ */ (0,
|
|
114838
|
+
!isPlain && worktree.name !== defaultBranch && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(ContextMenuItem2, { variant: "destructive", onClick: handleDelete, children: [
|
|
114839
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react5.Trash2, {}),
|
|
114737
114840
|
"Delete workspace"
|
|
114738
114841
|
] })
|
|
114739
114842
|
] })
|
|
@@ -114741,7 +114844,7 @@ var WorkspaceCard = (0, import_react21.memo)(function WorkspaceCard2({
|
|
|
114741
114844
|
});
|
|
114742
114845
|
|
|
114743
114846
|
// src/dashboard/components/ProjectList.tsx
|
|
114744
|
-
var
|
|
114847
|
+
var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
|
|
114745
114848
|
|
|
114746
114849
|
// src/dashboard/components/SettingsPage.tsx
|
|
114747
114850
|
var import_react24 = __toESM(require_react(), 1);
|
|
@@ -114750,16 +114853,16 @@ var import_react24 = __toESM(require_react(), 1);
|
|
|
114750
114853
|
var import_react23 = __toESM(require_react(), 1);
|
|
114751
114854
|
|
|
114752
114855
|
// src/dashboard/components/settings/SettingsRow.tsx
|
|
114753
|
-
var
|
|
114856
|
+
var import_jsx_runtime60 = __toESM(require_jsx_runtime(), 1);
|
|
114754
114857
|
|
|
114755
114858
|
// src/dashboard/components/settings/SettingsSection.tsx
|
|
114756
|
-
var
|
|
114859
|
+
var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
|
|
114757
114860
|
|
|
114758
114861
|
// src/dashboard/components/SettingsPage.tsx
|
|
114759
|
-
var
|
|
114862
|
+
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
|
|
114760
114863
|
|
|
114761
114864
|
// src/dashboard/components/DashboardShell.tsx
|
|
114762
|
-
var
|
|
114865
|
+
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1);
|
|
114763
114866
|
var isElectron = typeof window !== "undefined" && "__BAND_DESKTOP__" in window;
|
|
114764
114867
|
|
|
114765
114868
|
// src/dashboard/components/DiffView.tsx
|
|
@@ -115025,18 +115128,18 @@ function joinWorkspacePath(workspaceRoot, relativePath) {
|
|
|
115025
115128
|
}
|
|
115026
115129
|
|
|
115027
115130
|
// src/dashboard/components/FileStatusBadge.tsx
|
|
115028
|
-
var
|
|
115131
|
+
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
115029
115132
|
|
|
115030
115133
|
// src/dashboard/components/ChangesFileTree.tsx
|
|
115031
|
-
var
|
|
115134
|
+
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
115032
115135
|
|
|
115033
115136
|
// src/dashboard/components/RevertFileDialog.tsx
|
|
115034
|
-
var
|
|
115137
|
+
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1);
|
|
115035
115138
|
|
|
115036
115139
|
// src/dashboard/components/SearchBar.tsx
|
|
115037
115140
|
var import_lucide_react6 = __toESM(require_lucide_react(), 1);
|
|
115038
115141
|
var import_react33 = __toESM(require_react(), 1);
|
|
115039
|
-
var
|
|
115142
|
+
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
|
|
115040
115143
|
var DEFAULT_VISIBLE_OPTIONS = ["caseSensitive", "wholeWord", "regex"];
|
|
115041
115144
|
function ToggleButton({
|
|
115042
115145
|
active,
|
|
@@ -115044,7 +115147,7 @@ function ToggleButton({
|
|
|
115044
115147
|
title,
|
|
115045
115148
|
children
|
|
115046
115149
|
}) {
|
|
115047
|
-
return /* @__PURE__ */ (0,
|
|
115150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
115048
115151
|
"button",
|
|
115049
115152
|
{
|
|
115050
115153
|
type: "button",
|
|
@@ -115085,13 +115188,13 @@ var SearchBar = (0, import_react33.forwardRef)(function SearchBar2({
|
|
|
115085
115188
|
const toggleRegex = (0, import_react33.useCallback)(() => {
|
|
115086
115189
|
onOptionsChange({ ...options2, regex: !options2.regex });
|
|
115087
115190
|
}, [options2, onOptionsChange]);
|
|
115088
|
-
return /* @__PURE__ */ (0,
|
|
115191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
115089
115192
|
"div",
|
|
115090
115193
|
{
|
|
115091
115194
|
className: `flex shrink-0 items-center gap-1.5 border-b border-border bg-muted/30 px-3 py-1.5 ${className ?? ""}`,
|
|
115092
115195
|
children: [
|
|
115093
|
-
/* @__PURE__ */ (0,
|
|
115094
|
-
/* @__PURE__ */ (0,
|
|
115196
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.Search, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
115197
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
115095
115198
|
"input",
|
|
115096
115199
|
{
|
|
115097
115200
|
ref: inputRef,
|
|
@@ -115112,11 +115215,11 @@ var SearchBar = (0, import_react33.forwardRef)(function SearchBar2({
|
|
|
115112
115215
|
}
|
|
115113
115216
|
}
|
|
115114
115217
|
),
|
|
115115
|
-
showCase && /* @__PURE__ */ (0,
|
|
115116
|
-
showWholeWord && /* @__PURE__ */ (0,
|
|
115117
|
-
showRegex && /* @__PURE__ */ (0,
|
|
115118
|
-
matchInfo && query && /* @__PURE__ */ (0,
|
|
115119
|
-
onPrevious && /* @__PURE__ */ (0,
|
|
115218
|
+
showCase && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ToggleButton, { active: options2.caseSensitive, onClick: toggleCase, title: "Match Case", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.CaseSensitive, { className: "size-4" }) }),
|
|
115219
|
+
showWholeWord && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ToggleButton, { active: options2.wholeWord, onClick: toggleWholeWord, title: "Match Whole Word", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.WholeWord, { className: "size-4" }) }),
|
|
115220
|
+
showRegex && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ToggleButton, { active: options2.regex, onClick: toggleRegex, title: "Use Regular Expression", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.Regex, { className: "size-4" }) }),
|
|
115221
|
+
matchInfo && query && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: matchInfo.total > 0 ? `${matchInfo.current} of ${matchInfo.total}` : "No results" }),
|
|
115222
|
+
onPrevious && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
115120
115223
|
"button",
|
|
115121
115224
|
{
|
|
115122
115225
|
type: "button",
|
|
@@ -115124,10 +115227,10 @@ var SearchBar = (0, import_react33.forwardRef)(function SearchBar2({
|
|
|
115124
115227
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
115125
115228
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
115126
115229
|
title: "Previous match (Shift+Enter)",
|
|
115127
|
-
children: /* @__PURE__ */ (0,
|
|
115230
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.ChevronUp, { className: "size-3.5" })
|
|
115128
115231
|
}
|
|
115129
115232
|
),
|
|
115130
|
-
onNext && /* @__PURE__ */ (0,
|
|
115233
|
+
onNext && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
115131
115234
|
"button",
|
|
115132
115235
|
{
|
|
115133
115236
|
type: "button",
|
|
@@ -115135,17 +115238,17 @@ var SearchBar = (0, import_react33.forwardRef)(function SearchBar2({
|
|
|
115135
115238
|
disabled: !matchInfo || matchInfo.total === 0,
|
|
115136
115239
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground disabled:opacity-30",
|
|
115137
115240
|
title: "Next match (Enter)",
|
|
115138
|
-
children: /* @__PURE__ */ (0,
|
|
115241
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.ChevronDown, { className: "size-3.5" })
|
|
115139
115242
|
}
|
|
115140
115243
|
),
|
|
115141
|
-
onClose && /* @__PURE__ */ (0,
|
|
115244
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
|
|
115142
115245
|
"button",
|
|
115143
115246
|
{
|
|
115144
115247
|
type: "button",
|
|
115145
115248
|
onClick: onClose,
|
|
115146
115249
|
className: "inline-flex size-6 items-center justify-center rounded text-muted-foreground hover:text-foreground",
|
|
115147
115250
|
title: "Close (Escape)",
|
|
115148
|
-
children: /* @__PURE__ */ (0,
|
|
115251
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_lucide_react6.X, { className: "size-3.5" })
|
|
115149
115252
|
}
|
|
115150
115253
|
)
|
|
115151
115254
|
]
|
|
@@ -115154,7 +115257,7 @@ var SearchBar = (0, import_react33.forwardRef)(function SearchBar2({
|
|
|
115154
115257
|
});
|
|
115155
115258
|
|
|
115156
115259
|
// src/dashboard/components/DiffView.tsx
|
|
115157
|
-
var
|
|
115260
|
+
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
115158
115261
|
var diffTheme = EditorView.theme({
|
|
115159
115262
|
".cm-insertedLine": { backgroundColor: "rgba(34, 197, 94, 0.1)" },
|
|
115160
115263
|
".cm-deletedLine": { backgroundColor: "rgba(239, 68, 68, 0.1)" },
|
|
@@ -115206,7 +115309,7 @@ var diffTheme = EditorView.theme({
|
|
|
115206
115309
|
// src/dashboard/components/FileBrowser.tsx
|
|
115207
115310
|
var import_lucide_react7 = __toESM(require_lucide_react(), 1);
|
|
115208
115311
|
var import_react35 = __toESM(require_react(), 1);
|
|
115209
|
-
var
|
|
115312
|
+
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
115210
115313
|
var expandedStateCache = /* @__PURE__ */ new Map();
|
|
115211
115314
|
var dirContentsCache = /* @__PURE__ */ new Map();
|
|
115212
115315
|
function getCachedExpanded(wsId) {
|
|
@@ -115287,21 +115390,21 @@ function EntryNameInput({
|
|
|
115287
115390
|
}
|
|
115288
115391
|
};
|
|
115289
115392
|
const Icon = kind === "directory" ? import_lucide_react7.Folder : import_lucide_react7.File;
|
|
115290
|
-
return /* @__PURE__ */ (0,
|
|
115291
|
-
/* @__PURE__ */ (0,
|
|
115393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex w-full flex-col", style: { paddingLeft: `${depth * indent + basePad}px` }, children: [
|
|
115394
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115292
115395
|
"div",
|
|
115293
115396
|
{
|
|
115294
115397
|
className: `flex items-center ${compact ? "h-[28px] gap-1 pr-3 text-[13px]" : "h-[32px] gap-1.5 pr-4 text-[15px]"}`,
|
|
115295
115398
|
style: { height },
|
|
115296
115399
|
children: [
|
|
115297
|
-
/* @__PURE__ */ (0,
|
|
115298
|
-
/* @__PURE__ */ (0,
|
|
115400
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "size-3.5 shrink-0" }),
|
|
115401
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115299
115402
|
Icon,
|
|
115300
115403
|
{
|
|
115301
115404
|
className: kind === "directory" ? "size-4 shrink-0 text-blue-600 dark:text-blue-400" : "size-4 shrink-0 text-muted-foreground"
|
|
115302
115405
|
}
|
|
115303
115406
|
),
|
|
115304
|
-
/* @__PURE__ */ (0,
|
|
115407
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115305
115408
|
"input",
|
|
115306
115409
|
{
|
|
115307
115410
|
ref: inputRef,
|
|
@@ -115338,7 +115441,7 @@ function EntryNameInput({
|
|
|
115338
115441
|
]
|
|
115339
115442
|
}
|
|
115340
115443
|
),
|
|
115341
|
-
error2 && /* @__PURE__ */ (0,
|
|
115444
|
+
error2 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115342
115445
|
"div",
|
|
115343
115446
|
{
|
|
115344
115447
|
className: "pointer-events-none text-xs text-destructive",
|
|
@@ -115406,7 +115509,7 @@ function TreeNode2({
|
|
|
115406
115509
|
onOpenFilePinned(entryPath);
|
|
115407
115510
|
}
|
|
115408
115511
|
};
|
|
115409
|
-
const button = /* @__PURE__ */ (0,
|
|
115512
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115410
115513
|
"button",
|
|
115411
115514
|
{
|
|
115412
115515
|
ref: isSelected ? selectedRef : void 0,
|
|
@@ -115420,15 +115523,15 @@ function TreeNode2({
|
|
|
115420
115523
|
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" : ""}`,
|
|
115421
115524
|
style: { paddingLeft: `${depth * indent + basePad}px` },
|
|
115422
115525
|
children: [
|
|
115423
|
-
isDir ? isExpanded ? /* @__PURE__ */ (0,
|
|
115526
|
+
isDir ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ChevronDown, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ChevronRight, { className: "size-3.5 shrink-0 text-muted-foreground/70" }) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "size-3.5 shrink-0" }),
|
|
115424
115527
|
isDir ? (() => {
|
|
115425
115528
|
const FolderIcon = getFolderIcon(entry.name, isExpanded);
|
|
115426
|
-
return /* @__PURE__ */ (0,
|
|
115529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(FolderIcon, { className: "size-4 shrink-0" });
|
|
115427
115530
|
})() : (() => {
|
|
115428
115531
|
const FileIcon = getFileIcon(entry.name);
|
|
115429
|
-
return /* @__PURE__ */ (0,
|
|
115532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(FileIcon, { className: "size-4 shrink-0" });
|
|
115430
115533
|
})(),
|
|
115431
|
-
/* @__PURE__ */ (0,
|
|
115534
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "min-w-0 flex-1 truncate", children: entry.name })
|
|
115432
115535
|
]
|
|
115433
115536
|
}
|
|
115434
115537
|
);
|
|
@@ -115450,7 +115553,7 @@ function TreeNode2({
|
|
|
115450
115553
|
// a padding div with `depth={0}` would double-apply `basePad`, shifting
|
|
115451
115554
|
// the input ~4px to the right and giving it visibly less horizontal
|
|
115452
115555
|
// room than the rest of the tree.
|
|
115453
|
-
/* @__PURE__ */ (0,
|
|
115556
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115454
115557
|
EntryNameInput,
|
|
115455
115558
|
{
|
|
115456
115559
|
kind: isDir ? "directory" : "file",
|
|
@@ -115464,97 +115567,97 @@ function TreeNode2({
|
|
|
115464
115567
|
},
|
|
115465
115568
|
`rename-${entryPath}`
|
|
115466
115569
|
)
|
|
115467
|
-
) : /* @__PURE__ */ (0,
|
|
115570
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115468
115571
|
ContextMenu2,
|
|
115469
115572
|
{
|
|
115470
115573
|
onOpenChange: (open3) => {
|
|
115471
115574
|
if (open3) onSelectRow(entryPath, isDir ? "directory" : "file");
|
|
115472
115575
|
},
|
|
115473
115576
|
children: [
|
|
115474
|
-
/* @__PURE__ */ (0,
|
|
115475
|
-
/* @__PURE__ */ (0,
|
|
115476
|
-
isDir && /* @__PURE__ */ (0,
|
|
115477
|
-
/* @__PURE__ */ (0,
|
|
115577
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuTrigger2, { asChild: true, children: button }),
|
|
115578
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuContent2, { onCloseAutoFocus: menu.flush, children: [
|
|
115579
|
+
isDir && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
115580
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115478
115581
|
ContextMenuItem2,
|
|
115479
115582
|
{
|
|
115480
115583
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "file")),
|
|
115481
115584
|
children: [
|
|
115482
|
-
/* @__PURE__ */ (0,
|
|
115585
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.File, { className: "size-4" }),
|
|
115483
115586
|
"New File"
|
|
115484
115587
|
]
|
|
115485
115588
|
}
|
|
115486
115589
|
),
|
|
115487
|
-
/* @__PURE__ */ (0,
|
|
115590
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115488
115591
|
ContextMenuItem2,
|
|
115489
115592
|
{
|
|
115490
115593
|
onSelect: () => menu.queue(() => onRequestNewEntry(entryPath, "directory")),
|
|
115491
115594
|
children: [
|
|
115492
|
-
/* @__PURE__ */ (0,
|
|
115595
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.FolderPlus, { className: "size-4" }),
|
|
115493
115596
|
"New Folder"
|
|
115494
115597
|
]
|
|
115495
115598
|
}
|
|
115496
115599
|
),
|
|
115497
|
-
/* @__PURE__ */ (0,
|
|
115600
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuSeparator2, {})
|
|
115498
115601
|
] }),
|
|
115499
|
-
canCut && /* @__PURE__ */ (0,
|
|
115602
|
+
canCut && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115500
115603
|
ContextMenuItem2,
|
|
115501
115604
|
{
|
|
115502
115605
|
onSelect: () => menu.queue(() => onCut(entryPath, isDir ? "directory" : "file")),
|
|
115503
115606
|
children: [
|
|
115504
|
-
/* @__PURE__ */ (0,
|
|
115607
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.Scissors, { className: "size-4" }),
|
|
115505
115608
|
"Cut"
|
|
115506
115609
|
]
|
|
115507
115610
|
}
|
|
115508
115611
|
),
|
|
115509
|
-
canCopy && /* @__PURE__ */ (0,
|
|
115612
|
+
canCopy && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115510
115613
|
ContextMenuItem2,
|
|
115511
115614
|
{
|
|
115512
115615
|
onSelect: () => menu.queue(() => onCopy(entryPath, isDir ? "directory" : "file")),
|
|
115513
115616
|
children: [
|
|
115514
|
-
/* @__PURE__ */ (0,
|
|
115617
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.Copy, { className: "size-4" }),
|
|
115515
115618
|
"Copy"
|
|
115516
115619
|
]
|
|
115517
115620
|
}
|
|
115518
115621
|
),
|
|
115519
|
-
isDir && canPaste && /* @__PURE__ */ (0,
|
|
115520
|
-
/* @__PURE__ */ (0,
|
|
115622
|
+
isDir && canPaste && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuItem2, { onSelect: () => menu.queue(() => void onPaste(entryPath)), children: [
|
|
115623
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ClipboardPaste, { className: "size-4" }),
|
|
115521
115624
|
"Paste"
|
|
115522
115625
|
] }),
|
|
115523
|
-
(canCut || canCopy || isDir && canPaste) && /* @__PURE__ */ (0,
|
|
115524
|
-
/* @__PURE__ */ (0,
|
|
115626
|
+
(canCut || canCopy || isDir && canPaste) && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuSeparator2, {}),
|
|
115627
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115525
115628
|
ContextMenuItem2,
|
|
115526
115629
|
{
|
|
115527
115630
|
"data-testid": "file-tree__copy-relative-path",
|
|
115528
115631
|
onSelect: () => menu.queue(() => void writeClipboardText(entryPath)),
|
|
115529
115632
|
children: [
|
|
115530
|
-
/* @__PURE__ */ (0,
|
|
115633
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ClipboardCopy, { className: "size-4" }),
|
|
115531
115634
|
"Copy relative path"
|
|
115532
115635
|
]
|
|
115533
115636
|
}
|
|
115534
115637
|
),
|
|
115535
|
-
workspacePath && /* @__PURE__ */ (0,
|
|
115638
|
+
workspacePath && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115536
115639
|
ContextMenuItem2,
|
|
115537
115640
|
{
|
|
115538
115641
|
"data-testid": "file-tree__copy-absolute-path",
|
|
115539
115642
|
onSelect: () => menu.queue(() => void writeClipboardText(joinWorkspacePath(workspacePath, entryPath))),
|
|
115540
115643
|
children: [
|
|
115541
|
-
/* @__PURE__ */ (0,
|
|
115644
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ClipboardCopy, { className: "size-4" }),
|
|
115542
115645
|
"Copy absolute path"
|
|
115543
115646
|
]
|
|
115544
115647
|
}
|
|
115545
115648
|
),
|
|
115546
|
-
(canRename || canDelete) && /* @__PURE__ */ (0,
|
|
115547
|
-
canRename && /* @__PURE__ */ (0,
|
|
115548
|
-
/* @__PURE__ */ (0,
|
|
115649
|
+
(canRename || canDelete) && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuSeparator2, {}),
|
|
115650
|
+
canRename && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuItem2, { onSelect: () => menu.queue(() => onRequestRename(entryPath)), children: [
|
|
115651
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.Pencil, { className: "size-4" }),
|
|
115549
115652
|
"Rename"
|
|
115550
115653
|
] }),
|
|
115551
|
-
canDelete && /* @__PURE__ */ (0,
|
|
115654
|
+
canDelete && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
115552
115655
|
ContextMenuItem2,
|
|
115553
115656
|
{
|
|
115554
115657
|
variant: "destructive",
|
|
115555
115658
|
onSelect: () => menu.queue(() => onRequestDelete(entryPath, isDir ? "directory" : "file")),
|
|
115556
115659
|
children: [
|
|
115557
|
-
/* @__PURE__ */ (0,
|
|
115660
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.Trash2, { className: "size-4" }),
|
|
115558
115661
|
"Delete"
|
|
115559
115662
|
]
|
|
115560
115663
|
}
|
|
@@ -115564,13 +115667,13 @@ function TreeNode2({
|
|
|
115564
115667
|
}
|
|
115565
115668
|
);
|
|
115566
115669
|
const showInlineInput = newEntry?.parentPath === entryPath;
|
|
115567
|
-
return /* @__PURE__ */ (0,
|
|
115670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
115568
115671
|
row,
|
|
115569
115672
|
isExpanded && (() => {
|
|
115570
115673
|
const splitIdx = children?.findIndex((c2) => c2.type === "file") ?? -1;
|
|
115571
115674
|
const folderChildren = splitIdx === -1 ? children ?? [] : (children ?? []).slice(0, splitIdx);
|
|
115572
115675
|
const fileChildren = splitIdx === -1 ? [] : (children ?? []).slice(splitIdx);
|
|
115573
|
-
const renderChild = (child) => /* @__PURE__ */ (0,
|
|
115676
|
+
const renderChild = (child) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115574
115677
|
TreeNode2,
|
|
115575
115678
|
{
|
|
115576
115679
|
entry: child,
|
|
@@ -115608,7 +115711,7 @@ function TreeNode2({
|
|
|
115608
115711
|
},
|
|
115609
115712
|
child.name
|
|
115610
115713
|
);
|
|
115611
|
-
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0,
|
|
115714
|
+
const newEntryInput = showInlineInput ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115612
115715
|
EntryNameInput,
|
|
115613
115716
|
{
|
|
115614
115717
|
kind: newEntry.kind,
|
|
@@ -115620,9 +115723,9 @@ function TreeNode2({
|
|
|
115620
115723
|
},
|
|
115621
115724
|
`new-${newEntry.kind}-${entryPath}`
|
|
115622
115725
|
) : null;
|
|
115623
|
-
return /* @__PURE__ */ (0,
|
|
115726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
115624
115727
|
showInlineInput && newEntry.kind === "directory" && newEntryInput,
|
|
115625
|
-
isLoading && !children?.length && /* @__PURE__ */ (0,
|
|
115728
|
+
isLoading && !children?.length && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115626
115729
|
"div",
|
|
115627
115730
|
{
|
|
115628
115731
|
className: `flex items-center text-muted-foreground/70 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -115633,7 +115736,7 @@ function TreeNode2({
|
|
|
115633
115736
|
children: "Loading\u2026"
|
|
115634
115737
|
}
|
|
115635
115738
|
),
|
|
115636
|
-
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0,
|
|
115739
|
+
!isLoading && !showInlineInput && children && children.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
115637
115740
|
"div",
|
|
115638
115741
|
{
|
|
115639
115742
|
className: `flex items-center italic text-muted-foreground/50 ${compact ? "text-[13px]" : "text-[15px]"}`,
|
|
@@ -116079,7 +116182,7 @@ var FileBrowser = (0, import_react35.forwardRef)(function FileBrowser2({
|
|
|
116079
116182
|
);
|
|
116080
116183
|
const rootMenu = useDeferredMenuAction();
|
|
116081
116184
|
if (!adapter.listWorkspaceFiles) {
|
|
116082
|
-
return /* @__PURE__ */ (0,
|
|
116185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "File browsing not supported" });
|
|
116083
116186
|
}
|
|
116084
116187
|
const rootEntries = dirContents.get("") ?? [];
|
|
116085
116188
|
const rootLoading = loadingPaths.has("");
|
|
@@ -116116,20 +116219,20 @@ var FileBrowser = (0, import_react35.forwardRef)(function FileBrowser2({
|
|
|
116116
116219
|
void pasteInto(resolveDefaultTarget());
|
|
116117
116220
|
}
|
|
116118
116221
|
};
|
|
116119
|
-
return /* @__PURE__ */ (0,
|
|
116120
|
-
/* @__PURE__ */ (0,
|
|
116222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex h-full flex-col overflow-hidden", onKeyDown: handleKeyDown, children: [
|
|
116223
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
|
|
116121
116224
|
ContextMenu2,
|
|
116122
116225
|
{
|
|
116123
116226
|
onOpenChange: (open3) => {
|
|
116124
116227
|
if (open3) clearTreeSelection();
|
|
116125
116228
|
},
|
|
116126
116229
|
children: [
|
|
116127
|
-
/* @__PURE__ */ (0,
|
|
116230
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "min-h-0 flex-1 overflow-y-auto py-1 pl-px", children: [
|
|
116128
116231
|
(() => {
|
|
116129
116232
|
const rootSplitIdx = rootEntries.findIndex((e2) => e2.type === "file");
|
|
116130
116233
|
const rootFolders = rootSplitIdx === -1 ? rootEntries : rootEntries.slice(0, rootSplitIdx);
|
|
116131
116234
|
const rootFiles = rootSplitIdx === -1 ? [] : rootEntries.slice(rootSplitIdx);
|
|
116132
|
-
const renderRow = (entry) => /* @__PURE__ */ (0,
|
|
116235
|
+
const renderRow = (entry) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
116133
116236
|
TreeNode2,
|
|
116134
116237
|
{
|
|
116135
116238
|
entry,
|
|
@@ -116167,7 +116270,7 @@ var FileBrowser = (0, import_react35.forwardRef)(function FileBrowser2({
|
|
|
116167
116270
|
},
|
|
116168
116271
|
entry.name
|
|
116169
116272
|
);
|
|
116170
|
-
const rootInput = showRootInput ? /* @__PURE__ */ (0,
|
|
116273
|
+
const rootInput = showRootInput ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
116171
116274
|
EntryNameInput,
|
|
116172
116275
|
{
|
|
116173
116276
|
kind: newEntry.kind,
|
|
@@ -116179,30 +116282,30 @@ var FileBrowser = (0, import_react35.forwardRef)(function FileBrowser2({
|
|
|
116179
116282
|
},
|
|
116180
116283
|
`new-${newEntry.kind}-root`
|
|
116181
116284
|
) : null;
|
|
116182
|
-
return /* @__PURE__ */ (0,
|
|
116285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
116183
116286
|
showRootInput && newEntry.kind === "directory" && rootInput,
|
|
116184
|
-
rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0,
|
|
116185
|
-
!rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0,
|
|
116287
|
+
rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Loading\u2026" }),
|
|
116288
|
+
!rootLoading && rootEntries.length === 0 && !showRootInput && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex h-32 items-center justify-center text-sm text-muted-foreground", children: "Empty directory" }),
|
|
116186
116289
|
rootFolders.map(renderRow),
|
|
116187
116290
|
showRootInput && newEntry.kind === "file" && rootInput,
|
|
116188
116291
|
rootFiles.map(renderRow)
|
|
116189
116292
|
] });
|
|
116190
116293
|
})(),
|
|
116191
|
-
/* @__PURE__ */ (0,
|
|
116294
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "min-h-[40px] flex-1" })
|
|
116192
116295
|
] }) }),
|
|
116193
|
-
/* @__PURE__ */ (0,
|
|
116194
|
-
/* @__PURE__ */ (0,
|
|
116195
|
-
/* @__PURE__ */ (0,
|
|
116296
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuContent2, { onCloseAutoFocus: rootMenu.flush, children: [
|
|
116297
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "file")), children: [
|
|
116298
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.File, { className: "size-4" }),
|
|
116196
116299
|
"New File"
|
|
116197
116300
|
] }),
|
|
116198
|
-
/* @__PURE__ */ (0,
|
|
116199
|
-
/* @__PURE__ */ (0,
|
|
116301
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => requestNewEntry("", "directory")), children: [
|
|
116302
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.FolderPlus, { className: "size-4" }),
|
|
116200
116303
|
"New Folder"
|
|
116201
116304
|
] }),
|
|
116202
|
-
canPaste && /* @__PURE__ */ (0,
|
|
116203
|
-
/* @__PURE__ */ (0,
|
|
116204
|
-
/* @__PURE__ */ (0,
|
|
116205
|
-
/* @__PURE__ */ (0,
|
|
116305
|
+
canPaste && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
|
|
116306
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(ContextMenuSeparator2, {}),
|
|
116307
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(ContextMenuItem2, { onSelect: () => rootMenu.queue(() => void pasteInto("")), children: [
|
|
116308
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.ClipboardPaste, { className: "size-4" }),
|
|
116206
116309
|
"Paste"
|
|
116207
116310
|
] })
|
|
116208
116311
|
] })
|
|
@@ -116210,42 +116313,42 @@ var FileBrowser = (0, import_react35.forwardRef)(function FileBrowser2({
|
|
|
116210
116313
|
]
|
|
116211
116314
|
}
|
|
116212
116315
|
),
|
|
116213
|
-
/* @__PURE__ */ (0,
|
|
116316
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
116214
116317
|
Dialog2,
|
|
116215
116318
|
{
|
|
116216
116319
|
open: pendingDelete !== null,
|
|
116217
116320
|
onOpenChange: (open3) => {
|
|
116218
116321
|
if (!open3) cancelDelete();
|
|
116219
116322
|
},
|
|
116220
|
-
children: /* @__PURE__ */ (0,
|
|
116221
|
-
/* @__PURE__ */ (0,
|
|
116222
|
-
/* @__PURE__ */ (0,
|
|
116323
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(DialogContent2, { className: "sm:max-w-[425px]", onClick: (e2) => e2.stopPropagation(), children: [
|
|
116324
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(DialogHeader, { children: [
|
|
116325
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(DialogTitle2, { children: [
|
|
116223
116326
|
"Delete ",
|
|
116224
116327
|
pendingDelete?.kind === "directory" ? "folder" : "file"
|
|
116225
116328
|
] }),
|
|
116226
|
-
/* @__PURE__ */ (0,
|
|
116329
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(DialogDescription2, { children: [
|
|
116227
116330
|
"Are you sure you want to delete ",
|
|
116228
|
-
/* @__PURE__ */ (0,
|
|
116331
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("strong", { children: pendingDelete?.path }),
|
|
116229
116332
|
"?"
|
|
116230
116333
|
] })
|
|
116231
116334
|
] }),
|
|
116232
|
-
/* @__PURE__ */ (0,
|
|
116233
|
-
pendingDelete?.kind === "directory" && /* @__PURE__ */ (0,
|
|
116234
|
-
/* @__PURE__ */ (0,
|
|
116235
|
-
/* @__PURE__ */ (0,
|
|
116335
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex flex-col gap-2 text-sm", children: [
|
|
116336
|
+
pendingDelete?.kind === "directory" && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
|
|
116337
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.AlertTriangle, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
|
|
116338
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: "The folder and all of its contents will be deleted from disk. This cannot be undone." })
|
|
116236
116339
|
] }),
|
|
116237
|
-
pendingDelete?.kind === "file" && /* @__PURE__ */ (0,
|
|
116238
|
-
/* @__PURE__ */ (0,
|
|
116239
|
-
/* @__PURE__ */ (0,
|
|
116340
|
+
pendingDelete?.kind === "file" && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-yellow-500/30 bg-yellow-500/10 p-3", children: [
|
|
116341
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.AlertTriangle, { className: "size-4 shrink-0 text-yellow-500 mt-0.5" }),
|
|
116342
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: "The file will be deleted from disk. This cannot be undone." })
|
|
116240
116343
|
] }),
|
|
116241
|
-
deleteError && /* @__PURE__ */ (0,
|
|
116242
|
-
/* @__PURE__ */ (0,
|
|
116243
|
-
/* @__PURE__ */ (0,
|
|
116344
|
+
deleteError && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/10 p-3 text-destructive", children: [
|
|
116345
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_lucide_react7.AlertTriangle, { className: "size-4 shrink-0 mt-0.5" }),
|
|
116346
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: deleteError })
|
|
116244
116347
|
] })
|
|
116245
116348
|
] }),
|
|
116246
|
-
/* @__PURE__ */ (0,
|
|
116247
|
-
/* @__PURE__ */ (0,
|
|
116248
|
-
/* @__PURE__ */ (0,
|
|
116349
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(DialogFooter, { children: [
|
|
116350
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Button, { variant: "ghost", onClick: cancelDelete, disabled: deleteSubmitting, children: "Cancel" }),
|
|
116351
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
116249
116352
|
Button,
|
|
116250
116353
|
{
|
|
116251
116354
|
variant: "destructive",
|
|
@@ -116266,32 +116369,32 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
116266
116369
|
|
|
116267
116370
|
// src/dashboard/components/ImagePreview.tsx
|
|
116268
116371
|
var import_react36 = __toESM(require_react(), 1);
|
|
116269
|
-
var
|
|
116372
|
+
var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
|
|
116270
116373
|
|
|
116271
116374
|
// src/dashboard/components/LanguagePickerDialog.tsx
|
|
116272
116375
|
var import_react37 = __toESM(require_react(), 1);
|
|
116273
|
-
var
|
|
116376
|
+
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
|
|
116274
116377
|
|
|
116275
116378
|
// src/dashboard/components/PdfPreview.tsx
|
|
116276
|
-
var
|
|
116379
|
+
var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
116277
116380
|
|
|
116278
116381
|
// src/dashboard/components/FileViewer.tsx
|
|
116279
|
-
var
|
|
116382
|
+
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
|
|
116280
116383
|
|
|
116281
116384
|
// src/dashboard/components/QuickOpenDialog.tsx
|
|
116282
116385
|
var import_react39 = __toESM(require_react(), 1);
|
|
116283
|
-
var
|
|
116386
|
+
var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
|
|
116284
116387
|
|
|
116285
116388
|
// src/dashboard/components/SearchFilesDialog.tsx
|
|
116286
116389
|
var import_react40 = __toESM(require_react(), 1);
|
|
116287
|
-
var
|
|
116390
|
+
var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
|
|
116288
116391
|
|
|
116289
116392
|
// src/dashboard/components/WorkspacePickerDialog.tsx
|
|
116290
116393
|
var import_react41 = __toESM(require_react(), 1);
|
|
116291
|
-
var
|
|
116394
|
+
var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
|
|
116292
116395
|
|
|
116293
116396
|
// src/dashboard/components/WorkspaceTabNav.tsx
|
|
116294
|
-
var
|
|
116397
|
+
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
|
|
116295
116398
|
|
|
116296
116399
|
// src/dashboard/hooks/use-editor-history.ts
|
|
116297
116400
|
var import_react42 = __toESM(require_react(), 1);
|
|
@@ -118540,7 +118643,7 @@ var cmdClickLinkPlugin = ViewPlugin.fromClass(
|
|
|
118540
118643
|
|
|
118541
118644
|
// src/server/infra/git/git-client.ts
|
|
118542
118645
|
init_src();
|
|
118543
|
-
import { execFile as
|
|
118646
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
118544
118647
|
import { readFile, stat as stat3 } from "node:fs/promises";
|
|
118545
118648
|
import { join as join15 } from "node:path";
|
|
118546
118649
|
var log11 = createLogger("git");
|
|
@@ -118599,15 +118702,13 @@ async function resolveDetachedBranch(worktreePath) {
|
|
|
118599
118702
|
}
|
|
118600
118703
|
function gitCmd() {
|
|
118601
118704
|
const env = { ...process.env };
|
|
118602
|
-
|
|
118603
|
-
env.PATH = `/opt/homebrew/bin:/usr/local/bin:${env.PATH}`;
|
|
118604
|
-
}
|
|
118705
|
+
env.PATH = prependBinDirs(env.PATH);
|
|
118605
118706
|
return { command: "git", env };
|
|
118606
118707
|
}
|
|
118607
118708
|
function execGit(args, cwd) {
|
|
118608
118709
|
const { command, env } = gitCmd();
|
|
118609
118710
|
return new Promise((resolve12, reject) => {
|
|
118610
|
-
|
|
118711
|
+
execFile4(command, args, { cwd, env, maxBuffer: MAX_BUFFER }, (err, stdout, stderr) => {
|
|
118611
118712
|
if (err) {
|
|
118612
118713
|
reject(new Error(stderr || err.message));
|
|
118613
118714
|
return;
|
|
@@ -118618,11 +118719,9 @@ function execGit(args, cwd) {
|
|
|
118618
118719
|
}
|
|
118619
118720
|
function execGh(args, cwd) {
|
|
118620
118721
|
const env = { ...process.env };
|
|
118621
|
-
|
|
118622
|
-
env.PATH = `/opt/homebrew/bin:/usr/local/bin:${env.PATH}`;
|
|
118623
|
-
}
|
|
118722
|
+
env.PATH = prependBinDirs(env.PATH);
|
|
118624
118723
|
return new Promise((resolve12, reject) => {
|
|
118625
|
-
|
|
118724
|
+
execFile4("gh", args, { cwd, env, maxBuffer: MAX_BUFFER }, (err, stdout, stderr) => {
|
|
118626
118725
|
if (err) {
|
|
118627
118726
|
reject(new Error(stderr || err.message));
|
|
118628
118727
|
return;
|
|
@@ -118857,15 +118956,15 @@ function parseBatchedCIResponse(data, aliases, defaultBranches) {
|
|
|
118857
118956
|
}
|
|
118858
118957
|
|
|
118859
118958
|
// src/server/infra/db/queries/projects.ts
|
|
118860
|
-
import { existsSync as
|
|
118959
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
118861
118960
|
import { join as join16 } from "node:path";
|
|
118862
118961
|
function reconcileKindForProject(project) {
|
|
118863
|
-
if (!
|
|
118864
|
-
const detectedKind =
|
|
118962
|
+
if (!existsSync6(project.path)) return false;
|
|
118963
|
+
const detectedKind = existsSync6(join16(project.path, ".git")) ? "git" : "plain";
|
|
118865
118964
|
if (detectedKind === project.kind) return false;
|
|
118866
118965
|
project.kind = detectedKind;
|
|
118867
118966
|
if (detectedKind === "plain") {
|
|
118868
|
-
project.worktrees = [{ branch: "main", path: project.path, pinned: false }];
|
|
118967
|
+
project.worktrees = [{ name: "main", branch: "main", path: project.path, pinned: false }];
|
|
118869
118968
|
}
|
|
118870
118969
|
return true;
|
|
118871
118970
|
}
|
|
@@ -118883,6 +118982,10 @@ var ProjectQueries = class {
|
|
|
118883
118982
|
for (const row of worktreeRows) {
|
|
118884
118983
|
const list2 = wtByProject.get(row.projectName) ?? [];
|
|
118885
118984
|
list2.push({
|
|
118985
|
+
// Defensive `|| branch`: a row written before the `name` column
|
|
118986
|
+
// existed (backfilled by migration) should never be empty, but fall
|
|
118987
|
+
// back to branch so identity stays stable even if it somehow is.
|
|
118988
|
+
name: row.name || row.branch,
|
|
118886
118989
|
branch: row.branch,
|
|
118887
118990
|
path: row.path,
|
|
118888
118991
|
head: row.head ?? void 0,
|
|
@@ -118931,6 +119034,7 @@ var ProjectQueries = class {
|
|
|
118931
119034
|
for (const wt of project.worktrees) {
|
|
118932
119035
|
tx.insert(worktrees).values({
|
|
118933
119036
|
projectName: project.name,
|
|
119037
|
+
name: wt.name,
|
|
118934
119038
|
branch: wt.branch,
|
|
118935
119039
|
path: wt.path,
|
|
118936
119040
|
head: wt.head ?? null,
|
|
@@ -119046,14 +119150,19 @@ var WorkspaceQueries = class {
|
|
|
119046
119150
|
* Resolve a workspace ID back to its on-disk identity (project, branch,
|
|
119047
119151
|
* worktree path) by scanning the `worktrees` table.
|
|
119048
119152
|
*
|
|
119049
|
-
* The match expression mirrors `toWorkspaceId(project,
|
|
119050
|
-
* `${project}-${
|
|
119051
|
-
*
|
|
119052
|
-
*
|
|
119053
|
-
*
|
|
119054
|
-
*
|
|
119055
|
-
*
|
|
119056
|
-
*
|
|
119153
|
+
* The match expression mirrors `toWorkspaceId(project, name)`:
|
|
119154
|
+
* `${project}-${name.replaceAll("/", "-")}`
|
|
119155
|
+
* where `name` is the immutable workspace identity (see the `worktrees`
|
|
119156
|
+
* schema), NOT the live `branch`. SQLite's `REPLACE(str, "/", "-")` is
|
|
119157
|
+
* also a replace-all, so this is bit-identical to the JS computation.
|
|
119158
|
+
* Pushing the match down into SQL lets us read at most one row instead of
|
|
119159
|
+
* fanning out the projects + worktrees tree just to find a single
|
|
119160
|
+
* workspace (the previous `loadState()`-based implementation walked every
|
|
119161
|
+
* project's worktree list to find the match in JS).
|
|
119162
|
+
*
|
|
119163
|
+
* The returned `branch` is the live git branch, still useful to callers
|
|
119164
|
+
* that want the current checkout — identity is by `name`, git ops by
|
|
119165
|
+
* `branch`.
|
|
119057
119166
|
*
|
|
119058
119167
|
* Called from two places today: the workspace-status upsert path in
|
|
119059
119168
|
* `lib/state.ts::upsertWorkspaceStatus` (via the private
|
|
@@ -119063,7 +119172,7 @@ var WorkspaceQueries = class {
|
|
|
119063
119172
|
* loading the full project tree.
|
|
119064
119173
|
*
|
|
119065
119174
|
* TODO: `toWorkspaceId`'s encoding is not injective — project `foo-bar` +
|
|
119066
|
-
*
|
|
119175
|
+
* name `main` and project `foo` + name `bar/main` both serialize to
|
|
119067
119176
|
* `foo-bar-main`. `.get()` returns whichever row SQLite finds first, and
|
|
119068
119177
|
* the sanity check below cannot disambiguate (both candidates satisfy
|
|
119069
119178
|
* it). Fixing this requires changing the workspace-id encoding, which is
|
|
@@ -119073,12 +119182,13 @@ var WorkspaceQueries = class {
|
|
|
119073
119182
|
const db2 = getDb();
|
|
119074
119183
|
const row = db2.select({
|
|
119075
119184
|
project: worktrees.projectName,
|
|
119185
|
+
name: worktrees.name,
|
|
119076
119186
|
branch: worktrees.branch,
|
|
119077
119187
|
worktreePath: worktrees.path
|
|
119078
119188
|
}).from(worktrees).where(
|
|
119079
|
-
sql`${worktrees.projectName} || '-' || REPLACE(${worktrees.
|
|
119189
|
+
sql`${worktrees.projectName} || '-' || REPLACE(${worktrees.name}, '/', '-') = ${workspaceId}`
|
|
119080
119190
|
).get();
|
|
119081
|
-
if (row && toWorkspaceId(row.project, row.
|
|
119191
|
+
if (row && toWorkspaceId(row.project, row.name) === workspaceId) {
|
|
119082
119192
|
return { project: row.project, branch: row.branch, worktreePath: row.worktreePath };
|
|
119083
119193
|
}
|
|
119084
119194
|
return null;
|
|
@@ -119201,7 +119311,7 @@ function resolveWorkspaceIdByCwd(cwd) {
|
|
|
119201
119311
|
for (const proj of state.projects) {
|
|
119202
119312
|
for (const wt of proj.worktrees) {
|
|
119203
119313
|
if (cwd === wt.path || cwd.startsWith(`${wt.path}/`)) {
|
|
119204
|
-
return toWorkspaceId(proj.name, wt.
|
|
119314
|
+
return toWorkspaceId(proj.name, wt.name);
|
|
119205
119315
|
}
|
|
119206
119316
|
}
|
|
119207
119317
|
}
|
|
@@ -119275,13 +119385,17 @@ async function reconcileOneProject(project) {
|
|
|
119275
119385
|
let diskWorktrees;
|
|
119276
119386
|
try {
|
|
119277
119387
|
const gitWorktrees = await listWorktrees(project.path);
|
|
119278
|
-
const
|
|
119279
|
-
diskWorktrees = gitWorktrees.filter((wt) => !wt.isBare).map((wt) =>
|
|
119280
|
-
|
|
119281
|
-
|
|
119282
|
-
|
|
119283
|
-
|
|
119284
|
-
|
|
119388
|
+
const existingByPath = new Map(project.worktrees.map((wt) => [wt.path, wt]));
|
|
119389
|
+
diskWorktrees = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => {
|
|
119390
|
+
const existing = existingByPath.get(wt.path);
|
|
119391
|
+
return {
|
|
119392
|
+
name: existing?.name ?? wt.branch,
|
|
119393
|
+
branch: wt.branch,
|
|
119394
|
+
path: wt.path,
|
|
119395
|
+
head: wt.head,
|
|
119396
|
+
pinned: existing?.pinned ?? false
|
|
119397
|
+
};
|
|
119398
|
+
});
|
|
119285
119399
|
} catch {
|
|
119286
119400
|
if (project.hasOrigin) {
|
|
119287
119401
|
setProjectHasOrigin(project.name, false);
|
|
@@ -119332,6 +119446,7 @@ var pollerState = {
|
|
|
119332
119446
|
tickCount: 0,
|
|
119333
119447
|
activity: "active"
|
|
119334
119448
|
};
|
|
119449
|
+
var lastCIPollErrorByHost = /* @__PURE__ */ new Map();
|
|
119335
119450
|
function getWorkspaces() {
|
|
119336
119451
|
const state = loadState();
|
|
119337
119452
|
const workspaces = [];
|
|
@@ -119339,7 +119454,7 @@ function getWorkspaces() {
|
|
|
119339
119454
|
if (project.kind === "plain") continue;
|
|
119340
119455
|
for (const wt of project.worktrees) {
|
|
119341
119456
|
workspaces.push({
|
|
119342
|
-
workspaceId: toWorkspaceId(project.name, wt.
|
|
119457
|
+
workspaceId: toWorkspaceId(project.name, wt.name),
|
|
119343
119458
|
project: project.name,
|
|
119344
119459
|
branch: wt.branch,
|
|
119345
119460
|
defaultBranch: project.defaultBranch,
|
|
@@ -119420,6 +119535,7 @@ async function getBatchedCIStatuses(workspaces) {
|
|
|
119420
119535
|
}
|
|
119421
119536
|
}
|
|
119422
119537
|
if (resolved.length === 0) {
|
|
119538
|
+
lastCIPollErrorByHost.clear();
|
|
119423
119539
|
const results = /* @__PURE__ */ new Map();
|
|
119424
119540
|
for (const ws of workspaces) {
|
|
119425
119541
|
results.set(ws.workspaceId, { state: "none" });
|
|
@@ -119466,13 +119582,21 @@ async function getBatchedCIStatuses(workspaces) {
|
|
|
119466
119582
|
allResults.set(g15.ws.workspaceId, status);
|
|
119467
119583
|
}
|
|
119468
119584
|
}
|
|
119585
|
+
lastCIPollErrorByHost.delete(host);
|
|
119469
119586
|
} catch (err) {
|
|
119470
|
-
|
|
119471
|
-
|
|
119472
|
-
|
|
119473
|
-
|
|
119587
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119588
|
+
if (lastCIPollErrorByHost.get(host) !== message) {
|
|
119589
|
+
lastCIPollErrorByHost.set(host, message);
|
|
119590
|
+
console.error(
|
|
119591
|
+
`CI poll: GraphQL query failed for host (${group.length} workspaces):`,
|
|
119592
|
+
message
|
|
119593
|
+
);
|
|
119594
|
+
}
|
|
119474
119595
|
}
|
|
119475
119596
|
}
|
|
119597
|
+
for (const host of [...lastCIPollErrorByHost.keys()]) {
|
|
119598
|
+
if (!byHost.has(host)) lastCIPollErrorByHost.delete(host);
|
|
119599
|
+
}
|
|
119476
119600
|
for (const ws of workspaces) {
|
|
119477
119601
|
if (!allResults.has(ws.workspaceId)) {
|
|
119478
119602
|
allResults.set(ws.workspaceId, { state: "none" });
|
|
@@ -120412,7 +120536,7 @@ init_src();
|
|
|
120412
120536
|
init_zod();
|
|
120413
120537
|
import { execFile as execFile6 } from "node:child_process";
|
|
120414
120538
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
120415
|
-
import { existsSync as
|
|
120539
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync5, unlinkSync as unlinkSync3 } from "node:fs";
|
|
120416
120540
|
import { rm } from "node:fs/promises";
|
|
120417
120541
|
import { join as join20 } from "node:path";
|
|
120418
120542
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -120683,52 +120807,6 @@ init_src();
|
|
|
120683
120807
|
import { spawn as spawn6 } from "node:child_process";
|
|
120684
120808
|
import { dirname as dirname2, join as join17, resolve as resolve3 } from "node:path";
|
|
120685
120809
|
import { fileURLToPath } from "node:url";
|
|
120686
|
-
|
|
120687
|
-
// src/server/infra/process/path.ts
|
|
120688
|
-
import { execFile as execFile4 } from "node:child_process";
|
|
120689
|
-
var cachedShellPath = null;
|
|
120690
|
-
async function shellPath() {
|
|
120691
|
-
if (cachedShellPath) return cachedShellPath;
|
|
120692
|
-
const shell = process.env.SHELL || "/bin/zsh";
|
|
120693
|
-
try {
|
|
120694
|
-
const result = await new Promise((resolve12, reject) => {
|
|
120695
|
-
execFile4(shell, ["-li", "-c", "echo $PATH"], { timeout: 5e3 }, (err, stdout) => {
|
|
120696
|
-
if (err) {
|
|
120697
|
-
reject(err);
|
|
120698
|
-
return;
|
|
120699
|
-
}
|
|
120700
|
-
resolve12(stdout.trim());
|
|
120701
|
-
});
|
|
120702
|
-
});
|
|
120703
|
-
if (result) {
|
|
120704
|
-
cachedShellPath = result;
|
|
120705
|
-
return result;
|
|
120706
|
-
}
|
|
120707
|
-
} catch {
|
|
120708
|
-
}
|
|
120709
|
-
const fallback = `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH || ""}`;
|
|
120710
|
-
cachedShellPath = fallback;
|
|
120711
|
-
return fallback;
|
|
120712
|
-
}
|
|
120713
|
-
async function whichBinary(name3) {
|
|
120714
|
-
const resolvedPath = await shellPath();
|
|
120715
|
-
try {
|
|
120716
|
-
const result = await new Promise((resolve12, reject) => {
|
|
120717
|
-
execFile4("which", [name3], { env: { ...process.env, PATH: resolvedPath } }, (err, stdout) => {
|
|
120718
|
-
if (err) {
|
|
120719
|
-
reject(err);
|
|
120720
|
-
return;
|
|
120721
|
-
}
|
|
120722
|
-
resolve12(stdout.trim());
|
|
120723
|
-
});
|
|
120724
|
-
});
|
|
120725
|
-
return result || null;
|
|
120726
|
-
} catch {
|
|
120727
|
-
return null;
|
|
120728
|
-
}
|
|
120729
|
-
}
|
|
120730
|
-
|
|
120731
|
-
// src/server/infra/lsp/lsp-manager.ts
|
|
120732
120810
|
var workspaceQueries = new WorkspaceQueries();
|
|
120733
120811
|
var __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
120734
120812
|
var log16 = createLogger("lsp");
|
|
@@ -120828,7 +120906,7 @@ init_src();
|
|
|
120828
120906
|
import { execFile as execFile5 } from "node:child_process";
|
|
120829
120907
|
import {
|
|
120830
120908
|
copyFileSync as copyFileSync2,
|
|
120831
|
-
existsSync as
|
|
120909
|
+
existsSync as existsSync7,
|
|
120832
120910
|
globSync,
|
|
120833
120911
|
mkdirSync as mkdirSync4,
|
|
120834
120912
|
readFileSync as readFileSync7,
|
|
@@ -120961,7 +121039,7 @@ function resolveFromConfig(projectPath, missing) {
|
|
|
120961
121039
|
}
|
|
120962
121040
|
async function resolveFromWorktreeInclude(projectPath) {
|
|
120963
121041
|
const includePath = join18(projectPath, ".worktreeinclude");
|
|
120964
|
-
if (!
|
|
121042
|
+
if (!existsSync7(includePath)) return [];
|
|
120965
121043
|
const includeContent = readFileSync7(includePath, "utf-8");
|
|
120966
121044
|
const hasPatterns = includeContent.split(/\r?\n/).some((line2) => {
|
|
120967
121045
|
const trimmed = line2.trim();
|
|
@@ -122559,6 +122637,92 @@ var CronjobService = class {
|
|
|
122559
122637
|
};
|
|
122560
122638
|
var cronjobService = new CronjobService();
|
|
122561
122639
|
|
|
122640
|
+
// src/server/services/panel-focus-service.ts
|
|
122641
|
+
init_src();
|
|
122642
|
+
var log21 = createLogger("panel-focus-service");
|
|
122643
|
+
var PANEL_FOCUS_TYPE = "panel_focus";
|
|
122644
|
+
function focusRowId(workspaceId) {
|
|
122645
|
+
return `${PANEL_FOCUS_TYPE}:${workspaceId}`;
|
|
122646
|
+
}
|
|
122647
|
+
var PanelFocusService = class {
|
|
122648
|
+
/** workspaceId → last-focused panel ids. */
|
|
122649
|
+
focus = /* @__PURE__ */ new Map();
|
|
122650
|
+
/**
|
|
122651
|
+
* Workspaces whose focus row has been loaded from the DB into `focus`.
|
|
122652
|
+
* Separate from the map's own key presence because a workspace can have a
|
|
122653
|
+
* loaded-but-empty record (row absent) — we still don't want to re-hit the
|
|
122654
|
+
* DB on every read.
|
|
122655
|
+
*/
|
|
122656
|
+
hydrated = /* @__PURE__ */ new Set();
|
|
122657
|
+
/** Workspaces that already have a `panel_states` row (drives insert vs update). */
|
|
122658
|
+
persisted = /* @__PURE__ */ new Set();
|
|
122659
|
+
/**
|
|
122660
|
+
* Load a workspace's focus row from the DB on first access. Cheap and
|
|
122661
|
+
* idempotent — subsequent calls short-circuit on the `hydrated` set.
|
|
122662
|
+
*/
|
|
122663
|
+
ensureHydrated(workspaceId) {
|
|
122664
|
+
if (this.hydrated.has(workspaceId)) return;
|
|
122665
|
+
this.hydrated.add(workspaceId);
|
|
122666
|
+
const rows = listPanelStatesForWorkspace(workspaceId, PANEL_FOCUS_TYPE);
|
|
122667
|
+
const row = rows[0];
|
|
122668
|
+
if (!row) return;
|
|
122669
|
+
this.persisted.add(workspaceId);
|
|
122670
|
+
try {
|
|
122671
|
+
const parsed = JSON.parse(row.state);
|
|
122672
|
+
this.focus.set(workspaceId, {
|
|
122673
|
+
chat: parsed.chat,
|
|
122674
|
+
terminal: parsed.terminal,
|
|
122675
|
+
browser: parsed.browser
|
|
122676
|
+
});
|
|
122677
|
+
} catch (err) {
|
|
122678
|
+
log21.warn({ workspaceId, err }, "failed to parse persisted panel focus; ignoring");
|
|
122679
|
+
}
|
|
122680
|
+
}
|
|
122681
|
+
/** Get the last-focused panel ids for a workspace. */
|
|
122682
|
+
get(workspaceId) {
|
|
122683
|
+
this.ensureHydrated(workspaceId);
|
|
122684
|
+
return { ...this.focus.get(workspaceId) ?? {} };
|
|
122685
|
+
}
|
|
122686
|
+
/**
|
|
122687
|
+
* Record that `panelId` is the last-focused panel of `panelType` in
|
|
122688
|
+
* `workspaceId`. Write-through: updates the in-memory map and upserts the
|
|
122689
|
+
* backing `panel_states` row.
|
|
122690
|
+
*/
|
|
122691
|
+
set(workspaceId, panelType, panelId) {
|
|
122692
|
+
this.ensureHydrated(workspaceId);
|
|
122693
|
+
const current2 = this.focus.get(workspaceId) ?? {};
|
|
122694
|
+
if (current2[panelType] === panelId) return;
|
|
122695
|
+
const next = { ...current2, [panelType]: panelId };
|
|
122696
|
+
this.focus.set(workspaceId, next);
|
|
122697
|
+
const now = Date.now();
|
|
122698
|
+
const state = JSON.stringify(next);
|
|
122699
|
+
if (this.persisted.has(workspaceId)) {
|
|
122700
|
+
updatePanelState(focusRowId(workspaceId), { state, updatedAt: now });
|
|
122701
|
+
} else {
|
|
122702
|
+
insertPanelState({
|
|
122703
|
+
id: focusRowId(workspaceId),
|
|
122704
|
+
workspaceId,
|
|
122705
|
+
panelType: PANEL_FOCUS_TYPE,
|
|
122706
|
+
state,
|
|
122707
|
+
createdAt: now,
|
|
122708
|
+
updatedAt: now
|
|
122709
|
+
});
|
|
122710
|
+
this.persisted.add(workspaceId);
|
|
122711
|
+
}
|
|
122712
|
+
}
|
|
122713
|
+
/**
|
|
122714
|
+
* Drop all focus tracking for a workspace. Called from the workspace delete
|
|
122715
|
+
* path so the row doesn't outlive the workspace.
|
|
122716
|
+
*/
|
|
122717
|
+
remove(workspaceId) {
|
|
122718
|
+
this.focus.delete(workspaceId);
|
|
122719
|
+
this.hydrated.delete(workspaceId);
|
|
122720
|
+
this.persisted.delete(workspaceId);
|
|
122721
|
+
deletePanelState(focusRowId(workspaceId));
|
|
122722
|
+
}
|
|
122723
|
+
};
|
|
122724
|
+
var panelFocusService = new PanelFocusService();
|
|
122725
|
+
|
|
122562
122726
|
// src/server/services/terminal-service.ts
|
|
122563
122727
|
init_src();
|
|
122564
122728
|
init_zod();
|
|
@@ -122566,10 +122730,10 @@ init_zod();
|
|
|
122566
122730
|
// src/server/infra/terminals/terminal-pool.ts
|
|
122567
122731
|
init_src();
|
|
122568
122732
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
122569
|
-
import { existsSync as
|
|
122733
|
+
import { existsSync as existsSync8, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
122570
122734
|
import { tmpdir } from "node:os";
|
|
122571
122735
|
import { join as join19, sep as sep3 } from "node:path";
|
|
122572
|
-
var
|
|
122736
|
+
var log22 = createLogger("terminal-pool");
|
|
122573
122737
|
var MAX_SCROLLBACK_SIZE = 1e5;
|
|
122574
122738
|
var TerminalPool = class {
|
|
122575
122739
|
/** terminalId -> session */
|
|
@@ -122586,7 +122750,7 @@ var TerminalPool = class {
|
|
|
122586
122750
|
* stays oblivious to the workspace registry.
|
|
122587
122751
|
*/
|
|
122588
122752
|
async spawn(workspaceId, terminalId, workspaceRoot, options2) {
|
|
122589
|
-
const shell =
|
|
122753
|
+
const shell = defaultShell();
|
|
122590
122754
|
const resolvedPath = await shellPath();
|
|
122591
122755
|
const env = {};
|
|
122592
122756
|
for (const [key, value] of Object.entries(process.env)) {
|
|
@@ -122607,24 +122771,24 @@ var TerminalPool = class {
|
|
|
122607
122771
|
if (options2?.cwd) {
|
|
122608
122772
|
const resolved = join19(workspaceRoot, options2.cwd);
|
|
122609
122773
|
if (resolved !== workspaceRoot && !resolved.startsWith(workspaceRoot + sep3)) {
|
|
122610
|
-
|
|
122774
|
+
log22.warn(
|
|
122611
122775
|
"Ignoring cwd %s \u2014 resolves outside workspace root %s",
|
|
122612
122776
|
options2.cwd,
|
|
122613
122777
|
workspaceRoot
|
|
122614
122778
|
);
|
|
122615
|
-
} else if (
|
|
122779
|
+
} else if (existsSync8(resolved)) {
|
|
122616
122780
|
cwd = resolved;
|
|
122617
122781
|
} else {
|
|
122618
|
-
|
|
122782
|
+
log22.warn("Ignoring cwd %s \u2014 directory does not exist", options2.cwd);
|
|
122619
122783
|
}
|
|
122620
122784
|
}
|
|
122621
|
-
if (!
|
|
122785
|
+
if (!existsSync8(cwd)) {
|
|
122622
122786
|
throw new Error(`Workspace directory does not exist: ${cwd}`);
|
|
122623
122787
|
}
|
|
122624
|
-
if (!
|
|
122788
|
+
if (!existsSync8(shell)) {
|
|
122625
122789
|
throw new Error(`Shell not found: ${shell}`);
|
|
122626
122790
|
}
|
|
122627
|
-
|
|
122791
|
+
log22.debug(
|
|
122628
122792
|
"Spawning shell %s in %s for terminal %s (PATH=%s)",
|
|
122629
122793
|
shell,
|
|
122630
122794
|
cwd,
|
|
@@ -122643,7 +122807,7 @@ var TerminalPool = class {
|
|
|
122643
122807
|
});
|
|
122644
122808
|
} catch (err) {
|
|
122645
122809
|
const msg = err instanceof Error ? err.message : String(err);
|
|
122646
|
-
|
|
122810
|
+
log22.error("pty.spawn failed: %s (shell=%s, cwd=%s)", msg, shell, cwd);
|
|
122647
122811
|
throw err;
|
|
122648
122812
|
}
|
|
122649
122813
|
const session = { pty: ptyProcess, scrollback: "", workspaceId };
|
|
@@ -122673,7 +122837,7 @@ var TerminalPool = class {
|
|
|
122673
122837
|
}
|
|
122674
122838
|
});
|
|
122675
122839
|
ptyProcess.onExit(() => {
|
|
122676
|
-
|
|
122840
|
+
log22.debug("Terminal exited: %s (workspace %s)", terminalId, workspaceId);
|
|
122677
122841
|
this.terminals.delete(terminalId);
|
|
122678
122842
|
this.outputListeners.delete(terminalId);
|
|
122679
122843
|
const set = this.workspaceTerminals.get(workspaceId);
|
|
@@ -122728,7 +122892,7 @@ var TerminalPool = class {
|
|
|
122728
122892
|
`, { encoding: "utf-8", mode: 384, flag: "wx" });
|
|
122729
122893
|
session.autoRunFile = cmdFile;
|
|
122730
122894
|
} catch (err) {
|
|
122731
|
-
|
|
122895
|
+
log22.warn(
|
|
122732
122896
|
"autoRunCommand: temp-file staging failed (%s); writing command directly",
|
|
122733
122897
|
err instanceof Error ? err.message : String(err)
|
|
122734
122898
|
);
|
|
@@ -122746,7 +122910,7 @@ var TerminalPool = class {
|
|
|
122746
122910
|
try {
|
|
122747
122911
|
pty.write(sourceLine);
|
|
122748
122912
|
} catch (err) {
|
|
122749
|
-
|
|
122913
|
+
log22.warn("autoRunCommand: failed to inject command line (%s)", err);
|
|
122750
122914
|
}
|
|
122751
122915
|
};
|
|
122752
122916
|
let dataDisposed = false;
|
|
@@ -122925,7 +123089,7 @@ function removeTerminalFromLayout(workspaceId, terminalId) {
|
|
|
122925
123089
|
}
|
|
122926
123090
|
|
|
122927
123091
|
// src/server/services/terminal-service.ts
|
|
122928
|
-
var
|
|
123092
|
+
var log23 = createLogger("terminal-service");
|
|
122929
123093
|
var TerminalPaneConfigSchema = external_exports.object({
|
|
122930
123094
|
name: external_exports.string().optional(),
|
|
122931
123095
|
command: external_exports.string().optional(),
|
|
@@ -123083,7 +123247,7 @@ var TerminalService = class {
|
|
|
123083
123247
|
if (!terminalBlock) return null;
|
|
123084
123248
|
const result = WorkspaceTerminalConfigSchema.safeParse(terminalBlock);
|
|
123085
123249
|
if (!result.success) {
|
|
123086
|
-
|
|
123250
|
+
log23.warn(
|
|
123087
123251
|
"Invalid workspace.terminal config: %s",
|
|
123088
123252
|
result.error.issues.map((i2) => `${i2.path.join(".")}: ${i2.message}`).join("; ")
|
|
123089
123253
|
);
|
|
@@ -123096,7 +123260,7 @@ var terminalService = new TerminalService();
|
|
|
123096
123260
|
|
|
123097
123261
|
// src/server/services/workspace-service.ts
|
|
123098
123262
|
var execFileAsync2 = promisify2(execFile6);
|
|
123099
|
-
var
|
|
123263
|
+
var log24 = createLogger("workspace-service");
|
|
123100
123264
|
var workspaceVia = external_exports.enum(["chat", "terminal"]);
|
|
123101
123265
|
var workspaceCreateInput = external_exports.object({
|
|
123102
123266
|
project: external_exports.string(),
|
|
@@ -123116,16 +123280,20 @@ var workspaceCreateInput = external_exports.object({
|
|
|
123116
123280
|
});
|
|
123117
123281
|
var workspaceRemoveInput = external_exports.object({
|
|
123118
123282
|
project: external_exports.string(),
|
|
123119
|
-
|
|
123283
|
+
// Workspace identity (the immutable `name`), NOT the live git branch. The
|
|
123284
|
+
// live branch to delete is resolved from the worktree row.
|
|
123285
|
+
name: external_exports.string()
|
|
123120
123286
|
});
|
|
123121
123287
|
var workspaceSetPinnedInput = external_exports.object({
|
|
123122
123288
|
project: external_exports.string(),
|
|
123123
|
-
|
|
123289
|
+
// Workspace identity (immutable `name`), not the live git branch.
|
|
123290
|
+
name: external_exports.string(),
|
|
123124
123291
|
pinned: external_exports.boolean()
|
|
123125
123292
|
});
|
|
123126
123293
|
var workspaceGitInput = external_exports.object({
|
|
123127
123294
|
project: external_exports.string(),
|
|
123128
|
-
|
|
123295
|
+
// Workspace identity (immutable `name`), not the live git branch.
|
|
123296
|
+
name: external_exports.string()
|
|
123129
123297
|
});
|
|
123130
123298
|
var workspaceRunScriptInput = external_exports.object({
|
|
123131
123299
|
path: external_exports.string(),
|
|
@@ -123179,7 +123347,7 @@ var WorkspaceService = class {
|
|
|
123179
123347
|
const state = loadState();
|
|
123180
123348
|
for (const project of state.projects) {
|
|
123181
123349
|
for (const worktree of project.worktrees) {
|
|
123182
|
-
if (toWorkspaceId(project.name, worktree.
|
|
123350
|
+
if (toWorkspaceId(project.name, worktree.name) === workspaceId) {
|
|
123183
123351
|
return { project, worktree };
|
|
123184
123352
|
}
|
|
123185
123353
|
}
|
|
@@ -123255,7 +123423,9 @@ var WorkspaceService = class {
|
|
|
123255
123423
|
`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.`
|
|
123256
123424
|
);
|
|
123257
123425
|
}
|
|
123258
|
-
const existing = project.worktrees.find(
|
|
123426
|
+
const existing = project.worktrees.find(
|
|
123427
|
+
(wt) => wt.name === input.branch || wt.branch === input.branch
|
|
123428
|
+
);
|
|
123259
123429
|
if (existing) {
|
|
123260
123430
|
return { ok: true, path: existing.path };
|
|
123261
123431
|
}
|
|
@@ -123274,16 +123444,21 @@ var WorkspaceService = class {
|
|
|
123274
123444
|
} catch (e2) {
|
|
123275
123445
|
throw new Error(e2 instanceof Error ? e2.message : String(e2));
|
|
123276
123446
|
}
|
|
123277
|
-
project.worktrees.push({
|
|
123447
|
+
project.worktrees.push({
|
|
123448
|
+
name: input.branch,
|
|
123449
|
+
branch: input.branch,
|
|
123450
|
+
path: worktreePath,
|
|
123451
|
+
pinned: false
|
|
123452
|
+
});
|
|
123278
123453
|
saveState(state);
|
|
123279
123454
|
const workspaceId = toWorkspaceId(input.project, input.branch);
|
|
123280
123455
|
try {
|
|
123281
123456
|
const copied = await copyWorkspaceFiles(project.path, worktreePath);
|
|
123282
123457
|
if (copied.length > 0) {
|
|
123283
|
-
|
|
123458
|
+
log24.info({ workspaceId, count: copied.length }, "copied workspace files into new worktree");
|
|
123284
123459
|
}
|
|
123285
123460
|
} catch (err) {
|
|
123286
|
-
|
|
123461
|
+
log24.warn({ err, workspaceId }, "copyWorkspaceFiles raised \u2014 continuing");
|
|
123287
123462
|
}
|
|
123288
123463
|
const defaultChat = chatService.getOrCreateDefault(workspaceId);
|
|
123289
123464
|
let via = input.via ?? "chat";
|
|
@@ -123296,7 +123471,7 @@ var WorkspaceService = class {
|
|
|
123296
123471
|
adapter.abort?.();
|
|
123297
123472
|
if (!invocation || invocation.unsupported) {
|
|
123298
123473
|
const reason = invocation?.reason ?? "adapter does not expose cliInvocation";
|
|
123299
|
-
|
|
123474
|
+
log24.warn(
|
|
123300
123475
|
{ workspaceId, agentId: input.codingAgentId, reason },
|
|
123301
123476
|
"via=terminal requested but adapter does not support it; falling back to chat"
|
|
123302
123477
|
);
|
|
@@ -123306,7 +123481,7 @@ var WorkspaceService = class {
|
|
|
123306
123481
|
terminalId = randomUUID3();
|
|
123307
123482
|
}
|
|
123308
123483
|
} catch (err) {
|
|
123309
|
-
|
|
123484
|
+
log24.warn(
|
|
123310
123485
|
{
|
|
123311
123486
|
err: err instanceof Error ? err.message : String(err),
|
|
123312
123487
|
workspaceId,
|
|
@@ -123324,7 +123499,7 @@ var WorkspaceService = class {
|
|
|
123324
123499
|
}).then(() => {
|
|
123325
123500
|
emit({ kind: "terminal-created", workspaceId, terminalId });
|
|
123326
123501
|
}).catch((err) => {
|
|
123327
|
-
|
|
123502
|
+
log24.error(
|
|
123328
123503
|
{
|
|
123329
123504
|
err: err instanceof Error ? err.message : String(err),
|
|
123330
123505
|
workspaceId,
|
|
@@ -123395,7 +123570,7 @@ var WorkspaceService = class {
|
|
|
123395
123570
|
const terminalId = randomUUID3();
|
|
123396
123571
|
await terminalService.spawn(chat.workspaceId, terminalId, { command });
|
|
123397
123572
|
emit({ kind: "terminal-created", workspaceId: chat.workspaceId, terminalId });
|
|
123398
|
-
|
|
123573
|
+
log24.info(
|
|
123399
123574
|
{ chatId, workspaceId: chat.workspaceId, terminalId },
|
|
123400
123575
|
"continue chat session in terminal"
|
|
123401
123576
|
);
|
|
@@ -123433,11 +123608,16 @@ var WorkspaceService = class {
|
|
|
123433
123608
|
`Project "${input.project}" is a plain (non-git) project. Remove the project instead of the workspace.`
|
|
123434
123609
|
);
|
|
123435
123610
|
}
|
|
123611
|
+
const wtRow = project.worktrees.find((wt) => wt.name === input.name);
|
|
123612
|
+
if (!wtRow) {
|
|
123613
|
+
throw new WorkspaceNotFoundError(input.name);
|
|
123614
|
+
}
|
|
123615
|
+
const currentBranch = wtRow.branch;
|
|
123436
123616
|
const { command, env: gitEnv } = gitCmd();
|
|
123437
123617
|
const worktrees2 = await listWorktrees(project.path);
|
|
123438
|
-
const match = worktrees2.find((wt) => wt.branch ===
|
|
123618
|
+
const match = worktrees2.find((wt) => wt.branch === currentBranch);
|
|
123439
123619
|
if (!match) {
|
|
123440
|
-
throw new WorkspaceNotFoundError(input.
|
|
123620
|
+
throw new WorkspaceNotFoundError(input.name);
|
|
123441
123621
|
}
|
|
123442
123622
|
const worktreePath = match.path;
|
|
123443
123623
|
let teardownCmd;
|
|
@@ -123448,9 +123628,9 @@ var WorkspaceService = class {
|
|
|
123448
123628
|
}
|
|
123449
123629
|
} catch {
|
|
123450
123630
|
}
|
|
123451
|
-
project.worktrees = project.worktrees.filter((wt) => wt.
|
|
123631
|
+
project.worktrees = project.worktrees.filter((wt) => wt.name !== input.name);
|
|
123452
123632
|
saveState(state);
|
|
123453
|
-
const workspaceId = toWorkspaceId(input.project, input.
|
|
123633
|
+
const workspaceId = toWorkspaceId(input.project, input.name);
|
|
123454
123634
|
try {
|
|
123455
123635
|
unlinkSync3(join20(bandHome(), "workspace-prompts", `${workspaceId}.json`));
|
|
123456
123636
|
} catch {
|
|
@@ -123461,35 +123641,36 @@ var WorkspaceService = class {
|
|
|
123461
123641
|
browserService.removeAllForWorkspace(workspaceId);
|
|
123462
123642
|
terminalService.killWorkspace(workspaceId);
|
|
123463
123643
|
terminalService.deleteLayout(workspaceId);
|
|
123644
|
+
panelFocusService.remove(workspaceId);
|
|
123464
123645
|
killWorkspaceServers(workspaceId);
|
|
123465
123646
|
cronjobService.removeForKey(workspaceId);
|
|
123466
123647
|
try {
|
|
123467
123648
|
const deletedTasks = new TaskQueries().deleteWorkspaceTasks(workspaceId);
|
|
123468
123649
|
if (deletedTasks > 0) {
|
|
123469
|
-
|
|
123650
|
+
log24.info({ workspaceId, count: deletedTasks }, "deleted workspace tasks on removal");
|
|
123470
123651
|
}
|
|
123471
123652
|
} catch (err) {
|
|
123472
|
-
|
|
123653
|
+
log24.error({ workspaceId, err }, "failed to delete workspace tasks on removal");
|
|
123473
123654
|
}
|
|
123474
123655
|
try {
|
|
123475
123656
|
const deletedEvents = this.usageEventQueries.deleteWorkspaceEvents(workspaceId);
|
|
123476
123657
|
if (deletedEvents > 0) {
|
|
123477
|
-
|
|
123658
|
+
log24.info(
|
|
123478
123659
|
{ workspaceId, count: deletedEvents },
|
|
123479
123660
|
"deleted workspace usage events on removal"
|
|
123480
123661
|
);
|
|
123481
123662
|
}
|
|
123482
123663
|
} catch (err) {
|
|
123483
|
-
|
|
123664
|
+
log24.error({ workspaceId, err }, "failed to delete workspace usage events on removal");
|
|
123484
123665
|
}
|
|
123485
123666
|
try {
|
|
123486
123667
|
this.usageScanStateQueries.deleteWorkspace(workspaceId);
|
|
123487
123668
|
} catch (err) {
|
|
123488
|
-
|
|
123669
|
+
log24.error({ workspaceId, err }, "failed to delete workspace usage scan state on removal");
|
|
123489
123670
|
}
|
|
123490
123671
|
emit({ kind: "remove", workspaceId });
|
|
123491
123672
|
const projPath = project.path;
|
|
123492
|
-
const branchToDelete = match.branch.startsWith(DETACHED_BRANCH_PREFIX) ? null :
|
|
123673
|
+
const branchToDelete = match.branch.startsWith(DETACHED_BRANCH_PREFIX) ? null : currentBranch;
|
|
123493
123674
|
setImmediate(() => {
|
|
123494
123675
|
(async () => {
|
|
123495
123676
|
if (teardownCmd) {
|
|
@@ -123498,13 +123679,13 @@ var WorkspaceService = class {
|
|
|
123498
123679
|
cwd: worktreePath,
|
|
123499
123680
|
env: {
|
|
123500
123681
|
...process.env,
|
|
123501
|
-
PATH:
|
|
123682
|
+
PATH: prependBinDirs(process.env.PATH)
|
|
123502
123683
|
},
|
|
123503
123684
|
encoding: "utf-8",
|
|
123504
123685
|
timeout: 6e4
|
|
123505
123686
|
});
|
|
123506
123687
|
} catch (err) {
|
|
123507
|
-
|
|
123688
|
+
log24.warn({ err, workspaceId }, "teardown script failed");
|
|
123508
123689
|
}
|
|
123509
123690
|
}
|
|
123510
123691
|
try {
|
|
@@ -123517,7 +123698,7 @@ var WorkspaceService = class {
|
|
|
123517
123698
|
try {
|
|
123518
123699
|
await rm(worktreePath, { recursive: true, force: true });
|
|
123519
123700
|
} catch (err) {
|
|
123520
|
-
|
|
123701
|
+
log24.warn({ err, workspaceId, worktreePath }, "manual worktree rm failed");
|
|
123521
123702
|
}
|
|
123522
123703
|
try {
|
|
123523
123704
|
await execFileAsync2(command, ["worktree", "prune"], {
|
|
@@ -123526,7 +123707,7 @@ var WorkspaceService = class {
|
|
|
123526
123707
|
encoding: "utf-8"
|
|
123527
123708
|
});
|
|
123528
123709
|
} catch (err) {
|
|
123529
|
-
|
|
123710
|
+
log24.warn({ err, workspaceId }, "git worktree prune failed");
|
|
123530
123711
|
}
|
|
123531
123712
|
}
|
|
123532
123713
|
if (branchToDelete) {
|
|
@@ -123540,7 +123721,7 @@ var WorkspaceService = class {
|
|
|
123540
123721
|
}
|
|
123541
123722
|
}
|
|
123542
123723
|
})().catch((err) => {
|
|
123543
|
-
|
|
123724
|
+
log24.error({ err, workspaceId }, "background workspace cleanup failed");
|
|
123544
123725
|
});
|
|
123545
123726
|
});
|
|
123546
123727
|
return { ok: true };
|
|
@@ -123564,9 +123745,9 @@ var WorkspaceService = class {
|
|
|
123564
123745
|
`Project "${input.project}" is a plain (non-git) project. Pinning is not available.`
|
|
123565
123746
|
);
|
|
123566
123747
|
}
|
|
123567
|
-
const worktree = project.worktrees.find((w2) => w2.
|
|
123748
|
+
const worktree = project.worktrees.find((w2) => w2.name === input.name);
|
|
123568
123749
|
if (!worktree) {
|
|
123569
|
-
throw new WorkspaceNotFoundError(input.
|
|
123750
|
+
throw new WorkspaceNotFoundError(input.name);
|
|
123570
123751
|
}
|
|
123571
123752
|
worktree.pinned = input.pinned;
|
|
123572
123753
|
saveState(state);
|
|
@@ -123581,10 +123762,10 @@ var WorkspaceService = class {
|
|
|
123581
123762
|
* case and a thrown error would surface as a red toast.
|
|
123582
123763
|
*/
|
|
123583
123764
|
async gitPull(input) {
|
|
123584
|
-
const workspaceId = toWorkspaceId(input.project, input.
|
|
123765
|
+
const workspaceId = toWorkspaceId(input.project, input.name);
|
|
123585
123766
|
const workspace = this.resolve(workspaceId);
|
|
123586
123767
|
if (!workspace) {
|
|
123587
|
-
throw new WorkspaceNotFoundError(input.
|
|
123768
|
+
throw new WorkspaceNotFoundError(input.name);
|
|
123588
123769
|
}
|
|
123589
123770
|
if (workspace.project.kind === "plain") {
|
|
123590
123771
|
throw new PlainProjectError(
|
|
@@ -123611,10 +123792,10 @@ var WorkspaceService = class {
|
|
|
123611
123792
|
* a second failing push.
|
|
123612
123793
|
*/
|
|
123613
123794
|
async gitPush(input) {
|
|
123614
|
-
const workspaceId = toWorkspaceId(input.project, input.
|
|
123795
|
+
const workspaceId = toWorkspaceId(input.project, input.name);
|
|
123615
123796
|
const workspace = this.resolve(workspaceId);
|
|
123616
123797
|
if (!workspace) {
|
|
123617
|
-
throw new WorkspaceNotFoundError(input.
|
|
123798
|
+
throw new WorkspaceNotFoundError(input.name);
|
|
123618
123799
|
}
|
|
123619
123800
|
if (workspace.project.kind === "plain") {
|
|
123620
123801
|
throw new PlainProjectError(
|
|
@@ -123629,7 +123810,7 @@ var WorkspaceService = class {
|
|
|
123629
123810
|
if (!/has no upstream branch/i.test(msg)) {
|
|
123630
123811
|
throw err;
|
|
123631
123812
|
}
|
|
123632
|
-
await execGit(["push", "--set-upstream", "origin",
|
|
123813
|
+
await execGit(["push", "--set-upstream", "origin", workspace.worktree.branch], cwd);
|
|
123633
123814
|
}
|
|
123634
123815
|
return { ok: true };
|
|
123635
123816
|
}
|
|
@@ -123833,7 +124014,7 @@ var WorkspaceService = class {
|
|
|
123833
124014
|
*/
|
|
123834
124015
|
async runScript(input) {
|
|
123835
124016
|
const scriptPath = join20(input.path, ".band", input.scriptType);
|
|
123836
|
-
if (!
|
|
124017
|
+
if (!existsSync9(scriptPath)) {
|
|
123837
124018
|
throw new Error(`Script "${input.scriptType}" not found`);
|
|
123838
124019
|
}
|
|
123839
124020
|
try {
|
|
@@ -123847,7 +124028,7 @@ var WorkspaceService = class {
|
|
|
123847
124028
|
var workspaceService = new WorkspaceService();
|
|
123848
124029
|
|
|
123849
124030
|
// src/server/services/task-service.ts
|
|
123850
|
-
var
|
|
124031
|
+
var log25 = createLogger("task-service");
|
|
123851
124032
|
var taskQueries = new TaskQueries();
|
|
123852
124033
|
function listFiles(dir) {
|
|
123853
124034
|
try {
|
|
@@ -123940,7 +124121,7 @@ function persistTask(task) {
|
|
|
123940
124121
|
chatId: task.chatId
|
|
123941
124122
|
});
|
|
123942
124123
|
} catch (err) {
|
|
123943
|
-
|
|
124124
|
+
log25.warn({ err, taskId: task.taskRecordId }, "failed to persist task");
|
|
123944
124125
|
}
|
|
123945
124126
|
}
|
|
123946
124127
|
function broadcast(chatId, chunk) {
|
|
@@ -123964,7 +124145,7 @@ function broadcast(chatId, chunk) {
|
|
|
123964
124145
|
}
|
|
123965
124146
|
const subs = listeners2.get(chatId);
|
|
123966
124147
|
if (!subs || subs.size === 0) {
|
|
123967
|
-
|
|
124148
|
+
log25.debug({ chatId, chunkType: chunk.type }, "broadcast: no listeners");
|
|
123968
124149
|
return;
|
|
123969
124150
|
}
|
|
123970
124151
|
for (const listener of subs) {
|
|
@@ -124028,7 +124209,7 @@ function submitTask(options2) {
|
|
|
124028
124209
|
});
|
|
124029
124210
|
}
|
|
124030
124211
|
runTask(chatId, task).catch((err) => {
|
|
124031
|
-
|
|
124212
|
+
log25.error({ chatId, err }, "task execution failed");
|
|
124032
124213
|
if (task.status === "running") {
|
|
124033
124214
|
task.status = "failed";
|
|
124034
124215
|
task.completedAt = Date.now();
|
|
@@ -124070,7 +124251,7 @@ function abortTask(chatId) {
|
|
|
124070
124251
|
chatService.updateStatus(chatId, "idle");
|
|
124071
124252
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
124072
124253
|
emit({ kind: "update", status: updated });
|
|
124073
|
-
|
|
124254
|
+
log25.info({ chatId }, "task aborted by user");
|
|
124074
124255
|
return true;
|
|
124075
124256
|
}
|
|
124076
124257
|
function cancelTask(taskId) {
|
|
@@ -124095,7 +124276,7 @@ function cancelTask(taskId) {
|
|
|
124095
124276
|
chatService.updateStatus(chatId, "idle");
|
|
124096
124277
|
const updated = upsertWorkspaceStatus(task.workspaceId, { status: "waiting" });
|
|
124097
124278
|
emit({ kind: "update", status: updated });
|
|
124098
|
-
|
|
124279
|
+
log25.info({ chatId, taskId }, "task cancelled (was running in-memory)");
|
|
124099
124280
|
return { cancelled: true, workspaceId: task.workspaceId };
|
|
124100
124281
|
}
|
|
124101
124282
|
}
|
|
@@ -124103,7 +124284,7 @@ function cancelTask(taskId) {
|
|
|
124103
124284
|
if (record2) {
|
|
124104
124285
|
const updated = upsertWorkspaceStatus(record2.workspaceId, { status: "waiting" });
|
|
124105
124286
|
emit({ kind: "update", status: updated });
|
|
124106
|
-
|
|
124287
|
+
log25.info({ taskId, workspaceId: record2.workspaceId }, "orphaned task cancelled");
|
|
124107
124288
|
return { cancelled: true, workspaceId: record2.workspaceId };
|
|
124108
124289
|
}
|
|
124109
124290
|
return { cancelled: false };
|
|
@@ -124123,7 +124304,7 @@ async function runTask(chatId, task) {
|
|
|
124123
124304
|
const taskAgentId = task.codingAgentId;
|
|
124124
124305
|
const resolvedAgentId = taskAgentId ?? chatSession?.agent;
|
|
124125
124306
|
const needsReplace = taskAgentId && taskAgentId !== chatSession?.agent;
|
|
124126
|
-
|
|
124307
|
+
log25.info(
|
|
124127
124308
|
{ chatId, taskAgentId, chatAgent: chatSession?.agent, resolvedAgentId, needsReplace },
|
|
124128
124309
|
"resolving agent for task"
|
|
124129
124310
|
);
|
|
@@ -124170,7 +124351,7 @@ async function runTask(chatId, task) {
|
|
|
124170
124351
|
[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.]`;
|
|
124171
124352
|
const effectivePrompt = task.sessionId ? task.agentPrompt : task.agentPrompt + fileSharingHint;
|
|
124172
124353
|
for await (const event of agent.runSession(effectivePrompt, task.sessionId, sessionOptions)) {
|
|
124173
|
-
|
|
124354
|
+
log25.info({ chatId, eventType: event.type }, "task event");
|
|
124174
124355
|
switch (event.type) {
|
|
124175
124356
|
case "session-start": {
|
|
124176
124357
|
task.sessionId = event.sessionId;
|
|
@@ -124370,7 +124551,7 @@ async function runTask(chatId, task) {
|
|
|
124370
124551
|
break;
|
|
124371
124552
|
}
|
|
124372
124553
|
case "session-id-resolved": {
|
|
124373
|
-
|
|
124554
|
+
log25.info(
|
|
124374
124555
|
{ chatId, previous: event.previousSessionId, resolved: event.resolvedSessionId },
|
|
124375
124556
|
"session ID resolved"
|
|
124376
124557
|
);
|
|
@@ -124473,7 +124654,7 @@ ${queued.text}`;
|
|
|
124473
124654
|
});
|
|
124474
124655
|
autoStarted = true;
|
|
124475
124656
|
} catch (err) {
|
|
124476
|
-
|
|
124657
|
+
log25.warn({ chatId, err }, "failed to auto-start queued task");
|
|
124477
124658
|
}
|
|
124478
124659
|
}
|
|
124479
124660
|
}
|
|
@@ -124648,7 +124829,7 @@ var taskService = new TaskService();
|
|
|
124648
124829
|
var HISTORY_PAGE_SIZE = 50;
|
|
124649
124830
|
|
|
124650
124831
|
// src/api/chat-events.ts
|
|
124651
|
-
var
|
|
124832
|
+
var log26 = createLogger("chat-events");
|
|
124652
124833
|
var COLD_REPLAY_LIMIT = HISTORY_PAGE_SIZE;
|
|
124653
124834
|
async function handleChatEvents(req, res, chatId) {
|
|
124654
124835
|
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
@@ -124729,7 +124910,7 @@ async function handleChatEvents(req, res, chatId) {
|
|
|
124729
124910
|
chatWorkspaceId: chat?.workspaceId ?? explicitWorkspaceId,
|
|
124730
124911
|
agentTypeHint: chat?.agent
|
|
124731
124912
|
}).catch((err) => {
|
|
124732
|
-
|
|
124913
|
+
log26.warn({ chatId, err }, "replay phase failed; continuing to live tail");
|
|
124733
124914
|
});
|
|
124734
124915
|
try {
|
|
124735
124916
|
while (!res.destroyed && !writer.closed) {
|
|
@@ -124809,7 +124990,7 @@ async function replayPast(opts) {
|
|
|
124809
124990
|
}
|
|
124810
124991
|
}
|
|
124811
124992
|
} catch (err) {
|
|
124812
|
-
|
|
124993
|
+
log26.warn({ chatId, sessionId, err }, "JSONL backfill failed; falling through to buffer");
|
|
124813
124994
|
}
|
|
124814
124995
|
}
|
|
124815
124996
|
if (!jsonlEmittedAny && buf) {
|
|
@@ -124856,7 +125037,7 @@ async function replayPast(opts) {
|
|
|
124856
125037
|
}
|
|
124857
125038
|
}
|
|
124858
125039
|
} catch (err) {
|
|
124859
|
-
|
|
125040
|
+
log26.warn({ chatId, sessionId, err }, "JSONL backfill failed; falling through to buffer");
|
|
124860
125041
|
}
|
|
124861
125042
|
}
|
|
124862
125043
|
if (buf) {
|
|
@@ -124964,7 +125145,7 @@ function chunkToChatEvent(chunk, _sessionId) {
|
|
|
124964
125145
|
|
|
124965
125146
|
// src/api/chat-history.ts
|
|
124966
125147
|
init_src();
|
|
124967
|
-
var
|
|
125148
|
+
var log27 = createLogger("chat-history");
|
|
124968
125149
|
var DEFAULT_PAGE_LIMIT = HISTORY_PAGE_SIZE;
|
|
124969
125150
|
var MAX_PAGE_LIMIT = 200;
|
|
124970
125151
|
var MAX_CHAT_ID_LENGTH = 200;
|
|
@@ -125027,7 +125208,7 @@ async function handleChatHistory(req, res, chatId) {
|
|
|
125027
125208
|
oldestOffset: result.firstOffset
|
|
125028
125209
|
});
|
|
125029
125210
|
} catch (err) {
|
|
125030
|
-
|
|
125211
|
+
log27.warn(
|
|
125031
125212
|
{ chatId: chatId.slice(0, 8), err: err instanceof Error ? err.message : String(err) },
|
|
125032
125213
|
"chat-history: failed to read older page"
|
|
125033
125214
|
);
|
|
@@ -125067,7 +125248,7 @@ async function saveUploadedFilesDetailed(fileParts) {
|
|
|
125067
125248
|
}
|
|
125068
125249
|
|
|
125069
125250
|
// src/api/chat-submit.ts
|
|
125070
|
-
var
|
|
125251
|
+
var log28 = createLogger("chat-submit");
|
|
125071
125252
|
function readBody(req) {
|
|
125072
125253
|
return new Promise((resolve12, reject) => {
|
|
125073
125254
|
const chunks = [];
|
|
@@ -125104,7 +125285,7 @@ async function handleChatSubmit(req, res, chatId) {
|
|
|
125104
125285
|
if (files && files.length > 0) {
|
|
125105
125286
|
savedFiles = await saveUploadedFilesDetailed(files);
|
|
125106
125287
|
if (savedFiles.length !== files.length) {
|
|
125107
|
-
|
|
125288
|
+
log28.warn(
|
|
125108
125289
|
{ chatId, submitted: files.length, saved: savedFiles.length },
|
|
125109
125290
|
"chat-submit: some file uploads were dropped (malformed data URL?)"
|
|
125110
125291
|
);
|
|
@@ -125134,7 +125315,7 @@ ${text3}`;
|
|
|
125134
125315
|
model,
|
|
125135
125316
|
codingAgentId
|
|
125136
125317
|
});
|
|
125137
|
-
|
|
125318
|
+
log28.info({ chatId, workspaceId }, "chat-submit: task started");
|
|
125138
125319
|
sendJson2(res, 200, { ok: true, queued: false });
|
|
125139
125320
|
} catch (err) {
|
|
125140
125321
|
if (err instanceof TaskConflictError) {
|
|
@@ -125149,7 +125330,7 @@ ${text3}`;
|
|
|
125149
125330
|
}))
|
|
125150
125331
|
}
|
|
125151
125332
|
});
|
|
125152
|
-
|
|
125333
|
+
log28.info({ chatId, workspaceId }, "chat-submit: task busy, message queued");
|
|
125153
125334
|
sendJson2(res, 200, { ok: true, queued: true });
|
|
125154
125335
|
return;
|
|
125155
125336
|
}
|
|
@@ -125157,7 +125338,7 @@ ${text3}`;
|
|
|
125157
125338
|
sendJson2(res, 404, { error: err.message });
|
|
125158
125339
|
return;
|
|
125159
125340
|
}
|
|
125160
|
-
|
|
125341
|
+
log28.error({ chatId, err }, "chat-submit: unexpected error");
|
|
125161
125342
|
sendJson2(res, 500, { error: "Internal server error" });
|
|
125162
125343
|
}
|
|
125163
125344
|
}
|
|
@@ -136563,7 +136744,7 @@ import { extname as extname2, isAbsolute as isAbsolute2 } from "node:path";
|
|
|
136563
136744
|
|
|
136564
136745
|
// src/server/infra/browser-host/host-state.ts
|
|
136565
136746
|
init_src();
|
|
136566
|
-
var
|
|
136747
|
+
var log29 = createLogger("browser-host");
|
|
136567
136748
|
var DESKTOP_CDP_HOST = "127.0.0.1";
|
|
136568
136749
|
var DESKTOP_CDP_PORT = 9223;
|
|
136569
136750
|
var globalAny = globalThis;
|
|
@@ -136614,7 +136795,7 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
136614
136795
|
reject: rejectFn,
|
|
136615
136796
|
timeoutId
|
|
136616
136797
|
});
|
|
136617
|
-
|
|
136798
|
+
log29.info(
|
|
136618
136799
|
"ensureCdpTargetId emitting ensureView for %s (url=%s, listeners=%d)",
|
|
136619
136800
|
bandTabId,
|
|
136620
136801
|
tab.url,
|
|
@@ -136628,13 +136809,13 @@ async function ensureCdpTargetId(bandTabId) {
|
|
|
136628
136809
|
url: tab.url
|
|
136629
136810
|
});
|
|
136630
136811
|
} catch (err) {
|
|
136631
|
-
|
|
136812
|
+
log29.warn("ensureView listener threw: %s", err instanceof Error ? err.message : err);
|
|
136632
136813
|
}
|
|
136633
136814
|
}
|
|
136634
136815
|
return promise;
|
|
136635
136816
|
}
|
|
136636
136817
|
function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
136637
|
-
|
|
136818
|
+
log29.info("resolveTargetReady %s \u2192 %s", bandTabId, cdpTargetId);
|
|
136638
136819
|
targetIdByBandTabId.set(bandTabId, cdpTargetId);
|
|
136639
136820
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
136640
136821
|
if (pending2) {
|
|
@@ -136644,7 +136825,7 @@ function resolveTargetReady(bandTabId, cdpTargetId) {
|
|
|
136644
136825
|
}
|
|
136645
136826
|
}
|
|
136646
136827
|
function markTargetDestroyed(bandTabId) {
|
|
136647
|
-
|
|
136828
|
+
log29.info("markTargetDestroyed %s", bandTabId);
|
|
136648
136829
|
targetIdByBandTabId.delete(bandTabId);
|
|
136649
136830
|
const pending2 = pendingEnsures.get(bandTabId);
|
|
136650
136831
|
if (pending2) {
|
|
@@ -136655,10 +136836,10 @@ function markTargetDestroyed(bandTabId) {
|
|
|
136655
136836
|
}
|
|
136656
136837
|
function onEnsureView(listener) {
|
|
136657
136838
|
ensureListeners.add(listener);
|
|
136658
|
-
|
|
136839
|
+
log29.info("onEnsureView subscriber added (total=%d)", ensureListeners.size);
|
|
136659
136840
|
return () => {
|
|
136660
136841
|
ensureListeners.delete(listener);
|
|
136661
|
-
|
|
136842
|
+
log29.info("onEnsureView subscriber removed (total=%d)", ensureListeners.size);
|
|
136662
136843
|
if (ensureListeners.size === 0) {
|
|
136663
136844
|
for (const [bandTabId, pending2] of pendingEnsures) {
|
|
136664
136845
|
clearTimeout(pending2.timeoutId);
|
|
@@ -136698,7 +136879,7 @@ var t2 = initTRPC.context().create();
|
|
|
136698
136879
|
var publicProcedure = t2.procedure;
|
|
136699
136880
|
|
|
136700
136881
|
// src/server/api/browser-host/router.ts
|
|
136701
|
-
var
|
|
136882
|
+
var log30 = createLogger("trpc.browser-host");
|
|
136702
136883
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
136703
136884
|
var LANG_MAP = {
|
|
136704
136885
|
".js": "javascript",
|
|
@@ -136821,7 +137002,7 @@ var browserHostRouter = t2.router({
|
|
|
136821
137002
|
// can confirm in the server log that the bridge component actually
|
|
136822
137003
|
// executed. Drop once the experiment is stable.
|
|
136823
137004
|
ping: publicProcedure.input(external_exports.object({ where: external_exports.string() })).mutation(({ input }) => {
|
|
136824
|
-
|
|
137005
|
+
log30.info("browserHost.ping from %s", input.where);
|
|
136825
137006
|
return { ok: true };
|
|
136826
137007
|
}),
|
|
136827
137008
|
ensureView: publicProcedure.subscription(async function* (opts) {
|
|
@@ -136941,7 +137122,7 @@ var chatRouter = t2.router({
|
|
|
136941
137122
|
// src/server/api/chats/router.ts
|
|
136942
137123
|
init_src();
|
|
136943
137124
|
init_zod();
|
|
136944
|
-
var
|
|
137125
|
+
var log31 = createLogger("chats-router");
|
|
136945
137126
|
var chatLayoutRouter = t2.router({
|
|
136946
137127
|
get: publicProcedure.input(external_exports.object({ workspaceId: external_exports.string() })).query(({ input }) => {
|
|
136947
137128
|
return { tree: chatService.getLayout(input.workspaceId) };
|
|
@@ -137086,7 +137267,7 @@ var chatsRouter = t2.router({
|
|
|
137086
137267
|
summary = info?.summary;
|
|
137087
137268
|
lastModified = info?.lastModified;
|
|
137088
137269
|
} catch (err) {
|
|
137089
|
-
|
|
137270
|
+
log31.warn(
|
|
137090
137271
|
{ chatId: input.chatId, sessionId: input.sessionId, err },
|
|
137091
137272
|
"setActiveSession: getSessionInfo failed"
|
|
137092
137273
|
);
|
|
@@ -137391,7 +137572,7 @@ function throwAsTRPCError(err) {
|
|
|
137391
137572
|
init_zod();
|
|
137392
137573
|
|
|
137393
137574
|
// src/server/services/editor-service.ts
|
|
137394
|
-
import { existsSync as
|
|
137575
|
+
import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as statSync8 } from "node:fs";
|
|
137395
137576
|
import { isAbsolute as isAbsolute4, join as join25, resolve as resolve6, sep as sep4 } from "node:path";
|
|
137396
137577
|
|
|
137397
137578
|
// src/server/services/file-watcher.ts
|
|
@@ -137488,10 +137669,10 @@ function subscribeToFileChanges(workspaceId, listener) {
|
|
|
137488
137669
|
|
|
137489
137670
|
// src/server/services/formatter.ts
|
|
137490
137671
|
init_src();
|
|
137491
|
-
import { existsSync as
|
|
137672
|
+
import { existsSync as existsSync10, realpathSync as realpathSync4 } from "node:fs";
|
|
137492
137673
|
import { basename, dirname as dirname5, isAbsolute as isAbsolute3, join as join24, resolve as resolvePath } from "node:path";
|
|
137493
137674
|
import prettier from "prettier";
|
|
137494
|
-
var
|
|
137675
|
+
var log32 = createLogger("formatter");
|
|
137495
137676
|
var FormatterError = class extends Error {
|
|
137496
137677
|
code;
|
|
137497
137678
|
detail;
|
|
@@ -137515,7 +137696,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
137515
137696
|
const ignorePath = resolvePath(worktreePath, ".prettierignore");
|
|
137516
137697
|
const info = await prettier.getFileInfo(absFile, {
|
|
137517
137698
|
resolveConfig: true,
|
|
137518
|
-
ignorePath:
|
|
137699
|
+
ignorePath: existsSync10(ignorePath) ? ignorePath : void 0
|
|
137519
137700
|
});
|
|
137520
137701
|
if (info.ignored) {
|
|
137521
137702
|
return {
|
|
@@ -137546,7 +137727,7 @@ async function formatFile(worktreePath, filePath, content2, options2 = {}) {
|
|
|
137546
137727
|
}
|
|
137547
137728
|
const changed = formatted !== content2;
|
|
137548
137729
|
if (changed) {
|
|
137549
|
-
|
|
137730
|
+
log32.info(
|
|
137550
137731
|
"Formatted %s with parser=%s (%d bytes in)",
|
|
137551
137732
|
absFile,
|
|
137552
137733
|
info.inferredParser,
|
|
@@ -137699,7 +137880,7 @@ var EditorOpenError = class extends Error {
|
|
|
137699
137880
|
}
|
|
137700
137881
|
};
|
|
137701
137882
|
function canonicalizeMaybeMissing(p6) {
|
|
137702
|
-
if (
|
|
137883
|
+
if (existsSync11(p6)) {
|
|
137703
137884
|
try {
|
|
137704
137885
|
return realpathSync5(p6);
|
|
137705
137886
|
} catch {
|
|
@@ -137709,7 +137890,7 @@ function canonicalizeMaybeMissing(p6) {
|
|
|
137709
137890
|
const parts = p6.split(sep4);
|
|
137710
137891
|
for (let i2 = parts.length - 1; i2 > 0; i2--) {
|
|
137711
137892
|
const prefix = parts.slice(0, i2).join(sep4) || sep4;
|
|
137712
|
-
if (
|
|
137893
|
+
if (existsSync11(prefix)) {
|
|
137713
137894
|
try {
|
|
137714
137895
|
const canonicalPrefix = realpathSync5(prefix);
|
|
137715
137896
|
return join25(canonicalPrefix, ...parts.slice(i2));
|
|
@@ -138101,8 +138282,19 @@ var SystemService = class {
|
|
|
138101
138282
|
* `$PATH` (typically via `shellPath()`) so `brew` itself is locatable
|
|
138102
138283
|
* even when the Node process inherited a stripped-down PATH from
|
|
138103
138284
|
* launchd / Electron.
|
|
138285
|
+
*
|
|
138286
|
+
* Homebrew is macOS-only here: a stock Linux host has no `brew`, so
|
|
138287
|
+
* shelling out to it would fail with an opaque ENOENT. Guard on
|
|
138288
|
+
* `darwin` and surface a distro-appropriate hint on every other
|
|
138289
|
+
* platform — the message bubbles up to the dashboard's install flow as
|
|
138290
|
+
* a normal error instead of a crash.
|
|
138104
138291
|
*/
|
|
138105
138292
|
async installCloudflared(resolvedPath) {
|
|
138293
|
+
if (process.platform !== "darwin") {
|
|
138294
|
+
throw new Error(
|
|
138295
|
+
"Automatic cloudflared install is only supported on macOS (via Homebrew). On Linux, install it with your package manager (e.g. `sudo apt install cloudflared` or `sudo dnf install cloudflared`) or download it from https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/ and re-open the tunnel."
|
|
138296
|
+
);
|
|
138297
|
+
}
|
|
138106
138298
|
await brewInstall("cloudflared", resolvedPath);
|
|
138107
138299
|
}
|
|
138108
138300
|
/**
|
|
@@ -138241,7 +138433,7 @@ init_zod();
|
|
|
138241
138433
|
|
|
138242
138434
|
// src/server/services/model-refresh-service.ts
|
|
138243
138435
|
init_src();
|
|
138244
|
-
var
|
|
138436
|
+
var log33 = createLogger("model-refresh");
|
|
138245
138437
|
var ModelRefreshService = class {
|
|
138246
138438
|
constructor(queries = new SettingsQueries()) {
|
|
138247
138439
|
this.queries = queries;
|
|
@@ -138294,7 +138486,7 @@ var ModelRefreshService = class {
|
|
|
138294
138486
|
const models = await agent.listModels();
|
|
138295
138487
|
return models.map(toCachedModel);
|
|
138296
138488
|
} catch (err) {
|
|
138297
|
-
|
|
138489
|
+
log33.warn({ agentId, err }, "failed to load adapter defaults; returning empty list");
|
|
138298
138490
|
return [];
|
|
138299
138491
|
}
|
|
138300
138492
|
}
|
|
@@ -138331,7 +138523,7 @@ var ModelRefreshService = class {
|
|
|
138331
138523
|
}
|
|
138332
138524
|
} catch (err) {
|
|
138333
138525
|
error2 = classifyRefreshError(err);
|
|
138334
|
-
|
|
138526
|
+
log33.warn({ agentId, err }, "failed to refresh models; keeping prior cache");
|
|
138335
138527
|
}
|
|
138336
138528
|
if (fresh) {
|
|
138337
138529
|
const cachedFresh = fresh.map(toCachedModel);
|
|
@@ -138459,7 +138651,7 @@ var ModelRefreshService = class {
|
|
|
138459
138651
|
const agents = this.queries.load().codingAgents ?? [];
|
|
138460
138652
|
const idx = agents.findIndex((a6) => a6.id === agentId);
|
|
138461
138653
|
if (idx === -1) {
|
|
138462
|
-
|
|
138654
|
+
log33.warn({ agentId }, "refresh result for unknown agent; not persisting");
|
|
138463
138655
|
return false;
|
|
138464
138656
|
}
|
|
138465
138657
|
const next = agents.map(
|
|
@@ -138537,6 +138729,25 @@ var modesRouter = t2.router({
|
|
|
138537
138729
|
})
|
|
138538
138730
|
});
|
|
138539
138731
|
|
|
138732
|
+
// src/server/api/panel-focus/router.ts
|
|
138733
|
+
init_zod();
|
|
138734
|
+
var focusPanelType = external_exports.enum(["chat", "terminal", "browser"]);
|
|
138735
|
+
var panelFocusRouter = t2.router({
|
|
138736
|
+
get: publicProcedure.input(external_exports.object({ workspaceId: external_exports.string() })).query(({ input }) => {
|
|
138737
|
+
return panelFocusService.get(input.workspaceId);
|
|
138738
|
+
}),
|
|
138739
|
+
set: publicProcedure.input(
|
|
138740
|
+
external_exports.object({
|
|
138741
|
+
workspaceId: external_exports.string(),
|
|
138742
|
+
panelType: focusPanelType,
|
|
138743
|
+
panelId: external_exports.string()
|
|
138744
|
+
})
|
|
138745
|
+
).mutation(({ input }) => {
|
|
138746
|
+
panelFocusService.set(input.workspaceId, input.panelType, input.panelId);
|
|
138747
|
+
return { ok: true };
|
|
138748
|
+
})
|
|
138749
|
+
});
|
|
138750
|
+
|
|
138540
138751
|
// src/server/api/prereqs/router.ts
|
|
138541
138752
|
var prereqsRouter = t2.router({
|
|
138542
138753
|
check: publicProcedure.query(async () => {
|
|
@@ -138553,7 +138764,7 @@ var prereqsRouter = t2.router({
|
|
|
138553
138764
|
init_zod();
|
|
138554
138765
|
|
|
138555
138766
|
// src/server/services/project-service.ts
|
|
138556
|
-
import { existsSync as
|
|
138767
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
138557
138768
|
import { basename as basename2, join as join27, resolve as resolve7 } from "node:path";
|
|
138558
138769
|
var ProjectService = class {
|
|
138559
138770
|
constructor(queries = new ProjectQueries(), git = new GitClient(), settings = settingsService, statusQueries = new WorkspaceStatusQueries()) {
|
|
@@ -138590,16 +138801,22 @@ var ProjectService = class {
|
|
|
138590
138801
|
projects2.map(async (project) => {
|
|
138591
138802
|
let worktrees2 = project.worktrees;
|
|
138592
138803
|
if (project.kind === "git") {
|
|
138593
|
-
const
|
|
138594
|
-
const trackedByBranch = new Map(project.worktrees.map((wt) => [wt.branch, wt]));
|
|
138804
|
+
const trackedByPath = new Map(project.worktrees.map((wt) => [wt.path, wt]));
|
|
138595
138805
|
try {
|
|
138596
138806
|
const gitWorktrees = await this.git.listWorktrees(project.path);
|
|
138597
|
-
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare &&
|
|
138598
|
-
|
|
138599
|
-
|
|
138600
|
-
|
|
138601
|
-
|
|
138602
|
-
|
|
138807
|
+
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare && trackedByPath.has(wt.path)).map((wt) => {
|
|
138808
|
+
const tracked2 = trackedByPath.get(wt.path);
|
|
138809
|
+
return {
|
|
138810
|
+
// Carry the stable identity from the tracked row; fall back
|
|
138811
|
+
// to the branch for worktrees git knows about but state
|
|
138812
|
+
// doesn't.
|
|
138813
|
+
name: tracked2?.name ?? wt.branch,
|
|
138814
|
+
branch: wt.branch,
|
|
138815
|
+
path: wt.path,
|
|
138816
|
+
head: wt.head,
|
|
138817
|
+
pinned: tracked2?.pinned ?? false
|
|
138818
|
+
};
|
|
138819
|
+
});
|
|
138603
138820
|
} catch {
|
|
138604
138821
|
}
|
|
138605
138822
|
}
|
|
@@ -138610,7 +138827,7 @@ var ProjectService = class {
|
|
|
138610
138827
|
label: project.label,
|
|
138611
138828
|
kind: project.kind,
|
|
138612
138829
|
worktrees: worktrees2.map((wt) => {
|
|
138613
|
-
const workspaceId = toWorkspaceId(project.name, wt.
|
|
138830
|
+
const workspaceId = toWorkspaceId(project.name, wt.name);
|
|
138614
138831
|
const status = statusMap.get(workspaceId);
|
|
138615
138832
|
return {
|
|
138616
138833
|
...wt,
|
|
@@ -138630,7 +138847,7 @@ var ProjectService = class {
|
|
|
138630
138847
|
*/
|
|
138631
138848
|
checkPath(path3) {
|
|
138632
138849
|
const resolvedPath = resolve7(path3);
|
|
138633
|
-
const isGitRepo =
|
|
138850
|
+
const isGitRepo = existsSync12(join27(resolvedPath, ".git"));
|
|
138634
138851
|
return { isGitRepo };
|
|
138635
138852
|
}
|
|
138636
138853
|
/**
|
|
@@ -138666,7 +138883,7 @@ var ProjectService = class {
|
|
|
138666
138883
|
}
|
|
138667
138884
|
}
|
|
138668
138885
|
const resolvedPath = resolve7(path3);
|
|
138669
|
-
const kind =
|
|
138886
|
+
const kind = existsSync12(join27(resolvedPath, ".git")) ? "git" : "plain";
|
|
138670
138887
|
let defaultBranch = "main";
|
|
138671
138888
|
let worktrees2 = [];
|
|
138672
138889
|
if (kind === "git") {
|
|
@@ -138674,11 +138891,17 @@ var ProjectService = class {
|
|
|
138674
138891
|
if (branch) defaultBranch = branch;
|
|
138675
138892
|
try {
|
|
138676
138893
|
const gitWorktrees = await this.git.listWorktrees(resolvedPath);
|
|
138677
|
-
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({
|
|
138894
|
+
worktrees2 = gitWorktrees.filter((wt) => !wt.isBare).map((wt) => ({
|
|
138895
|
+
name: wt.branch,
|
|
138896
|
+
branch: wt.branch,
|
|
138897
|
+
path: wt.path,
|
|
138898
|
+
head: wt.head,
|
|
138899
|
+
pinned: false
|
|
138900
|
+
}));
|
|
138678
138901
|
} catch {
|
|
138679
138902
|
}
|
|
138680
138903
|
} else {
|
|
138681
|
-
worktrees2 = [{ branch: "main", path: resolvedPath, pinned: false }];
|
|
138904
|
+
worktrees2 = [{ name: "main", branch: "main", path: resolvedPath, pinned: false }];
|
|
138682
138905
|
}
|
|
138683
138906
|
const project = {
|
|
138684
138907
|
name: name3,
|
|
@@ -138724,7 +138947,7 @@ var ProjectService = class {
|
|
|
138724
138947
|
message: `Project "${name3}" is already a git project`
|
|
138725
138948
|
});
|
|
138726
138949
|
}
|
|
138727
|
-
if (!
|
|
138950
|
+
if (!existsSync12(project.path)) {
|
|
138728
138951
|
throw new TRPCError({
|
|
138729
138952
|
code: "NOT_FOUND",
|
|
138730
138953
|
message: `Project path "${project.path}" no longer exists. Remove the project and re-add it.`
|
|
@@ -138842,7 +139065,7 @@ init_src();
|
|
|
138842
139065
|
init_zod();
|
|
138843
139066
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
138844
139067
|
import { join as join28, resolve as resolve8, sep as sep5 } from "node:path";
|
|
138845
|
-
var
|
|
139068
|
+
var log34 = createLogger("trpc.queue");
|
|
138846
139069
|
var queuedFileSchema = external_exports.object({
|
|
138847
139070
|
mediaType: external_exports.string(),
|
|
138848
139071
|
url: external_exports.string(),
|
|
@@ -138874,7 +139097,7 @@ async function resolveQueuedFiles(chatId, files) {
|
|
|
138874
139097
|
const derivedPath = file.path ?? (uploadsUrlMatch ? join28(bandHome(), "uploads", uploadsUrlMatch[1]) : void 0);
|
|
138875
139098
|
if (derivedPath) {
|
|
138876
139099
|
if (!isPathWithinUploadDir(derivedPath)) {
|
|
138877
|
-
|
|
139100
|
+
log34.warn(
|
|
138878
139101
|
{ chatId, path: derivedPath, filename: file.filename },
|
|
138879
139102
|
"queue: dropping file with path outside uploads directory"
|
|
138880
139103
|
);
|
|
@@ -138899,7 +139122,7 @@ async function resolveQueuedFiles(chatId, files) {
|
|
|
138899
139122
|
});
|
|
138900
139123
|
continue;
|
|
138901
139124
|
}
|
|
138902
|
-
|
|
139125
|
+
log34.warn(
|
|
138903
139126
|
{ chatId, url: file.url, filename: file.filename },
|
|
138904
139127
|
"queue: dropping file with no path and non-data URL \u2014 cannot recover disk path"
|
|
138905
139128
|
);
|
|
@@ -138907,7 +139130,7 @@ async function resolveQueuedFiles(chatId, files) {
|
|
|
138907
139130
|
if (needsSave.length > 0) {
|
|
138908
139131
|
const saved = await saveUploadedFilesDetailed(needsSave);
|
|
138909
139132
|
if (saved.length !== needsSave.length) {
|
|
138910
|
-
|
|
139133
|
+
log34.error(
|
|
138911
139134
|
{ chatId, expected: needsSave.length, got: saved.length },
|
|
138912
139135
|
"queue: saveUploadedFilesDetailed returned unexpected count \u2014 dropping data-URL files (cannot map 1:1)"
|
|
138913
139136
|
);
|
|
@@ -138940,7 +139163,7 @@ var queueRouter = t2.router({
|
|
|
138940
139163
|
try {
|
|
138941
139164
|
files = await resolveQueuedFiles(chatId, input.files);
|
|
138942
139165
|
} catch (err) {
|
|
138943
|
-
|
|
139166
|
+
log34.error(
|
|
138944
139167
|
{ chatId, err: err instanceof Error ? err.message : err },
|
|
138945
139168
|
"queue.push: failed to persist file uploads; enqueuing text only"
|
|
138946
139169
|
);
|
|
@@ -138976,7 +139199,7 @@ var queueRouter = t2.router({
|
|
|
138976
139199
|
files: await resolveQueuedFiles(chatId, m11.files)
|
|
138977
139200
|
};
|
|
138978
139201
|
} catch (err) {
|
|
138979
|
-
|
|
139202
|
+
log34.error(
|
|
138980
139203
|
{ chatId, messageId: m11.id, err: err instanceof Error ? err.message : err },
|
|
138981
139204
|
"queue: failed to resolve files for queued message; dropping its files"
|
|
138982
139205
|
);
|
|
@@ -139101,7 +139324,7 @@ function aggregateTurnsByHourAndModel(snap, provider) {
|
|
|
139101
139324
|
}
|
|
139102
139325
|
return Array.from(buckets2.values());
|
|
139103
139326
|
}
|
|
139104
|
-
var
|
|
139327
|
+
var log35 = createLogger("usage-scanner");
|
|
139105
139328
|
var SCHEDULER_KEY2 = Symbol.for("band.usage-scanner");
|
|
139106
139329
|
var g14 = globalThis;
|
|
139107
139330
|
if (!g14[SCHEDULER_KEY2]) {
|
|
@@ -139163,14 +139386,14 @@ var UsageScannerService = class {
|
|
|
139163
139386
|
try {
|
|
139164
139387
|
totalRows += await this.scanPair(ws, a6);
|
|
139165
139388
|
} catch (err) {
|
|
139166
|
-
|
|
139389
|
+
log35.warn(
|
|
139167
139390
|
{ err, workspaceId: ws.workspaceId, agentType: a6.agentType },
|
|
139168
139391
|
"usage scanner pair failed"
|
|
139169
139392
|
);
|
|
139170
139393
|
}
|
|
139171
139394
|
}
|
|
139172
139395
|
}
|
|
139173
|
-
|
|
139396
|
+
log35.debug(
|
|
139174
139397
|
{ durationMs: this.now() - started, workspaces: workspaces.length, rowsWritten: totalRows },
|
|
139175
139398
|
"usage scanner tick complete"
|
|
139176
139399
|
);
|
|
@@ -139215,7 +139438,7 @@ var UsageScannerService = class {
|
|
|
139215
139438
|
try {
|
|
139216
139439
|
agent = await this.createWorkspaceAgent(ws.worktreePath, a6.agentId);
|
|
139217
139440
|
} catch (err) {
|
|
139218
|
-
|
|
139441
|
+
log35.debug({ err, agentId: a6.agentId }, "failed to instantiate agent for scan");
|
|
139219
139442
|
return 0;
|
|
139220
139443
|
}
|
|
139221
139444
|
if (!agent.listSessions || !agent.getSessionUsage) return 0;
|
|
@@ -139224,7 +139447,7 @@ var UsageScannerService = class {
|
|
|
139224
139447
|
try {
|
|
139225
139448
|
sessions = await agent.listSessions(ws.worktreePath);
|
|
139226
139449
|
} catch (err) {
|
|
139227
|
-
|
|
139450
|
+
log35.debug(
|
|
139228
139451
|
{ err, agentId: a6.agentId, worktreePath: ws.worktreePath },
|
|
139229
139452
|
"listSessions failed during usage scan"
|
|
139230
139453
|
);
|
|
@@ -139240,7 +139463,7 @@ var UsageScannerService = class {
|
|
|
139240
139463
|
try {
|
|
139241
139464
|
snap = await agent.getSessionUsage(s6.sessionId, ws.worktreePath);
|
|
139242
139465
|
} catch (err) {
|
|
139243
|
-
|
|
139466
|
+
log35.debug(
|
|
139244
139467
|
{ err, sessionId: s6.sessionId, agentType: a6.agentType },
|
|
139245
139468
|
"getSessionUsage failed"
|
|
139246
139469
|
);
|
|
@@ -139278,7 +139501,7 @@ var UsageScannerService = class {
|
|
|
139278
139501
|
this.scanState.set(ws.workspaceId, a6.agentType, maxObserved);
|
|
139279
139502
|
}
|
|
139280
139503
|
if (changed.length > slice.length) {
|
|
139281
|
-
|
|
139504
|
+
log35.debug(
|
|
139282
139505
|
{
|
|
139283
139506
|
workspaceId: ws.workspaceId,
|
|
139284
139507
|
agentType: a6.agentType,
|
|
@@ -139297,7 +139520,7 @@ function defaultListWorkspaces() {
|
|
|
139297
139520
|
for (const project of projects2) {
|
|
139298
139521
|
for (const worktree of project.worktrees) {
|
|
139299
139522
|
out.push({
|
|
139300
|
-
workspaceId: toWorkspaceId(project.name, worktree.
|
|
139523
|
+
workspaceId: toWorkspaceId(project.name, worktree.name),
|
|
139301
139524
|
project: project.name,
|
|
139302
139525
|
worktreePath: worktree.path
|
|
139303
139526
|
});
|
|
@@ -139333,11 +139556,11 @@ function startUsageScanner(options2 = {}) {
|
|
|
139333
139556
|
const intervalMs = options2.intervalMs ?? USAGE_SCAN_INTERVAL_MS;
|
|
139334
139557
|
const svc = getUsageScannerService();
|
|
139335
139558
|
svc.tick().catch((err) => {
|
|
139336
|
-
|
|
139559
|
+
log35.warn({ err }, "initial usage scanner tick failed");
|
|
139337
139560
|
});
|
|
139338
139561
|
const timer = setInterval(() => {
|
|
139339
139562
|
svc.tick().catch((err) => {
|
|
139340
|
-
|
|
139563
|
+
log35.warn({ err }, "scheduled usage scanner tick failed");
|
|
139341
139564
|
});
|
|
139342
139565
|
}, intervalMs);
|
|
139343
139566
|
timer.unref();
|
|
@@ -139459,7 +139682,7 @@ init_zod();
|
|
|
139459
139682
|
|
|
139460
139683
|
// src/server/services/session-service.ts
|
|
139461
139684
|
init_src();
|
|
139462
|
-
var
|
|
139685
|
+
var log36 = createLogger("session-service");
|
|
139463
139686
|
var SessionService = class {
|
|
139464
139687
|
/**
|
|
139465
139688
|
* List past sessions for a workspace's chat pane.
|
|
@@ -139479,7 +139702,7 @@ var SessionService = class {
|
|
|
139479
139702
|
if (!agent.supportedFeatures.sessionListing || !agent.listSessions) {
|
|
139480
139703
|
return { sessions: [], supported: false };
|
|
139481
139704
|
}
|
|
139482
|
-
|
|
139705
|
+
log36.debug({ chatId, workspaceId: input.workspaceId }, "listing past sessions for chat");
|
|
139483
139706
|
const allSessions = await agent.listSessions(workspace.worktree.path);
|
|
139484
139707
|
return { sessions: allSessions, supported: true };
|
|
139485
139708
|
}
|
|
@@ -139635,7 +139858,7 @@ function getToken() {
|
|
|
139635
139858
|
}
|
|
139636
139859
|
|
|
139637
139860
|
// src/server/infra/tunnels/tunnel-client.ts
|
|
139638
|
-
var
|
|
139861
|
+
var log37 = createLogger("tunnel");
|
|
139639
139862
|
var TunnelClient = class _TunnelClient {
|
|
139640
139863
|
tunnelProcess = null;
|
|
139641
139864
|
tunnelUrl = null;
|
|
@@ -139659,7 +139882,7 @@ var TunnelClient = class _TunnelClient {
|
|
|
139659
139882
|
}
|
|
139660
139883
|
spawnTunnel(options2, resolvedPath) {
|
|
139661
139884
|
const args = ["tunnel", "--config", "/dev/null", "--url", `http://localhost:${options2.port}`];
|
|
139662
|
-
|
|
139885
|
+
log37.debug("spawning cloudflared %s", args.join(" "));
|
|
139663
139886
|
return new Promise((resolve12, reject) => {
|
|
139664
139887
|
const child = spawn7("cloudflared", args, {
|
|
139665
139888
|
env: { ...process.env, PATH: resolvedPath },
|
|
@@ -139673,12 +139896,12 @@ var TunnelClient = class _TunnelClient {
|
|
|
139673
139896
|
for (const line2 of text3.split("\n")) {
|
|
139674
139897
|
const trimmed = line2.trim();
|
|
139675
139898
|
if (!trimmed) continue;
|
|
139676
|
-
|
|
139899
|
+
log37.debug("output: %s", trimmed);
|
|
139677
139900
|
const url = _TunnelClient.extractUrl(trimmed);
|
|
139678
139901
|
if (url) {
|
|
139679
139902
|
const token = getToken();
|
|
139680
139903
|
this.tunnelUrl = _TunnelClient.appendToken(url, token);
|
|
139681
|
-
|
|
139904
|
+
log37.debug("detected URL: %s", this.tunnelUrl);
|
|
139682
139905
|
emit({ kind: "tunnel-url", url: this.tunnelUrl });
|
|
139683
139906
|
if (!settled) {
|
|
139684
139907
|
settled = true;
|
|
@@ -139693,7 +139916,7 @@ var TunnelClient = class _TunnelClient {
|
|
|
139693
139916
|
handleOutput(data);
|
|
139694
139917
|
});
|
|
139695
139918
|
child.on("error", (err) => {
|
|
139696
|
-
|
|
139919
|
+
log37.debug("process error: %s", err.message);
|
|
139697
139920
|
this.tunnelProcess = null;
|
|
139698
139921
|
this.tunnelUrl = null;
|
|
139699
139922
|
emit({ kind: "tunnel-error", error: err.message });
|
|
@@ -139703,7 +139926,7 @@ var TunnelClient = class _TunnelClient {
|
|
|
139703
139926
|
}
|
|
139704
139927
|
});
|
|
139705
139928
|
child.on("exit", (code) => {
|
|
139706
|
-
|
|
139929
|
+
log37.debug("process exited with code: %d", code ?? -1);
|
|
139707
139930
|
const wasRunning = this.tunnelProcess !== null && settled;
|
|
139708
139931
|
this.tunnelProcess = null;
|
|
139709
139932
|
this.tunnelUrl = null;
|
|
@@ -139725,7 +139948,7 @@ var TunnelClient = class _TunnelClient {
|
|
|
139725
139948
|
});
|
|
139726
139949
|
setTimeout(() => {
|
|
139727
139950
|
if (!settled) {
|
|
139728
|
-
|
|
139951
|
+
log37.debug("30s timeout reached, resolving without URL");
|
|
139729
139952
|
settled = true;
|
|
139730
139953
|
resolve12();
|
|
139731
139954
|
}
|
|
@@ -139734,12 +139957,12 @@ var TunnelClient = class _TunnelClient {
|
|
|
139734
139957
|
}
|
|
139735
139958
|
async start(options2) {
|
|
139736
139959
|
if (this.startInProgress) {
|
|
139737
|
-
|
|
139960
|
+
log37.debug("start: start already in progress, waiting...");
|
|
139738
139961
|
await this.startInProgress;
|
|
139739
139962
|
return;
|
|
139740
139963
|
}
|
|
139741
139964
|
if (this.tunnelProcess) {
|
|
139742
|
-
|
|
139965
|
+
log37.debug("start: already running, re-emitting URL");
|
|
139743
139966
|
if (this.tunnelUrl) {
|
|
139744
139967
|
emit({ kind: "tunnel-url", url: this.tunnelUrl });
|
|
139745
139968
|
}
|
|
@@ -139804,7 +140027,7 @@ var TunnelService = class {
|
|
|
139804
140027
|
var tunnelService = new TunnelService();
|
|
139805
140028
|
|
|
139806
140029
|
// src/server/api/system/router.ts
|
|
139807
|
-
var
|
|
140030
|
+
var log38 = createLogger("trpc.system");
|
|
139808
140031
|
var systemRouter = t2.router({
|
|
139809
140032
|
/**
|
|
139810
140033
|
* Combined liveness probe — webserver is always true if this query
|
|
@@ -139812,15 +140035,15 @@ var systemRouter = t2.router({
|
|
|
139812
140035
|
* an interval to drive the bottom-bar status pill.
|
|
139813
140036
|
*/
|
|
139814
140037
|
health: publicProcedure.query(() => {
|
|
139815
|
-
|
|
140038
|
+
log38.debug("services.health called");
|
|
139816
140039
|
const tunnel = tunnelService.getStatus();
|
|
139817
|
-
|
|
140040
|
+
log38.debug({ tunnel }, "services.health: tunnel status");
|
|
139818
140041
|
const result = {
|
|
139819
140042
|
webserver: true,
|
|
139820
140043
|
tunnel: tunnel.running,
|
|
139821
140044
|
tunnel_url: tunnel.url
|
|
139822
140045
|
};
|
|
139823
|
-
|
|
140046
|
+
log38.debug({ result }, "services.health result");
|
|
139824
140047
|
return result;
|
|
139825
140048
|
}),
|
|
139826
140049
|
// Activity level controls how often the branch-status poller fires.
|
|
@@ -139938,7 +140161,7 @@ var systemRouter = t2.router({
|
|
|
139938
140161
|
// src/server/api/tasks/router.ts
|
|
139939
140162
|
init_src();
|
|
139940
140163
|
init_zod();
|
|
139941
|
-
var
|
|
140164
|
+
var log39 = createLogger("tasks-router");
|
|
139942
140165
|
var tasksRouter = t2.router({
|
|
139943
140166
|
list: publicProcedure.input(
|
|
139944
140167
|
external_exports.object({
|
|
@@ -139954,7 +140177,7 @@ var tasksRouter = t2.router({
|
|
|
139954
140177
|
const workspaceIds = /* @__PURE__ */ new Set();
|
|
139955
140178
|
for (const p6 of state.projects) {
|
|
139956
140179
|
for (const wt of p6.worktrees) {
|
|
139957
|
-
workspaceIds.add(toWorkspaceId(p6.name, wt.
|
|
140180
|
+
workspaceIds.add(toWorkspaceId(p6.name, wt.name));
|
|
139958
140181
|
}
|
|
139959
140182
|
}
|
|
139960
140183
|
return {
|
|
@@ -140001,7 +140224,7 @@ var tasksRouter = t2.router({
|
|
|
140001
140224
|
if (input.files && input.files.length > 0) {
|
|
140002
140225
|
const savedFiles = await saveUploadedFilesDetailed(input.files);
|
|
140003
140226
|
if (savedFiles.length !== input.files.length) {
|
|
140004
|
-
|
|
140227
|
+
log39.warn(
|
|
140005
140228
|
{ chatId, submitted: input.files.length, saved: savedFiles.length },
|
|
140006
140229
|
"tasks.submit: some file uploads were dropped (malformed data URL?)"
|
|
140007
140230
|
);
|
|
@@ -140223,25 +140446,25 @@ var terminalsRouters = {
|
|
|
140223
140446
|
// src/server/api/tunnel/router.ts
|
|
140224
140447
|
init_src();
|
|
140225
140448
|
init_zod();
|
|
140226
|
-
var
|
|
140449
|
+
var log40 = createLogger("trpc.tunnel");
|
|
140227
140450
|
var tunnelRouter = t2.router({
|
|
140228
140451
|
status: publicProcedure.query(() => {
|
|
140229
140452
|
return tunnelService.getStatus();
|
|
140230
140453
|
}),
|
|
140231
140454
|
start: publicProcedure.input(external_exports.object({}).optional()).mutation(async () => {
|
|
140232
|
-
|
|
140455
|
+
log40.debug("tunnel.start called");
|
|
140233
140456
|
try {
|
|
140234
140457
|
await tunnelService.start();
|
|
140235
140458
|
} catch (err) {
|
|
140236
|
-
|
|
140459
|
+
log40.debug({ err }, "tunnel.start: startTunnel failed");
|
|
140237
140460
|
return { ok: true, url: null };
|
|
140238
140461
|
}
|
|
140239
140462
|
const status = tunnelService.getStatus();
|
|
140240
|
-
|
|
140463
|
+
log40.debug({ status }, "tunnel.start: after startTunnel");
|
|
140241
140464
|
if (status.url) {
|
|
140242
140465
|
return { ok: true, url: status.url };
|
|
140243
140466
|
}
|
|
140244
|
-
|
|
140467
|
+
log40.debug("tunnel.start: no URL available");
|
|
140245
140468
|
return { ok: true, url: null };
|
|
140246
140469
|
}),
|
|
140247
140470
|
stop: publicProcedure.mutation(async () => {
|
|
@@ -140255,10 +140478,10 @@ init_zod();
|
|
|
140255
140478
|
|
|
140256
140479
|
// src/server/services/diff-service.ts
|
|
140257
140480
|
init_src();
|
|
140258
|
-
import { existsSync as
|
|
140481
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
140259
140482
|
import { readFile as readFile2, rm as rm2 } from "node:fs/promises";
|
|
140260
140483
|
import { join as join29, resolve as resolve9, sep as sep6 } from "node:path";
|
|
140261
|
-
var
|
|
140484
|
+
var log41 = createLogger("diff-service");
|
|
140262
140485
|
var EMPTY_TREE_ARGS = ["hash-object", "-t", "tree", "/dev/null"];
|
|
140263
140486
|
var EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
140264
140487
|
async function resolveDiffContext(cwd, defaultBranch, diffMode, compareBranchInput) {
|
|
@@ -140363,7 +140586,7 @@ var DiffService = class {
|
|
|
140363
140586
|
);
|
|
140364
140587
|
branches = output.trim().split("\n").map((b10) => b10.trim()).filter(Boolean);
|
|
140365
140588
|
} catch (err) {
|
|
140366
|
-
|
|
140589
|
+
log41.error(
|
|
140367
140590
|
`listBranches: for-each-ref failed for ${cwd}: ${err instanceof Error ? err.message : err}`
|
|
140368
140591
|
);
|
|
140369
140592
|
}
|
|
@@ -140462,7 +140685,7 @@ var DiffService = class {
|
|
|
140462
140685
|
async getDiffSummary(workspaceId, options2) {
|
|
140463
140686
|
const workspace = this.workspaces.resolve(workspaceId);
|
|
140464
140687
|
if (!workspace) throw new WorkspaceNotFoundError(workspaceId);
|
|
140465
|
-
const hasGit =
|
|
140688
|
+
const hasGit = existsSync13(join29(workspace.worktree.path, ".git"));
|
|
140466
140689
|
if (workspace.project.kind === "plain" || !hasGit) {
|
|
140467
140690
|
const defaultBranch2 = workspace.project.defaultBranch;
|
|
140468
140691
|
return {
|
|
@@ -140594,7 +140817,7 @@ var DiffService = class {
|
|
|
140594
140817
|
var diffService = new DiffService();
|
|
140595
140818
|
|
|
140596
140819
|
// src/server/services/files-service.ts
|
|
140597
|
-
import { existsSync as
|
|
140820
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
140598
140821
|
import { cp, mkdir as mkdir2, readdir as readdir2, readFile as readFile3, rename, rm as rm3, stat as stat4, writeFile as writeFile2 } from "node:fs/promises";
|
|
140599
140822
|
import { dirname as dirname7, extname as extname3, join as join30, resolve as resolve10, sep as sep7 } from "node:path";
|
|
140600
140823
|
var MAX_FILE_SIZE2 = 1024 * 1024;
|
|
@@ -140713,11 +140936,11 @@ var FilesService = class {
|
|
|
140713
140936
|
async createFile(workspaceId, path3, content2 = "") {
|
|
140714
140937
|
const { root, target } = this.resolveInside(workspaceId, path3, { allowRoot: false });
|
|
140715
140938
|
this.assertNotGitInternals(root, target, "create");
|
|
140716
|
-
if (
|
|
140939
|
+
if (existsSync14(target)) {
|
|
140717
140940
|
throw new Error("A file or directory already exists at this path");
|
|
140718
140941
|
}
|
|
140719
140942
|
const parent = dirname7(target);
|
|
140720
|
-
if (!
|
|
140943
|
+
if (!existsSync14(parent)) {
|
|
140721
140944
|
throw new Error("Parent directory does not exist");
|
|
140722
140945
|
}
|
|
140723
140946
|
const parentStat = await stat4(parent);
|
|
@@ -140730,11 +140953,11 @@ var FilesService = class {
|
|
|
140730
140953
|
async createDirectory(workspaceId, path3) {
|
|
140731
140954
|
const { root, target } = this.resolveInside(workspaceId, path3, { allowRoot: false });
|
|
140732
140955
|
this.assertNotGitInternals(root, target, "create");
|
|
140733
|
-
if (
|
|
140956
|
+
if (existsSync14(target)) {
|
|
140734
140957
|
throw new Error("A file or directory already exists at this path");
|
|
140735
140958
|
}
|
|
140736
140959
|
const parent = dirname7(target);
|
|
140737
|
-
if (!
|
|
140960
|
+
if (!existsSync14(parent)) {
|
|
140738
140961
|
throw new Error("Parent directory does not exist");
|
|
140739
140962
|
}
|
|
140740
140963
|
const parentStat = await stat4(parent);
|
|
@@ -140775,11 +140998,11 @@ var FilesService = class {
|
|
|
140775
140998
|
} catch {
|
|
140776
140999
|
throw new Error("Source path does not exist");
|
|
140777
141000
|
}
|
|
140778
|
-
if (
|
|
141001
|
+
if (existsSync14(toTarget)) {
|
|
140779
141002
|
throw new Error("A file or directory already exists at the destination");
|
|
140780
141003
|
}
|
|
140781
141004
|
const toParent = dirname7(toTarget);
|
|
140782
|
-
if (!
|
|
141005
|
+
if (!existsSync14(toParent)) {
|
|
140783
141006
|
throw new Error("Destination parent directory does not exist");
|
|
140784
141007
|
}
|
|
140785
141008
|
const toParentStat = await stat4(toParent);
|
|
@@ -140811,11 +141034,11 @@ var FilesService = class {
|
|
|
140811
141034
|
if (entryStat.isDirectory() && toTarget.startsWith(fromTarget + sep7)) {
|
|
140812
141035
|
throw new Error("Cannot copy a directory into itself");
|
|
140813
141036
|
}
|
|
140814
|
-
if (
|
|
141037
|
+
if (existsSync14(toTarget)) {
|
|
140815
141038
|
throw new Error("A file or directory already exists at the destination");
|
|
140816
141039
|
}
|
|
140817
141040
|
const toParent = dirname7(toTarget);
|
|
140818
|
-
if (!
|
|
141041
|
+
if (!existsSync14(toParent)) {
|
|
140819
141042
|
throw new Error("Destination parent directory does not exist");
|
|
140820
141043
|
}
|
|
140821
141044
|
const toParentStat = await stat4(toParent);
|
|
@@ -142344,6 +142567,7 @@ var appRouter = t2.router({
|
|
|
142344
142567
|
chat: chatRouter,
|
|
142345
142568
|
browsers: browsersRouter,
|
|
142346
142569
|
browserLayout: browserLayoutRouter,
|
|
142570
|
+
panelFocus: panelFocusRouter,
|
|
142347
142571
|
tasks: tasksRouter,
|
|
142348
142572
|
sessions: sessionsRouter,
|
|
142349
142573
|
...terminalsRouters,
|
|
@@ -142479,7 +142703,7 @@ function getScalarHtml(specUrl) {
|
|
|
142479
142703
|
|
|
142480
142704
|
// src/server/api/terminals/ws.ts
|
|
142481
142705
|
init_src();
|
|
142482
|
-
var
|
|
142706
|
+
var log42 = createLogger("terminal-ws");
|
|
142483
142707
|
var MAX_CLOSE_REASON_BYTES = 123;
|
|
142484
142708
|
var HEARTBEAT_INTERVAL_MS2 = 3e4;
|
|
142485
142709
|
function clampCloseReason(reason) {
|
|
@@ -142551,7 +142775,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
142551
142775
|
session = await terminalService.spawn(workspaceId, terminalId, spawnOpts);
|
|
142552
142776
|
} catch (err) {
|
|
142553
142777
|
const msg = err instanceof Error ? err.message : String(err);
|
|
142554
|
-
|
|
142778
|
+
log42.error("Failed to spawn terminal %s for workspace %s: %s", terminalId, workspaceId, msg);
|
|
142555
142779
|
safeClose(ws, 4001, msg);
|
|
142556
142780
|
return;
|
|
142557
142781
|
}
|
|
@@ -142565,7 +142789,7 @@ async function handleTerminalConnection(ws, req) {
|
|
|
142565
142789
|
});
|
|
142566
142790
|
}
|
|
142567
142791
|
function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
142568
|
-
|
|
142792
|
+
log42.debug(
|
|
142569
142793
|
"Terminal %s: %s (workspace %s)",
|
|
142570
142794
|
isNew ? "connected" : "reconnected",
|
|
142571
142795
|
terminalId,
|
|
@@ -142594,7 +142818,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
142594
142818
|
}, 3e3);
|
|
142595
142819
|
const exitDisposable = session.pty.onExit(({ exitCode }) => {
|
|
142596
142820
|
clearInterval(processInterval);
|
|
142597
|
-
|
|
142821
|
+
log42.debug("PTY exited with code %d for terminal %s", exitCode, terminalId);
|
|
142598
142822
|
if (ws.readyState === ws.OPEN) {
|
|
142599
142823
|
ws.close(1e3, "Terminal exited");
|
|
142600
142824
|
}
|
|
@@ -142622,7 +142846,7 @@ function attachSession(ws, terminalId, workspaceId, session, isNew) {
|
|
|
142622
142846
|
clearInterval(pingInterval);
|
|
142623
142847
|
dataDisposable.dispose();
|
|
142624
142848
|
exitDisposable.dispose();
|
|
142625
|
-
|
|
142849
|
+
log42.debug("Terminal disconnected: %s (PTY kept alive)", terminalId);
|
|
142626
142850
|
});
|
|
142627
142851
|
}
|
|
142628
142852
|
function handleMessage(ws, terminalId, session, message) {
|
|
@@ -142658,7 +142882,7 @@ function stripTerminalQueries(data) {
|
|
|
142658
142882
|
|
|
142659
142883
|
// src/server/infra/browser-host/cdp-proxy.ts
|
|
142660
142884
|
init_src();
|
|
142661
|
-
var
|
|
142885
|
+
var log43 = createLogger("cdp-proxy");
|
|
142662
142886
|
async function handleCdpConnection(ws, req) {
|
|
142663
142887
|
const url = new URL(req.url ?? "", `http://${req.headers.host}`);
|
|
142664
142888
|
const bandTabId = url.searchParams.get("bandTabId");
|
|
@@ -142681,17 +142905,17 @@ async function handleCdpConnection(ws, req) {
|
|
|
142681
142905
|
cdpTargetId = await ensureCdpTargetId(bandTabId);
|
|
142682
142906
|
} catch (err) {
|
|
142683
142907
|
const message = err instanceof Error ? err.message : String(err);
|
|
142684
|
-
|
|
142908
|
+
log43.debug("ensureCdpTargetId failed for %s: %s", bandTabId, message);
|
|
142685
142909
|
if (ws.readyState === ws.OPEN) {
|
|
142686
142910
|
ws.close(4001, message.slice(0, 123));
|
|
142687
142911
|
}
|
|
142688
142912
|
return;
|
|
142689
142913
|
}
|
|
142690
142914
|
const upstreamUrl = `ws://${DESKTOP_CDP_HOST}:${DESKTOP_CDP_PORT}/devtools/page/${encodeURIComponent(cdpTargetId)}`;
|
|
142691
|
-
|
|
142915
|
+
log43.info("CDP proxy connecting bandTabId=%s upstream=%s", bandTabId, upstreamUrl);
|
|
142692
142916
|
upstream = new wrapper_default(upstreamUrl);
|
|
142693
142917
|
upstream.on("open", () => {
|
|
142694
|
-
|
|
142918
|
+
log43.info("CDP upstream open bandTabId=%s pending=%d", bandTabId, pending2.length);
|
|
142695
142919
|
for (const msg of pending2) {
|
|
142696
142920
|
upstream?.send(msg);
|
|
142697
142921
|
}
|
|
@@ -142703,20 +142927,20 @@ async function handleCdpConnection(ws, req) {
|
|
|
142703
142927
|
}
|
|
142704
142928
|
});
|
|
142705
142929
|
upstream.on("error", (err) => {
|
|
142706
|
-
|
|
142930
|
+
log43.warn("CDP upstream error bandTabId=%s: %s", bandTabId, err.message);
|
|
142707
142931
|
markTargetDestroyed(bandTabId);
|
|
142708
142932
|
if (ws.readyState === ws.OPEN) {
|
|
142709
142933
|
ws.close(4001, `Desktop CDP error: ${err.message}`.slice(0, 123));
|
|
142710
142934
|
}
|
|
142711
142935
|
});
|
|
142712
142936
|
upstream.on("close", (code) => {
|
|
142713
|
-
|
|
142937
|
+
log43.info("CDP upstream closed bandTabId=%s code=%d", bandTabId, code);
|
|
142714
142938
|
if (ws.readyState === ws.OPEN) {
|
|
142715
142939
|
ws.close(1e3, "Upstream closed");
|
|
142716
142940
|
}
|
|
142717
142941
|
});
|
|
142718
142942
|
ws.on("close", () => {
|
|
142719
|
-
|
|
142943
|
+
log43.debug("CDP client closed bandTabId=%s", bandTabId);
|
|
142720
142944
|
if (upstream && (upstream.readyState === wrapper_default.OPEN || upstream.readyState === wrapper_default.CONNECTING)) {
|
|
142721
142945
|
try {
|
|
142722
142946
|
upstream.close();
|
|
@@ -142725,7 +142949,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
142725
142949
|
}
|
|
142726
142950
|
});
|
|
142727
142951
|
ws.on("error", (err) => {
|
|
142728
|
-
|
|
142952
|
+
log43.debug("CDP client error bandTabId=%s: %s", bandTabId, err.message);
|
|
142729
142953
|
try {
|
|
142730
142954
|
upstream?.close();
|
|
142731
142955
|
} catch {
|
|
@@ -142735,7 +142959,7 @@ async function handleCdpConnection(ws, req) {
|
|
|
142735
142959
|
|
|
142736
142960
|
// src/server/infra/browser-host/cdp-targets.ts
|
|
142737
142961
|
init_src();
|
|
142738
|
-
var
|
|
142962
|
+
var log44 = createLogger("cdp-targets");
|
|
142739
142963
|
var CdpUnreachableError = class extends Error {
|
|
142740
142964
|
constructor(message) {
|
|
142741
142965
|
super(message);
|
|
@@ -142791,7 +143015,7 @@ async function captureSnapshot(bandTabId) {
|
|
|
142791
143015
|
});
|
|
142792
143016
|
ws.on("error", (err) => {
|
|
142793
143017
|
clearTimeout(timeout);
|
|
142794
|
-
|
|
143018
|
+
log44.debug("captureSnapshot ws error for tab %s: %s", bandTabId, err.message);
|
|
142795
143019
|
markTargetDestroyed(bandTabId);
|
|
142796
143020
|
settle(new CdpUnreachableError(err.message));
|
|
142797
143021
|
});
|
|
@@ -142811,7 +143035,7 @@ function runMigrations() {
|
|
|
142811
143035
|
|
|
142812
143036
|
// src/server/infra/lsp/lsp-proxy.ts
|
|
142813
143037
|
init_src();
|
|
142814
|
-
var
|
|
143038
|
+
var log45 = createLogger("lsp-proxy");
|
|
142815
143039
|
function frameMessage(json2) {
|
|
142816
143040
|
const body = Buffer.from(json2, "utf-8");
|
|
142817
143041
|
const header = `Content-Length: ${body.byteLength}\r
|
|
@@ -142829,7 +143053,7 @@ function createFrameParser(onMessage) {
|
|
|
142829
143053
|
const headerStr = buffer.subarray(0, separatorIdx).toString("ascii");
|
|
142830
143054
|
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
142831
143055
|
if (!match) {
|
|
142832
|
-
|
|
143056
|
+
log45.warn("Malformed LSP header: %s", headerStr);
|
|
142833
143057
|
buffer = buffer.subarray(separatorIdx + 4);
|
|
142834
143058
|
continue;
|
|
142835
143059
|
}
|
|
@@ -142862,7 +143086,7 @@ async function handleLspConnection(ws, req) {
|
|
|
142862
143086
|
session = await getOrSpawnServer(workspaceId, lang);
|
|
142863
143087
|
} catch (err) {
|
|
142864
143088
|
const message = err instanceof Error ? err.message : String(err);
|
|
142865
|
-
|
|
143089
|
+
log45.error(
|
|
142866
143090
|
"Failed to spawn %s language server for workspace %s: %s",
|
|
142867
143091
|
lang,
|
|
142868
143092
|
workspaceId,
|
|
@@ -142876,12 +143100,12 @@ async function handleLspConnection(ws, req) {
|
|
|
142876
143100
|
ws.close(4002, "Language server stdio not available");
|
|
142877
143101
|
return;
|
|
142878
143102
|
}
|
|
142879
|
-
|
|
143103
|
+
log45.debug("LSP client connected: %s/%s", workspaceId, lang);
|
|
142880
143104
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
142881
143105
|
const retriedIds = /* @__PURE__ */ new Set();
|
|
142882
143106
|
const RETRY_DELAY_MS = 2e3;
|
|
142883
143107
|
const parseFrame = createFrameParser((json2) => {
|
|
142884
|
-
|
|
143108
|
+
log45.debug(
|
|
142885
143109
|
"LSP stdout [%s/%s]: %s",
|
|
142886
143110
|
workspaceId,
|
|
142887
143111
|
lang,
|
|
@@ -142893,7 +143117,7 @@ async function handleLspConnection(ws, req) {
|
|
|
142893
143117
|
const originalRequest = pendingRequests.get(msg.id);
|
|
142894
143118
|
retriedIds.add(msg.id);
|
|
142895
143119
|
pendingRequests.delete(msg.id);
|
|
142896
|
-
|
|
143120
|
+
log45.debug(
|
|
142897
143121
|
"LSP retrying request %d after 'No Project' error [%s/%s]",
|
|
142898
143122
|
msg.id,
|
|
142899
143123
|
workspaceId,
|
|
@@ -142915,14 +143139,14 @@ async function handleLspConnection(ws, req) {
|
|
|
142915
143139
|
const onStdoutData = (chunk) => parseFrame(chunk);
|
|
142916
143140
|
lspProcess.stdout.on("data", onStdoutData);
|
|
142917
143141
|
const onExit = (code) => {
|
|
142918
|
-
|
|
143142
|
+
log45.debug("LSP server exited (code %s), closing WebSocket", String(code));
|
|
142919
143143
|
if (ws.readyState === ws.OPEN) {
|
|
142920
143144
|
ws.close(1e3, "Language server exited");
|
|
142921
143145
|
}
|
|
142922
143146
|
};
|
|
142923
143147
|
lspProcess.on("exit", onExit);
|
|
142924
143148
|
function forwardToStdin(json2) {
|
|
142925
|
-
|
|
143149
|
+
log45.debug(
|
|
142926
143150
|
"LSP stdin [%s/%s]: %s",
|
|
142927
143151
|
workspaceId,
|
|
142928
143152
|
lang,
|
|
@@ -142949,7 +143173,7 @@ async function handleLspConnection(ws, req) {
|
|
|
142949
143173
|
ws.on("close", () => {
|
|
142950
143174
|
lspProcess.stdout?.off("data", onStdoutData);
|
|
142951
143175
|
lspProcess.off("exit", onExit);
|
|
142952
|
-
|
|
143176
|
+
log45.debug("LSP client disconnected: %s/%s (server kept alive)", workspaceId, lang);
|
|
142953
143177
|
});
|
|
142954
143178
|
}
|
|
142955
143179
|
|
|
@@ -143097,7 +143321,7 @@ async function installSkills(opts = {}) {
|
|
|
143097
143321
|
}
|
|
143098
143322
|
|
|
143099
143323
|
// src/server/services/setup-service.ts
|
|
143100
|
-
var
|
|
143324
|
+
var log46 = createLogger("setup");
|
|
143101
143325
|
var AGENT_CHECKS = [
|
|
143102
143326
|
{ id: "claude-code", type: "claude-code", label: "Claude Code", binary: "claude" },
|
|
143103
143327
|
{ id: "codex", type: "codex", label: "Codex", binary: "codex" },
|
|
@@ -143114,7 +143338,7 @@ async function runFirstTimeSetup() {
|
|
|
143114
143338
|
]);
|
|
143115
143339
|
for (const r6 of results) {
|
|
143116
143340
|
if (r6.status === "rejected") {
|
|
143117
|
-
|
|
143341
|
+
log46.warn(
|
|
143118
143342
|
"Setup step failed: %s",
|
|
143119
143343
|
r6.reason instanceof Error ? r6.reason.message : String(r6.reason)
|
|
143120
143344
|
);
|
|
@@ -143128,7 +143352,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
143128
143352
|
const ok2 = results.filter((r6) => !r6.error).length;
|
|
143129
143353
|
const failed = results.length - ok2;
|
|
143130
143354
|
if (results.length > 0) {
|
|
143131
|
-
|
|
143355
|
+
log46.info(
|
|
143132
143356
|
"Background model refresh: %d/%d agents updated (%d failed)",
|
|
143133
143357
|
ok2,
|
|
143134
143358
|
results.length,
|
|
@@ -143136,7 +143360,7 @@ async function refreshAgentModelsInBackground() {
|
|
|
143136
143360
|
);
|
|
143137
143361
|
}
|
|
143138
143362
|
} catch (err) {
|
|
143139
|
-
|
|
143363
|
+
log46.warn(
|
|
143140
143364
|
"Background model refresh failed: %s",
|
|
143141
143365
|
err instanceof Error ? err.message : String(err)
|
|
143142
143366
|
);
|
|
@@ -143150,7 +143374,7 @@ async function ensureProjectStateInSync() {
|
|
|
143150
143374
|
try {
|
|
143151
143375
|
await syncService.syncWorktrees();
|
|
143152
143376
|
} catch (err) {
|
|
143153
|
-
|
|
143377
|
+
log46.warn(
|
|
143154
143378
|
"Failed to sync project state at boot: %s",
|
|
143155
143379
|
err instanceof Error ? err.message : String(err)
|
|
143156
143380
|
);
|
|
@@ -143161,22 +143385,22 @@ async function ensureCliInstalled() {
|
|
|
143161
143385
|
try {
|
|
143162
143386
|
cliStatus = await checkCli();
|
|
143163
143387
|
} catch (err) {
|
|
143164
|
-
|
|
143388
|
+
log46.warn("Could not check CLI status: %s", err instanceof Error ? err.message : String(err));
|
|
143165
143389
|
return;
|
|
143166
143390
|
}
|
|
143167
143391
|
if (cliStatus === "Installed") {
|
|
143168
143392
|
return;
|
|
143169
143393
|
}
|
|
143170
143394
|
if (cliStatus !== "NotInstalled") {
|
|
143171
|
-
|
|
143395
|
+
log46.warn("CLI not auto-installed (status: %s)", cliStatus);
|
|
143172
143396
|
return;
|
|
143173
143397
|
}
|
|
143174
|
-
|
|
143398
|
+
log46.info("Installing band CLI...");
|
|
143175
143399
|
try {
|
|
143176
143400
|
await installCli();
|
|
143177
|
-
|
|
143401
|
+
log46.info("CLI installed to /usr/local/bin/band");
|
|
143178
143402
|
} catch (err) {
|
|
143179
|
-
|
|
143403
|
+
log46.warn("CLI installation failed: %s", err instanceof Error ? err.message : String(err));
|
|
143180
143404
|
}
|
|
143181
143405
|
}
|
|
143182
143406
|
async function ensureDefaultCodingAgents() {
|
|
@@ -143185,17 +143409,17 @@ async function ensureDefaultCodingAgents() {
|
|
|
143185
143409
|
if (Array.isArray(existing) && existing.length > 0) {
|
|
143186
143410
|
return;
|
|
143187
143411
|
}
|
|
143188
|
-
|
|
143412
|
+
log46.info("Detecting installed coding agents...");
|
|
143189
143413
|
const detected = [];
|
|
143190
143414
|
for (const check2 of AGENT_CHECKS) {
|
|
143191
143415
|
const path3 = await systemService.whichBinary(check2.binary);
|
|
143192
143416
|
if (path3) {
|
|
143193
|
-
|
|
143417
|
+
log46.info("Detected coding agent: %s (%s)", check2.id, path3);
|
|
143194
143418
|
detected.push({ id: check2.id, type: check2.type, label: check2.label });
|
|
143195
143419
|
}
|
|
143196
143420
|
}
|
|
143197
143421
|
if (detected.length === 0) {
|
|
143198
|
-
|
|
143422
|
+
log46.info("No coding agent CLIs detected on PATH");
|
|
143199
143423
|
return;
|
|
143200
143424
|
}
|
|
143201
143425
|
const current2 = loadSettings();
|
|
@@ -143204,7 +143428,7 @@ async function ensureDefaultCodingAgents() {
|
|
|
143204
143428
|
current2.defaultCodingAgent = detected[0].id;
|
|
143205
143429
|
}
|
|
143206
143430
|
saveSettings(current2);
|
|
143207
|
-
|
|
143431
|
+
log46.info("Enabled %d coding agent(s); default = %s", detected.length, current2.defaultCodingAgent);
|
|
143208
143432
|
}
|
|
143209
143433
|
function ensureNotificationDefaults() {
|
|
143210
143434
|
const settings = loadSettings();
|
|
@@ -143216,7 +143440,7 @@ function ensureNotificationDefaults() {
|
|
|
143216
143440
|
...settings,
|
|
143217
143441
|
notifications: { ...notifications, soundOnNeedsAttention: true }
|
|
143218
143442
|
});
|
|
143219
|
-
|
|
143443
|
+
log46.info("Set default notifications.soundOnNeedsAttention = true");
|
|
143220
143444
|
}
|
|
143221
143445
|
async function ensureClaudeHooks() {
|
|
143222
143446
|
try {
|
|
@@ -143225,9 +143449,9 @@ async function ensureClaudeHooks() {
|
|
|
143225
143449
|
return;
|
|
143226
143450
|
}
|
|
143227
143451
|
await installHooks();
|
|
143228
|
-
|
|
143452
|
+
log46.info("Installed Claude Code hooks");
|
|
143229
143453
|
} catch (err) {
|
|
143230
|
-
|
|
143454
|
+
log46.warn(
|
|
143231
143455
|
"Failed to install Claude Code hooks: %s",
|
|
143232
143456
|
err instanceof Error ? err.message : String(err)
|
|
143233
143457
|
);
|
|
@@ -143235,11 +143459,11 @@ async function ensureClaudeHooks() {
|
|
|
143235
143459
|
}
|
|
143236
143460
|
async function ensureSkillsInstalled() {
|
|
143237
143461
|
try {
|
|
143238
|
-
const result = await installSkills({ log:
|
|
143462
|
+
const result = await installSkills({ log: log46 });
|
|
143239
143463
|
const wrote = result.written.length + result.updated.length;
|
|
143240
143464
|
const linkChange = result.linked.length;
|
|
143241
143465
|
if (wrote > 0 || linkChange > 0 || result.conflicts.length > 0) {
|
|
143242
|
-
|
|
143466
|
+
log46.info(
|
|
143243
143467
|
"Synced CLI skills (shared: %d written, %d updated, %d unchanged; symlinks: %d created, %d already-linked, %d conflicts, %d skipped)",
|
|
143244
143468
|
result.written.length,
|
|
143245
143469
|
result.updated.length,
|
|
@@ -143251,7 +143475,7 @@ async function ensureSkillsInstalled() {
|
|
|
143251
143475
|
);
|
|
143252
143476
|
}
|
|
143253
143477
|
} catch (err) {
|
|
143254
|
-
|
|
143478
|
+
log46.warn("Failed to sync CLI skills: %s", err instanceof Error ? err.message : String(err));
|
|
143255
143479
|
}
|
|
143256
143480
|
}
|
|
143257
143481
|
var SetupService = class {
|