@zythum02/fello-server 0.1.53 → 0.1.54
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/out/renderer/assets/{_baseUniq-CJr3HkLS.js → _baseUniq-DYINnBRJ.js} +1 -1
- package/out/renderer/assets/_baseUniq-DYINnBRJ.js.br +0 -0
- package/out/renderer/assets/_baseUniq-DYINnBRJ.js.gz +0 -0
- package/out/renderer/assets/{arc-POsBroTF.js → arc-BSUyw88k.js} +1 -1
- package/out/renderer/assets/arc-BSUyw88k.js.br +0 -0
- package/out/renderer/assets/arc-BSUyw88k.js.gz +0 -0
- package/out/renderer/assets/{architectureDiagram-Q4EWVU46-CmToUhDb.js → architectureDiagram-Q4EWVU46-Cxb8DhYZ.js} +6 -6
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-Cxb8DhYZ.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-Cxb8DhYZ.js.gz +0 -0
- package/out/renderer/assets/{arrow-left-CxS1t3f7.js → arrow-left-CQqe9rrj.js} +1 -1
- package/out/renderer/assets/arrow-up-1eI4tva4.js +21 -0
- package/out/renderer/assets/{automation-Cyz3eLWp.js → automation-CQAOpWYp.js} +7 -7
- package/out/renderer/assets/automation-CQAOpWYp.js.br +0 -0
- package/out/renderer/assets/automation-CQAOpWYp.js.gz +0 -0
- package/out/renderer/assets/{blockDiagram-DXYQGD6D-M2nnTg9f.js → blockDiagram-DXYQGD6D-CFozis-v.js} +7 -7
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CFozis-v.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-CFozis-v.js.gz +0 -0
- package/out/renderer/assets/{c4Diagram-AHTNJAMY-CwLtsy_0.js → c4Diagram-AHTNJAMY-CcDDkZUp.js} +3 -3
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CcDDkZUp.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CcDDkZUp.js.gz +0 -0
- package/out/renderer/assets/{channel-BUNDMqpH.js → channel-B-VC_ZcK.js} +1 -1
- package/out/renderer/assets/{chunk-4BX2VUAB-B2qXmkDT.js → chunk-4BX2VUAB-ClHmnOTC.js} +1 -1
- package/out/renderer/assets/{chunk-4TB4RGXK-DXLZpPY5.js → chunk-4TB4RGXK-mwOvn19G.js} +5 -5
- package/out/renderer/assets/chunk-4TB4RGXK-mwOvn19G.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-mwOvn19G.js.gz +0 -0
- package/out/renderer/assets/{chunk-55IACEB6-CJeyefxI.js → chunk-55IACEB6-CE8f6iip.js} +1 -1
- package/out/renderer/assets/{chunk-EDXVE4YY-CNjJEQfY.js → chunk-EDXVE4YY-CU7aY96h.js} +1 -1
- package/out/renderer/assets/chunk-EDXVE4YY-CU7aY96h.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-CU7aY96h.js.gz +0 -0
- package/out/renderer/assets/{chunk-FMBD7UC4-DOAOsjRu.js → chunk-FMBD7UC4-B38kFkjv.js} +1 -1
- package/out/renderer/assets/{chunk-OYMX7WX6-BG4B1VQ7.js → chunk-OYMX7WX6-BriTCtaz.js} +3 -3
- package/out/renderer/assets/chunk-OYMX7WX6-BriTCtaz.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-BriTCtaz.js.gz +0 -0
- package/out/renderer/assets/{chunk-QZHKN3VN-B9zfXYIQ.js → chunk-QZHKN3VN-BwJ37p5G.js} +1 -1
- package/out/renderer/assets/{chunk-YZCP3GAM-jeoI2tsD.js → chunk-YZCP3GAM-BlHAYoQe.js} +1 -1
- package/out/renderer/assets/chunk-YZCP3GAM-BlHAYoQe.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-BlHAYoQe.js.gz +0 -0
- package/out/renderer/assets/{circle-x-B1kBsMlS.js → circle-x-D_gJIgxf.js} +1 -1
- package/out/renderer/assets/{classDiagram-v2-HSJHXN6E-DWPFF3Yt.js → classDiagram-6PBFFD2Q-D01ZMeaj.js} +7 -7
- package/out/renderer/assets/{classDiagram-6PBFFD2Q-DWPFF3Yt.js → classDiagram-v2-HSJHXN6E-D01ZMeaj.js} +7 -7
- package/out/renderer/assets/{clone-Dcvr9oKv.js → clone-qctAbdCx.js} +1 -1
- package/out/renderer/assets/{code-editor-CEXlC4aV.js → code-editor-tm0AYOLz.js} +2 -2
- package/out/renderer/assets/code-editor-tm0AYOLz.js.br +0 -0
- package/out/renderer/assets/code-editor-tm0AYOLz.js.gz +0 -0
- package/out/renderer/assets/{collapsible-CMuCJUWG.js → collapsible-DD6NlDid.js} +1 -1
- package/out/renderer/assets/collapsible-DD6NlDid.js.br +0 -0
- package/out/renderer/assets/collapsible-DD6NlDid.js.gz +0 -0
- package/out/renderer/assets/command-BF4jOeoL.js +11 -0
- package/out/renderer/assets/{cose-bilkent-S5V4N54A-B3bgImVS.js → cose-bilkent-S5V4N54A-CF4brbsf.js} +2 -2
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CF4brbsf.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-CF4brbsf.js.gz +0 -0
- package/out/renderer/assets/{dagre-KV5264BT-DTbumBA_.js → dagre-KV5264BT-C6I5VgRp.js} +7 -7
- package/out/renderer/assets/dagre-KV5264BT-C6I5VgRp.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-C6I5VgRp.js.gz +0 -0
- package/out/renderer/assets/{diagram-5BDNPKRD-B34Y6e8q.js → diagram-5BDNPKRD-BAO72D5R.js} +7 -7
- package/out/renderer/assets/diagram-5BDNPKRD-BAO72D5R.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-BAO72D5R.js.gz +0 -0
- package/out/renderer/assets/{diagram-G4DWMVQ6-BBiBmFR4.js → diagram-G4DWMVQ6-BmpkrtJs.js} +7 -7
- package/out/renderer/assets/diagram-G4DWMVQ6-BmpkrtJs.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-BmpkrtJs.js.gz +0 -0
- package/out/renderer/assets/{diagram-MMDJMWI5-P-YslDjG.js → diagram-MMDJMWI5-8keZZjgB.js} +6 -6
- package/out/renderer/assets/diagram-MMDJMWI5-8keZZjgB.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-8keZZjgB.js.gz +0 -0
- package/out/renderer/assets/{diagram-TYMM5635-D_cLard_.js → diagram-TYMM5635-Be4uDvHI.js} +6 -6
- package/out/renderer/assets/diagram-TYMM5635-Be4uDvHI.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-Be4uDvHI.js.gz +0 -0
- package/out/renderer/assets/{ellipsis-D1agTYu1.js → ellipsis-92s4sSUO.js} +1 -1
- package/out/renderer/assets/{erDiagram-SMLLAGMA-C1MHqKvC.js → erDiagram-SMLLAGMA-C6IgAbhi.js} +5 -5
- package/out/renderer/assets/erDiagram-SMLLAGMA-C6IgAbhi.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-C6IgAbhi.js.gz +0 -0
- package/out/renderer/assets/{field-DR3J0r9e.js → field-BPsDfe4e.js} +1 -1
- package/out/renderer/assets/field-BPsDfe4e.js.br +0 -0
- package/out/renderer/assets/field-BPsDfe4e.js.gz +0 -0
- package/out/renderer/assets/{file-text-nGCW6zu1.js → file-text-ITbWr8iW.js} +1 -1
- package/out/renderer/assets/{flowDiagram-DWJPFMVM-DprlEc3Z.js → flowDiagram-DWJPFMVM-vbYKBn4t.js} +7 -7
- package/out/renderer/assets/flowDiagram-DWJPFMVM-vbYKBn4t.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-vbYKBn4t.js.gz +0 -0
- package/out/renderer/assets/{ganttDiagram-T4ZO3ILL-CbTdumBm.js → ganttDiagram-T4ZO3ILL-AxXIe9I4.js} +3 -3
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-AxXIe9I4.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-AxXIe9I4.js.gz +0 -0
- package/out/renderer/assets/{gitGraphDiagram-UUTBAWPF-06bme-w8.js → gitGraphDiagram-UUTBAWPF-DSipARMB.js} +7 -7
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-DSipARMB.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-DSipARMB.js.gz +0 -0
- package/out/renderer/assets/{graph-BZhxluo9.js → graph-mNaHfg3r.js} +2 -2
- package/out/renderer/assets/graph-mNaHfg3r.js.br +0 -0
- package/out/renderer/assets/graph-mNaHfg3r.js.gz +0 -0
- package/out/renderer/assets/{highlighted-body-OFNGDK62-CvDMJtXf.js → highlighted-body-OFNGDK62-8846XFj-.js} +2 -2
- package/out/renderer/assets/{index-LmYTNvdF.js → index-BUwXrbHW.js} +1643 -776
- package/out/renderer/assets/index-BUwXrbHW.js.br +0 -0
- package/out/renderer/assets/index-BUwXrbHW.js.gz +0 -0
- package/out/renderer/assets/index-DOIzYXAl.css +382 -0
- package/out/renderer/assets/index-DOIzYXAl.css.br +0 -0
- package/out/renderer/assets/index-DOIzYXAl.css.gz +0 -0
- package/out/renderer/assets/{infoDiagram-42DDH7IO-DqivEzWL.js → infoDiagram-42DDH7IO-ThYxaM6U.js} +5 -5
- package/out/renderer/assets/infoDiagram-42DDH7IO-ThYxaM6U.js.br +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-ThYxaM6U.js.gz +0 -0
- package/out/renderer/assets/{ishikawaDiagram-UXIWVN3A-BKcg_z4w.js → ishikawaDiagram-UXIWVN3A-EcWEDDQ3.js} +2 -2
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-EcWEDDQ3.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-EcWEDDQ3.js.gz +0 -0
- package/out/renderer/assets/{item-BHEUMM9H.js → item-Dph2aCdz.js} +20 -2
- package/out/renderer/assets/item-Dph2aCdz.js.br +0 -0
- package/out/renderer/assets/item-Dph2aCdz.js.gz +0 -0
- package/out/renderer/assets/{journeyDiagram-VCZTEJTY-Bvv8xuxQ.js → journeyDiagram-VCZTEJTY-Ct6VLkXK.js} +5 -5
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Ct6VLkXK.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Ct6VLkXK.js.gz +0 -0
- package/out/renderer/assets/{kanban-definition-6JOO6SKY-C-gRMpeM.js → kanban-definition-6JOO6SKY-DHWulQen.js} +3 -3
- package/out/renderer/assets/kanban-definition-6JOO6SKY-DHWulQen.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-DHWulQen.js.gz +0 -0
- package/out/renderer/assets/{layout-B4dSyItA.js → layout-pfquJ3N_.js} +4 -4
- package/out/renderer/assets/layout-pfquJ3N_.js.br +0 -0
- package/out/renderer/assets/layout-pfquJ3N_.js.gz +0 -0
- package/out/renderer/assets/{linear-CoVhuer7.js → linear-CdfVBcAB.js} +1 -1
- package/out/renderer/assets/linear-CdfVBcAB.js.br +0 -0
- package/out/renderer/assets/linear-CdfVBcAB.js.gz +0 -0
- package/out/renderer/assets/{link-2-DHUPzNSt.js → link-2-DpdZfD3m.js} +1 -1
- package/out/renderer/assets/{mermaid-GHXKKRXX-CZqkhGx7.js → mermaid-GHXKKRXX-CqMNodCp.js} +36 -36
- package/out/renderer/assets/mermaid-GHXKKRXX-CqMNodCp.js.br +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-CqMNodCp.js.gz +0 -0
- package/out/renderer/assets/{mic-BgSvicCB.js → mic-CT1bYBEV.js} +1 -1
- package/out/renderer/assets/{min-emzuJjmk.js → min-CiK16GFr.js} +2 -2
- package/out/renderer/assets/min-CiK16GFr.js.br +0 -0
- package/out/renderer/assets/min-CiK16GFr.js.gz +0 -0
- package/out/renderer/assets/{mindmap-definition-QFDTVHPH-DQ4JNECm.js → mindmap-definition-QFDTVHPH-BvmM-Xdx.js} +4 -4
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-BvmM-Xdx.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-BvmM-Xdx.js.gz +0 -0
- package/out/renderer/assets/{open-guide-CfLO-Sdk.js → open-guide-BqiUQfrM.js} +1 -1
- package/out/renderer/assets/{package-search-CrF2Iegl.js → package-search-BxIuIl9F.js} +1 -1
- package/out/renderer/assets/{pieDiagram-DEJITSTG-0H6CGQQt.js → pieDiagram-DEJITSTG-CQY4NZ_4.js} +7 -7
- package/out/renderer/assets/pieDiagram-DEJITSTG-CQY4NZ_4.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-CQY4NZ_4.js.gz +0 -0
- package/out/renderer/assets/{plus-YNCXW-GD.js → plus-C5XdFVFm.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-34T5L4WZ-D0aPKp5z.js → quadrantDiagram-34T5L4WZ-BiDWKNht.js} +3 -3
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-BiDWKNht.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-BiDWKNht.js.gz +0 -0
- package/out/renderer/assets/{requirementDiagram-MS252O5E-BkzwapW_.js → requirementDiagram-MS252O5E-D-KxL9Tf.js} +4 -4
- package/out/renderer/assets/requirementDiagram-MS252O5E-D-KxL9Tf.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-D-KxL9Tf.js.gz +0 -0
- package/out/renderer/assets/{resizable-cStzNJ8V.js → resizable-ObbINbIB.js} +1 -1
- package/out/renderer/assets/resizable-ObbINbIB.js.br +0 -0
- package/out/renderer/assets/resizable-ObbINbIB.js.gz +0 -0
- package/out/renderer/assets/{sankeyDiagram-XADWPNL6-Dbde7usj.js → sankeyDiagram-XADWPNL6-BIFbqkzs.js} +2 -2
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-BIFbqkzs.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-BIFbqkzs.js.gz +0 -0
- package/out/renderer/assets/{schedule-DNMCsk-G.js → schedule-BtuArq_x.js} +9 -9
- package/out/renderer/assets/schedule-BtuArq_x.js.br +0 -0
- package/out/renderer/assets/schedule-BtuArq_x.js.gz +0 -0
- package/out/renderer/assets/{search-BEY9yGF_.js → search-TCnuQyCi.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-FGHM5R23-DI8l1pSL.js → sequenceDiagram-FGHM5R23-DQX-_zuj.js} +4 -4
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DQX-_zuj.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DQX-_zuj.js.gz +0 -0
- package/out/renderer/assets/{session-Bn5k9ScR.js → session-C_1BpGhU.js} +956 -269
- package/out/renderer/assets/session-C_1BpGhU.js.br +0 -0
- package/out/renderer/assets/session-C_1BpGhU.js.gz +0 -0
- package/out/renderer/assets/{setting-dialog-sqfPfGsy.js → setting-dialog-D1_-4H95.js} +3 -3
- package/out/renderer/assets/setting-dialog-D1_-4H95.js.br +0 -0
- package/out/renderer/assets/setting-dialog-D1_-4H95.js.gz +0 -0
- package/out/renderer/assets/{settings-2-DRhoXOO8.js → settings-2-BwfZrIw6.js} +1 -1
- package/out/renderer/assets/{settings-agents-Bntc31Nn.js → settings-agents-BtuYXQ1V.js} +26 -14
- package/out/renderer/assets/settings-agents-BtuYXQ1V.js.br +0 -0
- package/out/renderer/assets/settings-agents-BtuYXQ1V.js.gz +0 -0
- package/out/renderer/assets/{settings-general-DhbLb9cP.js → settings-general-cHqsKFFa.js} +36 -3
- package/out/renderer/assets/settings-general-cHqsKFFa.js.br +0 -0
- package/out/renderer/assets/settings-general-cHqsKFFa.js.gz +0 -0
- package/out/renderer/assets/{settings-ilink-C7nGGjwT.js → settings-ilink-BR1Vd9t9.js} +3 -3
- package/out/renderer/assets/settings-ilink-BR1Vd9t9.js.br +0 -0
- package/out/renderer/assets/settings-ilink-BR1Vd9t9.js.gz +0 -0
- package/out/renderer/assets/{settings-image-generation-H2dgqG7Y.js → settings-image-generation-MUHYnpbm.js} +6 -6
- package/out/renderer/assets/settings-image-generation-MUHYnpbm.js.br +0 -0
- package/out/renderer/assets/settings-image-generation-MUHYnpbm.js.gz +0 -0
- package/out/renderer/assets/{settings-layout-ATto1xpJ.js → settings-layout-SBihzFfb.js} +10 -3
- package/out/renderer/assets/settings-layout-SBihzFfb.js.br +0 -0
- package/out/renderer/assets/settings-layout-SBihzFfb.js.gz +0 -0
- package/out/renderer/assets/{settings-mcp-DUdMuoJ-.js → settings-mcp-Co88s-0y.js} +8 -8
- package/out/renderer/assets/settings-mcp-Co88s-0y.js.br +0 -0
- package/out/renderer/assets/settings-mcp-Co88s-0y.js.gz +0 -0
- package/out/renderer/assets/{settings-memory-CJLG4aHW.js → settings-memory-CNH9gHYC.js} +2 -3
- package/out/renderer/assets/settings-memory-CNH9gHYC.js.br +0 -0
- package/out/renderer/assets/settings-memory-CNH9gHYC.js.gz +0 -0
- package/out/renderer/assets/settings-shortcuts-C1s7YIMj.js +267 -0
- package/out/renderer/assets/settings-shortcuts-C1s7YIMj.js.br +0 -0
- package/out/renderer/assets/settings-shortcuts-C1s7YIMj.js.gz +0 -0
- package/out/renderer/assets/{settings-snippets-B4VcnD5Z.js → settings-snippets-DGgI6mxm.js} +7 -7
- package/out/renderer/assets/settings-snippets-DGgI6mxm.js.br +0 -0
- package/out/renderer/assets/settings-snippets-DGgI6mxm.js.gz +0 -0
- package/out/renderer/assets/{settings-speech-to-text-DQ7lfkTu.js → settings-speech-to-text-CV0xM7yz.js} +5 -5
- package/out/renderer/assets/settings-speech-to-text-CV0xM7yz.js.br +0 -0
- package/out/renderer/assets/settings-speech-to-text-CV0xM7yz.js.gz +0 -0
- package/out/renderer/assets/{settings-webui-DZf9O-6j.js → settings-webui-Bj9dJDcm.js} +2 -2
- package/out/renderer/assets/settings-webui-Bj9dJDcm.js.br +0 -0
- package/out/renderer/assets/settings-webui-Bj9dJDcm.js.gz +0 -0
- package/out/renderer/assets/{skills-installed-Dp0r_4I-.js → skills-installed-Bhd5a33I.js} +4 -4
- package/out/renderer/assets/skills-installed-Bhd5a33I.js.br +0 -0
- package/out/renderer/assets/skills-installed-Bhd5a33I.js.gz +0 -0
- package/out/renderer/assets/{skills-layout-D-5rlY38.js → skills-layout-DZFDa1cw.js} +2 -2
- package/out/renderer/assets/skills-layout-DZFDa1cw.js.br +0 -0
- package/out/renderer/assets/skills-layout-DZFDa1cw.js.gz +0 -0
- package/out/renderer/assets/{skills-skills-sh-CcLoIrSw.js → skills-skills-sh-DF59nekm.js} +4 -4
- package/out/renderer/assets/skills-skills-sh-DF59nekm.js.br +0 -0
- package/out/renderer/assets/skills-skills-sh-DF59nekm.js.gz +0 -0
- package/out/renderer/assets/{sortable.esm-knFxDx0Y.js → sortable.esm-BlhN8Kkg.js} +1 -1
- package/out/renderer/assets/sortable.esm-BlhN8Kkg.js.br +0 -0
- package/out/renderer/assets/sortable.esm-BlhN8Kkg.js.gz +0 -0
- package/out/renderer/assets/{standard-schema-dKXoCekr.js → standard-schema-CGAs4bGi.js} +1 -1
- package/out/renderer/assets/standard-schema-CGAs4bGi.js.br +0 -0
- package/out/renderer/assets/standard-schema-CGAs4bGi.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-FHFEXIEX-DWWz4PMv.js → stateDiagram-FHFEXIEX-DappRrGm.js} +9 -9
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DappRrGm.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DappRrGm.js.gz +0 -0
- package/out/renderer/assets/{stateDiagram-v2-QKLJ7IA2-Dm2qD5bg.js → stateDiagram-v2-QKLJ7IA2-mbgJN2Ya.js} +5 -5
- package/out/renderer/assets/{task-C5dyYbfn.js → task-C7tCZ6e3.js} +11 -11
- package/out/renderer/assets/task-C7tCZ6e3.js.br +0 -0
- package/out/renderer/assets/task-C7tCZ6e3.js.gz +0 -0
- package/out/renderer/assets/{textarea-DTqKlQbL.js → textarea-DNSPhqFr.js} +2 -2
- package/out/renderer/assets/{timeline-definition-GMOUNBTQ-A1tEoL9d.js → timeline-definition-GMOUNBTQ-o8XIUDyn.js} +3 -3
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-o8XIUDyn.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-o8XIUDyn.js.gz +0 -0
- package/out/renderer/assets/{vennDiagram-DHZGUBPP-tNdYrJi_.js → vennDiagram-DHZGUBPP-mnc6bpmR.js} +2 -2
- package/out/renderer/assets/vennDiagram-DHZGUBPP-mnc6bpmR.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-mnc6bpmR.js.gz +0 -0
- package/out/renderer/assets/{wardley-RL74JXVD-BxN5_Sp6.js → wardley-RL74JXVD-wdJYeEiD.js} +4 -4
- package/out/renderer/assets/wardley-RL74JXVD-wdJYeEiD.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-wdJYeEiD.js.gz +0 -0
- package/out/renderer/assets/{wardleyDiagram-NUSXRM2D-B_3jA8zU.js → wardleyDiagram-NUSXRM2D-Ddx6k7tJ.js} +6 -6
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-Ddx6k7tJ.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-Ddx6k7tJ.js.gz +0 -0
- package/out/renderer/assets/{wrench-7r-g9MUq.js → wrench-BsjH8RPm.js} +1 -1
- package/out/renderer/assets/wrench-BsjH8RPm.js.br +0 -0
- package/out/renderer/assets/wrench-BsjH8RPm.js.gz +0 -0
- package/out/renderer/assets/{xlsx-view-Bv0YhA5m.js → xlsx-view-CQd4jbk-.js} +21 -13
- package/out/renderer/assets/xlsx-view-CQd4jbk-.js.br +0 -0
- package/out/renderer/assets/xlsx-view-CQd4jbk-.js.gz +0 -0
- package/out/renderer/assets/{xychartDiagram-5P7HB3ND-NNVuzC4j.js → xychartDiagram-5P7HB3ND-VIQ9wuz0.js} +3 -3
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-VIQ9wuz0.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-VIQ9wuz0.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-skills/server.mjs +1 -1
- package/out/server/main.js +44 -1
- package/package.json +1 -1
- package/out/renderer/assets/_baseUniq-CJr3HkLS.js.br +0 -0
- package/out/renderer/assets/_baseUniq-CJr3HkLS.js.gz +0 -0
- package/out/renderer/assets/arc-POsBroTF.js.br +0 -0
- package/out/renderer/assets/arc-POsBroTF.js.gz +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.br +0 -0
- package/out/renderer/assets/architectureDiagram-Q4EWVU46-CmToUhDb.js.gz +0 -0
- package/out/renderer/assets/automation-Cyz3eLWp.js.br +0 -0
- package/out/renderer/assets/automation-Cyz3eLWp.js.gz +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.br +0 -0
- package/out/renderer/assets/blockDiagram-DXYQGD6D-M2nnTg9f.js.gz +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.br +0 -0
- package/out/renderer/assets/c4Diagram-AHTNJAMY-CwLtsy_0.js.gz +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.br +0 -0
- package/out/renderer/assets/chunk-4TB4RGXK-DXLZpPY5.js.gz +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.br +0 -0
- package/out/renderer/assets/chunk-EDXVE4YY-CNjJEQfY.js.gz +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.br +0 -0
- package/out/renderer/assets/chunk-OYMX7WX6-BG4B1VQ7.js.gz +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.br +0 -0
- package/out/renderer/assets/chunk-YZCP3GAM-jeoI2tsD.js.gz +0 -0
- package/out/renderer/assets/code-editor-CEXlC4aV.js.br +0 -0
- package/out/renderer/assets/code-editor-CEXlC4aV.js.gz +0 -0
- package/out/renderer/assets/collapsible-CMuCJUWG.js.br +0 -0
- package/out/renderer/assets/collapsible-CMuCJUWG.js.gz +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.br +0 -0
- package/out/renderer/assets/cose-bilkent-S5V4N54A-B3bgImVS.js.gz +0 -0
- package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.br +0 -0
- package/out/renderer/assets/dagre-KV5264BT-DTbumBA_.js.gz +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.br +0 -0
- package/out/renderer/assets/diagram-5BDNPKRD-B34Y6e8q.js.gz +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.br +0 -0
- package/out/renderer/assets/diagram-G4DWMVQ6-BBiBmFR4.js.gz +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.br +0 -0
- package/out/renderer/assets/diagram-MMDJMWI5-P-YslDjG.js.gz +0 -0
- package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.br +0 -0
- package/out/renderer/assets/diagram-TYMM5635-D_cLard_.js.gz +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.br +0 -0
- package/out/renderer/assets/erDiagram-SMLLAGMA-C1MHqKvC.js.gz +0 -0
- package/out/renderer/assets/field-DR3J0r9e.js.br +0 -0
- package/out/renderer/assets/field-DR3J0r9e.js.gz +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.br +0 -0
- package/out/renderer/assets/flowDiagram-DWJPFMVM-DprlEc3Z.js.gz +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.br +0 -0
- package/out/renderer/assets/ganttDiagram-T4ZO3ILL-CbTdumBm.js.gz +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.br +0 -0
- package/out/renderer/assets/gitGraphDiagram-UUTBAWPF-06bme-w8.js.gz +0 -0
- package/out/renderer/assets/graph-BZhxluo9.js.br +0 -0
- package/out/renderer/assets/graph-BZhxluo9.js.gz +0 -0
- package/out/renderer/assets/index-LmYTNvdF.js.br +0 -0
- package/out/renderer/assets/index-LmYTNvdF.js.gz +0 -0
- package/out/renderer/assets/index-aGJ_yZib.css +0 -382
- package/out/renderer/assets/index-aGJ_yZib.css.br +0 -0
- package/out/renderer/assets/index-aGJ_yZib.css.gz +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.br +0 -0
- package/out/renderer/assets/infoDiagram-42DDH7IO-DqivEzWL.js.gz +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.br +0 -0
- package/out/renderer/assets/ishikawaDiagram-UXIWVN3A-BKcg_z4w.js.gz +0 -0
- package/out/renderer/assets/item-BHEUMM9H.js.br +0 -0
- package/out/renderer/assets/item-BHEUMM9H.js.gz +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.br +0 -0
- package/out/renderer/assets/journeyDiagram-VCZTEJTY-Bvv8xuxQ.js.gz +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.br +0 -0
- package/out/renderer/assets/kanban-definition-6JOO6SKY-C-gRMpeM.js.gz +0 -0
- package/out/renderer/assets/layout-B4dSyItA.js.br +0 -0
- package/out/renderer/assets/layout-B4dSyItA.js.gz +0 -0
- package/out/renderer/assets/linear-CoVhuer7.js.br +0 -0
- package/out/renderer/assets/linear-CoVhuer7.js.gz +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.br +0 -0
- package/out/renderer/assets/mermaid-GHXKKRXX-CZqkhGx7.js.gz +0 -0
- package/out/renderer/assets/min-emzuJjmk.js.br +0 -0
- package/out/renderer/assets/min-emzuJjmk.js.gz +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.br +0 -0
- package/out/renderer/assets/mindmap-definition-QFDTVHPH-DQ4JNECm.js.gz +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.br +0 -0
- package/out/renderer/assets/pieDiagram-DEJITSTG-0H6CGQQt.js.gz +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.br +0 -0
- package/out/renderer/assets/quadrantDiagram-34T5L4WZ-D0aPKp5z.js.gz +0 -0
- package/out/renderer/assets/refresh-cw-Bvm578nW.js +0 -11
- package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.br +0 -0
- package/out/renderer/assets/requirementDiagram-MS252O5E-BkzwapW_.js.gz +0 -0
- package/out/renderer/assets/resizable-cStzNJ8V.js.br +0 -0
- package/out/renderer/assets/resizable-cStzNJ8V.js.gz +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.br +0 -0
- package/out/renderer/assets/sankeyDiagram-XADWPNL6-Dbde7usj.js.gz +0 -0
- package/out/renderer/assets/schedule-DNMCsk-G.js.br +0 -0
- package/out/renderer/assets/schedule-DNMCsk-G.js.gz +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.br +0 -0
- package/out/renderer/assets/sequenceDiagram-FGHM5R23-DI8l1pSL.js.gz +0 -0
- package/out/renderer/assets/session-Bn5k9ScR.js.br +0 -0
- package/out/renderer/assets/session-Bn5k9ScR.js.gz +0 -0
- package/out/renderer/assets/setting-dialog-sqfPfGsy.js.br +0 -0
- package/out/renderer/assets/setting-dialog-sqfPfGsy.js.gz +0 -0
- package/out/renderer/assets/settings-agents-Bntc31Nn.js.br +0 -0
- package/out/renderer/assets/settings-agents-Bntc31Nn.js.gz +0 -0
- package/out/renderer/assets/settings-general-DhbLb9cP.js.br +0 -0
- package/out/renderer/assets/settings-general-DhbLb9cP.js.gz +0 -0
- package/out/renderer/assets/settings-ilink-C7nGGjwT.js.br +0 -0
- package/out/renderer/assets/settings-ilink-C7nGGjwT.js.gz +0 -0
- package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.br +0 -0
- package/out/renderer/assets/settings-image-generation-H2dgqG7Y.js.gz +0 -0
- package/out/renderer/assets/settings-layout-ATto1xpJ.js.br +0 -0
- package/out/renderer/assets/settings-layout-ATto1xpJ.js.gz +0 -0
- package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.br +0 -0
- package/out/renderer/assets/settings-mcp-DUdMuoJ-.js.gz +0 -0
- package/out/renderer/assets/settings-memory-CJLG4aHW.js.br +0 -0
- package/out/renderer/assets/settings-memory-CJLG4aHW.js.gz +0 -0
- package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.br +0 -0
- package/out/renderer/assets/settings-snippets-B4VcnD5Z.js.gz +0 -0
- package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.br +0 -0
- package/out/renderer/assets/settings-speech-to-text-DQ7lfkTu.js.gz +0 -0
- package/out/renderer/assets/settings-webui-DZf9O-6j.js.br +0 -0
- package/out/renderer/assets/settings-webui-DZf9O-6j.js.gz +0 -0
- package/out/renderer/assets/skills-installed-Dp0r_4I-.js.br +0 -0
- package/out/renderer/assets/skills-installed-Dp0r_4I-.js.gz +0 -0
- package/out/renderer/assets/skills-layout-D-5rlY38.js.br +0 -0
- package/out/renderer/assets/skills-layout-D-5rlY38.js.gz +0 -0
- package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.br +0 -0
- package/out/renderer/assets/skills-skills-sh-CcLoIrSw.js.gz +0 -0
- package/out/renderer/assets/sortable.esm-knFxDx0Y.js.br +0 -0
- package/out/renderer/assets/sortable.esm-knFxDx0Y.js.gz +0 -0
- package/out/renderer/assets/standard-schema-dKXoCekr.js.br +0 -0
- package/out/renderer/assets/standard-schema-dKXoCekr.js.gz +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.br +0 -0
- package/out/renderer/assets/stateDiagram-FHFEXIEX-DWWz4PMv.js.gz +0 -0
- package/out/renderer/assets/task-C5dyYbfn.js.br +0 -0
- package/out/renderer/assets/task-C5dyYbfn.js.gz +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.br +0 -0
- package/out/renderer/assets/timeline-definition-GMOUNBTQ-A1tEoL9d.js.gz +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.br +0 -0
- package/out/renderer/assets/vennDiagram-DHZGUBPP-tNdYrJi_.js.gz +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.br +0 -0
- package/out/renderer/assets/wardley-RL74JXVD-BxN5_Sp6.js.gz +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.br +0 -0
- package/out/renderer/assets/wardleyDiagram-NUSXRM2D-B_3jA8zU.js.gz +0 -0
- package/out/renderer/assets/wrench-7r-g9MUq.js.br +0 -0
- package/out/renderer/assets/wrench-7r-g9MUq.js.gz +0 -0
- package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.br +0 -0
- package/out/renderer/assets/xlsx-view-Bv0YhA5m.js.gz +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.br +0 -0
- package/out/renderer/assets/xychartDiagram-5P7HB3ND-NNVuzC4j.js.gz +0 -0
|
@@ -1,36 +1,21 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-
|
|
2
|
-
import {
|
|
3
|
-
import { S as Settings2 } from "./settings-2-
|
|
4
|
-
import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { S as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { P as Plus } from "./plus-
|
|
14
|
-
import { R as ResizablePanelGroup, a as ResizablePanel, b as ResizableHandle } from "./resizable-
|
|
15
|
-
import "./collapsible-
|
|
16
|
-
import "./item-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./code-editor-tm0AYOLz.js","./index-BUwXrbHW.js","./index-DOIzYXAl.css","./mermaid-GHXKKRXX-CqMNodCp.js","./code-editor-BwxubRqT.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import { c as createLucideIcon, r as reactExports, av as formatErrorMessage, bz as ReactStore, bA as popupStoreSelectors, bB as triggerHover, au as triggerPress, bC as escapeKey, bD as attachPreventUnmountOnClose, bE as closePress, bF as PATIENT_CLICK_THRESHOLD, an as reactDomExports, bG as focusOut, bH as setPopupOpenState, bI as createInitialPopupStoreState, bJ as createPopupFloatingRootContext, bK as Timeout, bL as PopupTriggerMap, j as jsxRuntimeExports, bM as FloatingTree, bN as usePopupRootSync, bO as useImplicitActiveTrigger, bP as useOpenStateTransitions, at as createChangeEventDetails, bQ as imperativeAction, bR as PopupHandleAttachment, bS as usePopupRootStore, bT as useDismiss, bU as usePopupInteractionProps, bV as usePopupHandleStore, ar as useBaseUiId, bW as useTriggerDataForwarding, bX as useHoverReferenceInteraction, bY as safePolygon, bZ as useClick, b_ as useOpenMethodTriggerProps, az as useButton, b$ as useTriggerFocusGuards, ay as useRenderElement, c0 as CLICK_TRIGGER_IDENTIFIER, c1 as FocusGuard, c2 as pressableTriggerOpenStateMapping, c3 as triggerOpenStateMapping, c4 as FloatingPortal, c5 as POPUP_COLLISION_AVOIDANCE, c6 as useFloatingNodeId, aC as useAnimationsFinished, c7 as useAnchorPositioning, aD as useIsoLayoutEffect, c8 as useAnchoredPopupScrollLock, c9 as usePositioner, ca as InternalBackdrop, cb as inertValue, cc as FloatingNode, as as useStableCallback, cd as useToolbarRootContext, aE as useOpenChangeComplete, ce as useHoverFloatingInteraction, cf as createDefaultInitialFocus, cg as FOCUSABLE_POPUP_PROPS, bj as COMPOSITE_KEYS, ch as getDisabledMountTransitionStyles, ci as FloatingFocusManager, cj as isHTMLElement, ck as popupTransitionStateMapping, u as useTranslation, b as useMessage, X as useNavigate, a as useAppStore, f as request, g as extractErrorMessage, _ as Badge, cl as formatUpdatedTime, V as electron, aK as Tabs, aL as TabsList, aM as TabsTrigger, af as ALL_FEATURES, ag as FEATURE_I18N_KEYS, M as cn$1, d as Switch, B as Button, R as LoaderCircle, cm as buttonVariants, C as Check, e as Copy, i as isWebUI, U as FolderOpen, cn as restartSession, co as SessionLifecycleBusyError, cp as closeSession, h as copyText, cq as RestartSessionError, am as React, cr as Tooltip, cs as TooltipTrigger, ct as TooltipContent, cu as useFocusTarget, S as ScrollArea, a1 as Bot, cv as formatDuration, ao as getDefaultExportFromCjs, cw as ReactDOM, Y as subscribe, cx as clientId, A as DropdownMenu, E as DropdownMenuTrigger, cy as ChevronDown, F as DropdownMenuContent, G as DropdownMenuItem, cz as v$2, J as generateUUID, aP as reduceFlushStreaming, cA as HoverCard, cB as HoverCardTrigger, cC as HoverCardContent, cD as X$1, aR as Folder, L as Library, cE as DropdownMenuSub, cF as DropdownMenuSubTrigger, cG as DropdownMenuSubContent, cH as CircleQuestionMark, cI as ChevronUp, aQ as Clock, cJ as z$1, a0 as CircleCheck, cK as __vitePreload, I as Input, m as ContextMenuContent, n as ContextMenuItem, o as ContextMenuSeparator, cL as Code, bt as EDITOR_LABELS, k as ContextMenu, l as ContextMenuTrigger, aN as webUIBaseUrl, a6 as RefreshCw, a7 as ChevronRight, cM as MessageSquare, cN as FolderPlus, cO as Eye, P as Pencil, T as Trash2, cP as useProjectState, cQ as useFocusTargetRegistry, cR as TabsContent, cS as loadSession } from "./index-BUwXrbHW.js";
|
|
3
|
+
import { S as Settings2 } from "./settings-2-BwfZrIw6.js";
|
|
4
|
+
import { i as isValidMessageToDisplay, M as MessageBubble, A as ArrowUpToLine, S as Square, j as jsonToPrettyYamlExports, p as parseFileReference, c as CodeCompareView, r as resolveFileUrl, I as ImageView, P as PdfView, D as DocxView, a as PptxView, X as XlsxView, R as RotateCcw, F as Folders } from "./xlsx-view-CQd4jbk-.js";
|
|
5
|
+
import { a as ArrowDown, A as ArrowUp, b as ArrowRight } from "./arrow-up-1eI4tva4.js";
|
|
6
|
+
import { M as Mic, C as Clipboard } from "./mic-CT1bYBEV.js";
|
|
7
|
+
import { I as Image, W as Wrench } from "./wrench-BsjH8RPm.js";
|
|
8
|
+
import { F as FileText } from "./file-text-ITbWr8iW.js";
|
|
9
|
+
import { A as ArrowLeft } from "./arrow-left-CQqe9rrj.js";
|
|
10
|
+
import { aQ as CodeView, S as StreamMarkdown, aR as FileIcon } from "./mermaid-GHXKKRXX-CqMNodCp.js";
|
|
11
|
+
import { S as Search } from "./search-TCnuQyCi.js";
|
|
12
|
+
import { E as ExternalLink } from "./link-2-DpdZfD3m.js";
|
|
13
|
+
import { P as Plus } from "./plus-C5XdFVFm.js";
|
|
14
|
+
import { R as ResizablePanelGroup, a as ResizablePanel, b as ResizableHandle } from "./resizable-ObbINbIB.js";
|
|
15
|
+
import "./collapsible-DD6NlDid.js";
|
|
16
|
+
import "./item-Dph2aCdz.js";
|
|
17
17
|
import "./schemas-c0X-G5_P.js";
|
|
18
|
-
import "./ellipsis-
|
|
19
|
-
const __iconNode$k = [
|
|
20
|
-
["path", { d: "M12 5v14", key: "s699le" }],
|
|
21
|
-
["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
|
|
22
|
-
];
|
|
23
|
-
const ArrowDown = createLucideIcon("arrow-down", __iconNode$k);
|
|
24
|
-
const __iconNode$j = [
|
|
25
|
-
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
26
|
-
["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
|
|
27
|
-
];
|
|
28
|
-
const ArrowRight = createLucideIcon("arrow-right", __iconNode$j);
|
|
29
|
-
const __iconNode$i = [
|
|
30
|
-
["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
|
|
31
|
-
["path", { d: "M12 19V5", key: "x0mq9r" }]
|
|
32
|
-
];
|
|
33
|
-
const ArrowUp = createLucideIcon("arrow-up", __iconNode$i);
|
|
18
|
+
import "./ellipsis-92s4sSUO.js";
|
|
34
19
|
const __iconNode$h = [
|
|
35
20
|
[
|
|
36
21
|
"path",
|
|
@@ -815,76 +800,71 @@ function ChatHeader({ session }) {
|
|
|
815
800
|
const currentProjectInfo = projects.find((project) => project.id === currentProjectId);
|
|
816
801
|
const [localMcpServers, setLocalMcpServers] = reactExports.useState([]);
|
|
817
802
|
const [localFeatures, setLocalFeatures] = reactExports.useState([]);
|
|
803
|
+
const [isRestarting, setIsRestarting] = reactExports.useState(false);
|
|
818
804
|
const [isClosing, setIsClosing] = reactExports.useState(false);
|
|
819
805
|
const handleToggle = reactExports.useCallback((mcpId) => {
|
|
820
806
|
setLocalMcpServers(
|
|
821
807
|
(prev) => prev.includes(mcpId) ? prev.filter((id) => id !== mcpId) : [...prev, mcpId]
|
|
822
808
|
);
|
|
823
809
|
}, []);
|
|
810
|
+
const handlePermissionChange = reactExports.useCallback(
|
|
811
|
+
async (permissionMode) => {
|
|
812
|
+
try {
|
|
813
|
+
await request.updateSession({ sessionId: session.id, permissionMode });
|
|
814
|
+
} catch (err) {
|
|
815
|
+
console.error("Failed to update session permission:", err);
|
|
816
|
+
toast.error(
|
|
817
|
+
extractErrorMessage(err) || t("chatHeader.failedToUpdatePermission", "Failed to update permission.")
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
[session.id, t, toast]
|
|
822
|
+
);
|
|
824
823
|
const handleSyncAndRefresh = async () => {
|
|
825
|
-
if (!session) return;
|
|
824
|
+
if (!session || isClosing || isRestarting) return;
|
|
825
|
+
setIsRestarting(true);
|
|
826
826
|
try {
|
|
827
|
-
await
|
|
828
|
-
|
|
827
|
+
await restartSession({
|
|
828
|
+
session,
|
|
829
829
|
mcpServers: localMcpServers,
|
|
830
830
|
features: localFeatures
|
|
831
831
|
});
|
|
832
832
|
} catch (err) {
|
|
833
|
-
console.error("Failed to
|
|
834
|
-
|
|
835
|
-
extractErrorMessage(err) || t("chat.failedToUpdateMcpServers", "Failed to update MCP servers")
|
|
836
|
-
);
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
const { resetSessionState, updateSessionState, updateSession } = useAppStore.getState();
|
|
840
|
-
try {
|
|
841
|
-
updateSession({ ...session, isStreaming: false });
|
|
842
|
-
updateSessionState(session.id, (prev) => reduceFlushStreaming(prev));
|
|
843
|
-
resetSessionState(session.id);
|
|
844
|
-
updateSessionState(session.id, () => ({ isLoading: true }));
|
|
845
|
-
const result = await request.getSessionHistory({ sessionId: session.id });
|
|
846
|
-
if (!result) return;
|
|
847
|
-
let state = useAppStore.getState().getSessionState(session.id);
|
|
848
|
-
state = { ...state, messages: [], activeToolCalls: /* @__PURE__ */ new Map(), activeSubagents: /* @__PURE__ */ new Map() };
|
|
849
|
-
for (const notification of result.messages) {
|
|
850
|
-
state = reduceSessionNotification(session.id, state, notification);
|
|
851
|
-
}
|
|
852
|
-
const displayIds = new Set(
|
|
853
|
-
result.messages.map((m) => m?.update?._meta?.fello?.displayId).filter(Boolean)
|
|
854
|
-
);
|
|
855
|
-
for (const notification of state.pendingNotifications) {
|
|
856
|
-
const did = notification.update._meta?.fello?.displayId;
|
|
857
|
-
if (did && displayIds.has(did)) continue;
|
|
858
|
-
state = reduceSessionNotification(session.id, state, notification);
|
|
859
|
-
}
|
|
860
|
-
state = {
|
|
861
|
-
...state,
|
|
862
|
-
pendingNotifications: [],
|
|
863
|
-
isLoading: false
|
|
864
|
-
};
|
|
865
|
-
updateSessionState(session.id, () => state);
|
|
866
|
-
request.loadSession({ sessionId: session.id, force: true }).catch((err) => {
|
|
867
|
-
console.error("Failed to load session:", err);
|
|
833
|
+
console.error("Failed to restart session:", err);
|
|
834
|
+
if (err instanceof SessionLifecycleBusyError) {
|
|
868
835
|
toast.error(
|
|
869
|
-
|
|
836
|
+
t(
|
|
837
|
+
"chatHeader.sessionOperationInProgress",
|
|
838
|
+
"Another session operation is already in progress."
|
|
839
|
+
)
|
|
870
840
|
);
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const
|
|
875
|
-
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
const lifecycleError = err instanceof RestartSessionError ? err : null;
|
|
844
|
+
const cause = lifecycleError?.cause ?? err;
|
|
845
|
+
const fallback = lifecycleError?.stage === "update" ? t("chat.failedToUpdateMcpServers", "Failed to update MCP servers") : t("chat.failedToLoadSession", "Failed to load session.");
|
|
846
|
+
toast.error(extractErrorMessage(cause) || fallback);
|
|
876
847
|
} finally {
|
|
877
|
-
|
|
848
|
+
setIsRestarting(false);
|
|
878
849
|
}
|
|
879
850
|
};
|
|
880
851
|
const handleCloseSession = async () => {
|
|
881
|
-
if (isClosing) return;
|
|
852
|
+
if (isClosing || isRestarting) return;
|
|
882
853
|
setIsClosing(true);
|
|
883
854
|
try {
|
|
884
|
-
await
|
|
855
|
+
await closeSession(session.id);
|
|
885
856
|
navigate("/");
|
|
886
857
|
} catch (err) {
|
|
887
858
|
console.error("Failed to close session:", err);
|
|
859
|
+
if (err instanceof SessionLifecycleBusyError) {
|
|
860
|
+
toast.error(
|
|
861
|
+
t(
|
|
862
|
+
"chatHeader.sessionOperationInProgress",
|
|
863
|
+
"Another session operation is already in progress."
|
|
864
|
+
)
|
|
865
|
+
);
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
888
868
|
toast.error(
|
|
889
869
|
extractErrorMessage(err) || t("chatHeader.failedToCloseSession", "Failed to close session.")
|
|
890
870
|
);
|
|
@@ -903,7 +883,7 @@ function ChatHeader({ session }) {
|
|
|
903
883
|
children: [
|
|
904
884
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "px-1 text-[10px] uppercase select-none", children: session.agentId }),
|
|
905
885
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 min-w-0 items-baseline gap-2", children: [
|
|
906
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-[13px] font-normal text-sidebar-foreground/85", children: session.title || t("sidebar.
|
|
886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate text-[13px] font-normal text-sidebar-foreground/85", children: session.title || t("sidebar.newSession", "New Session") }),
|
|
907
887
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-[10px] text-muted-foreground truncate", children: currentProjectInfo?.cwd }),
|
|
908
888
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 text-xs text-sidebar-foreground/70 whitespace-nowrap", children: formatUpdatedTime(session.updatedAt) })
|
|
909
889
|
] }),
|
|
@@ -920,8 +900,8 @@ function ChatHeader({ session }) {
|
|
|
920
900
|
},
|
|
921
901
|
children: [
|
|
922
902
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { className: "flex size-7 items-center justify-center rounded-md text-sidebar-foreground/45 hover:bg-sidebar-accent/30 hover:text-sidebar-foreground/70 outline-none transition-colors data-pressed:bg-sidebar-accent/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Settings2, { className: "size-4" }) }),
|
|
923
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPortal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPositioner, { side: "bottom", align: "end", sideOffset: 4, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverPopup, { className: "z-10
|
|
924
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-
|
|
903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPortal, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverPositioner, { side: "bottom", align: "end", sideOffset: 4, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(PopoverPopup, { className: "z-10 w-110 rounded-lg border border-border bg-popover text-popover-foreground shadow-lg outline-none p-1.5 origin-(--transform-origin) data-ending-style:scale-90 data-starting-style:scale-90 data-ending-style:opacity-0 data-starting-style:opacity-0 transition-[transform,opacity] duration-100", children: [
|
|
904
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-px py-1", children: [
|
|
925
905
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
926
906
|
CopyableRow,
|
|
927
907
|
{
|
|
@@ -950,6 +930,24 @@ function ChatHeader({ session }) {
|
|
|
950
930
|
) })
|
|
951
931
|
] }),
|
|
952
932
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t border-border/50 my-1" }),
|
|
933
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2 py-1 text-xs font-semibold text-foreground/80", children: t("sidebar.newSessionDialog.permission", "Permission") }),
|
|
934
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
935
|
+
Tabs,
|
|
936
|
+
{
|
|
937
|
+
value: session.permissionMode,
|
|
938
|
+
onValueChange: (value) => {
|
|
939
|
+
if (value === "ask" || value === "allow-all") {
|
|
940
|
+
void handlePermissionChange(value);
|
|
941
|
+
}
|
|
942
|
+
},
|
|
943
|
+
className: "w-full px-2 my-2",
|
|
944
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { className: "w-full", children: [
|
|
945
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "ask", className: "text-xs", children: t("sidebar.newSessionDialog.permissionAsk", "Ask") }),
|
|
946
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "allow-all", className: "text-xs", children: t("sidebar.newSessionDialog.permissionAllowAll", "Allow all") })
|
|
947
|
+
] })
|
|
948
|
+
}
|
|
949
|
+
),
|
|
950
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-t border-border/50 my-1" }),
|
|
953
951
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2 py-1 text-xs font-semibold text-foreground/80", children: t("constant.feature.title", "Features") }),
|
|
954
952
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: ALL_FEATURES.length >= 2 ? "grid grid-cols-2 gap-0.5" : "", children: ALL_FEATURES.map((feature) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
955
953
|
"div",
|
|
@@ -1024,14 +1022,17 @@ function ChatHeader({ session }) {
|
|
|
1024
1022
|
)
|
|
1025
1023
|
] }),
|
|
1026
1024
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex gap-1", children: [
|
|
1027
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
1025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1028
1026
|
Button,
|
|
1029
1027
|
{
|
|
1030
1028
|
size: "xs",
|
|
1031
1029
|
className: "flex flex-3 items-center gap-2 h-7 text-xs font-normal",
|
|
1032
1030
|
onClick: handleSyncAndRefresh,
|
|
1033
|
-
disabled: isClosing,
|
|
1034
|
-
children:
|
|
1031
|
+
disabled: isClosing || isRestarting,
|
|
1032
|
+
children: [
|
|
1033
|
+
isRestarting && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3 animate-spin" }),
|
|
1034
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("chatHeader.refresh", "Restart Session") })
|
|
1035
|
+
]
|
|
1035
1036
|
}
|
|
1036
1037
|
),
|
|
1037
1038
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -1041,7 +1042,7 @@ function ChatHeader({ session }) {
|
|
|
1041
1042
|
variant: "destructive",
|
|
1042
1043
|
className: "flex flex-1 items-center gap-1.5 h-7 text-xs font-normal",
|
|
1043
1044
|
onClick: handleCloseSession,
|
|
1044
|
-
disabled: isClosing,
|
|
1045
|
+
disabled: isClosing || isRestarting,
|
|
1045
1046
|
children: [
|
|
1046
1047
|
isClosing && /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3 animate-spin" }),
|
|
1047
1048
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isClosing ? t("chatHeader.closingSession", "Closing…") : t("chatHeader.closeSession", "Close Session") })
|
|
@@ -1175,23 +1176,23 @@ function CopyableRow({
|
|
|
1175
1176
|
":"
|
|
1176
1177
|
] }),
|
|
1177
1178
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 truncate font-mono text-muted-foreground/70 select-all", children: value }),
|
|
1178
|
-
|
|
1179
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1179
1180
|
"button",
|
|
1180
1181
|
{
|
|
1181
1182
|
type: "button",
|
|
1182
1183
|
className: "shrink-0 flex items-center justify-center size-5 rounded hover:bg-accent/50 text-muted-foreground/50 hover:text-muted-foreground transition-colors -mr-1",
|
|
1183
|
-
onClick:
|
|
1184
|
-
|
|
1185
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3" })
|
|
1184
|
+
onClick: handleCopy,
|
|
1185
|
+
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3" })
|
|
1186
1186
|
}
|
|
1187
1187
|
),
|
|
1188
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1188
|
+
!isWebUI && onOpenFolder && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1189
1189
|
"button",
|
|
1190
1190
|
{
|
|
1191
1191
|
type: "button",
|
|
1192
1192
|
className: "shrink-0 flex items-center justify-center size-5 rounded hover:bg-accent/50 text-muted-foreground/50 hover:text-muted-foreground transition-colors -mr-1",
|
|
1193
|
-
onClick:
|
|
1194
|
-
|
|
1193
|
+
onClick: onOpenFolder,
|
|
1194
|
+
title: openFolderTitle,
|
|
1195
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3" })
|
|
1195
1196
|
}
|
|
1196
1197
|
)
|
|
1197
1198
|
] });
|
|
@@ -1372,14 +1373,14 @@ function ChatTimeline({ items, activeDisplayId, onSelect: onSelect2 }) {
|
|
|
1372
1373
|
{
|
|
1373
1374
|
type: "button",
|
|
1374
1375
|
onClick: () => handleSelect(item.displayId),
|
|
1375
|
-
className: "p-1 group pointer-events-auto",
|
|
1376
|
+
className: "p-1 group/timeline pointer-events-auto outline-0",
|
|
1376
1377
|
"aria-label": ariaLabel,
|
|
1377
1378
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1378
1379
|
"div",
|
|
1379
1380
|
{
|
|
1380
1381
|
className: cn$1(
|
|
1381
|
-
"size-2 rounded-full transition-colors outline-none focus-visible:ring-
|
|
1382
|
-
isActive ? "bg-foreground/40" : "bg-muted-foreground/15 group-hover:bg-muted-foreground/40"
|
|
1382
|
+
"size-2 rounded-full transition-colors outline-none group-focus-visible/timeline:ring-1 group-focus-visible/timeline:ring-ring",
|
|
1383
|
+
isActive ? "bg-foreground/40" : "bg-muted-foreground/15 group-hover/timeline:bg-muted-foreground/40"
|
|
1383
1384
|
)
|
|
1384
1385
|
}
|
|
1385
1386
|
)
|
|
@@ -1438,6 +1439,12 @@ function ChatArea({ session }) {
|
|
|
1438
1439
|
const getViewport = reactExports.useCallback(() => {
|
|
1439
1440
|
return scrollAreaRef.current?.querySelector('[data-slot="scroll-area-viewport"]');
|
|
1440
1441
|
}, []);
|
|
1442
|
+
const focusChatArea = reactExports.useCallback(() => {
|
|
1443
|
+
const viewport = getViewport();
|
|
1444
|
+
if (!viewport) return;
|
|
1445
|
+
viewport.focus({ preventScroll: true });
|
|
1446
|
+
}, [getViewport]);
|
|
1447
|
+
useFocusTarget("chat-area", focusChatArea);
|
|
1441
1448
|
const scrollToBottom = reactExports.useCallback((behavior) => {
|
|
1442
1449
|
if (scrollTimeoutRef.current) {
|
|
1443
1450
|
clearTimeout(scrollTimeoutRef.current);
|
|
@@ -1708,7 +1715,7 @@ function ChatArea({ session }) {
|
|
|
1708
1715
|
const copyText$1 = reactExports.useCallback(async (text) => {
|
|
1709
1716
|
return copyText(text);
|
|
1710
1717
|
}, []);
|
|
1711
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full relative min-h-0 flex flex-1
|
|
1718
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full relative min-h-0 flex flex-1 group/chat-area", children: [
|
|
1712
1719
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0 w-6 -mr-6 relative z-1 pointer-events-none", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1713
1720
|
ChatTimeline,
|
|
1714
1721
|
{
|
|
@@ -1722,7 +1729,7 @@ function ChatArea({ session }) {
|
|
|
1722
1729
|
{
|
|
1723
1730
|
ref: scrollAreaRef,
|
|
1724
1731
|
className: "flex-1 w-full transform-gpu",
|
|
1725
|
-
viewportClassName: "animate-in fade-in",
|
|
1732
|
+
viewportClassName: "animate-in fade-in chat-area",
|
|
1726
1733
|
children: [
|
|
1727
1734
|
hasMore && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 px-10 py-3 max-w-5xl mx-auto", children: [
|
|
1728
1735
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 border-b border-dashed border-muted-foreground/30" }),
|
|
@@ -1892,7 +1899,8 @@ function ChatArea({ session }) {
|
|
|
1892
1899
|
"aria-label": t("chatArea.scrollToBottom", "Scroll to bottom"),
|
|
1893
1900
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDown, { className: "size-4" })
|
|
1894
1901
|
}
|
|
1895
|
-
)
|
|
1902
|
+
),
|
|
1903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pointer-events-none absolute -top-px left-0 right-0 h-px bg-linear-to-r from-ring/30 from-10% via-ring/80 via-30% to-ring/30 animate-out fill-mode-both fade-out ease-out duration-1500 hidden group-has-[.chat-area:focus-visible]/chat-area:block" })
|
|
1896
1904
|
] });
|
|
1897
1905
|
}
|
|
1898
1906
|
function _arrayWithoutHoles$1(arr) {
|
|
@@ -4586,7 +4594,10 @@ function useRealtimeAsr(options) {
|
|
|
4586
4594
|
}
|
|
4587
4595
|
const ASR_WAVEFORM_BARS = [0.35, 0.65, 0.95, 0.55, 0.8, 0.45, 0.9, 0.6, 0.38];
|
|
4588
4596
|
const DEFAULT_MAX_DURATION = 5 * 60 * 1e3;
|
|
4597
|
+
const ALT_DOUBLE_PRESS_WINDOW = 350;
|
|
4589
4598
|
const VOICE_INPUT_DEVICE_STORAGE_KEY = "fello.voice-input.device-id";
|
|
4599
|
+
let activeVoiceRecording = null;
|
|
4600
|
+
let voiceRecordingStartChain = Promise.resolve();
|
|
4590
4601
|
function getInputCursor(input) {
|
|
4591
4602
|
return input.selectionStart ?? input.value.length;
|
|
4592
4603
|
}
|
|
@@ -4599,11 +4610,16 @@ function VoiceInputButton({
|
|
|
4599
4610
|
}) {
|
|
4600
4611
|
const { t } = useTranslation();
|
|
4601
4612
|
const { toast } = useMessage();
|
|
4613
|
+
const altDoublePressEnabled = useAppStore((state) => state.voiceInput.altDoublePress);
|
|
4614
|
+
const [instanceId] = reactExports.useState(() => /* @__PURE__ */ Symbol("VoiceInputButton"));
|
|
4615
|
+
const stopAsrRef = reactExports.useRef(() => Promise.resolve());
|
|
4602
4616
|
const asrApplyingRef = reactExports.useRef(false);
|
|
4603
4617
|
const asrSegmentsRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
4604
4618
|
const asrTailRef = reactExports.useRef(0);
|
|
4605
4619
|
const asrCurrentKeyRef = reactExports.useRef(null);
|
|
4606
4620
|
const asrSequenceRef = reactExports.useRef(0);
|
|
4621
|
+
const lastAltTapAtRef = reactExports.useRef(null);
|
|
4622
|
+
const suppressAltUntilRef = reactExports.useRef(0);
|
|
4607
4623
|
const freezeAsrSegments = reactExports.useCallback(() => {
|
|
4608
4624
|
asrSegmentsRef.current.clear();
|
|
4609
4625
|
asrCurrentKeyRef.current = null;
|
|
@@ -4639,17 +4655,32 @@ function VoiceInputButton({
|
|
|
4639
4655
|
},
|
|
4640
4656
|
[inputRef]
|
|
4641
4657
|
);
|
|
4658
|
+
const handleRecordingChange = reactExports.useCallback(
|
|
4659
|
+
(recording) => {
|
|
4660
|
+
if (recording) {
|
|
4661
|
+
activeVoiceRecording = {
|
|
4662
|
+
owner: instanceId,
|
|
4663
|
+
stop: () => stopAsrRef.current()
|
|
4664
|
+
};
|
|
4665
|
+
} else {
|
|
4666
|
+
freezeAsrSegments();
|
|
4667
|
+
if (activeVoiceRecording?.owner === instanceId) {
|
|
4668
|
+
activeVoiceRecording = null;
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
},
|
|
4672
|
+
[freezeAsrSegments, instanceId]
|
|
4673
|
+
);
|
|
4642
4674
|
const asr = useRealtimeAsr({
|
|
4643
4675
|
onTranscript: applyAsrTranscript,
|
|
4644
4676
|
onError: (message) => toast.error(message),
|
|
4645
|
-
onRecordingChange:
|
|
4646
|
-
if (!recording) freezeAsrSegments();
|
|
4647
|
-
}
|
|
4677
|
+
onRecordingChange: handleRecordingChange
|
|
4648
4678
|
});
|
|
4649
4679
|
const { start: startAsr, stop: stopAsr, refreshInputDevices } = asr;
|
|
4650
4680
|
const handleStop = reactExports.useCallback(async () => {
|
|
4651
4681
|
await stopAsr();
|
|
4652
4682
|
}, [stopAsr]);
|
|
4683
|
+
stopAsrRef.current = handleStop;
|
|
4653
4684
|
reactExports.useImperativeHandle(
|
|
4654
4685
|
ref,
|
|
4655
4686
|
() => ({
|
|
@@ -4659,23 +4690,28 @@ function VoiceInputButton({
|
|
|
4659
4690
|
);
|
|
4660
4691
|
const handleStart = reactExports.useCallback(
|
|
4661
4692
|
async (deviceId) => {
|
|
4662
|
-
const
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4693
|
+
const startOperation = voiceRecordingStartChain.then(async () => {
|
|
4694
|
+
await activeVoiceRecording?.stop();
|
|
4695
|
+
const textarea = inputRef.current;
|
|
4696
|
+
if (!textarea) return;
|
|
4697
|
+
textarea.focus();
|
|
4698
|
+
const cursorPosition = getInputCursor(textarea);
|
|
4699
|
+
const before = textarea.value.slice(0, cursorPosition);
|
|
4700
|
+
if (before.length > 0 && !/\s$/.test(before)) {
|
|
4701
|
+
asrApplyingRef.current = true;
|
|
4702
|
+
try {
|
|
4703
|
+
document.execCommand("insertText", false, " ");
|
|
4704
|
+
} finally {
|
|
4705
|
+
asrApplyingRef.current = false;
|
|
4706
|
+
}
|
|
4673
4707
|
}
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4708
|
+
asrSegmentsRef.current.clear();
|
|
4709
|
+
asrCurrentKeyRef.current = null;
|
|
4710
|
+
asrTailRef.current = getInputCursor(textarea);
|
|
4711
|
+
await startAsr(deviceId);
|
|
4712
|
+
});
|
|
4713
|
+
voiceRecordingStartChain = startOperation.catch(() => void 0);
|
|
4714
|
+
await startOperation;
|
|
4679
4715
|
},
|
|
4680
4716
|
[startAsr, inputRef]
|
|
4681
4717
|
);
|
|
@@ -4687,6 +4723,7 @@ function VoiceInputButton({
|
|
|
4687
4723
|
}
|
|
4688
4724
|
});
|
|
4689
4725
|
const [deviceMenuOpen, setDeviceMenuOpen] = reactExports.useState(false);
|
|
4726
|
+
const [starting, setStarting] = reactExports.useState(false);
|
|
4690
4727
|
const rememberDevice = reactExports.useCallback((deviceId) => {
|
|
4691
4728
|
setSavedDeviceId(deviceId);
|
|
4692
4729
|
try {
|
|
@@ -4702,14 +4739,44 @@ function VoiceInputButton({
|
|
|
4702
4739
|
[rememberDevice]
|
|
4703
4740
|
);
|
|
4704
4741
|
const handleMicClick = reactExports.useCallback(async () => {
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
await
|
|
4709
|
-
|
|
4710
|
-
|
|
4742
|
+
if (disabled || !asr.configured || starting) return;
|
|
4743
|
+
setStarting(true);
|
|
4744
|
+
try {
|
|
4745
|
+
const devices = await refreshInputDevices();
|
|
4746
|
+
const hasSavedDevice = savedDeviceId != null && devices.some((device) => device.deviceId === savedDeviceId);
|
|
4747
|
+
if (hasSavedDevice) {
|
|
4748
|
+
await handleStart(savedDeviceId);
|
|
4749
|
+
} else {
|
|
4750
|
+
setDeviceMenuOpen(true);
|
|
4751
|
+
}
|
|
4752
|
+
} finally {
|
|
4753
|
+
setStarting(false);
|
|
4754
|
+
}
|
|
4755
|
+
}, [asr.configured, disabled, handleStart, refreshInputDevices, savedDeviceId, starting]);
|
|
4756
|
+
const handleShortcutToggle = reactExports.useCallback(async () => {
|
|
4757
|
+
if (disabled || !asr.configured || starting) return;
|
|
4758
|
+
if (asr.recording) {
|
|
4759
|
+
await handleStop();
|
|
4760
|
+
return;
|
|
4761
|
+
}
|
|
4762
|
+
setStarting(true);
|
|
4763
|
+
try {
|
|
4764
|
+
const devices = await refreshInputDevices();
|
|
4765
|
+
const hasSavedDevice = savedDeviceId != null && devices.some((device) => device.deviceId === savedDeviceId);
|
|
4766
|
+
await handleStart(hasSavedDevice ? savedDeviceId : void 0);
|
|
4767
|
+
} finally {
|
|
4768
|
+
setStarting(false);
|
|
4711
4769
|
}
|
|
4712
|
-
}, [
|
|
4770
|
+
}, [
|
|
4771
|
+
asr.configured,
|
|
4772
|
+
asr.recording,
|
|
4773
|
+
disabled,
|
|
4774
|
+
handleStart,
|
|
4775
|
+
handleStop,
|
|
4776
|
+
refreshInputDevices,
|
|
4777
|
+
savedDeviceId,
|
|
4778
|
+
starting
|
|
4779
|
+
]);
|
|
4713
4780
|
const handleDeviceMenuChange = reactExports.useCallback(
|
|
4714
4781
|
(open) => {
|
|
4715
4782
|
setDeviceMenuOpen(open);
|
|
@@ -4717,6 +4784,76 @@ function VoiceInputButton({
|
|
|
4717
4784
|
},
|
|
4718
4785
|
[refreshInputDevices]
|
|
4719
4786
|
);
|
|
4787
|
+
reactExports.useEffect(() => {
|
|
4788
|
+
lastAltTapAtRef.current = null;
|
|
4789
|
+
const handleKeyDown = (event) => {
|
|
4790
|
+
const input = inputRef.current;
|
|
4791
|
+
if (!input || document.activeElement !== input) {
|
|
4792
|
+
lastAltTapAtRef.current = null;
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4795
|
+
if (event.key === "Escape") {
|
|
4796
|
+
lastAltTapAtRef.current = null;
|
|
4797
|
+
suppressAltUntilRef.current = 0;
|
|
4798
|
+
if (!event.repeat && !event.ctrlKey && !event.metaKey && !event.shiftKey && asr.recording) {
|
|
4799
|
+
event.preventDefault();
|
|
4800
|
+
void handleStop();
|
|
4801
|
+
}
|
|
4802
|
+
return;
|
|
4803
|
+
}
|
|
4804
|
+
if (event.key !== "Alt") {
|
|
4805
|
+
lastAltTapAtRef.current = null;
|
|
4806
|
+
return;
|
|
4807
|
+
}
|
|
4808
|
+
if (!altDoublePressEnabled || event.repeat || event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
4809
|
+
lastAltTapAtRef.current = null;
|
|
4810
|
+
return;
|
|
4811
|
+
}
|
|
4812
|
+
const now = Date.now();
|
|
4813
|
+
if (now < suppressAltUntilRef.current) {
|
|
4814
|
+
lastAltTapAtRef.current = null;
|
|
4815
|
+
return;
|
|
4816
|
+
}
|
|
4817
|
+
if (asr.recording) {
|
|
4818
|
+
lastAltTapAtRef.current = null;
|
|
4819
|
+
suppressAltUntilRef.current = now + ALT_DOUBLE_PRESS_WINDOW;
|
|
4820
|
+
event.preventDefault();
|
|
4821
|
+
void handleStop();
|
|
4822
|
+
return;
|
|
4823
|
+
}
|
|
4824
|
+
const lastTapAt = lastAltTapAtRef.current;
|
|
4825
|
+
if (lastTapAt !== null && now - lastTapAt <= ALT_DOUBLE_PRESS_WINDOW) {
|
|
4826
|
+
lastAltTapAtRef.current = null;
|
|
4827
|
+
event.preventDefault();
|
|
4828
|
+
void handleShortcutToggle();
|
|
4829
|
+
}
|
|
4830
|
+
};
|
|
4831
|
+
const handleKeyUp = (event) => {
|
|
4832
|
+
if (event.key !== "Alt") return;
|
|
4833
|
+
const input = inputRef.current;
|
|
4834
|
+
if (!input || document.activeElement !== input) {
|
|
4835
|
+
lastAltTapAtRef.current = null;
|
|
4836
|
+
return;
|
|
4837
|
+
}
|
|
4838
|
+
if (Date.now() < suppressAltUntilRef.current) {
|
|
4839
|
+
lastAltTapAtRef.current = null;
|
|
4840
|
+
return;
|
|
4841
|
+
}
|
|
4842
|
+
lastAltTapAtRef.current = Date.now();
|
|
4843
|
+
};
|
|
4844
|
+
const resetAltTap = () => {
|
|
4845
|
+
lastAltTapAtRef.current = null;
|
|
4846
|
+
suppressAltUntilRef.current = 0;
|
|
4847
|
+
};
|
|
4848
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
4849
|
+
window.addEventListener("keyup", handleKeyUp);
|
|
4850
|
+
window.addEventListener("blur", resetAltTap);
|
|
4851
|
+
return () => {
|
|
4852
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
4853
|
+
window.removeEventListener("keyup", handleKeyUp);
|
|
4854
|
+
window.removeEventListener("blur", resetAltTap);
|
|
4855
|
+
};
|
|
4856
|
+
}, [altDoublePressEnabled, asr.recording, handleShortcutToggle, handleStop, inputRef]);
|
|
4720
4857
|
reactExports.useEffect(() => {
|
|
4721
4858
|
const textarea = inputRef.current;
|
|
4722
4859
|
if (!textarea) return;
|
|
@@ -4739,7 +4876,7 @@ function VoiceInputButton({
|
|
|
4739
4876
|
"div",
|
|
4740
4877
|
{
|
|
4741
4878
|
className: cn$1(
|
|
4742
|
-
"relative inline-flex h-7 transition-[width] duration-300 ease-out",
|
|
4879
|
+
"relative inline-flex h-7 transition-[width] duration-300 ease-out flex-none",
|
|
4743
4880
|
asr.recording ? "w-18" : "w-12.5",
|
|
4744
4881
|
className
|
|
4745
4882
|
),
|
|
@@ -4802,10 +4939,11 @@ function VoiceInputButton({
|
|
|
4802
4939
|
size: "sm",
|
|
4803
4940
|
className: "h-full w-8 rounded-r-none border-r-0 bg-muted hover:bg-input border border-input text-amber-300/50 hover:text-amber-200",
|
|
4804
4941
|
onClick: () => void handleMicClick(),
|
|
4805
|
-
disabled: disabled || !asr.configured,
|
|
4806
|
-
"aria-
|
|
4807
|
-
|
|
4808
|
-
|
|
4942
|
+
disabled: disabled || !asr.configured || starting,
|
|
4943
|
+
"aria-busy": starting,
|
|
4944
|
+
"aria-label": starting ? t("chatInput.startingVoiceInput", "Starting voice input") : t("chatInput.voiceInput", "Voice input"),
|
|
4945
|
+
title: starting ? t("chatInput.startingVoiceInput", "Starting voice input") : asr.configured ? t("chatInput.voiceInput", "Voice input") : t("chatInput.voiceInputNotConfigured", "Configure voice input in Settings"),
|
|
4946
|
+
children: starting ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Mic, { className: "size-3.5" })
|
|
4809
4947
|
}
|
|
4810
4948
|
),
|
|
4811
4949
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -4816,7 +4954,7 @@ function VoiceInputButton({
|
|
|
4816
4954
|
{
|
|
4817
4955
|
size: "icon",
|
|
4818
4956
|
className: "h-full w-4.5 rounded-l-none bg-muted hover:bg-input border border-input border-l-0 px-0 text-amber-300/50 hover:text-amber-200",
|
|
4819
|
-
disabled: disabled || !asr.configured,
|
|
4957
|
+
disabled: disabled || !asr.configured || starting,
|
|
4820
4958
|
"aria-label": t("chatInput.selectVoiceInputDevice", "Select microphone"),
|
|
4821
4959
|
title: t("chatInput.selectVoiceInputDevice", "Select microphone")
|
|
4822
4960
|
}
|
|
@@ -4996,6 +5134,13 @@ function ChatInput({ session }) {
|
|
|
4996
5134
|
const textareaRef = reactExports.useRef(null);
|
|
4997
5135
|
const voiceInputRef = reactExports.useRef(null);
|
|
4998
5136
|
const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
|
|
5137
|
+
const focusInput = reactExports.useCallback(() => {
|
|
5138
|
+
const textarea = getTextarea();
|
|
5139
|
+
if (!textarea || textarea.disabled) return false;
|
|
5140
|
+
textarea.focus({ preventScroll: true });
|
|
5141
|
+
return document.activeElement === textarea;
|
|
5142
|
+
}, [getTextarea]);
|
|
5143
|
+
useFocusTarget("chat-input", focusInput);
|
|
4999
5144
|
const insertTriggerChar = reactExports.useCallback(
|
|
5000
5145
|
(char) => {
|
|
5001
5146
|
const textarea = getTextarea();
|
|
@@ -5554,14 +5699,14 @@ function ChatInput({ session }) {
|
|
|
5554
5699
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5555
5700
|
"div",
|
|
5556
5701
|
{
|
|
5557
|
-
className: "flex cursor-text items-center justify-between gap-2
|
|
5702
|
+
className: "flex cursor-text items-center justify-between gap-2 -mt-3 overflow-hidden",
|
|
5558
5703
|
onClick: (e) => {
|
|
5559
5704
|
const target = e.target;
|
|
5560
5705
|
if (target.closest("button, select, [role='combobox']")) return;
|
|
5561
5706
|
getTextarea()?.focus();
|
|
5562
5707
|
},
|
|
5563
5708
|
children: [
|
|
5564
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 overflow-hidden", children: [
|
|
5709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 p-2 overflow-hidden -mr-4", children: [
|
|
5565
5710
|
availableModes.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
|
|
5566
5711
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5567
5712
|
DropdownMenuTrigger,
|
|
@@ -5571,7 +5716,7 @@ function ChatInput({ session }) {
|
|
|
5571
5716
|
{
|
|
5572
5717
|
variant: "outline",
|
|
5573
5718
|
size: "sm",
|
|
5574
|
-
className: "h-7 text-xs text-muted-foreground hover:text-foreground gap-2 max-w-48 shrink overflow-hidden"
|
|
5719
|
+
className: "h-7 min-w-16 text-xs text-muted-foreground hover:text-foreground gap-2 max-w-48 shrink overflow-hidden"
|
|
5575
5720
|
}
|
|
5576
5721
|
),
|
|
5577
5722
|
children: [
|
|
@@ -5693,7 +5838,7 @@ function ChatInput({ session }) {
|
|
|
5693
5838
|
] })
|
|
5694
5839
|
] })
|
|
5695
5840
|
] }),
|
|
5696
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 overflow-hidden", children: [
|
|
5841
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 p-2 overflow-hidden", children: [
|
|
5697
5842
|
availableModels.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
|
|
5698
5843
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5699
5844
|
DropdownMenuTrigger,
|
|
@@ -5703,7 +5848,7 @@ function ChatInput({ session }) {
|
|
|
5703
5848
|
{
|
|
5704
5849
|
variant: "outline",
|
|
5705
5850
|
size: "sm",
|
|
5706
|
-
className: "h-7 text-xs text-muted-foreground hover:text-foreground gap-2 max-w-48 shrink overflow-hidden"
|
|
5851
|
+
className: "h-7 min-w-16 text-xs text-muted-foreground hover:text-foreground gap-2 max-w-48 shrink overflow-hidden"
|
|
5707
5852
|
}
|
|
5708
5853
|
),
|
|
5709
5854
|
children: [
|
|
@@ -5839,14 +5984,7 @@ function ChatInput({ session }) {
|
|
|
5839
5984
|
}
|
|
5840
5985
|
)
|
|
5841
5986
|
] }),
|
|
5842
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5843
|
-
VoiceInputButton,
|
|
5844
|
-
{
|
|
5845
|
-
ref: voiceInputRef,
|
|
5846
|
-
inputRef: textareaRef,
|
|
5847
|
-
disabled
|
|
5848
|
-
}
|
|
5849
|
-
),
|
|
5987
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(VoiceInputButton, { ref: voiceInputRef, inputRef: textareaRef, disabled }),
|
|
5850
5988
|
isStreaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5851
5989
|
Button,
|
|
5852
5990
|
{
|
|
@@ -5890,14 +6028,14 @@ const mentionsInputStyle = {
|
|
|
5890
6028
|
highlighter: {
|
|
5891
6029
|
padding: "12px 16px 8px",
|
|
5892
6030
|
border: "none",
|
|
5893
|
-
maxHeight:
|
|
6031
|
+
maxHeight: "80vh"
|
|
5894
6032
|
},
|
|
5895
6033
|
input: {
|
|
5896
6034
|
padding: "12px 16px 8px",
|
|
5897
6035
|
border: "none",
|
|
5898
6036
|
outline: "none",
|
|
5899
6037
|
overflow: "auto",
|
|
5900
|
-
maxHeight:
|
|
6038
|
+
maxHeight: "80vh",
|
|
5901
6039
|
color: "var(--foreground)",
|
|
5902
6040
|
fontSize: 13,
|
|
5903
6041
|
lineHeight: "1.5",
|
|
@@ -5990,12 +6128,15 @@ function AskUserDialog({ sessionId }) {
|
|
|
5990
6128
|
"div",
|
|
5991
6129
|
{
|
|
5992
6130
|
ref: cardRef,
|
|
6131
|
+
role: "dialog",
|
|
6132
|
+
"aria-labelledby": "ask-user-dialog-title",
|
|
6133
|
+
"aria-describedby": currentRequest.description ? "ask-user-dialog-description" : void 0,
|
|
5993
6134
|
onClick: () => setCollapsed(false),
|
|
5994
6135
|
className: "grid grid-rows-[auto_1fr_auto] rounded-xl border border-border bg-card p-4 shadow-lg shadow-primary/5 max-h-[90vh]",
|
|
5995
6136
|
children: [
|
|
5996
6137
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 min-h-0", children: [
|
|
5997
6138
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleQuestionMark, { className: "size-4.5 shrink-0 text-sky-500" }),
|
|
5998
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium leading-snug truncate", children: currentRequest.title || t("askUser.title", "Request") }),
|
|
6139
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { id: "ask-user-dialog-title", className: "text-sm font-medium leading-snug truncate", children: currentRequest.title || t("askUser.title", "Request") }),
|
|
5999
6140
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center ml-auto gap-1", children: [
|
|
6000
6141
|
currentRequest.timeoutAt != null && /* @__PURE__ */ jsxRuntimeExports.jsx(AskUserCountdown, { timeoutAt: currentRequest.timeoutAt }),
|
|
6001
6142
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -6009,13 +6150,14 @@ function AskUserDialog({ sessionId }) {
|
|
|
6009
6150
|
setCollapsed((c) => !c);
|
|
6010
6151
|
},
|
|
6011
6152
|
"aria-label": collapsed ? t("askUser.expand", "Expand") : t("askUser.collapse", "Collapse"),
|
|
6153
|
+
"aria-expanded": !collapsed,
|
|
6012
6154
|
title: collapsed ? t("askUser.expand", "Expand") : t("askUser.collapse", "Collapse"),
|
|
6013
6155
|
children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "size-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" })
|
|
6014
6156
|
}
|
|
6015
6157
|
)
|
|
6016
6158
|
] })
|
|
6017
6159
|
] }),
|
|
6018
|
-
currentRequest.description && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "h-full rounded-md bg-muted/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-3 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs text-muted-foreground leading-relaxed whitespace-pre-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: formatDescription(currentRequest.description) }) }) }) }) }),
|
|
6160
|
+
currentRequest.description && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { id: "ask-user-dialog-description", className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "h-full rounded-md bg-muted/40", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-3 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs text-muted-foreground leading-relaxed whitespace-pre-wrap", children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: formatDescription(currentRequest.description) }) }) }) }) }),
|
|
6019
6161
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn$1("pt-3 min-h-0", collapsed ? "pointer-events-none" : ""), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6020
6162
|
AskUserOptions,
|
|
6021
6163
|
{
|
|
@@ -6079,12 +6221,21 @@ function AskUserOptions({
|
|
|
6079
6221
|
const [highlightedIndex, setHighlightedIndex] = reactExports.useState(null);
|
|
6080
6222
|
const [isDragOver, setIsDragOver] = reactExports.useState(false);
|
|
6081
6223
|
const inputContainerRef = reactExports.useRef(null);
|
|
6224
|
+
const optionRefs = reactExports.useRef([]);
|
|
6225
|
+
const otherButtonRef = reactExports.useRef(null);
|
|
6082
6226
|
const textareaRef = reactExports.useRef(null);
|
|
6083
6227
|
const voiceInputRef = reactExports.useRef(null);
|
|
6084
6228
|
const navigate = useNavigate();
|
|
6085
6229
|
const snippets = useAppStore((s15) => s15.snippets);
|
|
6086
6230
|
const fileInputRef = reactExports.useRef(null);
|
|
6087
6231
|
const getTextarea = reactExports.useCallback(() => textareaRef.current, []);
|
|
6232
|
+
const focusAskUser = reactExports.useCallback(() => {
|
|
6233
|
+
const target = mode === "input" ? textareaRef.current : optionRefs.current[0];
|
|
6234
|
+
if (!target || target.disabled) return false;
|
|
6235
|
+
target.focus({ preventScroll: true });
|
|
6236
|
+
return document.activeElement === target;
|
|
6237
|
+
}, [mode]);
|
|
6238
|
+
useFocusTarget("ask-user-dialog", focusAskUser);
|
|
6088
6239
|
const insertTriggerChar = reactExports.useCallback(
|
|
6089
6240
|
(char) => {
|
|
6090
6241
|
const textarea = getTextarea();
|
|
@@ -6254,31 +6405,53 @@ function AskUserOptions({
|
|
|
6254
6405
|
}
|
|
6255
6406
|
};
|
|
6256
6407
|
reactExports.useEffect(() => {
|
|
6257
|
-
if (mode
|
|
6258
|
-
|
|
6259
|
-
}
|
|
6408
|
+
if (mode !== "input") return;
|
|
6409
|
+
textareaRef.current?.focus();
|
|
6260
6410
|
}, [mode]);
|
|
6411
|
+
reactExports.useEffect(() => {
|
|
6412
|
+
if (mode !== "options" || !hasOptions) return;
|
|
6413
|
+
const frame = window.requestAnimationFrame(() => optionRefs.current[0]?.focus());
|
|
6414
|
+
return () => window.cancelAnimationFrame(frame);
|
|
6415
|
+
}, [hasOptions, mode]);
|
|
6416
|
+
const handleOptionKeyDown = (event, index) => {
|
|
6417
|
+
const { key } = event;
|
|
6418
|
+
if (key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End") {
|
|
6419
|
+
event.preventDefault();
|
|
6420
|
+
event.stopPropagation();
|
|
6421
|
+
if (key === "Home") {
|
|
6422
|
+
optionRefs.current[0]?.focus();
|
|
6423
|
+
} else if (key === "End") {
|
|
6424
|
+
if (showOther) otherButtonRef.current?.focus();
|
|
6425
|
+
else optionRefs.current[request$1.options.length - 1]?.focus();
|
|
6426
|
+
} else if (key === "ArrowDown") {
|
|
6427
|
+
if (index < request$1.options.length - 1) {
|
|
6428
|
+
optionRefs.current[index + 1]?.focus();
|
|
6429
|
+
} else if (showOther) {
|
|
6430
|
+
otherButtonRef.current?.focus();
|
|
6431
|
+
}
|
|
6432
|
+
} else if (index > 0) {
|
|
6433
|
+
optionRefs.current[index - 1]?.focus();
|
|
6434
|
+
}
|
|
6435
|
+
}
|
|
6436
|
+
};
|
|
6261
6437
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6262
6438
|
mode === "options" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
6263
6439
|
request$1.options.map((option, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
6264
|
-
"
|
|
6440
|
+
"button",
|
|
6265
6441
|
{
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
className: `relative flex w-full min-h-8 py-2 px-2 text-xs text-left rounded-lg border transition-all select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px ${highlightedIndex === index ? "ring-1 ring-sky-500 bg-sky-500/10 border-sky-500/30" : option.danger ? "bg-destructive/10 text-destructive hover:bg-destructive/20 border-destructive/20" : "bg-secondary/50 hover:bg-secondary hover:text-foreground"}`,
|
|
6269
|
-
onClick: () => handleSelectOption(option.value),
|
|
6270
|
-
onKeyDown: (e) => {
|
|
6271
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
6272
|
-
e.preventDefault();
|
|
6273
|
-
handleSelectOption(option.value);
|
|
6274
|
-
}
|
|
6442
|
+
ref: (element) => {
|
|
6443
|
+
optionRefs.current[index] = element;
|
|
6275
6444
|
},
|
|
6445
|
+
type: "button",
|
|
6446
|
+
className: `relative flex w-full min-h-8 py-2 px-2 text-xs text-left rounded-lg border transition-all select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 active:translate-y-px ${highlightedIndex === index ? "ring-1 ring-sky-500 bg-sky-500/10 border-sky-500/30" : option.danger ? "bg-destructive/10 text-destructive hover:bg-destructive/20 border-destructive/20" : "bg-secondary/50 hover:bg-secondary hover:text-foreground"}`,
|
|
6447
|
+
onClick: () => handleSelectOption(option.value),
|
|
6448
|
+
onKeyDown: (event) => handleOptionKeyDown(event, index),
|
|
6276
6449
|
children: [
|
|
6277
6450
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-start gap-1.5 w-full", children: [
|
|
6278
6451
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex size-5 items-center justify-center rounded bg-muted-foreground/10 text-[10px] font-mono shrink-0 self-start mt-0.5", children: index + 1 }),
|
|
6279
6452
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 whitespace-normal self-start py-1", children: option.label })
|
|
6280
6453
|
] }),
|
|
6281
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
6454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute top-0.5 right-1 text-[9px] leading-none text-muted-foreground/30 shrink-0 self-start font-mono", children: option.priority })
|
|
6282
6455
|
]
|
|
6283
6456
|
},
|
|
6284
6457
|
option.value
|
|
@@ -6286,10 +6459,22 @@ function AskUserOptions({
|
|
|
6286
6459
|
showOther && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
6287
6460
|
Button,
|
|
6288
6461
|
{
|
|
6462
|
+
ref: otherButtonRef,
|
|
6289
6463
|
variant: "ghost",
|
|
6290
6464
|
size: "sm",
|
|
6291
6465
|
className: "justify-start h-8 px-2 text-xs text-muted-foreground",
|
|
6292
6466
|
onClick: () => setMode("input"),
|
|
6467
|
+
onKeyDown: (event) => {
|
|
6468
|
+
if (event.key === "ArrowUp") {
|
|
6469
|
+
event.preventDefault();
|
|
6470
|
+
event.stopPropagation();
|
|
6471
|
+
optionRefs.current[request$1.options.length - 1]?.focus();
|
|
6472
|
+
} else if (event.key === "Home") {
|
|
6473
|
+
event.preventDefault();
|
|
6474
|
+
event.stopPropagation();
|
|
6475
|
+
optionRefs.current[0]?.focus();
|
|
6476
|
+
}
|
|
6477
|
+
},
|
|
6293
6478
|
children: [
|
|
6294
6479
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("askUser.other", "Custom reply") }),
|
|
6295
6480
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { className: "size-3" })
|
|
@@ -6689,7 +6874,7 @@ function useFile(projectId, file, options = {}) {
|
|
|
6689
6874
|
};
|
|
6690
6875
|
}
|
|
6691
6876
|
const CodeEditor = reactExports.lazy(
|
|
6692
|
-
() => __vitePreload(() => import("./code-editor-
|
|
6877
|
+
() => __vitePreload(() => import("./code-editor-tm0AYOLz.js"), true ? __vite__mapDeps([0,1,2,3,4]) : void 0, import.meta.url).then((m) => ({ default: m.CodeEditor }))
|
|
6693
6878
|
);
|
|
6694
6879
|
const MAX_EDIT_SIZE = 1024 * 1024;
|
|
6695
6880
|
const EditPanel = reactExports.forwardRef(function EditPanel2({ projectId, filePath, content, loading = false, onCancel, onSaved }, ref) {
|
|
@@ -17260,6 +17445,9 @@ const GIT_SUMMARY_BADGES = [
|
|
|
17260
17445
|
{ key: "C", color: "text-yellow-500" },
|
|
17261
17446
|
{ key: "D", color: "text-red-500" }
|
|
17262
17447
|
];
|
|
17448
|
+
function fileNavigationItemKey(item) {
|
|
17449
|
+
return item.type === "action" ? `action:${item.action}` : `tree:${item.id}`;
|
|
17450
|
+
}
|
|
17263
17451
|
function TreeItem({
|
|
17264
17452
|
node,
|
|
17265
17453
|
depth,
|
|
@@ -17273,7 +17461,10 @@ function TreeItem({
|
|
|
17273
17461
|
onEditChange,
|
|
17274
17462
|
onEditSubmit,
|
|
17275
17463
|
onEditCancel,
|
|
17276
|
-
actions
|
|
17464
|
+
actions,
|
|
17465
|
+
onKeyDown: onKeyDown2,
|
|
17466
|
+
registerRef,
|
|
17467
|
+
onFocus
|
|
17277
17468
|
}) {
|
|
17278
17469
|
const { t } = useTranslation();
|
|
17279
17470
|
const isOpen = openFolders.has(node.id);
|
|
@@ -17284,6 +17475,15 @@ function TreeItem({
|
|
|
17284
17475
|
reactExports.useEffect(() => {
|
|
17285
17476
|
if (isEditing) setTimeout(() => inputRef.current?.focus(), 0);
|
|
17286
17477
|
}, [isEditing]);
|
|
17478
|
+
const handleView = (e) => {
|
|
17479
|
+
if (node.isFolder) {
|
|
17480
|
+
actions.toggle(node);
|
|
17481
|
+
actions.select(node.id, e);
|
|
17482
|
+
} else {
|
|
17483
|
+
actions.previewFile(node.id);
|
|
17484
|
+
actions.select(node.id, e);
|
|
17485
|
+
}
|
|
17486
|
+
};
|
|
17287
17487
|
const childProps = {
|
|
17288
17488
|
selectedIds,
|
|
17289
17489
|
openFolders,
|
|
@@ -17294,7 +17494,10 @@ function TreeItem({
|
|
|
17294
17494
|
onEditChange,
|
|
17295
17495
|
onEditSubmit,
|
|
17296
17496
|
onEditCancel,
|
|
17297
|
-
actions
|
|
17497
|
+
actions,
|
|
17498
|
+
onKeyDown: onKeyDown2,
|
|
17499
|
+
registerRef,
|
|
17500
|
+
onFocus
|
|
17298
17501
|
};
|
|
17299
17502
|
const status = gitStatusMap.get(node.id);
|
|
17300
17503
|
let statusText = "";
|
|
@@ -17331,7 +17534,22 @@ function TreeItem({
|
|
|
17331
17534
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
17332
17535
|
ContextMenuTrigger,
|
|
17333
17536
|
{
|
|
17334
|
-
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17537
|
+
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17538
|
+
"div",
|
|
17539
|
+
{
|
|
17540
|
+
ref: (element) => registerRef(node.id, element),
|
|
17541
|
+
tabIndex: -1,
|
|
17542
|
+
role: "treeitem",
|
|
17543
|
+
"aria-level": depth + 1,
|
|
17544
|
+
"aria-expanded": node.isFolder ? isOpen : void 0,
|
|
17545
|
+
"aria-selected": isSelected,
|
|
17546
|
+
className: "outline-0 focus-visible:inset-ring-1 focus-visible:inset-ring-ring/80 rounded-md",
|
|
17547
|
+
onKeyDown: (e) => {
|
|
17548
|
+
if (e.target === e.currentTarget) onKeyDown2(e, node);
|
|
17549
|
+
},
|
|
17550
|
+
onFocus: () => onFocus(node.id)
|
|
17551
|
+
}
|
|
17552
|
+
),
|
|
17335
17553
|
draggable: !isEditing,
|
|
17336
17554
|
onDragStart: (e) => {
|
|
17337
17555
|
e.stopPropagation();
|
|
@@ -17349,7 +17567,6 @@ function TreeItem({
|
|
|
17349
17567
|
},
|
|
17350
17568
|
className: cn$1(
|
|
17351
17569
|
"flex h-6 cursor-default select-none items-center gap-1.5 px-1.5 text-sx leading-none text-foreground/60",
|
|
17352
|
-
node.ignored && "opacity-50",
|
|
17353
17570
|
node.id === previewId ? "bg-primary/8 hover:bg-primary/10" : "hover:bg-primary/5 hover:text-foreground",
|
|
17354
17571
|
isSelected ? "text-foreground bg-primary/6" : "",
|
|
17355
17572
|
isDragOver && "relative ring-1 ring-primary bg-primary/5"
|
|
@@ -17361,13 +17578,7 @@ function TreeItem({
|
|
|
17361
17578
|
actions.select(node.id, e);
|
|
17362
17579
|
return;
|
|
17363
17580
|
}
|
|
17364
|
-
|
|
17365
|
-
actions.toggle(node);
|
|
17366
|
-
actions.select(node.id, e);
|
|
17367
|
-
} else {
|
|
17368
|
-
actions.previewFile(node.id);
|
|
17369
|
-
actions.select(node.id, e);
|
|
17370
|
-
}
|
|
17581
|
+
handleView(e);
|
|
17371
17582
|
},
|
|
17372
17583
|
children: [
|
|
17373
17584
|
node.isFolder ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -17375,10 +17586,11 @@ function TreeItem({
|
|
|
17375
17586
|
{
|
|
17376
17587
|
className: cn$1(
|
|
17377
17588
|
"size-3.5 shrink-0 text-muted-foreground scale-110 transition-transform",
|
|
17378
|
-
isOpen && "rotate-90"
|
|
17589
|
+
isOpen && "rotate-90",
|
|
17590
|
+
node.ignored && "opacity-50"
|
|
17379
17591
|
)
|
|
17380
17592
|
}
|
|
17381
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { name: node.name, className: "size-3.5 shrink-0 text-muted-foreground/90" }),
|
|
17593
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { name: node.name, className: cn$1("size-3.5 shrink-0 text-muted-foreground/90", node.ignored && "opacity-50") }),
|
|
17382
17594
|
isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
17383
17595
|
"input",
|
|
17384
17596
|
{
|
|
@@ -17399,7 +17611,8 @@ function TreeItem({
|
|
|
17399
17611
|
{
|
|
17400
17612
|
className: cn$1(
|
|
17401
17613
|
"flex-1 truncate leading-normal",
|
|
17402
|
-
statusText && !node.isFolder && statusColor
|
|
17614
|
+
statusText && !node.isFolder && statusColor,
|
|
17615
|
+
node.ignored && "opacity-50"
|
|
17403
17616
|
),
|
|
17404
17617
|
children: node.name
|
|
17405
17618
|
}
|
|
@@ -17419,6 +17632,11 @@ function TreeItem({
|
|
|
17419
17632
|
}
|
|
17420
17633
|
),
|
|
17421
17634
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { children: [
|
|
17635
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onClick: handleView, children: [
|
|
17636
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Eye, {}),
|
|
17637
|
+
t("filePanel.view")
|
|
17638
|
+
] }),
|
|
17639
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
|
|
17422
17640
|
node.isFolder ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
17423
17641
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onClick: () => actions.createIn(node.id, false), children: [
|
|
17424
17642
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, {}),
|
|
@@ -17558,7 +17776,13 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
17558
17776
|
onPreviewFile
|
|
17559
17777
|
}) {
|
|
17560
17778
|
const { t } = useTranslation();
|
|
17561
|
-
const
|
|
17779
|
+
const treeRef = reactExports.useRef(null);
|
|
17780
|
+
const treeItemRefs = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
17781
|
+
const navigationActionRefs = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
17782
|
+
const lastFocusedActionRef = reactExports.useRef(null);
|
|
17783
|
+
const focusedTreeItemIdRef = reactExports.useRef(null);
|
|
17784
|
+
const pendingFocusIdRef = reactExports.useRef(null);
|
|
17785
|
+
const pendingFocusRestoreRef = reactExports.useRef(false);
|
|
17562
17786
|
const [data, setData] = reactExports.useState([]);
|
|
17563
17787
|
const [loading, setLoading] = reactExports.useState(false);
|
|
17564
17788
|
const [showLoading, setShowLoading] = reactExports.useState(false);
|
|
@@ -17769,6 +17993,144 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
17769
17993
|
},
|
|
17770
17994
|
[openFolders]
|
|
17771
17995
|
);
|
|
17996
|
+
const registerTreeItemRef = reactExports.useCallback((id, element) => {
|
|
17997
|
+
if (element) {
|
|
17998
|
+
treeItemRefs.current.set(id, element);
|
|
17999
|
+
} else {
|
|
18000
|
+
treeItemRefs.current.delete(id);
|
|
18001
|
+
}
|
|
18002
|
+
}, []);
|
|
18003
|
+
const registerNavigationActionRef = reactExports.useCallback(
|
|
18004
|
+
(action, element) => {
|
|
18005
|
+
if (element) {
|
|
18006
|
+
navigationActionRefs.current.set(action, element);
|
|
18007
|
+
} else {
|
|
18008
|
+
navigationActionRefs.current.delete(action);
|
|
18009
|
+
}
|
|
18010
|
+
},
|
|
18011
|
+
[]
|
|
18012
|
+
);
|
|
18013
|
+
const handleTreeItemFocus = reactExports.useCallback((id) => {
|
|
18014
|
+
focusedTreeItemIdRef.current = id;
|
|
18015
|
+
}, []);
|
|
18016
|
+
const focusTreeItem = reactExports.useCallback(
|
|
18017
|
+
(id) => {
|
|
18018
|
+
let element = treeItemRefs.current.get(id);
|
|
18019
|
+
if (!element) {
|
|
18020
|
+
const visibleIds = flattenTree(data);
|
|
18021
|
+
const itemIndex = visibleIds.indexOf(id);
|
|
18022
|
+
if (itemIndex !== -1) {
|
|
18023
|
+
element = treeRef.current?.querySelectorAll('[role="treeitem"]')[itemIndex];
|
|
18024
|
+
}
|
|
18025
|
+
}
|
|
18026
|
+
if (!element) return;
|
|
18027
|
+
element.focus({ preventScroll: true });
|
|
18028
|
+
element.scrollIntoView({ block: "nearest" });
|
|
18029
|
+
},
|
|
18030
|
+
[data, flattenTree]
|
|
18031
|
+
);
|
|
18032
|
+
const fileNavigationItems = reactExports.useMemo(() => {
|
|
18033
|
+
const items = [];
|
|
18034
|
+
if (!isWebUI && cwd) {
|
|
18035
|
+
items.push({ type: "action", action: "reveal" });
|
|
18036
|
+
items.push({ type: "action", action: "editor" });
|
|
18037
|
+
}
|
|
18038
|
+
if (!loading) {
|
|
18039
|
+
items.push(
|
|
18040
|
+
{ type: "action", action: "new-file" },
|
|
18041
|
+
{ type: "action", action: "new-folder" },
|
|
18042
|
+
{ type: "action", action: "refresh" },
|
|
18043
|
+
{ type: "action", action: "collapse" }
|
|
18044
|
+
);
|
|
18045
|
+
}
|
|
18046
|
+
items.push(...flattenTree(data).map((id) => ({ type: "tree", id })));
|
|
18047
|
+
return items;
|
|
18048
|
+
}, [cwd, data, flattenTree, loading]);
|
|
18049
|
+
const fileActionItems = reactExports.useMemo(
|
|
18050
|
+
() => fileNavigationItems.filter(
|
|
18051
|
+
(item) => item.type === "action"
|
|
18052
|
+
),
|
|
18053
|
+
[fileNavigationItems]
|
|
18054
|
+
);
|
|
18055
|
+
const treeNavigationItems = reactExports.useMemo(
|
|
18056
|
+
() => fileNavigationItems.filter(
|
|
18057
|
+
(item) => item.type === "tree"
|
|
18058
|
+
),
|
|
18059
|
+
[fileNavigationItems]
|
|
18060
|
+
);
|
|
18061
|
+
const focusFileNavigationItem = reactExports.useCallback(
|
|
18062
|
+
(item) => {
|
|
18063
|
+
if (item.type === "action") {
|
|
18064
|
+
const element = navigationActionRefs.current.get(item.action);
|
|
18065
|
+
if (!element) return;
|
|
18066
|
+
element.focus({ preventScroll: true });
|
|
18067
|
+
return;
|
|
18068
|
+
}
|
|
18069
|
+
focusTreeItem(item.id);
|
|
18070
|
+
},
|
|
18071
|
+
[focusTreeItem]
|
|
18072
|
+
);
|
|
18073
|
+
const handleFileNavigationKeyDown = reactExports.useCallback(
|
|
18074
|
+
(event, items, item) => {
|
|
18075
|
+
event.preventDefault();
|
|
18076
|
+
event.stopPropagation();
|
|
18077
|
+
if (items.length === 0) return;
|
|
18078
|
+
const currentIndex = items.findIndex(
|
|
18079
|
+
(navigationItem) => fileNavigationItemKey(navigationItem) === fileNavigationItemKey(item)
|
|
18080
|
+
);
|
|
18081
|
+
const nextIndex = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : Math.max(
|
|
18082
|
+
0,
|
|
18083
|
+
Math.min(
|
|
18084
|
+
items.length - 1,
|
|
18085
|
+
currentIndex + (event.key === "ArrowRight" || event.key === "ArrowDown" ? 1 : -1)
|
|
18086
|
+
)
|
|
18087
|
+
);
|
|
18088
|
+
const nextItem = items[nextIndex];
|
|
18089
|
+
if (nextItem) focusFileNavigationItem(nextItem);
|
|
18090
|
+
},
|
|
18091
|
+
[focusFileNavigationItem]
|
|
18092
|
+
);
|
|
18093
|
+
const focusFileTree = reactExports.useCallback(() => {
|
|
18094
|
+
const visibleIds = flattenTree(data);
|
|
18095
|
+
const targetId = lastSelectedId && visibleIds.includes(lastSelectedId) && lastSelectedId || visibleIds.find((id) => selectedIds.has(id)) || visibleIds[0];
|
|
18096
|
+
if (targetId) {
|
|
18097
|
+
focusTreeItem(targetId);
|
|
18098
|
+
} else if (fileActionItems[0]) {
|
|
18099
|
+
focusFileNavigationItem(fileActionItems[0]);
|
|
18100
|
+
}
|
|
18101
|
+
}, [
|
|
18102
|
+
data,
|
|
18103
|
+
fileActionItems,
|
|
18104
|
+
flattenTree,
|
|
18105
|
+
focusFileNavigationItem,
|
|
18106
|
+
focusTreeItem,
|
|
18107
|
+
lastSelectedId,
|
|
18108
|
+
selectedIds
|
|
18109
|
+
]);
|
|
18110
|
+
useFocusTarget("file-tree-content", focusFileTree);
|
|
18111
|
+
reactExports.useEffect(() => {
|
|
18112
|
+
if (!pendingFocusRestoreRef.current || loading) return;
|
|
18113
|
+
const visibleIds = flattenTree(data);
|
|
18114
|
+
const pendingId = pendingFocusIdRef.current;
|
|
18115
|
+
const targetId = pendingId && visibleIds.includes(pendingId) ? pendingId : visibleIds[0];
|
|
18116
|
+
const fallbackAction = fileActionItems[0];
|
|
18117
|
+
pendingFocusRestoreRef.current = false;
|
|
18118
|
+
pendingFocusIdRef.current = null;
|
|
18119
|
+
window.requestAnimationFrame(() => {
|
|
18120
|
+
if (targetId) {
|
|
18121
|
+
focusTreeItem(targetId);
|
|
18122
|
+
} else if (fallbackAction) {
|
|
18123
|
+
focusFileNavigationItem(fallbackAction);
|
|
18124
|
+
}
|
|
18125
|
+
});
|
|
18126
|
+
}, [
|
|
18127
|
+
data,
|
|
18128
|
+
fileActionItems,
|
|
18129
|
+
flattenTree,
|
|
18130
|
+
focusFileNavigationItem,
|
|
18131
|
+
focusTreeItem,
|
|
18132
|
+
loading
|
|
18133
|
+
]);
|
|
17772
18134
|
reactExports.useEffect(() => {
|
|
17773
18135
|
useAppStore.getState().updateProjectState(projectId, () => ({
|
|
17774
18136
|
openFolders: Array.from(openFolders)
|
|
@@ -17820,6 +18182,86 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
17820
18182
|
},
|
|
17821
18183
|
[activeProjectId]
|
|
17822
18184
|
);
|
|
18185
|
+
const handleTreeKeyDown = reactExports.useCallback(
|
|
18186
|
+
(event, node) => {
|
|
18187
|
+
const { key } = event;
|
|
18188
|
+
const isVerticalNavigationKey = key === "ArrowUp" || key === "ArrowDown" || key === "Home" || key === "End";
|
|
18189
|
+
if (isVerticalNavigationKey) {
|
|
18190
|
+
const treeItem = { type: "tree", id: node.id };
|
|
18191
|
+
const currentIndex = treeNavigationItems.findIndex((item) => item.id === node.id);
|
|
18192
|
+
if (key === "ArrowUp" && currentIndex === 0) {
|
|
18193
|
+
const actionItem = fileActionItems.find((item) => item.action === lastFocusedActionRef.current) ?? fileActionItems[0];
|
|
18194
|
+
if (actionItem) {
|
|
18195
|
+
event.preventDefault();
|
|
18196
|
+
event.stopPropagation();
|
|
18197
|
+
focusFileNavigationItem(actionItem);
|
|
18198
|
+
return;
|
|
18199
|
+
}
|
|
18200
|
+
}
|
|
18201
|
+
handleFileNavigationKeyDown(event, treeNavigationItems, treeItem);
|
|
18202
|
+
return;
|
|
18203
|
+
}
|
|
18204
|
+
if (key === "/") {
|
|
18205
|
+
event.preventDefault();
|
|
18206
|
+
event.stopPropagation();
|
|
18207
|
+
const target = event.currentTarget;
|
|
18208
|
+
const rect = target.getBoundingClientRect();
|
|
18209
|
+
target.dispatchEvent(
|
|
18210
|
+
new MouseEvent("contextmenu", {
|
|
18211
|
+
bubbles: true,
|
|
18212
|
+
cancelable: true,
|
|
18213
|
+
view: window,
|
|
18214
|
+
button: 2,
|
|
18215
|
+
buttons: 2,
|
|
18216
|
+
clientX: rect.left + rect.width / 2,
|
|
18217
|
+
clientY: rect.top + rect.height / 2
|
|
18218
|
+
})
|
|
18219
|
+
);
|
|
18220
|
+
return;
|
|
18221
|
+
}
|
|
18222
|
+
if (key === "ArrowLeft" || key === "ArrowRight") {
|
|
18223
|
+
event.preventDefault();
|
|
18224
|
+
event.stopPropagation();
|
|
18225
|
+
if (key === "ArrowRight" && node.isFolder) {
|
|
18226
|
+
if (!openFolders.has(node.id)) {
|
|
18227
|
+
toggle(node);
|
|
18228
|
+
} else {
|
|
18229
|
+
const firstChild = node.children?.[0];
|
|
18230
|
+
if (firstChild) focusTreeItem(firstChild.id);
|
|
18231
|
+
}
|
|
18232
|
+
} else if (key === "ArrowLeft") {
|
|
18233
|
+
if (node.isFolder && openFolders.has(node.id)) {
|
|
18234
|
+
toggle(node);
|
|
18235
|
+
} else {
|
|
18236
|
+
const parentId = node.id.slice(0, node.id.lastIndexOf("/"));
|
|
18237
|
+
if (parentId) focusTreeItem(parentId);
|
|
18238
|
+
}
|
|
18239
|
+
}
|
|
18240
|
+
return;
|
|
18241
|
+
}
|
|
18242
|
+
if (key === "Enter" || key === " " || key === "Spacebar") {
|
|
18243
|
+
event.preventDefault();
|
|
18244
|
+
event.stopPropagation();
|
|
18245
|
+
setSelectedIds(/* @__PURE__ */ new Set([node.id]));
|
|
18246
|
+
setLastSelectedId(node.id);
|
|
18247
|
+
if (node.isFolder) {
|
|
18248
|
+
toggle(node);
|
|
18249
|
+
} else {
|
|
18250
|
+
onPreviewFile(node.id);
|
|
18251
|
+
}
|
|
18252
|
+
}
|
|
18253
|
+
},
|
|
18254
|
+
[
|
|
18255
|
+
fileActionItems,
|
|
18256
|
+
focusFileNavigationItem,
|
|
18257
|
+
focusTreeItem,
|
|
18258
|
+
handleFileNavigationKeyDown,
|
|
18259
|
+
onPreviewFile,
|
|
18260
|
+
openFolders,
|
|
18261
|
+
toggle,
|
|
18262
|
+
treeNavigationItems
|
|
18263
|
+
]
|
|
18264
|
+
);
|
|
17823
18265
|
const collapseAll = reactExports.useCallback(() => {
|
|
17824
18266
|
setOpenFolders(/* @__PURE__ */ new Set());
|
|
17825
18267
|
openFoldersRef.current = /* @__PURE__ */ new Set();
|
|
@@ -17958,6 +18400,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
17958
18400
|
request.getPlatform().then((p) => setOsPlatform(p));
|
|
17959
18401
|
}, []);
|
|
17960
18402
|
const trashLabel = osPlatform === "darwin" ? t("filePanel.moveToTrash") : osPlatform === "win32" ? t("filePanel.moveToRecycleBin") : t("filePanel.moveToTrash");
|
|
18403
|
+
const prepareFocusAfterDelete = (ids) => {
|
|
18404
|
+
const isDeletedId = (id) => ids.some((deletedId) => id === deletedId || id.startsWith(`${deletedId}/`));
|
|
18405
|
+
const referenceId = (focusedTreeItemIdRef.current && isDeletedId(focusedTreeItemIdRef.current) ? focusedTreeItemIdRef.current : null) ?? (lastSelectedId && isDeletedId(lastSelectedId) ? lastSelectedId : null) ?? ids.find(isDeletedId);
|
|
18406
|
+
if (!referenceId) return;
|
|
18407
|
+
const visibleIds = flattenTree(data);
|
|
18408
|
+
const referenceIndex = visibleIds.indexOf(referenceId);
|
|
18409
|
+
const targetId = (referenceIndex !== -1 ? visibleIds.slice(referenceIndex + 1).find((id) => !isDeletedId(id)) : void 0) ?? (referenceIndex !== -1 ? [...visibleIds.slice(0, referenceIndex)].reverse().find((id) => !isDeletedId(id)) : void 0) ?? visibleIds.find((id) => !isDeletedId(id));
|
|
18410
|
+
pendingFocusIdRef.current = targetId ?? null;
|
|
18411
|
+
pendingFocusRestoreRef.current = true;
|
|
18412
|
+
};
|
|
17961
18413
|
const deleteNode = async (ids) => {
|
|
17962
18414
|
if (ids.length === 0 || !activeProjectId) return;
|
|
17963
18415
|
await confirm2({
|
|
@@ -17986,7 +18438,9 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
17986
18438
|
} catch (err) {
|
|
17987
18439
|
console.error("Delete failed:", extractErrorMessage(err));
|
|
17988
18440
|
}
|
|
18441
|
+
prepareFocusAfterDelete(ids);
|
|
17989
18442
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
18443
|
+
setLastSelectedId(null);
|
|
17990
18444
|
refresh();
|
|
17991
18445
|
return "trashed";
|
|
17992
18446
|
}
|
|
@@ -18004,7 +18458,9 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18004
18458
|
} catch (err) {
|
|
18005
18459
|
console.error("Delete failed:", extractErrorMessage(err));
|
|
18006
18460
|
}
|
|
18461
|
+
prepareFocusAfterDelete(ids);
|
|
18007
18462
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
18463
|
+
setLastSelectedId(null);
|
|
18008
18464
|
refresh();
|
|
18009
18465
|
return "deleted";
|
|
18010
18466
|
}
|
|
@@ -18445,6 +18901,47 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18445
18901
|
}
|
|
18446
18902
|
return null;
|
|
18447
18903
|
};
|
|
18904
|
+
const handleFileActionKeyDown = (event, action) => {
|
|
18905
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Home" || event.key === "End") {
|
|
18906
|
+
handleFileNavigationKeyDown(event, fileActionItems, { type: "action", action });
|
|
18907
|
+
return;
|
|
18908
|
+
}
|
|
18909
|
+
if (event.key === "ArrowDown") {
|
|
18910
|
+
event.preventDefault();
|
|
18911
|
+
event.stopPropagation();
|
|
18912
|
+
const firstTreeItem = treeNavigationItems[0];
|
|
18913
|
+
if (firstTreeItem) focusFileNavigationItem(firstTreeItem);
|
|
18914
|
+
return;
|
|
18915
|
+
}
|
|
18916
|
+
if (event.key !== "Enter" && event.key !== " " && event.key !== "Spacebar") return;
|
|
18917
|
+
event.preventDefault();
|
|
18918
|
+
event.stopPropagation();
|
|
18919
|
+
switch (action) {
|
|
18920
|
+
case "reveal":
|
|
18921
|
+
if (cwd) void revealInFinder(cwd);
|
|
18922
|
+
break;
|
|
18923
|
+
case "editor":
|
|
18924
|
+
if (cwd) {
|
|
18925
|
+
const editorName = useAppStore.getState().editor.name;
|
|
18926
|
+
void electron.openInEditor(cwd, editorName).catch((err) => {
|
|
18927
|
+
console.error("openInEditor failed:", extractErrorMessage(err));
|
|
18928
|
+
});
|
|
18929
|
+
}
|
|
18930
|
+
break;
|
|
18931
|
+
case "new-file":
|
|
18932
|
+
createIn(getSelectedFolder(), false);
|
|
18933
|
+
break;
|
|
18934
|
+
case "new-folder":
|
|
18935
|
+
createIn(getSelectedFolder(), true);
|
|
18936
|
+
break;
|
|
18937
|
+
case "refresh":
|
|
18938
|
+
refresh();
|
|
18939
|
+
break;
|
|
18940
|
+
case "collapse":
|
|
18941
|
+
collapseAll();
|
|
18942
|
+
break;
|
|
18943
|
+
}
|
|
18944
|
+
};
|
|
18448
18945
|
if (!projectId) {
|
|
18449
18946
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: t("filePanel.noProject", "No project selected") });
|
|
18450
18947
|
}
|
|
@@ -18464,9 +18961,12 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18464
18961
|
onEditChange: setEditingValue,
|
|
18465
18962
|
onEditSubmit: submitEdit,
|
|
18466
18963
|
onEditCancel: () => setEditingId(null),
|
|
18467
|
-
actions
|
|
18964
|
+
actions,
|
|
18965
|
+
onKeyDown: handleTreeKeyDown,
|
|
18966
|
+
registerRef: registerTreeItemRef,
|
|
18967
|
+
onFocus: handleTreeItemFocus
|
|
18468
18968
|
};
|
|
18469
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
18969
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full min-h-0 flex-col text-xs w-full", children: [
|
|
18470
18970
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-10 items-center gap-0.5 border-b border-border", children: [
|
|
18471
18971
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex text-muted-foreground items-center gap-1 px-3", children: [
|
|
18472
18972
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Folders, { className: "size-3.5" }),
|
|
@@ -18477,10 +18977,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18477
18977
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18478
18978
|
Button,
|
|
18479
18979
|
{
|
|
18980
|
+
ref: (element) => registerNavigationActionRef("reveal", element),
|
|
18480
18981
|
variant: "ghost",
|
|
18481
18982
|
size: "icon",
|
|
18983
|
+
tabIndex: -1,
|
|
18482
18984
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18483
18985
|
disabled: !cwd,
|
|
18986
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "reveal"),
|
|
18987
|
+
onFocus: () => {
|
|
18988
|
+
lastFocusedActionRef.current = "reveal";
|
|
18989
|
+
},
|
|
18484
18990
|
onClick: () => revealInFinder(cwd),
|
|
18485
18991
|
title: t("filePanel.revealInFinder"),
|
|
18486
18992
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "size-3.5" })
|
|
@@ -18489,10 +18995,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18489
18995
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18490
18996
|
Button,
|
|
18491
18997
|
{
|
|
18998
|
+
ref: (element) => registerNavigationActionRef("editor", element),
|
|
18492
18999
|
variant: "ghost",
|
|
18493
19000
|
size: "icon",
|
|
19001
|
+
tabIndex: -1,
|
|
18494
19002
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18495
19003
|
disabled: !cwd,
|
|
19004
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "editor"),
|
|
19005
|
+
onFocus: () => {
|
|
19006
|
+
lastFocusedActionRef.current = "editor";
|
|
19007
|
+
},
|
|
18496
19008
|
onClick: () => {
|
|
18497
19009
|
if (!cwd) return;
|
|
18498
19010
|
const editorName = useAppStore.getState().editor.name;
|
|
@@ -18510,10 +19022,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18510
19022
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18511
19023
|
Button,
|
|
18512
19024
|
{
|
|
19025
|
+
ref: (element) => registerNavigationActionRef("new-file", element),
|
|
18513
19026
|
variant: "ghost",
|
|
18514
19027
|
size: "icon",
|
|
19028
|
+
tabIndex: -1,
|
|
18515
19029
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18516
19030
|
disabled: loading,
|
|
19031
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "new-file"),
|
|
19032
|
+
onFocus: () => {
|
|
19033
|
+
lastFocusedActionRef.current = "new-file";
|
|
19034
|
+
},
|
|
18517
19035
|
onClick: () => createIn(getSelectedFolder(), false),
|
|
18518
19036
|
title: t("filePanel.newFile"),
|
|
18519
19037
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "size-3.5" })
|
|
@@ -18522,10 +19040,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18522
19040
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18523
19041
|
Button,
|
|
18524
19042
|
{
|
|
19043
|
+
ref: (element) => registerNavigationActionRef("new-folder", element),
|
|
18525
19044
|
variant: "ghost",
|
|
18526
19045
|
size: "icon",
|
|
19046
|
+
tabIndex: -1,
|
|
18527
19047
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18528
19048
|
disabled: loading,
|
|
19049
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "new-folder"),
|
|
19050
|
+
onFocus: () => {
|
|
19051
|
+
lastFocusedActionRef.current = "new-folder";
|
|
19052
|
+
},
|
|
18529
19053
|
onClick: () => createIn(getSelectedFolder(), true),
|
|
18530
19054
|
title: t("filePanel.newFolder"),
|
|
18531
19055
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "size-3.5" })
|
|
@@ -18534,10 +19058,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18534
19058
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18535
19059
|
Button,
|
|
18536
19060
|
{
|
|
19061
|
+
ref: (element) => registerNavigationActionRef("refresh", element),
|
|
18537
19062
|
variant: "ghost",
|
|
18538
19063
|
size: "icon",
|
|
19064
|
+
tabIndex: -1,
|
|
18539
19065
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18540
19066
|
disabled: loading,
|
|
19067
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "refresh"),
|
|
19068
|
+
onFocus: () => {
|
|
19069
|
+
lastFocusedActionRef.current = "refresh";
|
|
19070
|
+
},
|
|
18541
19071
|
onClick: refresh,
|
|
18542
19072
|
title: t("filePanel.refresh", "Refresh"),
|
|
18543
19073
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3.5" })
|
|
@@ -18546,10 +19076,16 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18546
19076
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18547
19077
|
Button,
|
|
18548
19078
|
{
|
|
19079
|
+
ref: (element) => registerNavigationActionRef("collapse", element),
|
|
18549
19080
|
variant: "ghost",
|
|
18550
19081
|
size: "icon",
|
|
19082
|
+
tabIndex: -1,
|
|
18551
19083
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18552
19084
|
disabled: loading,
|
|
19085
|
+
onKeyDown: (event) => handleFileActionKeyDown(event, "collapse"),
|
|
19086
|
+
onFocus: () => {
|
|
19087
|
+
lastFocusedActionRef.current = "collapse";
|
|
19088
|
+
},
|
|
18553
19089
|
onClick: collapseAll,
|
|
18554
19090
|
title: t("filePanel.collapseFolders"),
|
|
18555
19091
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ListChevronsDownUp, { className: "size-3.5" })
|
|
@@ -18571,11 +19107,18 @@ const FilePanel = reactExports.memo(function FilePanel2({
|
|
|
18571
19107
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground/70", children: t("filePanel.emptyDirectory") })
|
|
18572
19108
|
]
|
|
18573
19109
|
}
|
|
18574
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "min-h-0 flex-1
|
|
19110
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "min-h-0 flex-1 px-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenu, { children: [
|
|
18575
19111
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18576
19112
|
ContextMenuTrigger,
|
|
18577
19113
|
{
|
|
18578
|
-
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19114
|
+
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19115
|
+
"div",
|
|
19116
|
+
{
|
|
19117
|
+
ref: treeRef,
|
|
19118
|
+
role: "tree",
|
|
19119
|
+
"aria-label": t("filePanel.title", "Files")
|
|
19120
|
+
}
|
|
19121
|
+
),
|
|
18579
19122
|
className: "min-h-full py-1",
|
|
18580
19123
|
onClick: (e) => {
|
|
18581
19124
|
if (e.target === e.currentTarget) clearSelection();
|
|
@@ -18703,6 +19246,10 @@ function findNode(node, id) {
|
|
|
18703
19246
|
}
|
|
18704
19247
|
return null;
|
|
18705
19248
|
}
|
|
19249
|
+
const ADD_TERMINAL_NAVIGATION_ID = "__add_terminal__";
|
|
19250
|
+
function terminalNavigationItemKey(item) {
|
|
19251
|
+
return item.type === "add" ? ADD_TERMINAL_NAVIGATION_ID : item.id;
|
|
19252
|
+
}
|
|
18706
19253
|
function TerminalPanel({
|
|
18707
19254
|
projectId,
|
|
18708
19255
|
activeTerminalId,
|
|
@@ -18712,7 +19259,51 @@ function TerminalPanel({
|
|
|
18712
19259
|
const projectState = useProjectState(projectId);
|
|
18713
19260
|
const terminals = projectState.terminals;
|
|
18714
19261
|
const updateProjectState = useAppStore((s15) => s15.updateProjectState);
|
|
18715
|
-
|
|
19262
|
+
const navigationItemRefs = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
19263
|
+
const focusedNavigationItemIdRef = reactExports.useRef(null);
|
|
19264
|
+
const navigationItems = reactExports.useMemo(() => {
|
|
19265
|
+
const items = [{ type: "add" }];
|
|
19266
|
+
items.push(
|
|
19267
|
+
...terminals.map(
|
|
19268
|
+
(terminal) => ({ type: "terminal", id: terminal.id })
|
|
19269
|
+
)
|
|
19270
|
+
);
|
|
19271
|
+
return items;
|
|
19272
|
+
}, [terminals]);
|
|
19273
|
+
const terminalItems = reactExports.useMemo(
|
|
19274
|
+
() => navigationItems.filter(
|
|
19275
|
+
(item) => item.type === "terminal"
|
|
19276
|
+
),
|
|
19277
|
+
[navigationItems]
|
|
19278
|
+
);
|
|
19279
|
+
const registerNavigationItemRef = reactExports.useCallback((id, element) => {
|
|
19280
|
+
if (element) {
|
|
19281
|
+
navigationItemRefs.current.set(id, element);
|
|
19282
|
+
} else {
|
|
19283
|
+
navigationItemRefs.current.delete(id);
|
|
19284
|
+
}
|
|
19285
|
+
}, []);
|
|
19286
|
+
const focusNavigationItem = reactExports.useCallback((item) => {
|
|
19287
|
+
const element = navigationItemRefs.current.get(terminalNavigationItemKey(item));
|
|
19288
|
+
if (!element) return;
|
|
19289
|
+
element.focus({ preventScroll: true });
|
|
19290
|
+
element.scrollIntoView({ block: "nearest" });
|
|
19291
|
+
}, []);
|
|
19292
|
+
const focusTerminalList = reactExports.useCallback(() => {
|
|
19293
|
+
const activeItem = activeTerminalId ? navigationItems.find(
|
|
19294
|
+
(item) => item.type === "terminal" && item.id === activeTerminalId
|
|
19295
|
+
) : void 0;
|
|
19296
|
+
focusNavigationItem(activeItem ?? navigationItems[0]);
|
|
19297
|
+
}, [activeTerminalId, focusNavigationItem, navigationItems]);
|
|
19298
|
+
useFocusTarget("terminal-list-content", focusTerminalList);
|
|
19299
|
+
const selectTerminal = reactExports.useCallback(
|
|
19300
|
+
(terminalId) => {
|
|
19301
|
+
updateProjectState(projectId, () => ({ activeTerminalId: terminalId }));
|
|
19302
|
+
onSelectTerminal(terminalId);
|
|
19303
|
+
},
|
|
19304
|
+
[onSelectTerminal, projectId, updateProjectState]
|
|
19305
|
+
);
|
|
19306
|
+
const createTerminal = reactExports.useCallback(async () => {
|
|
18716
19307
|
if (!projectId) return;
|
|
18717
19308
|
const { terminalId } = await request.createTerminal({ projectId, cwd: "", clientId });
|
|
18718
19309
|
updateProjectState(projectId, (prev) => ({
|
|
@@ -18720,9 +19311,14 @@ function TerminalPanel({
|
|
|
18720
19311
|
activeTerminalId: terminalId
|
|
18721
19312
|
}));
|
|
18722
19313
|
onSelectTerminal(terminalId);
|
|
18723
|
-
}
|
|
19314
|
+
}, [onSelectTerminal, projectId, updateProjectState]);
|
|
18724
19315
|
async function deleteTerminal(terminalId, e) {
|
|
18725
|
-
e
|
|
19316
|
+
e?.stopPropagation();
|
|
19317
|
+
const shouldRestoreFocus = focusedNavigationItemIdRef.current === terminalId;
|
|
19318
|
+
const deletedIndex = navigationItems.findIndex(
|
|
19319
|
+
(item) => item.type === "terminal" && item.id === terminalId
|
|
19320
|
+
);
|
|
19321
|
+
const focusTarget = deletedIndex === -1 ? void 0 : navigationItems[deletedIndex + 1] ?? navigationItems[deletedIndex - 1] ?? navigationItems[0];
|
|
18726
19322
|
destroyTerminalInstance(terminalId);
|
|
18727
19323
|
await request.killTerminal({ terminalId });
|
|
18728
19324
|
updateProjectState(projectId, (prev) => {
|
|
@@ -18732,7 +19328,81 @@ function TerminalPanel({
|
|
|
18732
19328
|
activeTerminalId: prev.activeTerminalId === terminalId ? nextList[nextList.length - 1]?.id ?? null : prev.activeTerminalId
|
|
18733
19329
|
};
|
|
18734
19330
|
});
|
|
19331
|
+
if (shouldRestoreFocus && focusTarget) {
|
|
19332
|
+
window.requestAnimationFrame(() => focusNavigationItem(focusTarget));
|
|
19333
|
+
}
|
|
18735
19334
|
}
|
|
19335
|
+
const handleNavigationKeyDown = reactExports.useCallback(
|
|
19336
|
+
(event, item) => {
|
|
19337
|
+
const { key } = event;
|
|
19338
|
+
if (item.type === "add") {
|
|
19339
|
+
if (key === "ArrowLeft" || key === "ArrowRight" || key === "Home" || key === "End") {
|
|
19340
|
+
event.preventDefault();
|
|
19341
|
+
event.stopPropagation();
|
|
19342
|
+
focusNavigationItem(item);
|
|
19343
|
+
return;
|
|
19344
|
+
}
|
|
19345
|
+
if (key === "ArrowDown") {
|
|
19346
|
+
event.preventDefault();
|
|
19347
|
+
event.stopPropagation();
|
|
19348
|
+
const firstTerminal = terminalItems[0];
|
|
19349
|
+
if (firstTerminal) focusNavigationItem(firstTerminal);
|
|
19350
|
+
return;
|
|
19351
|
+
}
|
|
19352
|
+
if (key === "Enter" || key === " " || key === "Spacebar") {
|
|
19353
|
+
event.preventDefault();
|
|
19354
|
+
event.stopPropagation();
|
|
19355
|
+
void createTerminal();
|
|
19356
|
+
}
|
|
19357
|
+
return;
|
|
19358
|
+
}
|
|
19359
|
+
const isVerticalNavigationKey = key === "ArrowUp" || key === "ArrowDown" || key === "Home" || key === "End";
|
|
19360
|
+
if (isVerticalNavigationKey) {
|
|
19361
|
+
event.preventDefault();
|
|
19362
|
+
event.stopPropagation();
|
|
19363
|
+
const currentIndex = terminalItems.findIndex((terminal) => terminal.id === item.id);
|
|
19364
|
+
if (key === "ArrowUp" && currentIndex === 0) {
|
|
19365
|
+
focusNavigationItem({ type: "add" });
|
|
19366
|
+
return;
|
|
19367
|
+
}
|
|
19368
|
+
if (terminalItems.length === 0) return;
|
|
19369
|
+
const nextIndex = key === "Home" ? 0 : key === "End" ? terminalItems.length - 1 : Math.max(
|
|
19370
|
+
0,
|
|
19371
|
+
Math.min(
|
|
19372
|
+
terminalItems.length - 1,
|
|
19373
|
+
currentIndex + (key === "ArrowDown" ? 1 : -1)
|
|
19374
|
+
)
|
|
19375
|
+
);
|
|
19376
|
+
const nextTerminal = terminalItems[nextIndex];
|
|
19377
|
+
if (nextTerminal) focusNavigationItem(nextTerminal);
|
|
19378
|
+
return;
|
|
19379
|
+
}
|
|
19380
|
+
if (key === "/") {
|
|
19381
|
+
event.preventDefault();
|
|
19382
|
+
event.stopPropagation();
|
|
19383
|
+
const target = event.currentTarget;
|
|
19384
|
+
const rect = target.getBoundingClientRect();
|
|
19385
|
+
target.dispatchEvent(
|
|
19386
|
+
new MouseEvent("contextmenu", {
|
|
19387
|
+
bubbles: true,
|
|
19388
|
+
cancelable: true,
|
|
19389
|
+
view: window,
|
|
19390
|
+
button: 2,
|
|
19391
|
+
buttons: 2,
|
|
19392
|
+
clientX: rect.left + rect.width / 2,
|
|
19393
|
+
clientY: rect.top + rect.height / 2
|
|
19394
|
+
})
|
|
19395
|
+
);
|
|
19396
|
+
return;
|
|
19397
|
+
}
|
|
19398
|
+
if (key === "Enter" || key === " " || key === "Spacebar") {
|
|
19399
|
+
event.preventDefault();
|
|
19400
|
+
event.stopPropagation();
|
|
19401
|
+
selectTerminal(item.id);
|
|
19402
|
+
}
|
|
19403
|
+
},
|
|
19404
|
+
[createTerminal, focusNavigationItem, selectTerminal, terminalItems]
|
|
19405
|
+
);
|
|
18736
19406
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
18737
19407
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-10 items-center gap-0.5 border-b border-border", children: [
|
|
18738
19408
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex text-muted-foreground items-center gap-1 px-3", children: [
|
|
@@ -18742,10 +19412,16 @@ function TerminalPanel({
|
|
|
18742
19412
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto mr-2 flex items-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18743
19413
|
Button,
|
|
18744
19414
|
{
|
|
19415
|
+
ref: (element) => registerNavigationItemRef(ADD_TERMINAL_NAVIGATION_ID, element),
|
|
18745
19416
|
variant: "ghost",
|
|
18746
19417
|
size: "icon",
|
|
19418
|
+
tabIndex: -1,
|
|
18747
19419
|
className: "size-6 text-muted-foreground hover:text-foreground",
|
|
18748
19420
|
onClick: () => void createTerminal(),
|
|
19421
|
+
onKeyDown: (event) => handleNavigationKeyDown(event, { type: "add" }),
|
|
19422
|
+
onFocus: () => {
|
|
19423
|
+
focusedNavigationItemIdRef.current = ADD_TERMINAL_NAVIGATION_ID;
|
|
19424
|
+
},
|
|
18749
19425
|
"aria-label": t("terminalPanel.addTerminal", "Add terminal"),
|
|
18750
19426
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-3.5" })
|
|
18751
19427
|
}
|
|
@@ -18754,41 +19430,70 @@ function TerminalPanel({
|
|
|
18754
19430
|
terminals.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center text-muted-foreground", children: [
|
|
18755
19431
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "size-10 rounded-full bg-muted flex items-center justify-center mb-3 -mt-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SquareTerminal, { className: "size-5 text-muted-foreground/60" }) }),
|
|
18756
19432
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground/70", children: t("terminalPanel.noTerminalSelected", "No terminals") })
|
|
18757
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 py-1 px-1", children: terminals.map((terminal) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
onSelectTerminal(terminal.id);
|
|
18764
|
-
},
|
|
18765
|
-
className: cn$1(
|
|
18766
|
-
"flex h-8 items-center gap-2 rounded-md pl-2 pr-1.5 text-xs w-full transition-colors",
|
|
18767
|
-
terminal.id === activeTerminalId ? "bg-accent text-accent-foreground" : "text-foreground/70 hover:bg-accent/50 hover:text-foreground"
|
|
18768
|
-
),
|
|
18769
|
-
children: [
|
|
18770
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18771
|
-
Circle,
|
|
19433
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-0.5 py-1 px-1", children: terminals.map((terminal) => /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenu, { children: [
|
|
19434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
19435
|
+
ContextMenuTrigger,
|
|
19436
|
+
{
|
|
19437
|
+
render: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19438
|
+
"button",
|
|
18772
19439
|
{
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
19440
|
+
ref: (element) => registerNavigationItemRef(terminal.id, element),
|
|
19441
|
+
type: "button",
|
|
19442
|
+
tabIndex: -1,
|
|
19443
|
+
className: "outline-0 focus-visible:inset-ring-1 focus-visible:inset-ring-ring/80 rounded-md",
|
|
19444
|
+
"aria-current": terminal.id === activeTerminalId ? "true" : void 0,
|
|
19445
|
+
onKeyDown: (event) => handleNavigationKeyDown(event, { type: "terminal", id: terminal.id }),
|
|
19446
|
+
onFocus: () => {
|
|
19447
|
+
focusedNavigationItemIdRef.current = terminal.id;
|
|
19448
|
+
}
|
|
18777
19449
|
}
|
|
18778
19450
|
),
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
"
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
19451
|
+
onClick: () => selectTerminal(terminal.id),
|
|
19452
|
+
className: cn$1(
|
|
19453
|
+
"flex h-8 items-center gap-2 rounded-md pl-2 pr-1.5 text-xs w-full transition-colors",
|
|
19454
|
+
terminal.id === activeTerminalId ? "bg-accent text-accent-foreground" : "text-foreground/70 hover:bg-accent/50 hover:text-foreground"
|
|
19455
|
+
),
|
|
19456
|
+
children: [
|
|
19457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19458
|
+
Circle,
|
|
19459
|
+
{
|
|
19460
|
+
className: cn$1(
|
|
19461
|
+
"size-2 shrink-0",
|
|
19462
|
+
terminal.running ? "fill-emerald-400 text-emerald-400" : "text-muted-foreground"
|
|
19463
|
+
)
|
|
19464
|
+
}
|
|
19465
|
+
),
|
|
19466
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-left", children: terminal.id.slice(0, 8) }),
|
|
19467
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19468
|
+
"span",
|
|
19469
|
+
{
|
|
19470
|
+
className: "flex size-5 shrink-0 items-center justify-center rounded hover:bg-background/70",
|
|
19471
|
+
onClick: (e) => void deleteTerminal(terminal.id, e),
|
|
19472
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "size-3 text-muted-foreground" })
|
|
19473
|
+
}
|
|
19474
|
+
)
|
|
19475
|
+
]
|
|
19476
|
+
}
|
|
19477
|
+
),
|
|
19478
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuContent, { children: [
|
|
19479
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { onClick: () => selectTerminal(terminal.id), children: [
|
|
19480
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Eye, {}),
|
|
19481
|
+
t("terminalPanel.view", "View")
|
|
19482
|
+
] }),
|
|
19483
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
|
|
19484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
19485
|
+
ContextMenuItem,
|
|
19486
|
+
{
|
|
19487
|
+
variant: "destructive",
|
|
19488
|
+
onClick: () => void deleteTerminal(terminal.id),
|
|
19489
|
+
children: [
|
|
19490
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, {}),
|
|
19491
|
+
t("terminalPanel.delete", "Delete")
|
|
19492
|
+
]
|
|
19493
|
+
}
|
|
19494
|
+
)
|
|
19495
|
+
] })
|
|
19496
|
+
] }, terminal.id)) }) })
|
|
18792
19497
|
] });
|
|
18793
19498
|
}
|
|
18794
19499
|
function Panel({
|
|
@@ -18801,6 +19506,27 @@ function Panel({
|
|
|
18801
19506
|
onSelectTerminal
|
|
18802
19507
|
}) {
|
|
18803
19508
|
const { t } = useTranslation();
|
|
19509
|
+
const { focus } = useFocusTargetRegistry();
|
|
19510
|
+
const focusFileTree = reactExports.useCallback(() => {
|
|
19511
|
+
const focusFileTreeContent = () => focus("file-tree-content");
|
|
19512
|
+
if (tab === "files") {
|
|
19513
|
+
focusFileTreeContent();
|
|
19514
|
+
return;
|
|
19515
|
+
}
|
|
19516
|
+
onTabChange("files");
|
|
19517
|
+
window.requestAnimationFrame(focusFileTreeContent);
|
|
19518
|
+
}, [focus, onTabChange, tab]);
|
|
19519
|
+
useFocusTarget("file-tree", focusFileTree, Boolean(projectId));
|
|
19520
|
+
const focusTerminalList = reactExports.useCallback(() => {
|
|
19521
|
+
const focusTerminalListContent = () => focus("terminal-list-content");
|
|
19522
|
+
if (tab === "terminal") {
|
|
19523
|
+
focusTerminalListContent();
|
|
19524
|
+
return;
|
|
19525
|
+
}
|
|
19526
|
+
onTabChange("terminal");
|
|
19527
|
+
window.requestAnimationFrame(focusTerminalListContent);
|
|
19528
|
+
}, [focus, onTabChange, tab]);
|
|
19529
|
+
useFocusTarget("terminal-list", focusTerminalList, Boolean(projectId));
|
|
18804
19530
|
if (!projectId) {
|
|
18805
19531
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground border-l border-border bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t("panel.noProjectSelected", "No project selected") }) });
|
|
18806
19532
|
}
|
|
@@ -18821,7 +19547,7 @@ function Panel({
|
|
|
18821
19547
|
t("panel.terminal", "Terminal")
|
|
18822
19548
|
] })
|
|
18823
19549
|
] }) }),
|
|
18824
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "files", className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19550
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "files", keepMounted: true, className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18825
19551
|
FilePanel,
|
|
18826
19552
|
{
|
|
18827
19553
|
projectId,
|
|
@@ -18829,7 +19555,7 @@ function Panel({
|
|
|
18829
19555
|
onPreviewFile
|
|
18830
19556
|
}
|
|
18831
19557
|
) }),
|
|
18832
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "terminal", className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
19558
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TabsContent, { value: "terminal", keepMounted: true, className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
18833
19559
|
TerminalPanel,
|
|
18834
19560
|
{
|
|
18835
19561
|
projectId,
|
|
@@ -18911,61 +19637,21 @@ function Session({ session }) {
|
|
|
18911
19637
|
const [connectionError, setConnectionError] = reactExports.useState(false);
|
|
18912
19638
|
reactExports.useEffect(() => {
|
|
18913
19639
|
setConnectionError(false);
|
|
18914
|
-
|
|
19640
|
+
const sessionState = useAppStore.getState().getSessionState(sessionId);
|
|
19641
|
+
const shouldLoadHistory = sessionState.messages.length === 0 && !isCreatingSession && sessionState.loadedAt === null;
|
|
19642
|
+
if (shouldLoadHistory && fetchingRef.current === sessionId) return;
|
|
19643
|
+
if (shouldLoadHistory) fetchingRef.current = sessionId;
|
|
19644
|
+
void loadSession(sessionId, { loadHistory: shouldLoadHistory }).catch((err) => {
|
|
19645
|
+
if (err instanceof SessionLifecycleBusyError) return;
|
|
18915
19646
|
setConnectionError(true);
|
|
18916
19647
|
toast.error(err instanceof Error ? err.message : String(err));
|
|
19648
|
+
}).finally(() => {
|
|
19649
|
+
if (fetchingRef.current === sessionId) fetchingRef.current = null;
|
|
18917
19650
|
});
|
|
18918
|
-
const sessionState = useAppStore.getState().getSessionState(sessionId);
|
|
18919
|
-
if (sessionState.messages.length > 0 || isCreatingSession || sessionState.loadedAt !== null) {
|
|
18920
|
-
return;
|
|
18921
|
-
}
|
|
18922
|
-
if (fetchingRef.current === sessionId) return;
|
|
18923
|
-
fetchingRef.current = sessionId;
|
|
18924
|
-
async function fetchHistory() {
|
|
18925
|
-
useAppStore.getState().updateSessionState(sessionId, (prev) => ({
|
|
18926
|
-
...reduceFlushStreaming(prev),
|
|
18927
|
-
isLoading: true
|
|
18928
|
-
}));
|
|
18929
|
-
try {
|
|
18930
|
-
const result = await request.getSessionHistory({ sessionId });
|
|
18931
|
-
let state = useAppStore.getState().getSessionState(sessionId);
|
|
18932
|
-
state = { ...state, messages: [], activeToolCalls: /* @__PURE__ */ new Map(), activeSubagents: /* @__PURE__ */ new Map() };
|
|
18933
|
-
const displayIds = /* @__PURE__ */ new Set();
|
|
18934
|
-
for (const notification of result.messages) {
|
|
18935
|
-
const displayId = notification?.update?._meta?.fello?.displayId;
|
|
18936
|
-
if (displayId) {
|
|
18937
|
-
displayIds.add(displayId);
|
|
18938
|
-
}
|
|
18939
|
-
if (!notification?.update) continue;
|
|
18940
|
-
state = reduceSessionNotification(sessionId, state, notification);
|
|
18941
|
-
}
|
|
18942
|
-
for (const notification of state.pendingNotifications) {
|
|
18943
|
-
const did = notification.update._meta?.fello?.displayId;
|
|
18944
|
-
if (did && displayIds.has(did)) {
|
|
18945
|
-
continue;
|
|
18946
|
-
}
|
|
18947
|
-
state = reduceSessionNotification(sessionId, state, notification);
|
|
18948
|
-
}
|
|
18949
|
-
state = reduceFlushStreaming(state);
|
|
18950
|
-
state = {
|
|
18951
|
-
...state,
|
|
18952
|
-
isLoading: false,
|
|
18953
|
-
pendingNotifications: [],
|
|
18954
|
-
loadedAt: Date.now()
|
|
18955
|
-
};
|
|
18956
|
-
useAppStore.getState().updateSessionState(sessionId, () => state);
|
|
18957
|
-
} catch (err) {
|
|
18958
|
-
console.error("Failed to fetch session history", err);
|
|
18959
|
-
useAppStore.getState().updateSessionState(sessionId, (prev) => ({ ...prev, isLoading: false }));
|
|
18960
|
-
} finally {
|
|
18961
|
-
fetchingRef.current = null;
|
|
18962
|
-
}
|
|
18963
|
-
}
|
|
18964
|
-
void fetchHistory();
|
|
18965
19651
|
}, [sessionId, isCreatingSession, toast]);
|
|
18966
19652
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("main", { ref: setMainEl, className: "flex min-w-0 flex-1 flex-col relative overflow-hidden", children: isLoading || sessionConnected !== "connected" || isCreatingSession ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 relative", children: [
|
|
18967
19653
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-0 right-0 h-12", style: { WebkitAppRegion: "drag" } }),
|
|
18968
|
-
connectionError &&
|
|
19654
|
+
connectionError && !isCreatingSession ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
18969
19655
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-normal text-muted-foreground", children: t("session.connectionFailed") }),
|
|
18970
19656
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
18971
19657
|
Button,
|
|
@@ -18974,7 +19660,8 @@ function Session({ session }) {
|
|
|
18974
19660
|
size: "sm",
|
|
18975
19661
|
onClick: () => {
|
|
18976
19662
|
setConnectionError(false);
|
|
18977
|
-
|
|
19663
|
+
void loadSession(sessionId, { force: true, loadHistory: true }).catch((err) => {
|
|
19664
|
+
if (err instanceof SessionLifecycleBusyError) return;
|
|
18978
19665
|
setConnectionError(true);
|
|
18979
19666
|
toast.error(err instanceof Error ? err.message : String(err));
|
|
18980
19667
|
});
|