@zythum02/fello-server 0.1.46 → 0.1.49
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/README.md +11 -2
- package/out/renderer/assets/{_baseUniq-JI50qq3v.js → _baseUniq-jsNn2Q0s.js} +1 -1
- package/out/renderer/assets/_baseUniq-jsNn2Q0s.js.br +0 -0
- package/out/renderer/assets/_baseUniq-jsNn2Q0s.js.gz +0 -0
- package/out/renderer/assets/{arc-D82BffDI.js → arc-CZMdjunT.js} +1 -1
- package/out/renderer/assets/arc-CZMdjunT.js.br +0 -0
- package/out/renderer/assets/arc-CZMdjunT.js.gz +0 -0
- package/out/renderer/assets/{architectureDiagram-Q4EWVU46-BBRMDHvv.js → architectureDiagram-Q4EWVU46-BNFtPc1v.js} +5 -5
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-BNFtPc1v.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-BNFtPc1v.js.gz +0 -0
- package/out/renderer/assets/{blockDiagram-DXYQGD6D-CiCuaiyL.js → blockDiagram-DXYQGD6D-CPK2QuaJ.js} +6 -6
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CPK2QuaJ.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CPK2QuaJ.js.gz +0 -0
- package/out/renderer/assets/{c4Diagram-AHTNJAMY-D9PM_R8p.js → c4Diagram-AHTNJAMY-DLQf0xBh.js} +2 -2
- package/out/renderer/assets/c4Diagram-AHTNJAMY-DLQf0xBh.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-DLQf0xBh.js.gz +0 -0
- package/out/renderer/assets/{channel-CklIgqOK.js → channel-sFWrTS52.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-DK0KQU1M.js → chunk-4BX2VUAB-CUoBhtu2.js} +1 -1
- package/out/renderer/assets/{chunk-4TB4RGXK-CxHdBbdg.js → chunk-4TB4RGXK-CRjlV65P.js} +5 -5
- package/out/renderer/assets/chunk-4TB4RGXK-CRjlV65P.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-CRjlV65P.js.gz +0 -0
- package/out/renderer/assets/{chunk-55IACEB6-ykIH_AN3.js → chunk-55IACEB6-zrgWErN1.js} +1 -1
- package/out/renderer/assets/{chunk-EDXVE4YY-DUOS0pBH.js → chunk-EDXVE4YY-B5b9dJFI.js} +1 -1
- package/out/renderer/assets/chunk-EDXVE4YY-B5b9dJFI.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-B5b9dJFI.js.gz +0 -0
- package/out/renderer/assets/{chunk-FMBD7UC4-Bm3BHCuh.js → chunk-FMBD7UC4-Bb0FhBnd.js} +1 -1
- package/out/renderer/assets/{chunk-OYMX7WX6-DH9JMSMI.js → chunk-OYMX7WX6-CkUp0SL9.js} +3 -3
- package/out/renderer/assets/chunk-OYMX7WX6-CkUp0SL9.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-CkUp0SL9.js.gz +0 -0
- package/out/renderer/assets/{chunk-QZHKN3VN-LffrA1jF.js → chunk-QZHKN3VN-Bqt7zsAR.js} +1 -1
- package/out/renderer/assets/{chunk-YZCP3GAM-B1pm_POM.js → chunk-YZCP3GAM-Crg82fz2.js} +1 -1
- package/out/renderer/assets/chunk-YZCP3GAM-Crg82fz2.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-Crg82fz2.js.gz +0 -0
- package/out/renderer/assets/{classDiagram-6PBFFD2Q-O6uMquiH.js → classDiagram-6PBFFD2Q-BInpfZnW.js} +6 -6
- package/out/renderer/assets/{classDiagram-v2-HSJHXN6E-O6uMquiH.js → classDiagram-v2-HSJHXN6E-BInpfZnW.js} +6 -6
- package/out/renderer/assets/{clone-BhlnPWG5.js → clone-Brsdp_jq.js} +1 -1
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-ljZi9cz-.js → cose-bilkent-S5V4N54A-CH_2zOJR.js} +1 -1
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CH_2zOJR.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CH_2zOJR.js.gz +0 -0
- package/out/renderer/assets/{dagre-KV5264BT-DqnNoP69.js → dagre-KV5264BT-H1wB7v-Q.js} +6 -6
- package/out/renderer/assets/dagre-KV5264BT-H1wB7v-Q.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-H1wB7v-Q.js.gz +0 -0
- package/out/renderer/assets/{diagram-5BDNPKRD-pBYJseHI.js → diagram-5BDNPKRD-D9VV_-Xi.js} +6 -6
- package/out/renderer/assets/diagram-5BDNPKRD-D9VV_-Xi.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-D9VV_-Xi.js.gz +0 -0
- package/out/renderer/assets/{diagram-G4DWMVQ6-IPm9zWeG.js → diagram-G4DWMVQ6-CfRglPBg.js} +6 -6
- package/out/renderer/assets/diagram-G4DWMVQ6-CfRglPBg.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-CfRglPBg.js.gz +0 -0
- package/out/renderer/assets/{diagram-MMDJMWI5-DSH58P_m.js → diagram-MMDJMWI5-BnwRyNpR.js} +5 -5
- package/out/renderer/assets/diagram-MMDJMWI5-BnwRyNpR.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-BnwRyNpR.js.gz +0 -0
- package/out/renderer/assets/{diagram-TYMM5635-Czl-GGCp.js → diagram-TYMM5635-BKn_5Ga7.js} +5 -5
- package/out/renderer/assets/diagram-TYMM5635-BKn_5Ga7.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-BKn_5Ga7.js.gz +0 -0
- package/out/renderer/assets/{erDiagram-SMLLAGMA-BENPNKae.js → erDiagram-SMLLAGMA-B35CLzqQ.js} +4 -4
- package/out/renderer/assets/erDiagram-SMLLAGMA-B35CLzqQ.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-B35CLzqQ.js.gz +0 -0
- package/out/renderer/assets/{flowDiagram-DWJPFMVM-T3H9Pqwa.js → flowDiagram-DWJPFMVM-BidIy8zc.js} +6 -6
- package/out/renderer/assets/flowDiagram-DWJPFMVM-BidIy8zc.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-BidIy8zc.js.gz +0 -0
- package/out/renderer/assets/{ganttDiagram-T4ZO3ILL-Hh-AJvLC.js → ganttDiagram-T4ZO3ILL-CqV1ei6S.js} +2 -2
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CqV1ei6S.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CqV1ei6S.js.gz +0 -0
- package/out/renderer/assets/{gitGraphDiagram-UUTBAWPF-BDXB9jT_.js → gitGraphDiagram-UUTBAWPF-7wQ8gKPV.js} +6 -6
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-7wQ8gKPV.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-7wQ8gKPV.js.gz +0 -0
- package/out/renderer/assets/{graph-MWvZ47Hf.js → graph-Ck9_bXv5.js} +2 -2
- package/out/renderer/assets/graph-Ck9_bXv5.js.br +0 -0
- package/out/renderer/assets/graph-Ck9_bXv5.js.gz +0 -0
- package/out/renderer/assets/{highlighted-body-OFNGDK62-Bvl34wyh.js → highlighted-body-OFNGDK62-gS-2OBX1.js} +1 -1
- package/out/renderer/assets/{index-BTEKdfpj.css → index-BtjFxpR5.css} +1 -1
- package/out/renderer/assets/index-BtjFxpR5.css.br +0 -0
- package/out/renderer/assets/index-BtjFxpR5.css.gz +0 -0
- package/out/renderer/assets/{index-BpPCAjGn.js → index-Cy_TZSUE.js} +2040 -1485
- package/out/renderer/assets/index-Cy_TZSUE.js.br +0 -0
- package/out/renderer/assets/index-Cy_TZSUE.js.gz +0 -0
- package/out/renderer/assets/{infoDiagram-42DDH7IO-Ca_9-363.js → infoDiagram-42DDH7IO-DlKxzT4w.js} +4 -4
- package/out/renderer/assets/{ishikawaDiagram-UXIWVN3A-D3GtyA4e.js → ishikawaDiagram-UXIWVN3A-DmOMlIE8.js} +1 -1
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-DmOMlIE8.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-DmOMlIE8.js.gz +0 -0
- package/out/renderer/assets/{journeyDiagram-VCZTEJTY-DkQAlc0b.js → journeyDiagram-VCZTEJTY-CYRPGJN7.js} +4 -4
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-CYRPGJN7.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-CYRPGJN7.js.gz +0 -0
- package/out/renderer/assets/{kanban-definition-6JOO6SKY-DamLzi6S.js → kanban-definition-6JOO6SKY-Dovb_i6Z.js} +2 -2
- package/out/renderer/assets/kanban-definition-6JOO6SKY-Dovb_i6Z.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-Dovb_i6Z.js.gz +0 -0
- package/out/renderer/assets/{layout-Dw_ZcO_L.js → layout-BUs47sjz.js} +4 -4
- package/out/renderer/assets/layout-BUs47sjz.js.br +0 -0
- package/out/renderer/assets/layout-BUs47sjz.js.gz +0 -0
- package/out/renderer/assets/{linear-Dh5vwFy4.js → linear-CO24wS_v.js} +1 -1
- package/out/renderer/assets/linear-CO24wS_v.js.br +0 -0
- package/out/renderer/assets/linear-CO24wS_v.js.gz +0 -0
- package/out/renderer/assets/{min-DDCW5FhP.js → min-Dd_ATNHv.js} +2 -2
- package/out/renderer/assets/min-Dd_ATNHv.js.br +0 -0
- package/out/renderer/assets/min-Dd_ATNHv.js.gz +0 -0
- package/out/renderer/assets/{mindmap-definition-QFDTVHPH-B3rcYXPK.js → mindmap-definition-QFDTVHPH-CC3W7LA-.js} +3 -3
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-CC3W7LA-.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-CC3W7LA-.js.gz +0 -0
- package/out/renderer/assets/{pieDiagram-DEJITSTG-CsCXUSKq.js → pieDiagram-DEJITSTG-BN6Ummnw.js} +6 -6
- package/out/renderer/assets/pieDiagram-DEJITSTG-BN6Ummnw.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-BN6Ummnw.js.gz +0 -0
- package/out/renderer/assets/{quadrantDiagram-34T5L4WZ-B91qjO1u.js → quadrantDiagram-34T5L4WZ-DTE_dLJv.js} +2 -2
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-DTE_dLJv.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-DTE_dLJv.js.gz +0 -0
- package/out/renderer/assets/{requirementDiagram-MS252O5E-oDcN7qN5.js → requirementDiagram-MS252O5E-DVDS2RYN.js} +3 -3
- package/out/renderer/assets/requirementDiagram-MS252O5E-DVDS2RYN.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-DVDS2RYN.js.gz +0 -0
- package/out/renderer/assets/{sankeyDiagram-XADWPNL6-DNQO_6oX.js → sankeyDiagram-XADWPNL6-D4_LywJM.js} +1 -1
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-D4_LywJM.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-D4_LywJM.js.gz +0 -0
- package/out/renderer/assets/{sequenceDiagram-FGHM5R23-DCh5u6wY.js → sequenceDiagram-FGHM5R23-89GBJZmd.js} +3 -3
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-89GBJZmd.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-89GBJZmd.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-FHFEXIEX-DV0gaxkj.js → stateDiagram-FHFEXIEX-YKrUbogP.js} +8 -8
- package/out/renderer/assets/stateDiagram-FHFEXIEX-YKrUbogP.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-YKrUbogP.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-v2-QKLJ7IA2-D1Sk_TKE.js → stateDiagram-v2-QKLJ7IA2-CO0pZRqI.js} +4 -4
- package/out/renderer/assets/{timeline-definition-GMOUNBTQ-Nq47TkPV.js → timeline-definition-GMOUNBTQ-BW2oxhj-.js} +2 -2
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-BW2oxhj-.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-BW2oxhj-.js.gz +0 -0
- package/out/renderer/assets/{vennDiagram-DHZGUBPP-CMbmY-R_.js → vennDiagram-DHZGUBPP-DSy9zL6k.js} +1 -1
- package/out/renderer/assets/vennDiagram-DHZGUBPP-DSy9zL6k.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-DSy9zL6k.js.gz +0 -0
- package/out/renderer/assets/{wardley-RL74JXVD-aLLqbf8o.js → wardley-RL74JXVD-DFRGDO55.js} +3 -3
- package/out/renderer/assets/wardley-RL74JXVD-DFRGDO55.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-DFRGDO55.js.gz +0 -0
- package/out/renderer/assets/{wardleyDiagram-NUSXRM2D-8Kc4VQIw.js → wardleyDiagram-NUSXRM2D-CJUPdnii.js} +5 -5
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-CJUPdnii.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-CJUPdnii.js.gz +0 -0
- package/out/renderer/assets/{xychartDiagram-5P7HB3ND-YtEoXmYf.js → xychartDiagram-5P7HB3ND-UGlSGsDE.js} +2 -2
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-UGlSGsDE.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-UGlSGsDE.js.gz +0 -0
- package/out/renderer/index.html +2 -2
- package/out/renderer/index.html.br +0 -0
- package/out/renderer/index.html.gz +0 -0
- package/out/scripts/mcp-search/server.mjs +46 -46
- package/out/server/main.js +1067 -318
- package/package.json +4 -1
- package/out/renderer/assets/_baseUniq-JI50qq3v.js.br +0 -0
- package/out/renderer/assets/_baseUniq-JI50qq3v.js.gz +0 -0
- package/out/renderer/assets/arc-D82BffDI.js.br +0 -0
- package/out/renderer/assets/arc-D82BffDI.js.gz +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-BBRMDHvv.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-BBRMDHvv.js.gz +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CiCuaiyL.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CiCuaiyL.js.gz +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-D9PM_R8p.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-D9PM_R8p.js.gz +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-CxHdBbdg.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-CxHdBbdg.js.gz +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-DUOS0pBH.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-DUOS0pBH.js.gz +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-DH9JMSMI.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-DH9JMSMI.js.gz +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-B1pm_POM.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-B1pm_POM.js.gz +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-ljZi9cz-.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-ljZi9cz-.js.gz +0 -0
- package/out/renderer/assets/dagre-KV5264BT-DqnNoP69.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-DqnNoP69.js.gz +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-pBYJseHI.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-pBYJseHI.js.gz +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-IPm9zWeG.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-IPm9zWeG.js.gz +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-DSH58P_m.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-DSH58P_m.js.gz +0 -0
- package/out/renderer/assets/diagram-TYMM5635-Czl-GGCp.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-Czl-GGCp.js.gz +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-BENPNKae.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-BENPNKae.js.gz +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-T3H9Pqwa.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-T3H9Pqwa.js.gz +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-Hh-AJvLC.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-Hh-AJvLC.js.gz +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-BDXB9jT_.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-BDXB9jT_.js.gz +0 -0
- package/out/renderer/assets/graph-MWvZ47Hf.js.br +0 -0
- package/out/renderer/assets/graph-MWvZ47Hf.js.gz +0 -0
- package/out/renderer/assets/index-BTEKdfpj.css.br +0 -0
- package/out/renderer/assets/index-BTEKdfpj.css.gz +0 -0
- package/out/renderer/assets/index-BpPCAjGn.js.br +0 -0
- package/out/renderer/assets/index-BpPCAjGn.js.gz +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-D3GtyA4e.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-D3GtyA4e.js.gz +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-DkQAlc0b.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-DkQAlc0b.js.gz +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-DamLzi6S.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-DamLzi6S.js.gz +0 -0
- package/out/renderer/assets/layout-Dw_ZcO_L.js.br +0 -0
- package/out/renderer/assets/layout-Dw_ZcO_L.js.gz +0 -0
- package/out/renderer/assets/linear-Dh5vwFy4.js.br +0 -0
- package/out/renderer/assets/linear-Dh5vwFy4.js.gz +0 -0
- package/out/renderer/assets/min-DDCW5FhP.js.br +0 -0
- package/out/renderer/assets/min-DDCW5FhP.js.gz +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-B3rcYXPK.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-B3rcYXPK.js.gz +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-CsCXUSKq.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-CsCXUSKq.js.gz +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-B91qjO1u.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-B91qjO1u.js.gz +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-oDcN7qN5.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-oDcN7qN5.js.gz +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-DNQO_6oX.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-DNQO_6oX.js.gz +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DCh5u6wY.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DCh5u6wY.js.gz +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DV0gaxkj.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DV0gaxkj.js.gz +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-Nq47TkPV.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-Nq47TkPV.js.gz +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-CMbmY-R_.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-CMbmY-R_.js.gz +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-aLLqbf8o.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-aLLqbf8o.js.gz +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-8Kc4VQIw.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-8Kc4VQIw.js.gz +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-YtEoXmYf.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-YtEoXmYf.js.gz +0 -0
package/out/server/main.js
CHANGED
|
@@ -57,6 +57,9 @@ var DEFAULT_SETTINGS = {
|
|
|
57
57
|
volume: 50,
|
|
58
58
|
muted: false,
|
|
59
59
|
theme: "soft"
|
|
60
|
+
},
|
|
61
|
+
proxy: {
|
|
62
|
+
mode: "off"
|
|
60
63
|
}
|
|
61
64
|
};
|
|
62
65
|
function settingsPath() {
|
|
@@ -188,6 +191,20 @@ function readSettings() {
|
|
|
188
191
|
theme: raw2.theme === "soft" || raw2.theme === "crisp" ? raw2.theme : DEFAULT_SETTINGS.sound.theme
|
|
189
192
|
};
|
|
190
193
|
})();
|
|
194
|
+
const proxy = (() => {
|
|
195
|
+
const raw2 = rawObj && isObject(rawObj.proxy) ? rawObj.proxy : null;
|
|
196
|
+
if (!raw2) return DEFAULT_SETTINGS.proxy;
|
|
197
|
+
const mode = raw2.mode === "off" || raw2.mode === "manual" || raw2.mode === "system" ? raw2.mode : DEFAULT_SETTINGS.proxy.mode;
|
|
198
|
+
const str = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
199
|
+
return {
|
|
200
|
+
mode,
|
|
201
|
+
httpProxy: str(raw2.httpProxy),
|
|
202
|
+
httpsProxy: str(raw2.httpsProxy),
|
|
203
|
+
noProxy: str(raw2.noProxy),
|
|
204
|
+
username: str(raw2.username),
|
|
205
|
+
password: str(raw2.password)
|
|
206
|
+
};
|
|
207
|
+
})();
|
|
191
208
|
const snippets = Array.isArray(rawObj?.snippets) ? rawObj.snippets.filter(
|
|
192
209
|
(s) => isObject(s) && typeof s.id === "string" && typeof s.title === "string" && typeof s.content === "string"
|
|
193
210
|
) : [];
|
|
@@ -230,6 +247,7 @@ function readSettings() {
|
|
|
230
247
|
ilink,
|
|
231
248
|
editor,
|
|
232
249
|
sound,
|
|
250
|
+
proxy,
|
|
233
251
|
snippets,
|
|
234
252
|
imageGeneration
|
|
235
253
|
};
|
|
@@ -321,6 +339,7 @@ function getSettings() {
|
|
|
321
339
|
muted: meta.sound.muted,
|
|
322
340
|
theme: meta.sound.theme
|
|
323
341
|
},
|
|
342
|
+
proxy: meta.proxy ?? DEFAULT_SETTINGS.proxy,
|
|
324
343
|
snippets: meta.snippets ?? [],
|
|
325
344
|
imageGeneration: (meta.imageGeneration ?? []).map((p) => ({
|
|
326
345
|
id: p.id,
|
|
@@ -461,6 +480,21 @@ function updateSettings(settings) {
|
|
|
461
480
|
theme: settings.sound.theme === "soft" || settings.sound.theme === "crisp" ? settings.sound.theme : prevMeta.sound.theme
|
|
462
481
|
};
|
|
463
482
|
})(),
|
|
483
|
+
proxy: (() => {
|
|
484
|
+
if (!settings.proxy) {
|
|
485
|
+
return prevMeta.proxy;
|
|
486
|
+
}
|
|
487
|
+
const mode = settings.proxy.mode === "off" || settings.proxy.mode === "manual" || settings.proxy.mode === "system" ? settings.proxy.mode : prevMeta.proxy?.mode ?? DEFAULT_SETTINGS.proxy.mode;
|
|
488
|
+
const str = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
489
|
+
return {
|
|
490
|
+
mode,
|
|
491
|
+
httpProxy: str(settings.proxy.httpProxy),
|
|
492
|
+
httpsProxy: str(settings.proxy.httpsProxy),
|
|
493
|
+
noProxy: str(settings.proxy.noProxy),
|
|
494
|
+
username: str(settings.proxy.username),
|
|
495
|
+
password: str(settings.proxy.password)
|
|
496
|
+
};
|
|
497
|
+
})(),
|
|
464
498
|
snippets: settings.snippets ?? prevMeta.snippets,
|
|
465
499
|
imageGeneration: settings.imageGeneration ? settings.imageGeneration.map((p) => ({
|
|
466
500
|
id: p.id,
|
|
@@ -1505,19 +1539,6 @@ import { relative as relative2, resolve as resolve2, isAbsolute as isAbsolute2 }
|
|
|
1505
1539
|
function toPosixPath(p) {
|
|
1506
1540
|
return p.replace(/\\/g, "/");
|
|
1507
1541
|
}
|
|
1508
|
-
var IGNORE_NAME_SET = /* @__PURE__ */ new Set([".git", ".svn", ".hg", "node_modules", "vendor", "__pycache__"]);
|
|
1509
|
-
function isIgnorePath(fullPath, cwd) {
|
|
1510
|
-
if (fullPath === cwd) return false;
|
|
1511
|
-
const relPath = relative2(cwd, fullPath);
|
|
1512
|
-
if (!relPath) return false;
|
|
1513
|
-
const segments = relPath.split(/[\\/]+/);
|
|
1514
|
-
for (let i = 0; i < segments.length; i++) {
|
|
1515
|
-
const name = segments[i];
|
|
1516
|
-
if (!name || name === ".") continue;
|
|
1517
|
-
if (IGNORE_NAME_SET.has(name)) return true;
|
|
1518
|
-
}
|
|
1519
|
-
return false;
|
|
1520
|
-
}
|
|
1521
1542
|
function resolveSafePath(cwd, relativePath) {
|
|
1522
1543
|
const safeCwd = resolve2(cwd);
|
|
1523
1544
|
const fullPath = resolve2(safeCwd, relativePath || "");
|
|
@@ -1779,11 +1800,11 @@ function createWebUIModule() {
|
|
|
1779
1800
|
}
|
|
1780
1801
|
});
|
|
1781
1802
|
});
|
|
1782
|
-
return new Promise((
|
|
1803
|
+
return new Promise((resolve9, reject) => {
|
|
1783
1804
|
const listenPort = options?.port && options.port > 0 ? options.port : 0;
|
|
1784
1805
|
httpServer.listen(listenPort, "0.0.0.0", () => {
|
|
1785
1806
|
isEnabled = true;
|
|
1786
|
-
|
|
1807
|
+
resolve9({ url: getWebUIUrl(httpServer.address()) });
|
|
1787
1808
|
});
|
|
1788
1809
|
httpServer.on("error", reject);
|
|
1789
1810
|
});
|
|
@@ -2168,7 +2189,7 @@ import { join as join12 } from "path";
|
|
|
2168
2189
|
|
|
2169
2190
|
// src/shared/zod/mcp-search-schema.ts
|
|
2170
2191
|
import { z } from "zod";
|
|
2171
|
-
var
|
|
2192
|
+
var grepRequestSchema = z.object({
|
|
2172
2193
|
pattern: z.string().describe("Search pattern (literal text by default, set regex=true for regex)."),
|
|
2173
2194
|
path: z.string().describe(
|
|
2174
2195
|
"Directory or file(s) to search. Accepts: relative path (relative to project root), absolute path (POSIX or Windows), or file:// URI."
|
|
@@ -2183,20 +2204,10 @@ var searchRequestSchema = z.object({
|
|
|
2183
2204
|
invertMatch: z.boolean().optional().describe("Show lines that do NOT match the pattern (-v)."),
|
|
2184
2205
|
wordMatch: z.boolean().optional().describe("Only match whole words (-w).")
|
|
2185
2206
|
});
|
|
2186
|
-
var
|
|
2207
|
+
var grepRespondSchema = z.object({
|
|
2187
2208
|
output: z.string(),
|
|
2188
2209
|
code: z.number()
|
|
2189
2210
|
});
|
|
2190
|
-
var rgRequestSchema = z.object({
|
|
2191
|
-
args: z.array(z.string()).describe(
|
|
2192
|
-
"Raw ripgrep CLI arguments (e.g. ['-i', 'pattern', 'src/']). The pattern and path are included in this array."
|
|
2193
|
-
)
|
|
2194
|
-
});
|
|
2195
|
-
var rgRespondSchema = z.object({
|
|
2196
|
-
output: z.string(),
|
|
2197
|
-
code: z.number(),
|
|
2198
|
-
stderr: z.string().optional()
|
|
2199
|
-
});
|
|
2200
2211
|
var fileOutlineRequestSchema = z.object({
|
|
2201
2212
|
path: z.string().describe(
|
|
2202
2213
|
"File path to analyze. Accepts: relative path (relative to project root), absolute path (POSIX or Windows), or file:// URI."
|
|
@@ -2205,6 +2216,20 @@ var fileOutlineRequestSchema = z.object({
|
|
|
2205
2216
|
var fileOutlineRespondSchema = z.object({
|
|
2206
2217
|
outline: z.string().describe("Structural outline of the file in text format.")
|
|
2207
2218
|
});
|
|
2219
|
+
var globRequestSchema = z.object({
|
|
2220
|
+
pattern: z.string().describe("Glob pattern, e.g. '**/*.rs', 'src/**/*.{ts,tsx}'."),
|
|
2221
|
+
path: z.string().optional().describe("Root directory to search from. Defaults to project root."),
|
|
2222
|
+
limit: z.number().int().positive().optional().describe("Maximum number of results to return."),
|
|
2223
|
+
maxDepth: z.number().int().positive().optional().describe("Maximum directory depth to traverse."),
|
|
2224
|
+
dot: z.boolean().optional().describe("Include dotfiles (hidden files/directories). Default: false."),
|
|
2225
|
+
onlyFiles: z.boolean().optional().describe("Only match files, not directories. Default: false (includes directories)."),
|
|
2226
|
+
gitignore: z.boolean().optional().describe("Respect .gitignore patterns. Default: true.")
|
|
2227
|
+
});
|
|
2228
|
+
var globRespondSchema = z.object({
|
|
2229
|
+
filePaths: z.array(z.string()),
|
|
2230
|
+
totalFiles: z.number(),
|
|
2231
|
+
truncated: z.boolean()
|
|
2232
|
+
});
|
|
2208
2233
|
|
|
2209
2234
|
// src/backend/search/file-outline.ts
|
|
2210
2235
|
import { extname, join as join10, isAbsolute as isAbsolute4, resolve as resolve3, relative as relative5 } from "path";
|
|
@@ -2627,7 +2652,7 @@ var LANGUAGES = [
|
|
|
2627
2652
|
}
|
|
2628
2653
|
];
|
|
2629
2654
|
async function parseInChild(filePath, config, cwd, timeout = 3e4) {
|
|
2630
|
-
return new Promise((
|
|
2655
|
+
return new Promise((resolve9, reject) => {
|
|
2631
2656
|
const modulePath = join10(process.scriptsPath, "/worker-file-outline/worker.mjs");
|
|
2632
2657
|
const child = fork(modulePath, [], { execArgv: [], cwd });
|
|
2633
2658
|
const timer = setTimeout(() => {
|
|
@@ -2636,7 +2661,7 @@ async function parseInChild(filePath, config, cwd, timeout = 3e4) {
|
|
|
2636
2661
|
}, timeout);
|
|
2637
2662
|
child.on("message", (msg) => {
|
|
2638
2663
|
clearTimeout(timer);
|
|
2639
|
-
if (msg.type === "result")
|
|
2664
|
+
if (msg.type === "result") resolve9({ symbols: msg.symbols, totalLines: msg.totalLines });
|
|
2640
2665
|
else reject(new Error(msg.error));
|
|
2641
2666
|
});
|
|
2642
2667
|
child.on("error", (err) => {
|
|
@@ -2799,7 +2824,7 @@ import { join as join11, isAbsolute as isAbsolute5, resolve as resolve4, relativ
|
|
|
2799
2824
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2800
2825
|
import { fork as fork2 } from "child_process";
|
|
2801
2826
|
function ripgrepInChild(args2, cwd, timeout = 3e4) {
|
|
2802
|
-
return new Promise((
|
|
2827
|
+
return new Promise((resolve9, reject) => {
|
|
2803
2828
|
const child = fork2(join11(process.scriptsPath, "worker-ripgrep/worker.mjs"), [], { cwd });
|
|
2804
2829
|
const timer = setTimeout(() => {
|
|
2805
2830
|
child.kill();
|
|
@@ -2808,7 +2833,7 @@ function ripgrepInChild(args2, cwd, timeout = 3e4) {
|
|
|
2808
2833
|
child.on("message", (msg) => {
|
|
2809
2834
|
clearTimeout(timer);
|
|
2810
2835
|
if (msg.type === "error") reject(new Error(msg.error));
|
|
2811
|
-
else
|
|
2836
|
+
else resolve9({ code: msg.code, stdout: msg.stdout, stderr: msg.stderr });
|
|
2812
2837
|
});
|
|
2813
2838
|
child.on("error", (err) => {
|
|
2814
2839
|
clearTimeout(timer);
|
|
@@ -2831,7 +2856,7 @@ function normalizePath2(inputPath, cwd) {
|
|
|
2831
2856
|
}
|
|
2832
2857
|
return resolve4(cwd ?? process.cwd(), inputPath);
|
|
2833
2858
|
}
|
|
2834
|
-
async function
|
|
2859
|
+
async function grep(options) {
|
|
2835
2860
|
const args2 = [];
|
|
2836
2861
|
args2.push("--heading");
|
|
2837
2862
|
args2.push("--line-number");
|
|
@@ -2853,16 +2878,38 @@ async function search(options) {
|
|
|
2853
2878
|
const { code, stdout } = await ripgrepInChild(args2, options.projectDir, options.timeout);
|
|
2854
2879
|
return { output: stdout || "", code };
|
|
2855
2880
|
}
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2881
|
+
|
|
2882
|
+
// src/backend/search/glob.ts
|
|
2883
|
+
import { globby } from "globby";
|
|
2884
|
+
import { isAbsolute as isAbsolute6, resolve as resolve5 } from "path";
|
|
2885
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
2886
|
+
function normalizePath3(inputPath, cwd) {
|
|
2887
|
+
if (inputPath.startsWith("file://")) {
|
|
2888
|
+
return fileURLToPath5(inputPath);
|
|
2889
|
+
}
|
|
2890
|
+
if (isAbsolute6(inputPath)) {
|
|
2891
|
+
return inputPath;
|
|
2892
|
+
}
|
|
2893
|
+
return resolve5(cwd ?? process.cwd(), inputPath);
|
|
2894
|
+
}
|
|
2895
|
+
async function glob(options) {
|
|
2896
|
+
const cwd = options.path ? normalizePath3(options.path, options.projectDir) : options.projectDir;
|
|
2897
|
+
const entries = await globby(options.pattern, {
|
|
2898
|
+
cwd,
|
|
2899
|
+
dot: options.dot ?? false,
|
|
2900
|
+
onlyFiles: options.onlyFiles ?? false,
|
|
2901
|
+
markDirectories: true,
|
|
2902
|
+
gitignore: options.gitignore ?? true,
|
|
2903
|
+
deep: options.maxDepth
|
|
2904
|
+
});
|
|
2905
|
+
entries.sort();
|
|
2906
|
+
const limit = options.limit ?? 500;
|
|
2907
|
+
const truncated = entries.length > limit;
|
|
2908
|
+
const filePaths = truncated ? entries.slice(0, limit) : entries;
|
|
2862
2909
|
return {
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2910
|
+
filePaths,
|
|
2911
|
+
totalFiles: entries.length,
|
|
2912
|
+
truncated
|
|
2866
2913
|
};
|
|
2867
2914
|
}
|
|
2868
2915
|
|
|
@@ -2871,21 +2918,21 @@ function createSearchModule(_ctx) {
|
|
|
2871
2918
|
return { registerSearchRoute, buildSearchMcpServer };
|
|
2872
2919
|
}
|
|
2873
2920
|
function registerSearchRoute(server, projectDir) {
|
|
2874
|
-
server.registry("search/
|
|
2875
|
-
const params =
|
|
2876
|
-
const result = await
|
|
2877
|
-
return
|
|
2878
|
-
});
|
|
2879
|
-
server.registry("search/rg", async (payload) => {
|
|
2880
|
-
const params = rgRequestSchema.parse(payload);
|
|
2881
|
-
const result = await rg({ projectDir, ...params });
|
|
2882
|
-
return rgRespondSchema.parse(result);
|
|
2921
|
+
server.registry("search/grep", async (payload) => {
|
|
2922
|
+
const params = grepRequestSchema.parse(payload);
|
|
2923
|
+
const result = await grep({ projectDir, ...params });
|
|
2924
|
+
return grepRespondSchema.parse(result);
|
|
2883
2925
|
});
|
|
2884
2926
|
server.registry("search/file_outline", async (payload) => {
|
|
2885
2927
|
const params = fileOutlineRequestSchema.parse(payload);
|
|
2886
2928
|
const result = await fileOutline({ projectDir, ...params });
|
|
2887
2929
|
return fileOutlineRespondSchema.parse(result);
|
|
2888
2930
|
});
|
|
2931
|
+
server.registry("search/glob", async (payload) => {
|
|
2932
|
+
const params = globRequestSchema.parse(payload);
|
|
2933
|
+
const result = await glob({ projectDir, ...params });
|
|
2934
|
+
return globRespondSchema.parse(result);
|
|
2935
|
+
});
|
|
2889
2936
|
}
|
|
2890
2937
|
function buildSearchMcpServer(options) {
|
|
2891
2938
|
return {
|
|
@@ -2948,7 +2995,11 @@ function createAskUserModule(ctx, deps) {
|
|
|
2948
2995
|
async function askUser(options) {
|
|
2949
2996
|
const { sessionId } = options;
|
|
2950
2997
|
const askUserId = randomUUID2();
|
|
2951
|
-
const request = {
|
|
2998
|
+
const request = {
|
|
2999
|
+
...options,
|
|
3000
|
+
askUserId,
|
|
3001
|
+
timeoutAt: Date.now() + USER_REQUEST_TIMEOUT_MS
|
|
3002
|
+
};
|
|
2952
3003
|
sendEvent("ask-user-request", request);
|
|
2953
3004
|
const ilinkBridge = deps.ilink.getBridge();
|
|
2954
3005
|
const ilinkActiveSessionId = deps.ilink.getActiveSessionId();
|
|
@@ -2963,13 +3014,13 @@ function createAskUserModule(ctx, deps) {
|
|
|
2963
3014
|
});
|
|
2964
3015
|
}
|
|
2965
3016
|
}
|
|
2966
|
-
return new Promise((
|
|
3017
|
+
return new Promise((resolve9) => {
|
|
2967
3018
|
const timeoutId = setTimeout(() => {
|
|
2968
3019
|
const pending = pendingRequests.get(askUserId);
|
|
2969
3020
|
if (pending) {
|
|
2970
3021
|
pendingRequests.delete(askUserId);
|
|
2971
3022
|
const response = { value: null, reason: "timeout" };
|
|
2972
|
-
|
|
3023
|
+
resolve9(response);
|
|
2973
3024
|
sendEvent("ask-user-response", {
|
|
2974
3025
|
sessionId,
|
|
2975
3026
|
askUserId,
|
|
@@ -2980,7 +3031,7 @@ function createAskUserModule(ctx, deps) {
|
|
|
2980
3031
|
console.warn(`[askUser] timeout fired but no pending request found for ${askUserId}`);
|
|
2981
3032
|
}
|
|
2982
3033
|
}, USER_REQUEST_TIMEOUT_MS);
|
|
2983
|
-
pendingRequests.set(askUserId, { resolve:
|
|
3034
|
+
pendingRequests.set(askUserId, { resolve: resolve9, timeoutId, sessionId, request });
|
|
2984
3035
|
});
|
|
2985
3036
|
}
|
|
2986
3037
|
async function getPendingAskUserRequests({ sessionId }) {
|
|
@@ -3048,8 +3099,8 @@ function createAskUserModule(ctx, deps) {
|
|
|
3048
3099
|
|
|
3049
3100
|
// src/backend/share-to-user.ts
|
|
3050
3101
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3051
|
-
import { join as join14 } from "path";
|
|
3052
|
-
import { fileURLToPath as
|
|
3102
|
+
import { join as join14, relative as relative7, isAbsolute as isAbsolute7 } from "path";
|
|
3103
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
3053
3104
|
import { readFile as readFile5, writeFile } from "fs/promises";
|
|
3054
3105
|
import { existsSync as existsSync6, mkdirSync as mkdirSync6 } from "fs";
|
|
3055
3106
|
import * as mimeTypes3 from "mime-types";
|
|
@@ -3098,23 +3149,29 @@ function createShareToUserModule(ctx, deps) {
|
|
|
3098
3149
|
const { sessionId, type, uri, data, name, mimeType } = options;
|
|
3099
3150
|
const resolvedMimeType = resolveMimeType(name, mimeType);
|
|
3100
3151
|
if (type === "project" && uri) {
|
|
3152
|
+
const session = storage.getSession(sessionId);
|
|
3153
|
+
if (!session) throw new Error(`Session not found: ${sessionId}`);
|
|
3154
|
+
let projectPath = uri.startsWith("file://") ? fileURLToPath6(uri) : uri;
|
|
3155
|
+
if (isAbsolute7(projectPath)) {
|
|
3156
|
+
const rel = relative7(session.cwd, projectPath);
|
|
3157
|
+
if (!rel.startsWith("..") && !isAbsolute7(rel)) {
|
|
3158
|
+
projectPath = rel;
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3101
3161
|
const ilinkBridge2 = deps.ilink.getBridge();
|
|
3102
3162
|
const ilinkActiveSessionId2 = deps.ilink.getActiveSessionId();
|
|
3103
3163
|
if (ilinkBridge2?.isConnected && sessionId === ilinkActiveSessionId2) {
|
|
3104
3164
|
const toUserId = ilinkBridge2.userId;
|
|
3105
3165
|
if (toUserId) {
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
mimeType: resolvedMimeType
|
|
3113
|
-
});
|
|
3114
|
-
}
|
|
3166
|
+
deps.ilink.appendMediaBuffer({
|
|
3167
|
+
filePath: join14(session.cwd, projectPath),
|
|
3168
|
+
name,
|
|
3169
|
+
toUserId,
|
|
3170
|
+
mimeType: resolvedMimeType
|
|
3171
|
+
});
|
|
3115
3172
|
}
|
|
3116
3173
|
}
|
|
3117
|
-
return { name, projectPath
|
|
3174
|
+
return { name, projectPath, mimeType: resolvedMimeType };
|
|
3118
3175
|
}
|
|
3119
3176
|
const shareId = randomUUID3();
|
|
3120
3177
|
const shareDir = storage.sessionShareDir(sessionId);
|
|
@@ -3132,7 +3189,7 @@ function createShareToUserModule(ctx, deps) {
|
|
|
3132
3189
|
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
3133
3190
|
buffer = Buffer.from(await response.arrayBuffer());
|
|
3134
3191
|
} else {
|
|
3135
|
-
const sourcePath = uri.startsWith("file://") ?
|
|
3192
|
+
const sourcePath = uri.startsWith("file://") ? fileURLToPath6(uri) : uri;
|
|
3136
3193
|
buffer = await readFile5(sourcePath);
|
|
3137
3194
|
}
|
|
3138
3195
|
} catch (err) {
|
|
@@ -3224,9 +3281,9 @@ function spawnStdioAgent(options) {
|
|
|
3224
3281
|
proc.stdin.end();
|
|
3225
3282
|
} catch {
|
|
3226
3283
|
}
|
|
3227
|
-
await new Promise((
|
|
3284
|
+
await new Promise((resolve9) => {
|
|
3228
3285
|
if (proc.exitCode !== null) {
|
|
3229
|
-
|
|
3286
|
+
resolve9();
|
|
3230
3287
|
return;
|
|
3231
3288
|
}
|
|
3232
3289
|
let killTimer = null;
|
|
@@ -3234,13 +3291,13 @@ function spawnStdioAgent(options) {
|
|
|
3234
3291
|
if (killTimer) {
|
|
3235
3292
|
clearTimeout(killTimer);
|
|
3236
3293
|
}
|
|
3237
|
-
|
|
3294
|
+
resolve9();
|
|
3238
3295
|
};
|
|
3239
3296
|
proc.once("exit", onExit);
|
|
3240
3297
|
killProcessGroup(proc, "SIGTERM");
|
|
3241
3298
|
killTimer = setTimeout(() => {
|
|
3242
3299
|
killProcessGroup(proc, "SIGKILL");
|
|
3243
|
-
|
|
3300
|
+
resolve9();
|
|
3244
3301
|
}, 2e3);
|
|
3245
3302
|
});
|
|
3246
3303
|
}
|
|
@@ -3356,7 +3413,7 @@ var AgentClientProxy = class {
|
|
|
3356
3413
|
};
|
|
3357
3414
|
|
|
3358
3415
|
// src/agents/acp-client-tools.ts
|
|
3359
|
-
import { resolve as
|
|
3416
|
+
import { resolve as resolve6 } from "path";
|
|
3360
3417
|
import { tool } from "ai";
|
|
3361
3418
|
import { z as z4 } from "zod";
|
|
3362
3419
|
|
|
@@ -3549,7 +3606,7 @@ Always prefer using line/limit to read specific sections, or use the Search MCP'
|
|
|
3549
3606
|
if (!connection) {
|
|
3550
3607
|
throw new Error("ACP connection is not available.");
|
|
3551
3608
|
}
|
|
3552
|
-
const filename =
|
|
3609
|
+
const filename = resolve6(cwd ?? params.cwd, path2);
|
|
3553
3610
|
let title = `ReadFile ${filename}`;
|
|
3554
3611
|
if (line || limit) {
|
|
3555
3612
|
title += `:${line ?? 0}`;
|
|
@@ -3656,7 +3713,7 @@ Always prefer using line/limit to read specific sections, or use the Search MCP'
|
|
|
3656
3713
|
if (!connection) {
|
|
3657
3714
|
throw new Error("ACP connection is not available.");
|
|
3658
3715
|
}
|
|
3659
|
-
const filename =
|
|
3716
|
+
const filename = resolve6(cwd ?? params.cwd, path2);
|
|
3660
3717
|
let title = `WriteFile ${filename}`;
|
|
3661
3718
|
const toolCall = {
|
|
3662
3719
|
toolCallId,
|
|
@@ -3741,7 +3798,7 @@ Use exact string matching for oldText and set replaceAll=true when needed.`,
|
|
|
3741
3798
|
if (!connection) {
|
|
3742
3799
|
throw new Error("ACP connection is not available.");
|
|
3743
3800
|
}
|
|
3744
|
-
const filename =
|
|
3801
|
+
const filename = resolve6(cwd ?? params.cwd, path2);
|
|
3745
3802
|
const title = `EditFile ${filename}`;
|
|
3746
3803
|
const toolCall = {
|
|
3747
3804
|
toolCallId,
|
|
@@ -3921,8 +3978,8 @@ Avoid destructive commands and prefer deterministic, non-interactive commands.`,
|
|
|
3921
3978
|
try {
|
|
3922
3979
|
const waitPromise = terminal.waitForExit();
|
|
3923
3980
|
if (timeoutMs) {
|
|
3924
|
-
const timeoutPromise = new Promise((
|
|
3925
|
-
setTimeout(() =>
|
|
3981
|
+
const timeoutPromise = new Promise((resolve9) => {
|
|
3982
|
+
setTimeout(() => resolve9(null), timeoutMs);
|
|
3926
3983
|
});
|
|
3927
3984
|
const waitResult = await Promise.race([waitPromise, timeoutPromise]);
|
|
3928
3985
|
if (waitResult === null) {
|
|
@@ -4041,6 +4098,208 @@ async function closeACPClientTools(session) {
|
|
|
4041
4098
|
import { createMCPClient } from "@ai-sdk/mcp";
|
|
4042
4099
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4043
4100
|
import { ContentBlockSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
4101
|
+
|
|
4102
|
+
// src/backend/proxy.ts
|
|
4103
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
4104
|
+
import http from "node:http";
|
|
4105
|
+
import https from "node:https";
|
|
4106
|
+
import { Agent as UndiciAgent, EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
|
|
4107
|
+
import { ProxyAgent as NodeProxyAgent } from "proxy-agent";
|
|
4108
|
+
var PROXY_ENV_KEYS = [
|
|
4109
|
+
"HTTP_PROXY",
|
|
4110
|
+
"HTTPS_PROXY",
|
|
4111
|
+
"NO_PROXY",
|
|
4112
|
+
"http_proxy",
|
|
4113
|
+
"https_proxy",
|
|
4114
|
+
"no_proxy"
|
|
4115
|
+
];
|
|
4116
|
+
var currentConfig = { enabled: false };
|
|
4117
|
+
function settingProxyInfoToProxyConfig(input) {
|
|
4118
|
+
if (!input || input.mode === "off") return { enabled: false };
|
|
4119
|
+
const str = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
4120
|
+
return {
|
|
4121
|
+
enabled: true,
|
|
4122
|
+
httpProxy: str(input.httpProxy),
|
|
4123
|
+
httpsProxy: str(input.httpsProxy),
|
|
4124
|
+
noProxy: str(input.noProxy),
|
|
4125
|
+
username: str(input.username),
|
|
4126
|
+
password: str(input.password)
|
|
4127
|
+
};
|
|
4128
|
+
}
|
|
4129
|
+
function normalizeProxyUrl(raw) {
|
|
4130
|
+
if (!raw) return void 0;
|
|
4131
|
+
const trimmed = raw.trim();
|
|
4132
|
+
if (!trimmed) return void 0;
|
|
4133
|
+
let url;
|
|
4134
|
+
try {
|
|
4135
|
+
url = new URL(trimmed);
|
|
4136
|
+
} catch {
|
|
4137
|
+
try {
|
|
4138
|
+
url = new URL(`http://${trimmed}`);
|
|
4139
|
+
} catch {
|
|
4140
|
+
return void 0;
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return void 0;
|
|
4144
|
+
return url.toString().replace(/\/+$/, "");
|
|
4145
|
+
}
|
|
4146
|
+
function withAuth(url, username, password) {
|
|
4147
|
+
if (!username) return url;
|
|
4148
|
+
try {
|
|
4149
|
+
const parsed = new URL(url);
|
|
4150
|
+
parsed.username = username;
|
|
4151
|
+
if (password) parsed.password = password;
|
|
4152
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
4153
|
+
} catch {
|
|
4154
|
+
return url;
|
|
4155
|
+
}
|
|
4156
|
+
}
|
|
4157
|
+
function buildProxyEnv() {
|
|
4158
|
+
const config = currentConfig;
|
|
4159
|
+
if (config.enabled === false) return {};
|
|
4160
|
+
const httpProxy = normalizeProxyUrl(config.httpProxy);
|
|
4161
|
+
const httpsProxy = normalizeProxyUrl(config.httpsProxy ?? config.httpProxy);
|
|
4162
|
+
if (!httpProxy && !httpsProxy) return {};
|
|
4163
|
+
const noProxy = config.noProxy?.trim();
|
|
4164
|
+
const env = {};
|
|
4165
|
+
if (httpProxy) {
|
|
4166
|
+
const httpUrl = withAuth(httpProxy, config.username, config.password);
|
|
4167
|
+
if (httpUrl) {
|
|
4168
|
+
env.HTTP_PROXY = httpUrl;
|
|
4169
|
+
env.http_proxy = httpUrl;
|
|
4170
|
+
}
|
|
4171
|
+
}
|
|
4172
|
+
if (httpsProxy) {
|
|
4173
|
+
const httpsUrl = withAuth(httpsProxy, config.username, config.password);
|
|
4174
|
+
if (httpsUrl) {
|
|
4175
|
+
env.HTTPS_PROXY = httpsUrl;
|
|
4176
|
+
env.https_proxy = httpsUrl;
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
if (noProxy) {
|
|
4180
|
+
env.NO_PROXY = noProxy;
|
|
4181
|
+
env.no_proxy = noProxy;
|
|
4182
|
+
}
|
|
4183
|
+
return env;
|
|
4184
|
+
}
|
|
4185
|
+
function setProcessEnv(env) {
|
|
4186
|
+
for (const key of PROXY_ENV_KEYS) {
|
|
4187
|
+
if (env[key]) {
|
|
4188
|
+
process.env[key] = env[key];
|
|
4189
|
+
} else {
|
|
4190
|
+
delete process.env[key];
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
function resetGlobalDispatchers() {
|
|
4195
|
+
setGlobalDispatcher(new UndiciAgent());
|
|
4196
|
+
http.globalAgent = new http.Agent();
|
|
4197
|
+
https.globalAgent = new https.Agent();
|
|
4198
|
+
}
|
|
4199
|
+
function enableGlobalDispatchers() {
|
|
4200
|
+
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
4201
|
+
http.globalAgent = new NodeProxyAgent();
|
|
4202
|
+
https.globalAgent = new NodeProxyAgent();
|
|
4203
|
+
}
|
|
4204
|
+
function applyProxy(config) {
|
|
4205
|
+
currentConfig = config;
|
|
4206
|
+
if (config.enabled === false) {
|
|
4207
|
+
setProcessEnv({});
|
|
4208
|
+
resetGlobalDispatchers();
|
|
4209
|
+
return;
|
|
4210
|
+
}
|
|
4211
|
+
const env = buildProxyEnv();
|
|
4212
|
+
if (Object.keys(env).length === 0) {
|
|
4213
|
+
setProcessEnv({});
|
|
4214
|
+
resetGlobalDispatchers();
|
|
4215
|
+
return;
|
|
4216
|
+
}
|
|
4217
|
+
setProcessEnv(env);
|
|
4218
|
+
enableGlobalDispatchers();
|
|
4219
|
+
}
|
|
4220
|
+
function detectSystemProxy() {
|
|
4221
|
+
const envHttp = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;
|
|
4222
|
+
if (envHttp) {
|
|
4223
|
+
return {
|
|
4224
|
+
enabled: true,
|
|
4225
|
+
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy || void 0,
|
|
4226
|
+
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy || void 0,
|
|
4227
|
+
noProxy: process.env.NO_PROXY || process.env.no_proxy || void 0
|
|
4228
|
+
};
|
|
4229
|
+
}
|
|
4230
|
+
try {
|
|
4231
|
+
if (process.platform === "darwin") {
|
|
4232
|
+
const stdout = execFileSync2("scutil", ["--proxy"], { timeout: 3e3 }).toString();
|
|
4233
|
+
return parseScutilProxy(stdout);
|
|
4234
|
+
}
|
|
4235
|
+
if (process.platform === "win32") {
|
|
4236
|
+
const stdout = execFileSync2("netsh", ["winhttp", "show", "proxy"], {
|
|
4237
|
+
timeout: 3e3
|
|
4238
|
+
}).toString();
|
|
4239
|
+
return parseNetshProxy(stdout);
|
|
4240
|
+
}
|
|
4241
|
+
} catch {
|
|
4242
|
+
}
|
|
4243
|
+
return { enabled: false };
|
|
4244
|
+
}
|
|
4245
|
+
function parseScutilProxy(stdout) {
|
|
4246
|
+
const get = (key) => {
|
|
4247
|
+
const m = stdout.match(new RegExp(`^\\s*${key}\\s*:\\s*(.+)$`, "m"));
|
|
4248
|
+
return m ? m[1].trim() : void 0;
|
|
4249
|
+
};
|
|
4250
|
+
const host = (key) => {
|
|
4251
|
+
const value = get(key);
|
|
4252
|
+
if (!value || value === "<null>") return void 0;
|
|
4253
|
+
return value.replace(/^"|"$/g, "");
|
|
4254
|
+
};
|
|
4255
|
+
const port2 = (key) => {
|
|
4256
|
+
const value = get(key);
|
|
4257
|
+
return value && value !== "0" ? value : void 0;
|
|
4258
|
+
};
|
|
4259
|
+
const build = (enableKey, hostKey, portKey) => {
|
|
4260
|
+
if (get(enableKey) !== "1") return void 0;
|
|
4261
|
+
const h = host(hostKey);
|
|
4262
|
+
if (!h) return void 0;
|
|
4263
|
+
const p = port2(portKey);
|
|
4264
|
+
let proxyUrl = `http://${h}`;
|
|
4265
|
+
if (p) {
|
|
4266
|
+
proxyUrl += `:${p}`;
|
|
4267
|
+
}
|
|
4268
|
+
return proxyUrl;
|
|
4269
|
+
};
|
|
4270
|
+
const httpProxy = build("HTTPEnable", "HTTPProxy", "HTTPPort");
|
|
4271
|
+
const httpsProxy = build("HTTPSEnable", "HTTPSProxy", "HTTPSPort");
|
|
4272
|
+
if (!httpProxy && !httpsProxy) return { enabled: false };
|
|
4273
|
+
return { enabled: true, httpProxy, httpsProxy };
|
|
4274
|
+
}
|
|
4275
|
+
function parseNetshProxy(stdout) {
|
|
4276
|
+
const match = stdout.match(/Proxy\s*Server\(s\)\s*:\s*(.+)$/m);
|
|
4277
|
+
if (!match) return { enabled: false };
|
|
4278
|
+
const raw = match[1].trim();
|
|
4279
|
+
if (!raw || raw === "<none>") return { enabled: false };
|
|
4280
|
+
let httpProxy;
|
|
4281
|
+
let httpsProxy;
|
|
4282
|
+
for (const part of raw.split(";")) {
|
|
4283
|
+
const trimmed = part.trim();
|
|
4284
|
+
if (!trimmed) continue;
|
|
4285
|
+
const eq = trimmed.indexOf("=");
|
|
4286
|
+
if (eq === -1) {
|
|
4287
|
+
httpProxy = `http://${trimmed}`;
|
|
4288
|
+
httpsProxy = `http://${trimmed}`;
|
|
4289
|
+
} else {
|
|
4290
|
+
const scheme = trimmed.slice(0, eq).trim().toLowerCase();
|
|
4291
|
+
const value = trimmed.slice(eq + 1).trim();
|
|
4292
|
+
if (scheme === "http") httpProxy = `http://${value}`;
|
|
4293
|
+
else if (scheme === "https") httpsProxy = `http://${value}`;
|
|
4294
|
+
}
|
|
4295
|
+
}
|
|
4296
|
+
const bypass = stdout.match(/Bypass\s*List\s*:\s*(.+)$/m);
|
|
4297
|
+
const noProxy = bypass ? bypass[1].trim().replace(/<local>/g, "localhost,127.0.0.1") : void 0;
|
|
4298
|
+
if (!httpProxy && !httpsProxy) return { enabled: false };
|
|
4299
|
+
return { enabled: true, httpProxy, httpsProxy, noProxy };
|
|
4300
|
+
}
|
|
4301
|
+
|
|
4302
|
+
// src/agents/mcp-tools.ts
|
|
4044
4303
|
function sanitizeName(input) {
|
|
4045
4304
|
return input.trim().toLowerCase().replace(/[^a-z0-9_]+/g, "_").replace(/^_+|_+$/g, "");
|
|
4046
4305
|
}
|
|
@@ -4060,7 +4319,7 @@ function toEnvRecord(env) {
|
|
|
4060
4319
|
}
|
|
4061
4320
|
function inferToolKind(name) {
|
|
4062
4321
|
const normalized = name.toLowerCase();
|
|
4063
|
-
if (normalized.includes("read") || normalized.includes("list") || normalized.includes("search")) {
|
|
4322
|
+
if (normalized.includes("read") || normalized.includes("list") || normalized.includes("search") || normalized.includes("grep") || normalized.includes("glob")) {
|
|
4064
4323
|
return "read";
|
|
4065
4324
|
}
|
|
4066
4325
|
if (normalized.includes("write") || normalized.includes("edit") || normalized.includes("update")) {
|
|
@@ -4090,7 +4349,10 @@ async function createClient(server, cwd) {
|
|
|
4090
4349
|
transport: new StdioClientTransport({
|
|
4091
4350
|
command: server.command,
|
|
4092
4351
|
args: server.args,
|
|
4093
|
-
env:
|
|
4352
|
+
env: {
|
|
4353
|
+
...buildProxyEnv(),
|
|
4354
|
+
...toEnvRecord(server.env)
|
|
4355
|
+
},
|
|
4094
4356
|
cwd
|
|
4095
4357
|
}),
|
|
4096
4358
|
clientName: "fello-openai-compatible-agent",
|
|
@@ -4338,7 +4600,7 @@ Working style:
|
|
|
4338
4600
|
File reading & editing strategy:
|
|
4339
4601
|
- ReadFile will REJECT full reads of files over 100KB. Use line/limit to read specific sections, or set force=true if you genuinely need the full file content (rare).
|
|
4340
4602
|
- Use the Search MCP's file_outline tool to preview file structure before reading (function/class/interface names with line ranges). Supports TypeScript, JavaScript, TSX, Python, Go, C, C++, Swift, Kotlin, Dart.
|
|
4341
|
-
- Use the Search MCP's
|
|
4603
|
+
- Use the Search MCP's grep tool (structured pattern search) or glob tool (file finder) to search file contents instead of reading entire files.
|
|
4342
4604
|
- EditFile uses exact string matching (StrReplace style). Use unique surrounding code context in oldText to make matches precise. Set replaceAll=true when you intend to replace all occurrences.
|
|
4343
4605
|
- You do NOT need to re-read a file after editing it \u2014 the changes are already saved.
|
|
4344
4606
|
|
|
@@ -4362,7 +4624,7 @@ import { tool as tool3 } from "ai";
|
|
|
4362
4624
|
import { z as z6 } from "zod";
|
|
4363
4625
|
|
|
4364
4626
|
// src/agents/image-tools.ts
|
|
4365
|
-
import { resolve as
|
|
4627
|
+
import { resolve as resolve7 } from "path";
|
|
4366
4628
|
import { readFile as readFile6 } from "fs/promises";
|
|
4367
4629
|
import mime from "mime-types";
|
|
4368
4630
|
import { tool as tool2, generateText } from "ai";
|
|
@@ -4399,7 +4661,7 @@ Provide a specific query describing what you want to know about the image \u2014
|
|
|
4399
4661
|
});
|
|
4400
4662
|
}
|
|
4401
4663
|
try {
|
|
4402
|
-
const absPath =
|
|
4664
|
+
const absPath = resolve7(params.cwd, imgPath);
|
|
4403
4665
|
const buffer = await readFile6(absPath);
|
|
4404
4666
|
const base64 = buffer.toString("base64");
|
|
4405
4667
|
const mimeType = mime.lookup(absPath) || "image/png";
|
|
@@ -4754,7 +5016,6 @@ function buildWorkspaceSystemPrompt(cwd, additionalDirectories) {
|
|
|
4754
5016
|
const workspacePrompt = `Current session working directory (cwd): ${cwd}.${extras} Use this as the default base path for relative paths.`;
|
|
4755
5017
|
const now = /* @__PURE__ */ new Date();
|
|
4756
5018
|
const dateStr = now.toLocaleDateString("en-CA");
|
|
4757
|
-
const timeStr = now.toLocaleTimeString("en-US", { hour12: false });
|
|
4758
5019
|
const weekday = now.toLocaleDateString("en-US", { weekday: "long" });
|
|
4759
5020
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
4760
5021
|
const timezoneOffset = -now.getTimezoneOffset();
|
|
@@ -4763,7 +5024,7 @@ function buildWorkspaceSystemPrompt(cwd, additionalDirectories) {
|
|
|
4763
5024
|
const offsetMinutes = String(Math.abs(timezoneOffset) % 60).padStart(2, "0");
|
|
4764
5025
|
const utcOffset = `UTC${offsetSign}${offsetHours}:${offsetMinutes}`;
|
|
4765
5026
|
const platform = process.platform;
|
|
4766
|
-
const envContext = `Date
|
|
5027
|
+
const envContext = `Date: ${dateStr} (${weekday})
|
|
4767
5028
|
Timezone: ${timezone} (${utcOffset})
|
|
4768
5029
|
Platform: ${platform}`;
|
|
4769
5030
|
let prompt = `${BASE_SYSTEM_PROMPT}
|
|
@@ -5508,14 +5769,14 @@ function spawnOpenaiCompatibleApiAgent(options) {
|
|
|
5508
5769
|
}
|
|
5509
5770
|
|
|
5510
5771
|
// src/backend/agent/agent-terminal-manager.ts
|
|
5511
|
-
import { spawn as spawn2, execFileSync as
|
|
5772
|
+
import { spawn as spawn2, execFileSync as execFileSync3 } from "child_process";
|
|
5512
5773
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
5513
5774
|
function detectTerminalOutputEncoding() {
|
|
5514
5775
|
if (process.platform !== "win32") {
|
|
5515
5776
|
return "utf-8";
|
|
5516
5777
|
}
|
|
5517
5778
|
try {
|
|
5518
|
-
const output =
|
|
5779
|
+
const output = execFileSync3("cmd", ["/d", "/s", "/c", "chcp"], {
|
|
5519
5780
|
encoding: "buffer",
|
|
5520
5781
|
windowsHide: true
|
|
5521
5782
|
});
|
|
@@ -5603,11 +5864,11 @@ var AgentTerminalManager = class {
|
|
|
5603
5864
|
if (terminal.isFinished) {
|
|
5604
5865
|
return { exitCode: terminal.exitCode, signal: terminal.signal };
|
|
5605
5866
|
}
|
|
5606
|
-
return new Promise((
|
|
5867
|
+
return new Promise((resolve9) => {
|
|
5607
5868
|
const originalOnExit = terminal.onExit;
|
|
5608
5869
|
terminal.onExit = (code, signal) => {
|
|
5609
5870
|
originalOnExit(code, signal);
|
|
5610
|
-
|
|
5871
|
+
resolve9({ exitCode: code, signal });
|
|
5611
5872
|
};
|
|
5612
5873
|
});
|
|
5613
5874
|
}
|
|
@@ -5775,7 +6036,14 @@ var ACPBridge = class {
|
|
|
5775
6036
|
}
|
|
5776
6037
|
async connect() {
|
|
5777
6038
|
const acpId = this.id;
|
|
5778
|
-
const proc = this.options.agentInfo.type === "stdio" ? spawnStdioAgent({
|
|
6039
|
+
const proc = this.options.agentInfo.type === "stdio" ? spawnStdioAgent({
|
|
6040
|
+
...this.options.agentInfo,
|
|
6041
|
+
cwd: this.options.cwd,
|
|
6042
|
+
env: {
|
|
6043
|
+
...this.options.agentEnv,
|
|
6044
|
+
...this.options.agentInfo.env
|
|
6045
|
+
}
|
|
6046
|
+
}) : this.options.agentInfo.provider === "openai-compatible" ? spawnOpenaiCompatibleApiAgent(this.options.agentInfo) : (() => {
|
|
5779
6047
|
throw new Error(`Unsupported api provider: ${this.options.agentInfo.provider}`);
|
|
5780
6048
|
})();
|
|
5781
6049
|
this.process = proc;
|
|
@@ -5816,7 +6084,7 @@ var ACPBridge = class {
|
|
|
5816
6084
|
const applyConfigOptions = this.applyConfigOptions.bind(this);
|
|
5817
6085
|
const terminalManager = this.terminalManager;
|
|
5818
6086
|
const sessionsCwdMap = this._sessionsCwdMap;
|
|
5819
|
-
|
|
6087
|
+
let clientApp = client({ name: "Fello" }).onRequest(methods3.client.session.requestPermission, (ctx) => {
|
|
5820
6088
|
return onPermission(ctx.params);
|
|
5821
6089
|
}).onNotification(methods3.client.session.update, (ctx) => {
|
|
5822
6090
|
const params = ctx.params;
|
|
@@ -5859,25 +6127,12 @@ var ACPBridge = class {
|
|
|
5859
6127
|
}).onRequest(methods3.client.terminal.release, (ctx) => {
|
|
5860
6128
|
terminalManager.release(ctx.params.terminalId);
|
|
5861
6129
|
return {};
|
|
5862
|
-
})
|
|
5863
|
-
|
|
5864
|
-
(
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
).onNotification(
|
|
5869
|
-
"_kiro.dev/commands/available",
|
|
5870
|
-
(p) => p,
|
|
5871
|
-
(ctx) => {
|
|
5872
|
-
onExtNotification("_kiro.dev/commands/available", ctx.params);
|
|
5873
|
-
}
|
|
5874
|
-
).onNotification(
|
|
5875
|
-
"_kiro.dev/subagent/list_update",
|
|
5876
|
-
(p) => p,
|
|
5877
|
-
(ctx) => {
|
|
5878
|
-
onExtNotification("_kiro.dev/subagent/list_update", ctx.params);
|
|
5879
|
-
}
|
|
5880
|
-
);
|
|
6130
|
+
});
|
|
6131
|
+
for (const spec of this.options.extNotificationSpecs) {
|
|
6132
|
+
clientApp = clientApp.onNotification(spec.method, spec.parse, (ctx) => {
|
|
6133
|
+
onExtNotification(spec.method, ctx.params);
|
|
6134
|
+
});
|
|
6135
|
+
}
|
|
5881
6136
|
this.connection = clientApp.connect(stream);
|
|
5882
6137
|
const initResult = await this.connection.agent.request(methods3.agent.initialize, {
|
|
5883
6138
|
protocolVersion: PROTOCOL_VERSION2,
|
|
@@ -6103,7 +6358,9 @@ var ACPBridge = class {
|
|
|
6103
6358
|
}
|
|
6104
6359
|
async sendPrompt(params) {
|
|
6105
6360
|
if (!this.connection) throw new Error("Not connected");
|
|
6106
|
-
|
|
6361
|
+
const res = await this.connection.agent.request(methods3.agent.session.prompt, params);
|
|
6362
|
+
this.options.onPromptCompleted?.(params.sessionId, res);
|
|
6363
|
+
return res;
|
|
6107
6364
|
}
|
|
6108
6365
|
async cancel(params) {
|
|
6109
6366
|
if (!this.connection) return;
|
|
@@ -6139,6 +6396,378 @@ var ACPBridge = class {
|
|
|
6139
6396
|
}
|
|
6140
6397
|
};
|
|
6141
6398
|
|
|
6399
|
+
// src/backend/acp-adapters/acp-adapter.ts
|
|
6400
|
+
var AcpAdapter = class {
|
|
6401
|
+
/** Ext notification specs to register on the ACP client. */
|
|
6402
|
+
extNotificationSpecs = [];
|
|
6403
|
+
/**
|
|
6404
|
+
* Process an incoming notification.
|
|
6405
|
+
* - Return null to drop.
|
|
6406
|
+
* - Return [notification] to pass through (possibly transformed).
|
|
6407
|
+
* - Return [notification, ...synthetic] to pass through AND produce
|
|
6408
|
+
* additional notifications.
|
|
6409
|
+
*
|
|
6410
|
+
* Results go through the REST of the pipeline (title check, broadcast,
|
|
6411
|
+
* storage) — NOT through preprocessNotification again, so adapters
|
|
6412
|
+
* can safely inspect _meta fields without recursion risk. The original
|
|
6413
|
+
* notification (if included in results) is stored, which preserves
|
|
6414
|
+
* _meta for replay/state-rebuild.
|
|
6415
|
+
*/
|
|
6416
|
+
preprocessNotification(notification, _currentSessionId, _agentId) {
|
|
6417
|
+
return [notification];
|
|
6418
|
+
}
|
|
6419
|
+
handleExtNotification(_method, _params, _currentSessionId, _agentId) {
|
|
6420
|
+
return [];
|
|
6421
|
+
}
|
|
6422
|
+
/**
|
|
6423
|
+
* Agent process env vars to inject when spawning the agent. Protocol-
|
|
6424
|
+
* specific environment needed by the agent process (e.g.
|
|
6425
|
+
* CODEBUDDY_DEFER_TOOL_LOADING for CodeBuddy). Aggregated by
|
|
6426
|
+
* adapters.ts and applied by ACPBridge when spawning a stdio agent;
|
|
6427
|
+
* agent-specific agentInfo.env still takes precedence.
|
|
6428
|
+
*/
|
|
6429
|
+
getAgentEnv() {
|
|
6430
|
+
return {};
|
|
6431
|
+
}
|
|
6432
|
+
/**
|
|
6433
|
+
* Called by the bridge when a prompt round completes, with the full
|
|
6434
|
+
* PromptResponse in hand. Adapters that do turn-boundary / replay detection
|
|
6435
|
+
* override this to extract the agent's own protocol-clock timestamp and
|
|
6436
|
+
* freeze the boundary. Default no-op — only protocol-specific adapters
|
|
6437
|
+
* (e.g. CodeBuddy, which stamps PromptResponse._meta with
|
|
6438
|
+
* codebuddy.ai/requestId + timestamp) need it; generic adapters have no
|
|
6439
|
+
* protocol timestamp to work from.
|
|
6440
|
+
*/
|
|
6441
|
+
handlePromptCompleted(_sessionId, _res) {
|
|
6442
|
+
}
|
|
6443
|
+
// ── State lifecycle (default no-ops) ───────────────────────────────
|
|
6444
|
+
rekey(_oldKey, _newKey) {
|
|
6445
|
+
}
|
|
6446
|
+
cleanup(_sessionKey) {
|
|
6447
|
+
}
|
|
6448
|
+
clearAll() {
|
|
6449
|
+
}
|
|
6450
|
+
};
|
|
6451
|
+
|
|
6452
|
+
// src/backend/acp-adapters/codebuddy-adapter.ts
|
|
6453
|
+
var CODEBUDDY_STATUS_MAP = {
|
|
6454
|
+
running: "in_progress",
|
|
6455
|
+
completed: "completed",
|
|
6456
|
+
idle: "in_progress",
|
|
6457
|
+
pending: "pending",
|
|
6458
|
+
failed: "failed"
|
|
6459
|
+
};
|
|
6460
|
+
var CodebuddyAdapter = class extends AcpAdapter {
|
|
6461
|
+
stateMap = /* @__PURE__ */ new Map();
|
|
6462
|
+
/**
|
|
6463
|
+
* Per-session turn-boundary timestamp (epoch ms, from the agent's own
|
|
6464
|
+
* protocol clock). Frozen when a prompt completes (via handlePromptCompleted),
|
|
6465
|
+
* so content chunks emitted afterwards with an earlier protocol timestamp
|
|
6466
|
+
* are previous-turn replays. Only CodeBuddy stamps PromptResponse._meta
|
|
6467
|
+
* with a protocol timestamp, so this stays here rather than in the base.
|
|
6468
|
+
*/
|
|
6469
|
+
turnBoundaryTs = /* @__PURE__ */ new Map();
|
|
6470
|
+
/**
|
|
6471
|
+
* CodeBuddy spawn env.
|
|
6472
|
+
*/
|
|
6473
|
+
getAgentEnv() {
|
|
6474
|
+
return {
|
|
6475
|
+
CODEBUDDY_DEFER_TOOL_LOADING: "0",
|
|
6476
|
+
CODEBUDDY_DISABLE_AUTO_MEMORY: "1"
|
|
6477
|
+
};
|
|
6478
|
+
}
|
|
6479
|
+
/**
|
|
6480
|
+
* Freeze the turn-boundary on prompt completion. Only CodeBuddy stamps the
|
|
6481
|
+
* PromptResponse._meta with codebuddy.ai/requestId + a protocol timestamp,
|
|
6482
|
+
* so this stays here rather than in the generic bridge — the agent's own
|
|
6483
|
+
* clock is the boundary used to drop replayed prior-turn chunks (avoids
|
|
6484
|
+
* timezone / clock-skew issues that wall-clock Date.now() would introduce).
|
|
6485
|
+
*/
|
|
6486
|
+
handlePromptCompleted(sessionId, res) {
|
|
6487
|
+
const meta = res._meta;
|
|
6488
|
+
if (meta && typeof meta["codebuddy.ai/requestId"] === "string") {
|
|
6489
|
+
const ts = Date.parse(typeof meta["timestamp"] === "string" ? meta["timestamp"] : "");
|
|
6490
|
+
if (!isNaN(ts)) this.turnBoundaryTs.set(sessionId, ts);
|
|
6491
|
+
}
|
|
6492
|
+
}
|
|
6493
|
+
/**
|
|
6494
|
+
* One unified hook for all notification processing:
|
|
6495
|
+
*
|
|
6496
|
+
* 1. Replay detection — the adapter freezes a turn-boundary timestamp in
|
|
6497
|
+
* handlePromptCompleted() when a prompt completes (using the agent's own
|
|
6498
|
+
* protocol clock). Drop agent_message_chunk / agent_thought_chunk whose
|
|
6499
|
+
* _meta.timestamp is earlier than that boundary: CodeBuddy re-broadcasts
|
|
6500
|
+
* the previous turn's messages when a new prompt begins, and those
|
|
6501
|
+
* re-emitted chunks carry the previous turn's (earlier) timestamps. Only
|
|
6502
|
+
* applies to chunks that carry codebuddy.ai/requestId.
|
|
6503
|
+
* 2. memberEvent chunk routing — rewrite notification.sessionId from
|
|
6504
|
+
* parent to member sessionId (CodeBuddy stamps all member chunks
|
|
6505
|
+
* with the parent session).
|
|
6506
|
+
* 3. Drop teammate-directed user_message_chunks (task assignments from
|
|
6507
|
+
* team-lead to members, wrapped in <teammate-message>).
|
|
6508
|
+
* 4. teamUpdate lifecycle — convert team_created / member_status_change /
|
|
6509
|
+
* team_deleted into AddonSessionUpdate broadcasts via _meta.fello.update.
|
|
6510
|
+
*
|
|
6511
|
+
* Returns null to drop, [notification] to pass through, or
|
|
6512
|
+
* [notification, ...synthetic] to pass through + produce additional.
|
|
6513
|
+
* Results go through the REST of the pipeline (not this method again).
|
|
6514
|
+
*/
|
|
6515
|
+
preprocessNotification(notification, currentSessionId, agentId) {
|
|
6516
|
+
const meta = notification.update?._meta;
|
|
6517
|
+
const sessionUpdate = notification.update?.sessionUpdate;
|
|
6518
|
+
const requestId = meta?.["codebuddy.ai/requestId"];
|
|
6519
|
+
const metaTimestamp = meta?.["timestamp"];
|
|
6520
|
+
if (typeof requestId === "string" && typeof metaTimestamp === "string" && (sessionUpdate === "agent_message_chunk" || sessionUpdate === "agent_thought_chunk")) {
|
|
6521
|
+
const ts = Date.parse(metaTimestamp);
|
|
6522
|
+
if (!isNaN(ts)) {
|
|
6523
|
+
const boundary = this.turnBoundaryTs.get(currentSessionId);
|
|
6524
|
+
if (boundary !== void 0 && ts < boundary) {
|
|
6525
|
+
return null;
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
const memberEvent = meta?.["codebuddy.ai/memberEvent"];
|
|
6530
|
+
if (sessionUpdate === "user_message_chunk" && typeof memberEvent === "string") {
|
|
6531
|
+
return null;
|
|
6532
|
+
}
|
|
6533
|
+
let result = notification;
|
|
6534
|
+
if (typeof memberEvent === "string") {
|
|
6535
|
+
const state = this.stateMap.get(currentSessionId);
|
|
6536
|
+
const memberSessionId = state?.members.get(memberEvent)?.sessionId;
|
|
6537
|
+
if (memberSessionId && notification.sessionId !== memberSessionId) {
|
|
6538
|
+
result = { ...notification, sessionId: memberSessionId };
|
|
6539
|
+
}
|
|
6540
|
+
}
|
|
6541
|
+
const teamUpdate = meta?.["codebuddy.ai/teamUpdate"];
|
|
6542
|
+
if (teamUpdate && typeof teamUpdate === "object") {
|
|
6543
|
+
const synthetic = this.processTeamUpdate(
|
|
6544
|
+
teamUpdate,
|
|
6545
|
+
currentSessionId,
|
|
6546
|
+
agentId
|
|
6547
|
+
);
|
|
6548
|
+
return synthetic.length > 0 ? [result, ...synthetic] : [result];
|
|
6549
|
+
}
|
|
6550
|
+
return [result];
|
|
6551
|
+
}
|
|
6552
|
+
// ── Team update processing ─────────────────────────────────────────
|
|
6553
|
+
/**
|
|
6554
|
+
* Process a codebuddy.ai/teamUpdate event. Updates the cached team
|
|
6555
|
+
* state and produces synthetic subagent_update notifications.
|
|
6556
|
+
*
|
|
6557
|
+
* - team_created → cache teamName as activeTeamName (no notifications)
|
|
6558
|
+
* - member_status_change → resolve each member's teamName via event-level
|
|
6559
|
+
* teamName / existing member's teamName / activeTeamName, then produce
|
|
6560
|
+
* a subagent_update notification per member
|
|
6561
|
+
* - team_deleted → mark still-active members of THAT team as `failed`
|
|
6562
|
+
* (preserving completed/failed), then produce a notification per active
|
|
6563
|
+
* member. Only removes that team's members from the cache.
|
|
6564
|
+
* - team_idle / others → no-op
|
|
6565
|
+
*/
|
|
6566
|
+
processTeamUpdate(teamUpdate, currentSessionId, agentId) {
|
|
6567
|
+
const type = typeof teamUpdate.type === "string" ? teamUpdate.type : "";
|
|
6568
|
+
const eventTeamName = typeof teamUpdate.teamName === "string" ? teamUpdate.teamName : null;
|
|
6569
|
+
const getOrCreateState = () => {
|
|
6570
|
+
let s = this.stateMap.get(currentSessionId);
|
|
6571
|
+
if (!s) {
|
|
6572
|
+
s = { members: /* @__PURE__ */ new Map(), activeTeamName: null };
|
|
6573
|
+
this.stateMap.set(currentSessionId, s);
|
|
6574
|
+
}
|
|
6575
|
+
return s;
|
|
6576
|
+
};
|
|
6577
|
+
const makeSubagentUpdate = (memberSessionId, memberName, prompt, status) => {
|
|
6578
|
+
const update = {
|
|
6579
|
+
sessionUpdate: "subagent_update",
|
|
6580
|
+
sessionId: memberSessionId,
|
|
6581
|
+
...memberName !== void 0 && { name: memberName },
|
|
6582
|
+
...prompt !== void 0 && { prompt },
|
|
6583
|
+
status
|
|
6584
|
+
};
|
|
6585
|
+
return {
|
|
6586
|
+
sessionId: currentSessionId.replace(`${agentId}:`, ""),
|
|
6587
|
+
update: {
|
|
6588
|
+
sessionUpdate: "session_info_update",
|
|
6589
|
+
_meta: { fello: { update } }
|
|
6590
|
+
}
|
|
6591
|
+
};
|
|
6592
|
+
};
|
|
6593
|
+
if (type === "team_created") {
|
|
6594
|
+
const state = getOrCreateState();
|
|
6595
|
+
if (eventTeamName) state.activeTeamName = eventTeamName;
|
|
6596
|
+
return [];
|
|
6597
|
+
}
|
|
6598
|
+
if (type === "team_deleted") {
|
|
6599
|
+
const state = this.stateMap.get(currentSessionId);
|
|
6600
|
+
if (!state || !eventTeamName) return [];
|
|
6601
|
+
const results = [];
|
|
6602
|
+
for (const [memberName, member] of state.members) {
|
|
6603
|
+
if (member.teamName !== eventTeamName) continue;
|
|
6604
|
+
if (member.status !== "completed" && member.status !== "failed") {
|
|
6605
|
+
results.push(makeSubagentUpdate(member.sessionId, void 0, void 0, "failed"));
|
|
6606
|
+
}
|
|
6607
|
+
state.members.delete(memberName);
|
|
6608
|
+
}
|
|
6609
|
+
if (state.activeTeamName === eventTeamName) {
|
|
6610
|
+
state.activeTeamName = null;
|
|
6611
|
+
}
|
|
6612
|
+
return results;
|
|
6613
|
+
}
|
|
6614
|
+
if (type === "member_status_change") {
|
|
6615
|
+
const state = getOrCreateState();
|
|
6616
|
+
const members = Array.isArray(teamUpdate.members) ? teamUpdate.members : [];
|
|
6617
|
+
const results = [];
|
|
6618
|
+
for (const member of members) {
|
|
6619
|
+
if (!member || typeof member !== "object") continue;
|
|
6620
|
+
const m = member;
|
|
6621
|
+
const memberName = typeof m.name === "string" ? m.name : null;
|
|
6622
|
+
const memberSessionId = typeof m.sessionId === "string" ? m.sessionId : null;
|
|
6623
|
+
if (!memberName || !memberSessionId) continue;
|
|
6624
|
+
const status = typeof m.status === "string" ? CODEBUDDY_STATUS_MAP[m.status] ?? "in_progress" : "in_progress";
|
|
6625
|
+
const existing = state.members.get(memberName);
|
|
6626
|
+
const resolvedTeamName = eventTeamName ?? existing?.teamName ?? state.activeTeamName ?? "";
|
|
6627
|
+
state.members.set(memberName, {
|
|
6628
|
+
sessionId: memberSessionId,
|
|
6629
|
+
status,
|
|
6630
|
+
teamName: resolvedTeamName
|
|
6631
|
+
});
|
|
6632
|
+
const prompt = typeof m.description === "string" ? m.description : void 0;
|
|
6633
|
+
results.push(makeSubagentUpdate(memberSessionId, memberName, prompt, status));
|
|
6634
|
+
}
|
|
6635
|
+
return results;
|
|
6636
|
+
}
|
|
6637
|
+
return [];
|
|
6638
|
+
}
|
|
6639
|
+
// ── State lifecycle (mirror bridge-connect) ────────────────────────
|
|
6640
|
+
rekey(oldKey, newKey) {
|
|
6641
|
+
const state = this.stateMap.get(oldKey);
|
|
6642
|
+
if (state) {
|
|
6643
|
+
this.stateMap.delete(oldKey);
|
|
6644
|
+
this.stateMap.set(newKey, state);
|
|
6645
|
+
}
|
|
6646
|
+
const boundary = this.turnBoundaryTs.get(oldKey);
|
|
6647
|
+
if (boundary !== void 0) {
|
|
6648
|
+
this.turnBoundaryTs.delete(oldKey);
|
|
6649
|
+
this.turnBoundaryTs.set(newKey, boundary);
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
cleanup(sessionKey) {
|
|
6653
|
+
this.stateMap.delete(sessionKey);
|
|
6654
|
+
this.turnBoundaryTs.delete(sessionKey);
|
|
6655
|
+
}
|
|
6656
|
+
clearAll() {
|
|
6657
|
+
this.stateMap.clear();
|
|
6658
|
+
this.turnBoundaryTs.clear();
|
|
6659
|
+
}
|
|
6660
|
+
};
|
|
6661
|
+
|
|
6662
|
+
// src/backend/acp-adapters/kiro-adapter.ts
|
|
6663
|
+
var KIRO_STATUS_MAP = {
|
|
6664
|
+
pending: "pending",
|
|
6665
|
+
working: "in_progress",
|
|
6666
|
+
terminated: "completed",
|
|
6667
|
+
failed: "failed"
|
|
6668
|
+
};
|
|
6669
|
+
var parseMetadata = (p) => p;
|
|
6670
|
+
var parseCommandsAvailable = (p) => p;
|
|
6671
|
+
var parseSubagentList = (p) => p;
|
|
6672
|
+
var KiroAdapter = class extends AcpAdapter {
|
|
6673
|
+
/** Ext notification specs declared here, registered by ACPBridge. */
|
|
6674
|
+
extNotificationSpecs = [
|
|
6675
|
+
{ method: "_kiro.dev/metadata", parse: parseMetadata },
|
|
6676
|
+
{ method: "_kiro.dev/commands/available", parse: parseCommandsAvailable },
|
|
6677
|
+
{ method: "_kiro.dev/subagent/list_update", parse: parseSubagentList }
|
|
6678
|
+
];
|
|
6679
|
+
/**
|
|
6680
|
+
* Translate a Kiro ext notification into synthetic SessionNotification(s).
|
|
6681
|
+
* Returns an empty array if the method is unrecognized.
|
|
6682
|
+
*/
|
|
6683
|
+
handleExtNotification(method, params, currentSessionId, agentId) {
|
|
6684
|
+
switch (method) {
|
|
6685
|
+
case "_kiro.dev/metadata":
|
|
6686
|
+
return this.handleMetadata(params, currentSessionId, agentId);
|
|
6687
|
+
case "_kiro.dev/commands/available":
|
|
6688
|
+
return this.handleCommandsAvailable(params, currentSessionId, agentId);
|
|
6689
|
+
case "_kiro.dev/subagent/list_update":
|
|
6690
|
+
return this.handleSubagentListUpdate(params, currentSessionId, agentId);
|
|
6691
|
+
default:
|
|
6692
|
+
return [];
|
|
6693
|
+
}
|
|
6694
|
+
}
|
|
6695
|
+
// ── Handlers ──────────────────────────────────────────────────────
|
|
6696
|
+
handleMetadata(params, currentSessionId, agentId) {
|
|
6697
|
+
if (typeof params === "object" && params && "sessionId" in params && typeof params.sessionId === "string" && "contextUsagePercentage" in params && typeof params.contextUsagePercentage === "number" && currentSessionId === `${agentId}:${params.sessionId}`) {
|
|
6698
|
+
return [
|
|
6699
|
+
{
|
|
6700
|
+
sessionId: params.sessionId,
|
|
6701
|
+
update: {
|
|
6702
|
+
sessionUpdate: "usage_update",
|
|
6703
|
+
used: params.contextUsagePercentage / 100,
|
|
6704
|
+
size: 1
|
|
6705
|
+
}
|
|
6706
|
+
}
|
|
6707
|
+
];
|
|
6708
|
+
}
|
|
6709
|
+
return [];
|
|
6710
|
+
}
|
|
6711
|
+
handleCommandsAvailable(params, currentSessionId, agentId) {
|
|
6712
|
+
if (typeof params === "object" && params && "sessionId" in params && typeof params.sessionId === "string" && "commands" in params && Array.isArray(params.commands) && currentSessionId === `${agentId}:${params.sessionId}`) {
|
|
6713
|
+
const commands = [];
|
|
6714
|
+
for (const item of params.commands) {
|
|
6715
|
+
if (typeof item === "object" && item && "name" in item && typeof item.name === "string") {
|
|
6716
|
+
commands.push({
|
|
6717
|
+
name: item.name.replace(/^\//, ""),
|
|
6718
|
+
description: item.description ? String(item.description) : ""
|
|
6719
|
+
});
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
return [
|
|
6723
|
+
{
|
|
6724
|
+
sessionId: params.sessionId,
|
|
6725
|
+
update: {
|
|
6726
|
+
sessionUpdate: "available_commands_update",
|
|
6727
|
+
availableCommands: commands
|
|
6728
|
+
}
|
|
6729
|
+
}
|
|
6730
|
+
];
|
|
6731
|
+
}
|
|
6732
|
+
return [];
|
|
6733
|
+
}
|
|
6734
|
+
handleSubagentListUpdate(params, currentSessionId, agentId) {
|
|
6735
|
+
if (typeof params === "object" && params && currentSessionId && "subagents" in params && Array.isArray(params.subagents)) {
|
|
6736
|
+
const results = [];
|
|
6737
|
+
for (const subagent of params.subagents) {
|
|
6738
|
+
if (typeof subagent === "object" && subagent && "sessionId" in subagent && typeof subagent.sessionId === "string") {
|
|
6739
|
+
const update = {
|
|
6740
|
+
sessionUpdate: "subagent_update",
|
|
6741
|
+
sessionId: subagent.sessionId,
|
|
6742
|
+
name: typeof subagent.sessionName === "string" ? subagent.sessionName : void 0,
|
|
6743
|
+
prompt: typeof subagent.initialQuery === "string" ? subagent.initialQuery : void 0,
|
|
6744
|
+
status: KIRO_STATUS_MAP[String(subagent?.status?.type)]
|
|
6745
|
+
};
|
|
6746
|
+
results.push({
|
|
6747
|
+
sessionId: currentSessionId.replace(`${agentId}:`, ""),
|
|
6748
|
+
update: {
|
|
6749
|
+
sessionUpdate: "session_info_update",
|
|
6750
|
+
_meta: { fello: { update } }
|
|
6751
|
+
}
|
|
6752
|
+
});
|
|
6753
|
+
}
|
|
6754
|
+
}
|
|
6755
|
+
return results;
|
|
6756
|
+
}
|
|
6757
|
+
return [];
|
|
6758
|
+
}
|
|
6759
|
+
};
|
|
6760
|
+
|
|
6761
|
+
// src/backend/acp-adapters/adapters.ts
|
|
6762
|
+
var codebuddyAdapter = new CodebuddyAdapter();
|
|
6763
|
+
var kiroAdapter = new KiroAdapter();
|
|
6764
|
+
var adapters = [codebuddyAdapter, kiroAdapter];
|
|
6765
|
+
var extNotificationSpecs = adapters.flatMap((a) => a.extNotificationSpecs);
|
|
6766
|
+
var agentEnv = Object.assign(
|
|
6767
|
+
{},
|
|
6768
|
+
...adapters.map((a) => a.getAgentEnv())
|
|
6769
|
+
);
|
|
6770
|
+
|
|
6142
6771
|
// src/backend/agent/resolve-agent-info.ts
|
|
6143
6772
|
function resolveAgentInfo(agentId) {
|
|
6144
6773
|
const settings = storageOps.getSettings();
|
|
@@ -6200,10 +6829,59 @@ function createBridgeConnectModule(ctx, deps) {
|
|
|
6200
6829
|
}
|
|
6201
6830
|
sessionAgentMap.set(sessionKey, agentId);
|
|
6202
6831
|
let currentSessionId = null;
|
|
6832
|
+
function processSessionUpdate(notification) {
|
|
6833
|
+
let results = [notification];
|
|
6834
|
+
if (currentSessionId) {
|
|
6835
|
+
for (const adapter of adapters) {
|
|
6836
|
+
const next = [];
|
|
6837
|
+
for (const n of results) {
|
|
6838
|
+
const processed = adapter.preprocessNotification(n, currentSessionId, agentId);
|
|
6839
|
+
if (processed !== null) {
|
|
6840
|
+
next.push(...processed);
|
|
6841
|
+
}
|
|
6842
|
+
}
|
|
6843
|
+
results = next;
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
if (results.length === 0) return;
|
|
6847
|
+
if (!currentSessionId) return;
|
|
6848
|
+
for (const result of results) {
|
|
6849
|
+
const sessionUpdate = result.update?.sessionUpdate;
|
|
6850
|
+
if (currentSessionId && currentSessionId === `${agentId}:${result.sessionId}`) {
|
|
6851
|
+
if (sessionUpdate === "session_info_update") {
|
|
6852
|
+
if (result.update.title) {
|
|
6853
|
+
storage.updateSession(currentSessionId, { title: result.update.title });
|
|
6854
|
+
const updated = storage.getSession(currentSessionId);
|
|
6855
|
+
if (updated) sendEvent("session-changed", { session: updated });
|
|
6856
|
+
}
|
|
6857
|
+
}
|
|
6858
|
+
if (sessionUpdate === "usage_update") {
|
|
6859
|
+
publishUsage(currentSessionId, result.update);
|
|
6860
|
+
continue;
|
|
6861
|
+
}
|
|
6862
|
+
if (sessionUpdate === "available_commands_update") {
|
|
6863
|
+
publishAvailableCommands(currentSessionId, result.update.availableCommands ?? []);
|
|
6864
|
+
continue;
|
|
6865
|
+
}
|
|
6866
|
+
if (sessionUpdate === "current_mode_update") {
|
|
6867
|
+
const session = storage.getSession(currentSessionId);
|
|
6868
|
+
if (session && session.modes) {
|
|
6869
|
+
session.modes.currentModeId = result.update.currentModeId ?? null;
|
|
6870
|
+
storage.updateSession(currentSessionId, { modes: session.modes });
|
|
6871
|
+
const updated = storage.getSession(currentSessionId);
|
|
6872
|
+
if (updated) sendEvent("session-changed", { session: updated });
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
}
|
|
6876
|
+
broadcastAndSaveSessionUpdate(currentSessionId, result);
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6203
6879
|
const agentInfo = resolveAgentInfo(agentId);
|
|
6204
6880
|
const bridge = new ACPBridge(agentId, {
|
|
6205
6881
|
agentInfo,
|
|
6206
6882
|
cwd,
|
|
6883
|
+
extNotificationSpecs,
|
|
6884
|
+
agentEnv,
|
|
6207
6885
|
onSessionConnect: (connection) => {
|
|
6208
6886
|
currentSessionId = `${agentId}:${connection.sessionId}`;
|
|
6209
6887
|
storage.updateSession(currentSessionId, { connectionStatus: "connected" }, false);
|
|
@@ -6211,96 +6889,17 @@ function createBridgeConnectModule(ctx, deps) {
|
|
|
6211
6889
|
if (updated) sendEvent("session-changed", { session: updated });
|
|
6212
6890
|
},
|
|
6213
6891
|
onSessionUpdate: (notification) => {
|
|
6214
|
-
|
|
6215
|
-
if (currentSessionId) {
|
|
6216
|
-
if (currentSessionId === `${agentId}:${notification.sessionId}`) {
|
|
6217
|
-
if (sessionUpdate === "session_info_update") {
|
|
6218
|
-
if (notification.update.title) {
|
|
6219
|
-
storage.updateSession(currentSessionId, { title: notification.update.title });
|
|
6220
|
-
const updated = storage.getSession(currentSessionId);
|
|
6221
|
-
if (updated) sendEvent("session-changed", { session: updated });
|
|
6222
|
-
}
|
|
6223
|
-
}
|
|
6224
|
-
if (sessionUpdate === "usage_update") {
|
|
6225
|
-
publishUsage(currentSessionId, notification.update);
|
|
6226
|
-
return;
|
|
6227
|
-
}
|
|
6228
|
-
if (sessionUpdate === "available_commands_update") {
|
|
6229
|
-
publishAvailableCommands(
|
|
6230
|
-
currentSessionId,
|
|
6231
|
-
notification.update.availableCommands ?? []
|
|
6232
|
-
);
|
|
6233
|
-
return;
|
|
6234
|
-
}
|
|
6235
|
-
if (sessionUpdate === "current_mode_update") {
|
|
6236
|
-
const session = storage.getSession(currentSessionId);
|
|
6237
|
-
if (session && session.modes) {
|
|
6238
|
-
session.modes.currentModeId = notification.update.currentModeId ?? null;
|
|
6239
|
-
storage.updateSession(currentSessionId, { modes: session.modes });
|
|
6240
|
-
const updated = storage.getSession(currentSessionId);
|
|
6241
|
-
if (updated) sendEvent("session-changed", { session: updated });
|
|
6242
|
-
}
|
|
6243
|
-
}
|
|
6244
|
-
}
|
|
6245
|
-
broadcastAndSaveSessionUpdate(currentSessionId, notification);
|
|
6246
|
-
}
|
|
6892
|
+
processSessionUpdate(notification);
|
|
6247
6893
|
},
|
|
6248
6894
|
onExtNotification: (method, params) => {
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
});
|
|
6255
|
-
}
|
|
6256
|
-
return;
|
|
6257
|
-
}
|
|
6258
|
-
if (method === "_kiro.dev/commands/available") {
|
|
6259
|
-
if (typeof params === "object" && params && "sessionId" in params && typeof params.sessionId === "string" && "commands" in params && Array.isArray(params.commands) && currentSessionId === `${agentId}:${params.sessionId}`) {
|
|
6260
|
-
const commands = [];
|
|
6261
|
-
for (const item of params.commands) {
|
|
6262
|
-
if (typeof item === "object" && item && "name" in item && typeof item.name === "string") {
|
|
6263
|
-
commands.push({
|
|
6264
|
-
name: item.name.replace(/^\//, ""),
|
|
6265
|
-
description: item.description ? String(item.description) : ""
|
|
6266
|
-
});
|
|
6267
|
-
}
|
|
6268
|
-
}
|
|
6269
|
-
publishAvailableCommands(currentSessionId, commands);
|
|
6270
|
-
}
|
|
6271
|
-
return;
|
|
6272
|
-
}
|
|
6273
|
-
if (method === "_kiro.dev/subagent/list_update") {
|
|
6274
|
-
if (typeof params === "object" && params && currentSessionId && "subagents" in params && Array.isArray(params.subagents)) {
|
|
6275
|
-
for (const subagent of params.subagents) {
|
|
6276
|
-
if (typeof subagent === "object" && subagent && "sessionId" in subagent && typeof subagent.sessionId === "string") {
|
|
6277
|
-
const update = {
|
|
6278
|
-
sessionUpdate: "subagent_update",
|
|
6279
|
-
sessionId: subagent.sessionId,
|
|
6280
|
-
name: typeof subagent.sessionName === "string" ? subagent.sessionName : void 0,
|
|
6281
|
-
prompt: typeof subagent.initialQuery === "string" ? subagent.initialQuery : void 0,
|
|
6282
|
-
status: {
|
|
6283
|
-
pending: "pending",
|
|
6284
|
-
working: "in_progress",
|
|
6285
|
-
terminated: "completed",
|
|
6286
|
-
failed: "failed"
|
|
6287
|
-
}[String(subagent?.status?.type)]
|
|
6288
|
-
};
|
|
6289
|
-
broadcastAndSaveSessionUpdate(currentSessionId, {
|
|
6290
|
-
sessionId: currentSessionId.replace(`${agentId}:`, ""),
|
|
6291
|
-
update: {
|
|
6292
|
-
sessionUpdate: "session_info_update",
|
|
6293
|
-
_meta: {
|
|
6294
|
-
fello: {
|
|
6295
|
-
update
|
|
6296
|
-
}
|
|
6297
|
-
}
|
|
6298
|
-
}
|
|
6299
|
-
});
|
|
6300
|
-
}
|
|
6895
|
+
for (const adapter of adapters) {
|
|
6896
|
+
const results = adapter.handleExtNotification(method, params, currentSessionId, agentId);
|
|
6897
|
+
if (results.length > 0) {
|
|
6898
|
+
for (const result of results) {
|
|
6899
|
+
processSessionUpdate(result);
|
|
6301
6900
|
}
|
|
6901
|
+
return;
|
|
6302
6902
|
}
|
|
6303
|
-
return;
|
|
6304
6903
|
}
|
|
6305
6904
|
},
|
|
6306
6905
|
onPermissionRequest: async (request) => {
|
|
@@ -6357,6 +6956,13 @@ function createBridgeConnectModule(ctx, deps) {
|
|
|
6357
6956
|
console.error("write terminal output error: ", { sessionId, terminalId, err });
|
|
6358
6957
|
}
|
|
6359
6958
|
sendEvent("agent-terminal-output", { sessionId, terminalId, data });
|
|
6959
|
+
},
|
|
6960
|
+
// On prompt completion, hand the full PromptResponse to each adapter so
|
|
6961
|
+
// it can freeze its own turn-boundary (CodeBuddy extracts its protocol
|
|
6962
|
+
// timestamp; other adapters are no-ops).
|
|
6963
|
+
onPromptCompleted: (sessionId, res) => {
|
|
6964
|
+
const key = `${agentId}:${sessionId}`;
|
|
6965
|
+
for (const a of adapters) a.handlePromptCompleted(key, res);
|
|
6360
6966
|
}
|
|
6361
6967
|
});
|
|
6362
6968
|
let newConnectPromise;
|
|
@@ -6382,12 +6988,14 @@ function createBridgeConnectModule(ctx, deps) {
|
|
|
6382
6988
|
sessionAgentMap.delete(oldKey);
|
|
6383
6989
|
sessionAgentMap.set(newKey, agentId);
|
|
6384
6990
|
}
|
|
6991
|
+
for (const a of adapters) a.rekey(oldKey, newKey);
|
|
6385
6992
|
}
|
|
6386
6993
|
async function killBridge(sessionKey) {
|
|
6387
6994
|
const p = bridges.get(sessionKey);
|
|
6388
6995
|
if (p) {
|
|
6389
6996
|
bridges.delete(sessionKey);
|
|
6390
6997
|
sessionAgentMap.delete(sessionKey);
|
|
6998
|
+
for (const a of adapters) a.cleanup(sessionKey);
|
|
6391
6999
|
try {
|
|
6392
7000
|
const b = await p;
|
|
6393
7001
|
await b.kill();
|
|
@@ -6417,6 +7025,7 @@ function createBridgeConnectModule(ctx, deps) {
|
|
|
6417
7025
|
}
|
|
6418
7026
|
bridges.clear();
|
|
6419
7027
|
sessionAgentMap.clear();
|
|
7028
|
+
for (const a of adapters) a.clearAll();
|
|
6420
7029
|
await Promise.all(killPromises);
|
|
6421
7030
|
}
|
|
6422
7031
|
return {
|
|
@@ -6677,10 +7286,109 @@ import {
|
|
|
6677
7286
|
copyFile
|
|
6678
7287
|
} from "fs/promises";
|
|
6679
7288
|
import * as mimeTypes4 from "mime-types";
|
|
6680
|
-
import { dirname as
|
|
7289
|
+
import { dirname as dirname7, join as join17, relative as relative9, extname as extname2, basename as basename3 } from "path";
|
|
7290
|
+
|
|
7291
|
+
// src/backend/project/git-utils.ts
|
|
7292
|
+
import { execFile, spawn as spawn3 } from "child_process";
|
|
7293
|
+
import { dirname as dirname6, relative as relative8 } from "path";
|
|
7294
|
+
import { promisify } from "util";
|
|
7295
|
+
var execFileAsync = promisify(execFile);
|
|
7296
|
+
async function getGitIgnoredPaths(cwd, relPaths) {
|
|
7297
|
+
if (relPaths.length === 0) return /* @__PURE__ */ new Set();
|
|
7298
|
+
return new Promise((resolve9) => {
|
|
7299
|
+
const child = spawn3("git", ["check-ignore", "-z", "--stdin"], {
|
|
7300
|
+
cwd,
|
|
7301
|
+
timeout: 3e3,
|
|
7302
|
+
// spawn defaults windowsHide to false; without this, every readDir
|
|
7303
|
+
// would flash a console window on Windows.
|
|
7304
|
+
windowsHide: true
|
|
7305
|
+
});
|
|
7306
|
+
const chunks = [];
|
|
7307
|
+
child.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
7308
|
+
child.on("error", () => resolve9(/* @__PURE__ */ new Set()));
|
|
7309
|
+
child.on("close", () => {
|
|
7310
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
7311
|
+
for (const p of Buffer.concat(chunks).toString("utf8").split("\0")) {
|
|
7312
|
+
if (p) ignored.add(toPosixPath(p));
|
|
7313
|
+
}
|
|
7314
|
+
resolve9(ignored);
|
|
7315
|
+
});
|
|
7316
|
+
try {
|
|
7317
|
+
child.stdin.write(relPaths.join("\0") + "\0");
|
|
7318
|
+
child.stdin.end();
|
|
7319
|
+
} catch {
|
|
7320
|
+
resolve9(/* @__PURE__ */ new Set());
|
|
7321
|
+
}
|
|
7322
|
+
});
|
|
7323
|
+
}
|
|
7324
|
+
async function getGitStatus(cwd) {
|
|
7325
|
+
try {
|
|
7326
|
+
const { stdout } = await execFileAsync("git", ["status", "--porcelain", "-b", "-z"], {
|
|
7327
|
+
cwd,
|
|
7328
|
+
timeout: 2e3,
|
|
7329
|
+
maxBuffer: 10 * 1024 * 1024
|
|
7330
|
+
});
|
|
7331
|
+
const lines = stdout.split("\0").filter(Boolean);
|
|
7332
|
+
if (lines.length === 0) return null;
|
|
7333
|
+
let branchLine = lines[0];
|
|
7334
|
+
let branch = "";
|
|
7335
|
+
if (branchLine.startsWith("## ")) {
|
|
7336
|
+
branchLine = branchLine.slice(3);
|
|
7337
|
+
if (branchLine.startsWith("No commits yet on "))
|
|
7338
|
+
branch = branchLine.slice("No commits yet on ".length);
|
|
7339
|
+
else if (branchLine.startsWith("HEAD (no branch)")) branch = "HEAD";
|
|
7340
|
+
else branch = branchLine.split("...")[0];
|
|
7341
|
+
}
|
|
7342
|
+
const files = {};
|
|
7343
|
+
for (let i = 1; i < lines.length; i++) {
|
|
7344
|
+
const line = lines[i];
|
|
7345
|
+
const status = line.slice(0, 2);
|
|
7346
|
+
if (line.length < 4) continue;
|
|
7347
|
+
let path2 = line.slice(3);
|
|
7348
|
+
if ((status.includes("R") || status.includes("C")) && i + 1 < lines.length) {
|
|
7349
|
+
path2 = lines[i + 1];
|
|
7350
|
+
i++;
|
|
7351
|
+
}
|
|
7352
|
+
files[toPosixPath(path2)] = status;
|
|
7353
|
+
}
|
|
7354
|
+
return { branch, files };
|
|
7355
|
+
} catch {
|
|
7356
|
+
return null;
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7359
|
+
async function readGitHeadFile(targetPath, encoding) {
|
|
7360
|
+
try {
|
|
7361
|
+
const cwd = dirname6(targetPath);
|
|
7362
|
+
const relPath = relative8(cwd, targetPath);
|
|
7363
|
+
const { stdout } = await execFileAsync("git", ["show", `HEAD:./${relPath}`], {
|
|
7364
|
+
cwd,
|
|
7365
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
7366
|
+
encoding: encoding ?? "utf8"
|
|
7367
|
+
});
|
|
7368
|
+
return stdout;
|
|
7369
|
+
} catch {
|
|
7370
|
+
return "";
|
|
7371
|
+
}
|
|
7372
|
+
}
|
|
7373
|
+
|
|
7374
|
+
// src/backend/project/filesystem.ts
|
|
6681
7375
|
var SEARCH_MAX_RESULTS = 10;
|
|
6682
7376
|
var SEARCH_FUSE_THRESHOLD = 0.4;
|
|
6683
7377
|
var SEARCH_CACHE_TTL_MS = 6e4;
|
|
7378
|
+
var IGNORE_NAME_SET = /* @__PURE__ */ new Set([".git", ".svn", ".hg"]);
|
|
7379
|
+
var SEARCH_IGNORE_NAME_SET = /* @__PURE__ */ new Set(["node_modules", "vendor", "__pycache__"]);
|
|
7380
|
+
function hasForbiddenSegment(fullPath, cwd, ...nameSets) {
|
|
7381
|
+
if (fullPath === cwd) return false;
|
|
7382
|
+
const relPath = relative9(cwd, fullPath);
|
|
7383
|
+
if (!relPath) return false;
|
|
7384
|
+
const segments = relPath.split(/[\\/]+/);
|
|
7385
|
+
for (let i = 0; i < segments.length; i++) {
|
|
7386
|
+
const name = segments[i];
|
|
7387
|
+
if (!name || name === ".") continue;
|
|
7388
|
+
if (nameSets.some((set) => set.has(name))) return true;
|
|
7389
|
+
}
|
|
7390
|
+
return false;
|
|
7391
|
+
}
|
|
6684
7392
|
function createFilesystemState(ctx) {
|
|
6685
7393
|
const { storage } = ctx;
|
|
6686
7394
|
const projectFsVersions = /* @__PURE__ */ new Map();
|
|
@@ -6713,9 +7421,9 @@ function createFilesystemState(ctx) {
|
|
|
6713
7421
|
const full = join17(dir, name);
|
|
6714
7422
|
const s = await stat4(full).catch(() => null);
|
|
6715
7423
|
if (!s) continue;
|
|
6716
|
-
if (
|
|
7424
|
+
if (hasForbiddenSegment(full, cwd, IGNORE_NAME_SET, SEARCH_IGNORE_NAME_SET)) continue;
|
|
6717
7425
|
if (fileScene.has(full)) continue;
|
|
6718
|
-
const rel =
|
|
7426
|
+
const rel = relative9(cwd, full);
|
|
6719
7427
|
const posixRel = toPosixPath(rel);
|
|
6720
7428
|
allFiles.push({ id: posixRel, filename: rel, isFolder: s.isDirectory() });
|
|
6721
7429
|
if (s.isDirectory()) await collect(full);
|
|
@@ -6727,12 +7435,12 @@ function createFilesystemState(ctx) {
|
|
|
6727
7435
|
async function getSystemFilePath({
|
|
6728
7436
|
projectId,
|
|
6729
7437
|
path: inputPath,
|
|
6730
|
-
isAbsolute:
|
|
7438
|
+
isAbsolute: isAbsolute8
|
|
6731
7439
|
}) {
|
|
6732
7440
|
const project = storage.getProject(projectId);
|
|
6733
7441
|
if (!project) throw new Error("Project not found");
|
|
6734
|
-
if (
|
|
6735
|
-
return
|
|
7442
|
+
if (isAbsolute8) return resolveSafePath(project.cwd, inputPath);
|
|
7443
|
+
return relative9(project.cwd, resolveSafePath(project.cwd, inputPath));
|
|
6736
7444
|
}
|
|
6737
7445
|
async function copyFileToWorkspace({
|
|
6738
7446
|
projectId,
|
|
@@ -6755,7 +7463,7 @@ function createFilesystemState(ctx) {
|
|
|
6755
7463
|
}
|
|
6756
7464
|
await copyFile(sourcePath, destPath);
|
|
6757
7465
|
markProjectFsDirty(projectId);
|
|
6758
|
-
return { success: true, destPath: toPosixPath(
|
|
7466
|
+
return { success: true, destPath: toPosixPath(relative9(cwd, destPath)) };
|
|
6759
7467
|
}
|
|
6760
7468
|
async function readUrlAsDataUrl({ url: inputUrl, mimeType }) {
|
|
6761
7469
|
const MAX_FILE_SIZE = 20 * 1024 * 1024;
|
|
@@ -6805,12 +7513,12 @@ function createFilesystemState(ctx) {
|
|
|
6805
7513
|
const results = [];
|
|
6806
7514
|
for (const name of entries) {
|
|
6807
7515
|
const full = join17(cwd, name);
|
|
6808
|
-
if (
|
|
7516
|
+
if (hasForbiddenSegment(full, cwd, IGNORE_NAME_SET, SEARCH_IGNORE_NAME_SET)) continue;
|
|
6809
7517
|
if (fileScene.has(full)) continue;
|
|
6810
7518
|
fileScene.add(full);
|
|
6811
7519
|
const s = await stat4(full).catch(() => null);
|
|
6812
7520
|
if (!s) continue;
|
|
6813
|
-
const rel =
|
|
7521
|
+
const rel = relative9(cwd, full);
|
|
6814
7522
|
results.push({ id: toPosixPath(rel), filename: rel, isFolder: s.isDirectory() });
|
|
6815
7523
|
if (results.length >= SEARCH_MAX_RESULTS) break;
|
|
6816
7524
|
}
|
|
@@ -6849,14 +7557,23 @@ function createFilesystemState(ctx) {
|
|
|
6849
7557
|
const full = join17(startPath, name);
|
|
6850
7558
|
const s = await stat4(full).catch(() => null);
|
|
6851
7559
|
if (!s) continue;
|
|
6852
|
-
if (
|
|
6853
|
-
const relId = toPosixPath(
|
|
6854
|
-
results.push({ id: relId, name, isFolder: s.isDirectory() });
|
|
7560
|
+
if (hasForbiddenSegment(full, cwd, IGNORE_NAME_SET)) continue;
|
|
7561
|
+
const relId = toPosixPath(relative9(cwd, full));
|
|
7562
|
+
results.push({ id: relId, name, isFolder: s.isDirectory(), ignored: false });
|
|
6855
7563
|
}
|
|
6856
7564
|
results.sort((a, b) => {
|
|
6857
7565
|
if (a.isFolder !== b.isFolder) return a.isFolder ? -1 : 1;
|
|
6858
7566
|
return a.name.localeCompare(b.name);
|
|
6859
7567
|
});
|
|
7568
|
+
const ignoredPaths = await getGitIgnoredPaths(
|
|
7569
|
+
cwd,
|
|
7570
|
+
results.map((r) => r.id)
|
|
7571
|
+
);
|
|
7572
|
+
if (ignoredPaths.size > 0) {
|
|
7573
|
+
for (const r of results) {
|
|
7574
|
+
if (ignoredPaths.has(r.id)) r.ignored = true;
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
6860
7577
|
return results;
|
|
6861
7578
|
}
|
|
6862
7579
|
async function createFile({
|
|
@@ -6870,7 +7587,7 @@ function createFilesystemState(ctx) {
|
|
|
6870
7587
|
if (isFolder) {
|
|
6871
7588
|
await mkdir(targetPath, { recursive: true });
|
|
6872
7589
|
} else {
|
|
6873
|
-
await mkdir(
|
|
7590
|
+
await mkdir(dirname7(targetPath), { recursive: true });
|
|
6874
7591
|
await writeFile3(targetPath, "");
|
|
6875
7592
|
}
|
|
6876
7593
|
markProjectFsDirty(projectId);
|
|
@@ -6977,6 +7694,22 @@ function createFilesystemState(ctx) {
|
|
|
6977
7694
|
await writeFile3(currentDest, buffer);
|
|
6978
7695
|
markProjectFsDirty(projectId);
|
|
6979
7696
|
}
|
|
7697
|
+
async function getGitStatus2({ projectId, cwd }) {
|
|
7698
|
+
const project = storage.getProject(projectId);
|
|
7699
|
+
if (!project) return null;
|
|
7700
|
+
const targetCwd = cwd ? resolveSafePath(project.cwd, cwd) : project.cwd;
|
|
7701
|
+
return getGitStatus(targetCwd);
|
|
7702
|
+
}
|
|
7703
|
+
async function readGitHeadFile2({
|
|
7704
|
+
projectId,
|
|
7705
|
+
relativePath,
|
|
7706
|
+
encoding
|
|
7707
|
+
}) {
|
|
7708
|
+
const project = storage.getProject(projectId);
|
|
7709
|
+
if (!project) return "";
|
|
7710
|
+
const targetPath = resolveSafePath(project.cwd, relativePath);
|
|
7711
|
+
return readGitHeadFile(targetPath, encoding);
|
|
7712
|
+
}
|
|
6980
7713
|
async function getPlatform() {
|
|
6981
7714
|
return process.platform;
|
|
6982
7715
|
}
|
|
@@ -6996,83 +7729,16 @@ function createFilesystemState(ctx) {
|
|
|
6996
7729
|
readFile: readFile11,
|
|
6997
7730
|
getFileInfo,
|
|
6998
7731
|
writeExternalFile,
|
|
7732
|
+
getGitStatus: getGitStatus2,
|
|
7733
|
+
readGitHeadFile: readGitHeadFile2,
|
|
6999
7734
|
getPlatform
|
|
7000
7735
|
};
|
|
7001
7736
|
}
|
|
7002
7737
|
|
|
7003
|
-
// src/backend/project/git.ts
|
|
7004
|
-
import { execFile } from "child_process";
|
|
7005
|
-
import { dirname as dirname7, relative as relative8 } from "path";
|
|
7006
|
-
import { promisify } from "util";
|
|
7007
|
-
var execFileAsync = promisify(execFile);
|
|
7008
|
-
function createGitHandlers(ctx) {
|
|
7009
|
-
const { storage } = ctx;
|
|
7010
|
-
async function getGitStatus({ projectId, cwd }) {
|
|
7011
|
-
try {
|
|
7012
|
-
const project = storage.getProject(projectId);
|
|
7013
|
-
if (!project) throw new Error("Project not found");
|
|
7014
|
-
const targetCwd = cwd ? resolveSafePath(project.cwd, cwd) : project.cwd;
|
|
7015
|
-
const { stdout } = await execFileAsync("git", ["status", "--porcelain", "-b", "-z"], {
|
|
7016
|
-
cwd: targetCwd,
|
|
7017
|
-
timeout: 2e3
|
|
7018
|
-
});
|
|
7019
|
-
const lines = stdout.split("\0").filter(Boolean);
|
|
7020
|
-
if (lines.length === 0) return null;
|
|
7021
|
-
let branchLine = lines[0];
|
|
7022
|
-
let branch = "";
|
|
7023
|
-
if (branchLine.startsWith("## ")) {
|
|
7024
|
-
branchLine = branchLine.slice(3);
|
|
7025
|
-
if (branchLine.startsWith("No commits yet on "))
|
|
7026
|
-
branch = branchLine.slice("No commits yet on ".length);
|
|
7027
|
-
else if (branchLine.startsWith("HEAD (no branch)")) branch = "HEAD";
|
|
7028
|
-
else branch = branchLine.split("...")[0];
|
|
7029
|
-
}
|
|
7030
|
-
const files = {};
|
|
7031
|
-
for (let i = 1; i < lines.length; i++) {
|
|
7032
|
-
const line = lines[i];
|
|
7033
|
-
const status = line.slice(0, 2);
|
|
7034
|
-
if (line.length < 4) continue;
|
|
7035
|
-
let path2 = line.slice(3);
|
|
7036
|
-
if ((status.includes("R") || status.includes("C")) && i + 1 < lines.length) {
|
|
7037
|
-
path2 = lines[i + 1];
|
|
7038
|
-
i++;
|
|
7039
|
-
}
|
|
7040
|
-
files[toPosixPath(path2)] = status;
|
|
7041
|
-
}
|
|
7042
|
-
return { branch, files };
|
|
7043
|
-
} catch {
|
|
7044
|
-
return null;
|
|
7045
|
-
}
|
|
7046
|
-
}
|
|
7047
|
-
async function readGitHeadFile({
|
|
7048
|
-
projectId,
|
|
7049
|
-
relativePath,
|
|
7050
|
-
encoding
|
|
7051
|
-
}) {
|
|
7052
|
-
try {
|
|
7053
|
-
const project = storage.getProject(projectId);
|
|
7054
|
-
if (!project) throw new Error("Project not found");
|
|
7055
|
-
const targetPath = resolveSafePath(project.cwd, relativePath);
|
|
7056
|
-
const cwd = dirname7(targetPath);
|
|
7057
|
-
const relPath = relative8(cwd, targetPath);
|
|
7058
|
-
const { stdout } = await execFileAsync("git", ["show", `HEAD:./${relPath}`], {
|
|
7059
|
-
cwd,
|
|
7060
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
7061
|
-
encoding: encoding ?? "utf8"
|
|
7062
|
-
});
|
|
7063
|
-
return stdout;
|
|
7064
|
-
} catch {
|
|
7065
|
-
return "";
|
|
7066
|
-
}
|
|
7067
|
-
}
|
|
7068
|
-
return { getGitStatus, readGitHeadFile };
|
|
7069
|
-
}
|
|
7070
|
-
|
|
7071
7738
|
// src/backend/project/index.ts
|
|
7072
7739
|
function createProjectModule(ctx, deps) {
|
|
7073
7740
|
const { sendEvent, onEvent, storage } = ctx;
|
|
7074
7741
|
const fs2 = createFilesystemState(ctx);
|
|
7075
|
-
const git = createGitHandlers(ctx);
|
|
7076
7742
|
onEvent((channel, payload) => {
|
|
7077
7743
|
if (channel === "fs-changed") {
|
|
7078
7744
|
fs2.markProjectFsDirty(payload.projectId);
|
|
@@ -7108,8 +7774,7 @@ function createProjectModule(ctx, deps) {
|
|
|
7108
7774
|
addProject: addProject2,
|
|
7109
7775
|
renameProject,
|
|
7110
7776
|
deleteProject: deleteProject2,
|
|
7111
|
-
...fs2
|
|
7112
|
-
...git
|
|
7777
|
+
...fs2
|
|
7113
7778
|
};
|
|
7114
7779
|
}
|
|
7115
7780
|
|
|
@@ -7172,7 +7837,7 @@ async function startSocketServer(socketPath) {
|
|
|
7172
7837
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
7173
7838
|
res.end(JSON.stringify({ error: "Not found" }));
|
|
7174
7839
|
});
|
|
7175
|
-
return new Promise((
|
|
7840
|
+
return new Promise((resolve9, reject) => {
|
|
7176
7841
|
server.listen(socketPath, () => {
|
|
7177
7842
|
const serverRef = {
|
|
7178
7843
|
stop: () => {
|
|
@@ -7192,7 +7857,7 @@ async function startSocketServer(socketPath) {
|
|
|
7192
7857
|
},
|
|
7193
7858
|
socketPath
|
|
7194
7859
|
};
|
|
7195
|
-
|
|
7860
|
+
resolve9(serverRef);
|
|
7196
7861
|
});
|
|
7197
7862
|
server.on("error", (err) => {
|
|
7198
7863
|
console.error("[socket-server] Failed to start:", err);
|
|
@@ -8261,7 +8926,7 @@ function createSessionModule(ctx, deps) {
|
|
|
8261
8926
|
askUser,
|
|
8262
8927
|
shareToUser,
|
|
8263
8928
|
skills,
|
|
8264
|
-
search
|
|
8929
|
+
search,
|
|
8265
8930
|
memory,
|
|
8266
8931
|
imageGeneration,
|
|
8267
8932
|
toolbox,
|
|
@@ -8271,7 +8936,7 @@ function createSessionModule(ctx, deps) {
|
|
|
8271
8936
|
skills,
|
|
8272
8937
|
askUser,
|
|
8273
8938
|
shareToUser,
|
|
8274
|
-
search
|
|
8939
|
+
search,
|
|
8275
8940
|
memory,
|
|
8276
8941
|
imageGeneration,
|
|
8277
8942
|
toolbox
|
|
@@ -8289,7 +8954,7 @@ function createSessionModule(ctx, deps) {
|
|
|
8289
8954
|
const server = await startSocketServer(options.socketPath);
|
|
8290
8955
|
toolbox.registerToolboxRoute(server, options.project.cwd);
|
|
8291
8956
|
skills.registerSkillsRoute(server, options.project.cwd);
|
|
8292
|
-
|
|
8957
|
+
search.registerSearchRoute(server, options.project.cwd);
|
|
8293
8958
|
imageGeneration.registerImageGenerationRoute(server, sessionId);
|
|
8294
8959
|
memory.registerMemoryRoute(server, options.project.id, sessionId);
|
|
8295
8960
|
askUser.registerAskUserRoute(server, sessionId);
|
|
@@ -8455,6 +9120,33 @@ function createSessionModule(ctx, deps) {
|
|
|
8455
9120
|
shouldUpdateCache = true;
|
|
8456
9121
|
} else finalThoughtLevels = session.thoughtLevels;
|
|
8457
9122
|
}
|
|
9123
|
+
const restorePushback = [];
|
|
9124
|
+
if (finalModels && session.models?.currentModelId && finalModels.currentModelId !== session.models.currentModelId && finalModels.availableModels.some((m) => m.modelId === session.models.currentModelId)) {
|
|
9125
|
+
const cachedModelId = session.models.currentModelId;
|
|
9126
|
+
finalModels = { ...finalModels, currentModelId: cachedModelId };
|
|
9127
|
+
restorePushback.push(
|
|
9128
|
+
b.setSessionModel({ sessionId: session.resumeId, modelId: cachedModelId }).catch((err) => console.warn("[loadSession] Failed to restore model selection:", err))
|
|
9129
|
+
);
|
|
9130
|
+
}
|
|
9131
|
+
if (finalModes && session.modes?.currentModeId && finalModes.currentModeId !== session.modes.currentModeId && finalModes.availableModes.some((m) => m.id === session.modes.currentModeId)) {
|
|
9132
|
+
const cachedModeId = session.modes.currentModeId;
|
|
9133
|
+
finalModes = { ...finalModes, currentModeId: cachedModeId };
|
|
9134
|
+
restorePushback.push(
|
|
9135
|
+
b.setSessionMode({ sessionId: session.resumeId, modeId: cachedModeId }).catch((err) => console.warn("[loadSession] Failed to restore mode selection:", err))
|
|
9136
|
+
);
|
|
9137
|
+
}
|
|
9138
|
+
if (finalThoughtLevels && session.thoughtLevels?.currentThoughtLevelId && finalThoughtLevels.currentThoughtLevelId !== session.thoughtLevels.currentThoughtLevelId && finalThoughtLevels.availableThoughtLevels.some(
|
|
9139
|
+
(m) => m.id === session.thoughtLevels.currentThoughtLevelId
|
|
9140
|
+
)) {
|
|
9141
|
+
const cachedId = session.thoughtLevels.currentThoughtLevelId;
|
|
9142
|
+
finalThoughtLevels = { ...finalThoughtLevels, currentThoughtLevelId: cachedId };
|
|
9143
|
+
restorePushback.push(
|
|
9144
|
+
b.setThoughtLevel({ sessionId: session.resumeId, thoughtLevelId: cachedId }).catch((err) => console.warn("[loadSession] Failed to restore thought level:", err))
|
|
9145
|
+
);
|
|
9146
|
+
}
|
|
9147
|
+
if (restorePushback.length > 0) {
|
|
9148
|
+
await Promise.all(restorePushback);
|
|
9149
|
+
}
|
|
8458
9150
|
if (shouldUpdateCache || b.initializeInfo) {
|
|
8459
9151
|
storage.updateSession(
|
|
8460
9152
|
session.id,
|
|
@@ -8521,7 +9213,7 @@ function createSessionModule(ctx, deps) {
|
|
|
8521
9213
|
`[SendPrompt] Killed ${killed} agent terminal(s) from previous generation for session ${sessionId}`
|
|
8522
9214
|
);
|
|
8523
9215
|
}
|
|
8524
|
-
await new Promise((
|
|
9216
|
+
await new Promise((resolve9) => setTimeout(resolve9, 30));
|
|
8525
9217
|
}
|
|
8526
9218
|
if (!session.title) {
|
|
8527
9219
|
const firstTextContent = contents.find((c) => c.type === "text");
|
|
@@ -8541,15 +9233,20 @@ function createSessionModule(ctx, deps) {
|
|
|
8541
9233
|
ctx,
|
|
8542
9234
|
mcpDeps
|
|
8543
9235
|
);
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
9236
|
+
notif.addRestoring(session.id);
|
|
9237
|
+
try {
|
|
9238
|
+
await b.loadSession({
|
|
9239
|
+
sessionId: session.resumeId,
|
|
9240
|
+
cwd: session.cwd,
|
|
9241
|
+
mcpServers: activeMcpServers
|
|
9242
|
+
});
|
|
9243
|
+
await createSessionSocketServer(session.id, {
|
|
9244
|
+
socketPath,
|
|
9245
|
+
project
|
|
9246
|
+
});
|
|
9247
|
+
} finally {
|
|
9248
|
+
notif.removeRestoring(session.id);
|
|
9249
|
+
}
|
|
8553
9250
|
}
|
|
8554
9251
|
storage.updateSession(sessionId, { isStreaming: true });
|
|
8555
9252
|
const updated = storage.getSession(sessionId);
|
|
@@ -9389,22 +10086,54 @@ function createInferenceModule(_ctx, deps) {
|
|
|
9389
10086
|
const textChunks = [];
|
|
9390
10087
|
const terminalLogs = {};
|
|
9391
10088
|
const agentInfo = resolveAgentInfo(agentId);
|
|
10089
|
+
let currentSessionId = null;
|
|
10090
|
+
function processNotification(notification) {
|
|
10091
|
+
let results = [notification];
|
|
10092
|
+
if (currentSessionId) {
|
|
10093
|
+
for (const adapter of adapters) {
|
|
10094
|
+
const next = [];
|
|
10095
|
+
for (const n of results) {
|
|
10096
|
+
const processed = adapter.preprocessNotification(n, currentSessionId, agentId);
|
|
10097
|
+
if (processed !== null) {
|
|
10098
|
+
next.push(...processed);
|
|
10099
|
+
}
|
|
10100
|
+
}
|
|
10101
|
+
results = next;
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
if (results.length === 0) return;
|
|
10105
|
+
for (const result of results) {
|
|
10106
|
+
notifications.push(result);
|
|
10107
|
+
if (result.update?.sessionUpdate === "agent_message_chunk") {
|
|
10108
|
+
const content = result.update.content;
|
|
10109
|
+
if (content?.type === "text" && content.text) {
|
|
10110
|
+
textChunks.push(content.text);
|
|
10111
|
+
}
|
|
10112
|
+
}
|
|
10113
|
+
}
|
|
10114
|
+
}
|
|
9392
10115
|
const bridge = new ACPBridge(agentId, {
|
|
9393
10116
|
agentInfo,
|
|
9394
10117
|
cwd,
|
|
9395
|
-
|
|
10118
|
+
extNotificationSpecs,
|
|
10119
|
+
agentEnv,
|
|
10120
|
+
onSessionConnect: (connection) => {
|
|
10121
|
+
currentSessionId = `${agentId}:${connection.sessionId}`;
|
|
9396
10122
|
},
|
|
9397
10123
|
onSessionUpdate: (notification) => {
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
10124
|
+
processNotification(notification);
|
|
10125
|
+
},
|
|
10126
|
+
onExtNotification: (method, params) => {
|
|
10127
|
+
for (const adapter of adapters) {
|
|
10128
|
+
const results = adapter.handleExtNotification(method, params, currentSessionId, agentId);
|
|
10129
|
+
if (results.length > 0) {
|
|
10130
|
+
for (const result of results) {
|
|
10131
|
+
processNotification(result);
|
|
10132
|
+
}
|
|
10133
|
+
return;
|
|
9403
10134
|
}
|
|
9404
10135
|
}
|
|
9405
10136
|
},
|
|
9406
|
-
onExtNotification: () => {
|
|
9407
|
-
},
|
|
9408
10137
|
onPermissionRequest: async (request) => {
|
|
9409
10138
|
const opt = request.options.find((o) => o.kind === "allow_always") ?? request.options.find((o) => o.kind === "allow_once") ?? request.options[0];
|
|
9410
10139
|
return { outcome: { outcome: "selected", optionId: opt?.optionId ?? "allow" } };
|
|
@@ -10143,7 +10872,15 @@ function createMemoryModule(_ctx, deps) {
|
|
|
10143
10872
|
if (file.entries.length === 0 && !existsSync8(getMemoryPath(projectId))) {
|
|
10144
10873
|
return null;
|
|
10145
10874
|
}
|
|
10146
|
-
return file;
|
|
10875
|
+
return { version: file.version, entries: getMemoEntries(file.entries) };
|
|
10876
|
+
}
|
|
10877
|
+
function deleteMemoryEntry(projectId, entryId) {
|
|
10878
|
+
const file = readMemoryFile(projectId);
|
|
10879
|
+
const index = file.entries.findIndex((entry) => getMemoryEntryId(entry.text) === entryId);
|
|
10880
|
+
if (index === -1) return false;
|
|
10881
|
+
file.entries.splice(index, 1);
|
|
10882
|
+
writeMemoryFile(projectId, file);
|
|
10883
|
+
return true;
|
|
10147
10884
|
}
|
|
10148
10885
|
function clearMemory(projectId) {
|
|
10149
10886
|
const memoryPath = getMemoryPath(projectId);
|
|
@@ -10159,6 +10896,7 @@ function createMemoryModule(_ctx, deps) {
|
|
|
10159
10896
|
registerMemoryRoute,
|
|
10160
10897
|
buildMemoryMcpServer,
|
|
10161
10898
|
getMemory,
|
|
10899
|
+
deleteMemoryEntry,
|
|
10162
10900
|
clearMemory,
|
|
10163
10901
|
getFilePath
|
|
10164
10902
|
};
|
|
@@ -10348,7 +11086,7 @@ function createImageGenerationModule(ctx, deps) {
|
|
|
10348
11086
|
}
|
|
10349
11087
|
|
|
10350
11088
|
// src/backend/toolbox.ts
|
|
10351
|
-
import { join as join23, resolve as
|
|
11089
|
+
import { join as join23, resolve as resolve8, dirname as dirname9, basename as basename4, extname as extname3 } from "path";
|
|
10352
11090
|
import { writeFile as writeFile6 } from "fs/promises";
|
|
10353
11091
|
import { createHash as createHash6, randomUUID as randomUUID13, randomInt } from "crypto";
|
|
10354
11092
|
import * as qr from "qr-image";
|
|
@@ -10595,15 +11333,15 @@ function createToolboxModule(_ctx) {
|
|
|
10595
11333
|
});
|
|
10596
11334
|
server.registry("toolbox/image-metadata", async (payload) => {
|
|
10597
11335
|
const { path: imgPath } = imageMetadataRequestSchema.parse(payload);
|
|
10598
|
-
const absPath =
|
|
11336
|
+
const absPath = resolve8(projectDir, imgPath);
|
|
10599
11337
|
const sharp = await getSharp();
|
|
10600
11338
|
const metadata = await sharp(absPath).metadata();
|
|
10601
11339
|
return { result: extractMetadata(metadata) };
|
|
10602
11340
|
});
|
|
10603
11341
|
server.registry("toolbox/image-thumbnail", async (payload) => {
|
|
10604
11342
|
const { path: imgPath, width, output } = imageThumbnailRequestSchema.parse(payload);
|
|
10605
|
-
const absPath =
|
|
10606
|
-
const outputPath = output ?
|
|
11343
|
+
const absPath = resolve8(projectDir, imgPath);
|
|
11344
|
+
const outputPath = output ? resolve8(projectDir, output) : join23(
|
|
10607
11345
|
dirname9(absPath),
|
|
10608
11346
|
`${basename4(absPath, extname3(absPath))}.thumb${width}${extname3(absPath)}`
|
|
10609
11347
|
);
|
|
@@ -10614,7 +11352,7 @@ function createToolboxModule(_ctx) {
|
|
|
10614
11352
|
});
|
|
10615
11353
|
server.registry("toolbox/image-resize", async (payload) => {
|
|
10616
11354
|
const { path: imgPath, width, height, fit, output } = imageResizeRequestSchema.parse(payload);
|
|
10617
|
-
const absPath =
|
|
11355
|
+
const absPath = resolve8(projectDir, imgPath);
|
|
10618
11356
|
const sharp = await getSharp();
|
|
10619
11357
|
const resized = await sharp(absPath).resize({ width, height, fit }).toBuffer();
|
|
10620
11358
|
const resizedMeta = await sharp(resized).metadata();
|
|
@@ -10622,15 +11360,15 @@ function createToolboxModule(_ctx) {
|
|
|
10622
11360
|
const actualHeight = resizedMeta.height ?? height ?? 0;
|
|
10623
11361
|
const ext = extname3(absPath);
|
|
10624
11362
|
const base = basename4(absPath, ext);
|
|
10625
|
-
const outputPath = output ?
|
|
11363
|
+
const outputPath = output ? resolve8(projectDir, output) : join23(dirname9(absPath), `${base}.${actualWidth}x${actualHeight}${ext}`);
|
|
10626
11364
|
await writeFile6(outputPath, resized);
|
|
10627
11365
|
const metadata = await sharp(outputPath).metadata();
|
|
10628
11366
|
return { result: { output: outputPath, metadata: extractMetadata(metadata) } };
|
|
10629
11367
|
});
|
|
10630
11368
|
server.registry("toolbox/image-convert", async (payload) => {
|
|
10631
11369
|
const { path: imgPath, format, quality, output } = imageConvertRequestSchema.parse(payload);
|
|
10632
|
-
const absPath =
|
|
10633
|
-
const outputPath = output ?
|
|
11370
|
+
const absPath = resolve8(projectDir, imgPath);
|
|
11371
|
+
const outputPath = output ? resolve8(projectDir, output) : join23(dirname9(absPath), `${basename4(absPath, extname3(absPath))}.${format}`);
|
|
10634
11372
|
const sharp = await getSharp();
|
|
10635
11373
|
let pipeline = sharp(absPath);
|
|
10636
11374
|
const opts = {};
|
|
@@ -10642,7 +11380,7 @@ function createToolboxModule(_ctx) {
|
|
|
10642
11380
|
});
|
|
10643
11381
|
server.registry("toolbox/image-qrcode", async (payload) => {
|
|
10644
11382
|
const { text, output, size, margin, errorCorrection } = qrCodeRequestSchema.parse(payload);
|
|
10645
|
-
const outputPath =
|
|
11383
|
+
const outputPath = resolve8(projectDir, output ?? "qrcode.png");
|
|
10646
11384
|
const png = qr.imageSync(text, {
|
|
10647
11385
|
type: "png",
|
|
10648
11386
|
size,
|
|
@@ -10691,11 +11429,11 @@ function initBackend(emitter) {
|
|
|
10691
11429
|
const askUser = createAskUserModule(ctx, { ilink: ilink.state });
|
|
10692
11430
|
const shareToUser = createShareToUserModule(ctx, { ilink: ilink.state });
|
|
10693
11431
|
const skills = createSkillsModule(ctx);
|
|
10694
|
-
const
|
|
11432
|
+
const search = createSearchModule(ctx);
|
|
10695
11433
|
const watcher2 = createWatcherModule(ctx);
|
|
10696
11434
|
const toolbox = createToolboxModule(ctx);
|
|
10697
11435
|
const bridgeConnect = createBridgeConnectModule(ctx, { askUser });
|
|
10698
|
-
const _inference = createInferenceModule(ctx, { skills, search
|
|
11436
|
+
const _inference = createInferenceModule(ctx, { skills, search, toolbox });
|
|
10699
11437
|
const memory = createMemoryModule(ctx, { inference: _inference });
|
|
10700
11438
|
const imageGeneration = createImageGenerationModule(ctx, { ilink: ilink.state });
|
|
10701
11439
|
const session = createSessionModule(ctx, {
|
|
@@ -10703,7 +11441,7 @@ function initBackend(emitter) {
|
|
|
10703
11441
|
askUser,
|
|
10704
11442
|
shareToUser,
|
|
10705
11443
|
skills,
|
|
10706
|
-
search
|
|
11444
|
+
search,
|
|
10707
11445
|
memory,
|
|
10708
11446
|
imageGeneration,
|
|
10709
11447
|
toolbox,
|
|
@@ -11071,6 +11809,9 @@ function initBackend(emitter) {
|
|
|
11071
11809
|
async getMemory({ projectId }) {
|
|
11072
11810
|
return memory.getMemory(projectId);
|
|
11073
11811
|
},
|
|
11812
|
+
async deleteMemoryEntry({ projectId, entryId }) {
|
|
11813
|
+
return memory.deleteMemoryEntry(projectId, entryId);
|
|
11814
|
+
},
|
|
11074
11815
|
async clearMemory({ projectId }) {
|
|
11075
11816
|
memory.clearMemory(projectId);
|
|
11076
11817
|
},
|
|
@@ -11085,7 +11826,7 @@ function initBackend(emitter) {
|
|
|
11085
11826
|
await ilink.stopIlink({ logout: false });
|
|
11086
11827
|
session.clearSession();
|
|
11087
11828
|
await bridgeConnect.clearAll();
|
|
11088
|
-
await new Promise((
|
|
11829
|
+
await new Promise((resolve9) => setTimeout(resolve9, 100));
|
|
11089
11830
|
terminal.killAllTerminals();
|
|
11090
11831
|
await watcher2.stopAll();
|
|
11091
11832
|
for (const file of await readdir2(TEMP_DIR)) {
|
|
@@ -11096,7 +11837,7 @@ function initBackend(emitter) {
|
|
|
11096
11837
|
}
|
|
11097
11838
|
|
|
11098
11839
|
// package.json
|
|
11099
|
-
var version = "0.1.
|
|
11840
|
+
var version = "0.1.49";
|
|
11100
11841
|
|
|
11101
11842
|
// src/server/main.ts
|
|
11102
11843
|
var port;
|
|
@@ -11125,6 +11866,14 @@ Options:
|
|
|
11125
11866
|
process.exit(0);
|
|
11126
11867
|
}
|
|
11127
11868
|
}
|
|
11869
|
+
var proxySettings = storageOps.getSettings().proxy;
|
|
11870
|
+
if (proxySettings.mode === "system") {
|
|
11871
|
+
const detected = detectSystemProxy();
|
|
11872
|
+
applyProxy(detected);
|
|
11873
|
+
console.log(`[proxy] system proxy: ${detected.httpProxy || detected.httpsProxy || "none"}`);
|
|
11874
|
+
} else {
|
|
11875
|
+
applyProxy(settingProxyInfoToProxyConfig(proxySettings));
|
|
11876
|
+
}
|
|
11128
11877
|
var { backendHandlers, closeBackend } = initBackend(() => false);
|
|
11129
11878
|
backendHandlers.startWebUIServer({ port, token }).then(({ url }) => {
|
|
11130
11879
|
const title = `Fello Server v${version}`;
|