@nextclaw/ui 0.15.25 → 0.15.27
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/CHANGELOG.md +34 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-DvTjgVMf.js → abnfDiagram-VRR7QNED-BcFJp_1X.js} +1 -1
- package/dist/assets/{aiden0z-pptx-renderer.es-C1nfBAXR.js → aiden0z-pptx-renderer.es-Dp2ezlQn.js} +1 -1
- package/dist/assets/{api-FK7tikI1.js → api-a_GaOFc7.js} +6 -6
- package/dist/assets/appearance-settings-page-DlGXLgff.js +1 -0
- package/dist/assets/{arc-BvhODBXv.js → arc-CkgyPMyW.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-DO2x53FK.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-BKO9RgNS.js → architectureDiagram-ZJ3FMSHR-CMd4cIjI.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-DHpDXy7D.js → blockDiagram-677ZJIJ3-Bz3tbhet.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-BG_iQnDr.js → c4Diagram-LMCZKHZV-D9hFNAGv.js} +1 -1
- package/dist/assets/channel-nBvMaVyP.js +1 -0
- package/dist/assets/{channels-list-page-CocdcIko.js → channels-list-page-BEEk4Uc9.js} +2 -2
- package/dist/assets/chat-page-DUQXXqQm.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-CJgqFDS4.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-DR9M0LLx.js → chunk-32BRIVSS-7NrjEITq.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-698iC3BB.js → chunk-52WLFC77-viIcqj9q.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-DikTj9Ey.js → chunk-5FCAYU7R-Vsu4J-VM.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-ko0o7_q0.js → chunk-5HE753X5-C-w6CQZK.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-CEHufhgo.js → chunk-5JV3BV7I-CuKgJQ4W.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-CGgno1cu.js → chunk-5TONJI2A-CYeiWZKb.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DkiB4cUQ.js → chunk-5VM5RSS4-DRCbfwIn.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-DzptcytQ.js → chunk-7BUUIJ7U-BvydOcm3.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-DMRSQJvT.js → chunk-BIQX33UG-RlppOXKo.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-Bw1BwwuY.js → chunk-C7G6YPKG-DAizzYwr.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-C0z6eHBk.js → chunk-CQNSW5MT-5eChJHca.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-ByPyAouO.js → chunk-CYSBUYHQ-YHPr53fv.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-CJlAXWZg.js → chunk-EMLP6XTP-CK4D7Hz5.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-Dqq4zKJu.js → chunk-EX3LRPZG-BmlDFIRW.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-B0SNoCmi.js → chunk-FWX5IMBZ-D0ksHZZ9.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-DG_GJih_.js → chunk-HOUHSVGY-DPkq8FCm.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-Drxk_6bE.js → chunk-ICXQ74PX-FAatv5fC.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-DdLFPpnd.js → chunk-JG7HCLWE-DLkIi4F7.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-B8M4G76F.js → chunk-JWPE2WC7-DawOjNE3.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-XP6FJHY_.js → chunk-MOJQB5TN-Di52TorW.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-C_6x18Qw.js → chunk-MOZMSUNE-PfyK9w1-.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-N25BzCmG.js → chunk-OGEWGWER-C3jdH3Ty.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-ASDEm7y0.js → chunk-OSBZ3O6U-CecHo-f0.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-CTlvAcn7.js → chunk-PUDLZKDR-f3IJh3sN.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-Da9BWfB6.js → chunk-Q4XR5HBZ-DQFeUPxZ.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-Bi6RpTJO.js → chunk-QBLGF6JB-BhUeG0y2.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-DkMsSPvK.js → chunk-R7FJI6CG-C3XpZ-2u.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DZp0eU-j.js → chunk-RYQCIY6F-CAqa5klQ.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-vfinDSrj.js → chunk-U6XO7XAA-D_WXezeD.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-C9Nksccs.js → chunk-V7JOEXUC-CZ70oOtp.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-BGvh3yIx.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-Xv6zfwXs.js → chunk-VR4S4FIN-B7AHEYYk.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-mOJNzbWl.js → chunk-WYO6CB5R-Dn9To_OI.js} +2 -2
- package/dist/assets/chunk-XXDRQBXY-DaBxG5gs.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-1-aKSu4o.js → chunk-YOTPTUD7-BYEgRBk3.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-OJ8veMpK.js → chunk-ZGVPDNZ5-C6YtZDU0.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-SR_Nq_PP.js → chunk-ZIRB5QZD-DMuYtnHF.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-P6N03G2R.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-B1_uLvMv.js +1 -0
- package/dist/assets/config-split-page-ps1Aod3g.js +1 -0
- package/dist/assets/confirm-dialog-DJSUNG33.js +5 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-NjVgz2Bw.js → cose-bilkent-JH36ORCC-Bc2Ex5Y3.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-B-H8Qp-n.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-B_17LDqD.js → cynefinDiagram-TSTJHNR4-DVysQoGz.js} +1 -1
- package/dist/assets/{dagre-CMe101gk.js → dagre-CMhQ1cAG.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-qo8nLb3B.js → dagre-VKFMJZFB-RYyWpPJZ.js} +1 -1
- package/dist/assets/desktop-update-config--zagjHic.js +1 -0
- package/dist/assets/{diagram-FQU43EPY-Ba3XIklC.js → diagram-FQU43EPY-BD6KONdF.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-CG45TcUx.js → diagram-G47NLZAW-CGB2ptRR.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-2F2HrwV-.js → diagram-NH7WQ7WH-DnkOI6cU.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-CXfWH9NZ.js → diagram-OA4YK3LP-DF82RZ7P.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-CH_4yepc.js → diagram-WEI45ONY-Be2v7Ck9.js} +1 -1
- package/dist/assets/{dist-CaYdVVeO.js → dist-BkTYNzm_.js} +1 -1
- package/dist/assets/{dist-BH7W5yCi.js → dist-DkR7_Dpl.js} +1 -1
- package/dist/assets/doc-browser-DahzJEWj.js +1 -0
- package/dist/assets/doc-browser-Q67TOGVS.js +1 -0
- package/dist/assets/doc-browser-context-BQim8SqD.js +1 -0
- package/dist/assets/{docx-preview-CoM4JK7_.js → docx-preview-BqwAjrj3.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-BwiG4Ea1.js → ebnfDiagram-CCIWWBDH-CP98OYk8.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BML3hpnQ.js → erDiagram-Q63AITRT-ZLlx8xfs.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-YVtShyFA.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-BeKXabVO.js +1 -0
- package/dist/assets/{form-actions-0c0aw_bl.js → form-actions-B2-bpFie.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-80enfWbD.js → ganttDiagram-NO4QXBWP-DXCDjHR2.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-jTSiBj-p.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-CVLqXr-b.js → gitGraphDiagram-IHSO6WYX-l2HWrTJp.js} +1 -1
- package/dist/assets/index-Ba_o5fu9.js +109 -0
- package/dist/assets/index-DSLK7zgR.css +1 -0
- package/dist/assets/info-DKCQHKI2-BIporNWb.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Dyvs2t0i.js → infoDiagram-FWYZ7A6U-D-DjX-bn.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-sSnxDKfh.js → ishikawaDiagram-FXEZZL3T-y_Xy128F.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-D22V71Mf.js → journeyDiagram-5HDEW3XC-DJn5xYcQ.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-D3ds0p-g.js → kanban-definition-HUTT4EX6-DJVIOR21.js} +1 -1
- package/dist/assets/{line-CbyFs065.js → line-Cos7PIOj.js} +1 -1
- package/dist/assets/{linear-4DKtnZBS.js → linear-BtDLqtzF.js} +1 -1
- package/dist/assets/loader-circle-DyXZU92l.js +1 -0
- package/dist/assets/{map-CcZzEoz6.js → map-BKnQyvd0.js} +1 -1
- package/dist/assets/mcp-marketplace-page-B0dBE5CV.js +1 -0
- package/dist/assets/mcp-marketplace-page-w8panjZG.js +9 -0
- package/dist/assets/{mermaid-parser.core-DPmMOjXD.js → mermaid-parser.core-XUNZhr2W.js} +2 -2
- package/dist/assets/{mermaid.core-BSf-ddRa.js → mermaid.core-ySrvolIe.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-BUTwWPyx.js → mindmap-definition-LN4V7U3C-BypL9tei.js} +1 -1
- package/dist/assets/model-config-page-rrhFaque.js +1 -0
- package/dist/assets/{navigation-link-CVy0_kVl.js → navigation-link-mpHFXwRr.js} +2 -2
- package/dist/assets/{ordinal-BgLYtOZE.js → ordinal-CxxVWxYU.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-CuFMADV0.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-BEu_ZBjc.js → pegDiagram-2B236MQR-D-U2KBGv.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-XUeIXhM9.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-CAwAwuBd.js → pieDiagram-ENE6RG2P-CBi3GusJ.js} +1 -1
- package/dist/assets/plus-Dhb4KuMH.js +1 -0
- package/dist/assets/provider-scoped-model-input-CFsfWEt9.js +1 -0
- package/dist/assets/providers-config-page-D-TYFZsF.js +1 -0
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-CwE6F-_2.js → quadrantDiagram-ABIIQ3AL-H0ZuvnZL.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-D-NNGh1k.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-C67_uDaM.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-BZ8Yflnd.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-B7zO7RoK.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-R63PTgLz.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-xgLekU3B.js → railroadDiagram-RFXS5EU6-D7Y2EqSd.js} +1 -1
- package/dist/assets/react-BlXwvOLo.js +8 -0
- package/dist/assets/{refresh-cw-j2bl79Ea.js → refresh-cw-JFuyDj_P.js} +1 -1
- package/dist/assets/remote-BwVv_Qq-.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-CyVUzEX5.js → requirementDiagram-TGXJPOKE-BiXNX1NN.js} +1 -1
- package/dist/assets/rotate-cw-DjbbiIW_.js +1 -0
- package/dist/assets/runtime-config-page-Br9j9Vxe.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-JK6bFmYB.js → sankeyDiagram-HTMAVEWB-qzDeLztW.js} +1 -1
- package/dist/assets/{save-BKNrtK81.js → save-BL8P8CLX.js} +1 -1
- package/dist/assets/{search-CkOm65W_.js → search-bZL75Pgc.js} +1 -1
- package/dist/assets/search-config-page-B3fvzMd1.js +1 -0
- package/dist/assets/secrets-config-page-ClwTxtXd.js +3 -0
- package/dist/assets/security-config-DmJw9QZA.js +1 -0
- package/dist/assets/{select-Ea7ffKCE.js → select-rUZ8nIZu.js} +2 -2
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-BR5IokXV.js → sequenceDiagram-DBY2YBRQ-BtRbPQtL.js} +1 -1
- package/dist/assets/{settings-2-CtyN3m_V.js → settings-2-BI4SCkxQ.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-SxG_YnMA.js → sizeCapture-X5ZJPWSS-CMYvM3SL.js} +1 -1
- package/dist/assets/skeleton-CVmEPG43.js +1 -0
- package/dist/assets/{src-vgz8E_-O.js → src-Bw-mzbQb.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-DD4OoYhn.js → stateDiagram-2N3HPSRC-BJ-mFeOz.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BE-HqxOK.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-BWkFeyCT.js → swimlanes-5IMT3BWC-BsucVOO2.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-Dr1H9LJH.js +8 -0
- package/dist/assets/{tag-chip-C9l4xsKp.js → tag-chip-BdI_yIOA.js} +1 -1
- package/dist/assets/{timeline-definition-FHXFAJF6-VTRPy6KA.js → timeline-definition-FHXFAJF6-Bicewlzo.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-npJ5dbqS.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-pYrBx6oa.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-Bvk42Pek.js → vennDiagram-L72KCM5P-BxOOnO9x.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-CmSRKLR8.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-DOFjx2s3.js → wardleyDiagram-EHGQE667-Cl7NltMv.js} +1 -1
- package/dist/assets/x-BcEayhV6.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-DY5yRTUc.js → xychartDiagram-FW5EYKEG-DiMIxQ7N.js} +1 -1
- package/dist/index.html +21 -22
- package/package.json +6 -6
- package/src/app/components/layout/app-layout.tsx +38 -2
- package/src/app/hooks/__tests__/use-app-event-consumers.test.ts +20 -0
- package/src/app/hooks/use-app-event-consumers.ts +21 -0
- package/src/app/presenters/app.presenter.ts +6 -0
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +312 -0
- package/src/features/apps/components/__tests__/apps-panel.test.tsx +58 -0
- package/src/features/apps/components/app-artwork.tsx +49 -0
- package/src/features/apps/components/app-marketplace-catalog.tsx +332 -0
- package/src/features/apps/components/app-marketplace-cover.tsx +64 -0
- package/src/features/apps/components/app-marketplace-detail.tsx +161 -0
- package/src/features/apps/components/app-marketplace-dialog.tsx +152 -0
- package/src/features/apps/components/app-marketplace-operation.tsx +84 -0
- package/src/features/apps/components/app-package-card.tsx +417 -0
- package/src/features/apps/components/app-packages-panel.tsx +373 -0
- package/src/features/apps/components/apps-panel.tsx +31 -23
- package/src/features/apps/hooks/use-app-marketplace.test.ts +144 -0
- package/src/features/apps/hooks/use-app-marketplace.ts +65 -0
- package/src/features/apps/hooks/use-app-packages.ts +114 -0
- package/src/features/apps/index.ts +1 -0
- package/src/features/apps/managers/__tests__/app-package-operation-settlement.manager.test.ts +81 -0
- package/src/features/apps/managers/app-package-operation-settlement.manager.ts +80 -0
- package/src/features/apps/services/app-marketplace.service.ts +223 -0
- package/src/features/apps/types/app-marketplace.types.ts +75 -0
- package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +27 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +36 -5
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +12 -13
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +49 -1
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +68 -7
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +25 -4
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +3 -0
- package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +24 -14
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-controller.test.tsx +53 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-run-queue.test.tsx +18 -0
- package/src/features/chat/features/conversation/hooks/use-chat-composer-reference-intent.ts +4 -1
- package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +126 -32
- package/src/features/chat/features/conversation/hooks/use-session-run-queue.ts +12 -2
- package/src/features/chat/features/conversation/hooks/use-system-object-reference-select.ts +27 -0
- package/src/features/chat/features/conversation/utils/session-message-composer.utils.ts +5 -0
- package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +102 -0
- package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +71 -120
- package/src/features/chat/features/input/input-surface-plugins/__tests__/context-reference-plugin.test.ts +265 -18
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +7 -2
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.utils.ts +124 -0
- package/src/features/chat/features/input/input-surface-plugins/context-reference-items.utils.ts +99 -15
- package/src/features/chat/features/input/input-surface-plugins/context-reference-plugin.utils.ts +143 -139
- package/src/features/chat/features/input/input-surface-plugins/panel-app-input-surface-items.utils.ts +116 -0
- package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +1 -1
- package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +84 -1
- package/src/features/chat/features/input/utils/chat-composer-token-protocol.utils.ts +10 -0
- package/src/features/chat/features/input/utils/chat-inline-token-composer.utils.ts +148 -0
- package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +55 -101
- package/src/features/chat/features/input/utils/chat-system-object-reference.utils.test.ts +44 -0
- package/src/features/chat/features/input/utils/chat-system-object-reference.utils.ts +46 -0
- package/src/features/chat/features/message/hooks/use-chat-inline-token-actions.ts +8 -1
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +155 -18
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-text-selection.test.tsx +12 -8
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +80 -62
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +9 -2
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +83 -13
- package/src/features/chat/features/workspace/components/project-files/workspace-project-tree-view.tsx +93 -0
- package/src/features/chat/features/workspace/hooks/use-workspace-explorer-layout.ts +8 -11
- package/src/features/chat/features/workspace/hooks/use-workspace-file-actions.ts +68 -46
- package/src/features/chat/features/workspace/stores/__tests__/workspace-project-tree.store.test.ts +38 -0
- package/src/features/chat/features/workspace/stores/workspace-project-tree.store.ts +160 -0
- package/src/features/chat/index.ts +2 -1
- package/src/features/chat/managers/__tests__/chat-composer-intent.manager.test.ts +29 -0
- package/src/features/chat/managers/chat-composer-intent.manager.ts +29 -2
- package/src/features/chat/managers/chat-draft-intent.manager.ts +18 -2
- package/src/features/chat/presenters/chat.presenter.ts +2 -2
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +6 -0
- package/src/features/chat/stores/chat-thread.store.ts +6 -0
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +38 -5
- package/src/features/inbox/components/inbox-reader-dialog.tsx +5 -3
- package/src/features/inbox/managers/inbox.manager.test.ts +28 -3
- package/src/features/inbox/managers/inbox.manager.ts +14 -4
- package/src/features/inbox/pages/inbox-page.test.ts +121 -2
- package/src/features/inbox/pages/inbox-page.tsx +5 -3
- package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +85 -1
- package/src/features/marketplace/hooks/__tests__/use-marketplace.test.tsx +44 -1
- package/src/features/marketplace/hooks/use-marketplace-item-actions.ts +23 -2
- package/src/features/marketplace/hooks/use-marketplace.ts +10 -0
- package/src/features/marketplace/index.ts +4 -0
- package/src/features/panel-apps/components/__tests__/panel-apps-list.test.tsx +1 -1
- package/src/features/panel-apps/components/panel-apps-list.tsx +1 -6
- package/src/features/panel-apps/index.ts +5 -1
- package/src/features/panel-apps/utils/__tests__/panel-app-doc-browser.utils.test.ts +13 -6
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +6 -3
- package/src/features/right-panel-resources/index.ts +1 -0
- package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-uri.utils.test.ts +34 -0
- package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +36 -4
- package/src/features/service-apps/components/service-apps-panel.tsx +3 -17
- package/src/features/system-status/components/__tests__/desktop-update-config.test.tsx +20 -1
- package/src/features/system-status/components/desktop-update-config.tsx +14 -13
- package/src/features/system-status/managers/__tests__/runtime-update.manager.test.ts +99 -0
- package/src/features/system-status/managers/runtime-update.manager.ts +22 -0
- package/src/features/system-status/stores/runtime-update.store.ts +1 -0
- package/src/platforms/desktop/components/desktop-app-shell.tsx +5 -0
- package/src/platforms/mobile/components/mobile-app-shell.tsx +9 -1
- package/src/shared/components/actions/__tests__/navigation-link.test.tsx +12 -0
- package/src/shared/components/actions/navigation-link.tsx +6 -3
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +34 -0
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +5 -0
- package/src/shared/components/doc-browser/doc-browser.tsx +11 -1
- package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +13 -0
- package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +15 -0
- package/src/shared/components/ui/actions/icon-action-button.tsx +4 -2
- package/src/shared/components/ui/tabs.tsx +24 -1
- package/src/shared/hooks/use-server-path-watch.ts +42 -0
- package/src/shared/hooks/use-system-object-references.ts +22 -0
- package/src/shared/lib/api/server-path/server-path.types.ts +10 -0
- package/src/shared/lib/api/types.ts +13 -0
- package/src/shared/lib/api/utils/server-path.utils.ts +10 -0
- package/src/shared/lib/i18n/locales/en-US/chat.json +17 -9
- package/src/shared/lib/i18n/locales/en-US/desktop-update.json +7 -4
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +82 -0
- package/src/shared/lib/i18n/locales/en-US/marketplace.json +3 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +19 -11
- package/src/shared/lib/i18n/locales/zh-CN/desktop-update.json +7 -4
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +82 -0
- package/src/shared/lib/i18n/locales/zh-CN/marketplace.json +3 -0
- package/vite.config.ts +32 -1
- package/dist/assets/appearance-settings-page-BYbvl2wj.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-Bjp9jf0h.js +0 -1
- package/dist/assets/channel-5T3pdR-s.js +0 -1
- package/dist/assets/chat-page-C5E-LLVd.js +0 -1
- package/dist/assets/chunk-2Q5K7J3B-DTZ3tGfE.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-HLGIHQ6k.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-Dl0m6Ni-.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-DcDnzGNX.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BKXKMzKM.js +0 -1
- package/dist/assets/config-split-page-CA_a0AJ5.js +0 -1
- package/dist/assets/confirm-dialog-CxZfenjK.js +0 -5
- package/dist/assets/cynefin-VYW2F7L2-BWg7U2UD.js +0 -1
- package/dist/assets/desktop-update-config-BEKC8Ly9.js +0 -1
- package/dist/assets/doc-browser-Cl2ldE3f.js +0 -1
- package/dist/assets/doc-browser-DXCSd63E.js +0 -1
- package/dist/assets/doc-browser-context-FDPs3gJf.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-SB-J4tpq.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-BQ_u-eLM.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-DPxNwsFd.js +0 -1
- package/dist/assets/i18n-provider-DkITJNz8.js +0 -1
- package/dist/assets/index-CQ2LcI2p.css +0 -1
- package/dist/assets/index-CrdfvBVg.js +0 -107
- package/dist/assets/info-DKCQHKI2-DNlNGH90.js +0 -1
- package/dist/assets/loader-circle-DHtUxCIA.js +0 -1
- package/dist/assets/mcp-marketplace-page-Bc_jI5iH.js +0 -9
- package/dist/assets/mcp-marketplace-page-CzCieD9r.js +0 -1
- package/dist/assets/model-config-page-C4jw-pcj.js +0 -1
- package/dist/assets/packet-7NZHBO7P-BpeiqkBZ.js +0 -1
- package/dist/assets/pie-RZYD4A2V-Cy1yxsPd.js +0 -1
- package/dist/assets/plus-CG1RwZQq.js +0 -1
- package/dist/assets/provider-scoped-model-input-CmH4BFvc.js +0 -1
- package/dist/assets/providers-config-page-CJQjwzaw.js +0 -1
- package/dist/assets/radar-I7S5WNFK-CEcPKCj8.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-CW38eNDs.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-ByrylcXf.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-CNB6GwP-.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-x6hnqlBG.js +0 -1
- package/dist/assets/react-DjFBVA0n.js +0 -8
- package/dist/assets/remote-BIlpD3yL.js +0 -1
- package/dist/assets/rotate-cw-bKG8zH8M.js +0 -1
- package/dist/assets/runtime-config-page-B_x2Glz5.js +0 -1
- package/dist/assets/search-config-page-BaIijtmO.js +0 -1
- package/dist/assets/secrets-config-page-CJjtdFAl.js +0 -3
- package/dist/assets/security-config-DB8apj09.js +0 -1
- package/dist/assets/skeleton-Bt6zxcAB.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-ZC6dFORv.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-CRkh51Im.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-Bw0DSCH7.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-DFWBFcfh.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-CoWturk0.js +0 -1
- package/dist/assets/x-CowtCu9Z.js +0 -1
- /package/dist/assets/{array-NADKd9aU.js → array-BQVzeGRt.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-BuyuzJJL.js → chunk-KEIR6QF5-f9psyCXK.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-D_B2ZRNt.js → chunk-Y2CYZVJY-D1mAU_Po.js} +0 -0
- /package/dist/assets/{config-hints-BcfVUMij.js → config-hints-nV5HPOvq.js} +0 -0
- /package/dist/assets/{cytoscape.esm-BANTlgza.js → cytoscape.esm-0uDtdD0l.js} +0 -0
- /package/dist/assets/{defaultLocale-C4_L0aEs.js → defaultLocale-DSWXGgt0.js} +0 -0
- /package/dist/assets/{dist-DAPEIJbz.js → dist--ta5rX12.js} +0 -0
- /package/dist/assets/{graphlib-ChqXg0dI.js → graphlib-CQ6QV4yP.js} +0 -0
- /package/dist/assets/{host-capabilities-D9C4CBK5.js → host-capabilities-Tk038i04.js} +0 -0
- /package/dist/assets/{init-D8wZg9xq.js → init-Y6h9jGtZ.js} +0 -0
- /package/dist/assets/{jszip.min-CkbBfwAQ.js → jszip.min-8hyJpgpx.js} +0 -0
- /package/dist/assets/{katex-TZJFa0J_.js → katex-ARhY9PS1.js} +0 -0
- /package/dist/assets/{middleware-B3k-TSmZ.js → middleware-DXsbf9xI.js} +0 -0
- /package/dist/assets/{path-DodfxcX7.js → path-10BjdyLh.js} +0 -0
- /package/dist/assets/{rough.esm-CUaa1Rbe.js → rough.esm-DxgC_14r.js} +0 -0
- /package/dist/assets/{xlsx-CxByi7bR.js → xlsx-DrDuDNAa.js} +0 -0
|
@@ -5,6 +5,7 @@ import { ChatSessionWorkspacePanelContent } from '@/features/chat/features/works
|
|
|
5
5
|
import type { ResolvedChildSessionTab } from '@/features/chat/features/ncp/hooks/use-ncp-child-session-tabs-view';
|
|
6
6
|
import { useChatThreadStore } from '@/features/chat/stores/chat-thread.store';
|
|
7
7
|
import { CHAT_WORKSPACE_EXPLORER_DEFAULT_WIDTH } from '@/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils';
|
|
8
|
+
import { useWorkspaceProjectTreeStore } from '@/features/chat/features/workspace/stores/workspace-project-tree.store';
|
|
8
9
|
|
|
9
10
|
const mocks = vi.hoisted(() => ({
|
|
10
11
|
browseEntries: [
|
|
@@ -27,7 +28,9 @@ const mocks = vi.hoisted(() => ({
|
|
|
27
28
|
deleteServerPathEntry: vi.fn(),
|
|
28
29
|
renameServerPathEntry: vi.fn(),
|
|
29
30
|
uploadServerPathFiles: vi.fn(),
|
|
31
|
+
watchDirectories: vi.fn(),
|
|
30
32
|
refetchBrowse: vi.fn(),
|
|
33
|
+
refetchQueries: vi.fn(),
|
|
31
34
|
requestDirectoryReference: vi.fn(),
|
|
32
35
|
requestFileReference: vi.fn(),
|
|
33
36
|
openChildSessions: vi.fn(),
|
|
@@ -41,6 +44,15 @@ const mocks = vi.hoisted(() => ({
|
|
|
41
44
|
scrollIntoView: vi.fn(),
|
|
42
45
|
}));
|
|
43
46
|
|
|
47
|
+
vi.mock('@/shared/hooks/use-server-path-watch', () => ({
|
|
48
|
+
useServerPathWatch: mocks.watchDirectories,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
vi.mock('@tanstack/react-query', async (importOriginal) => ({
|
|
52
|
+
...(await importOriginal()),
|
|
53
|
+
useQueryClient: () => ({ refetchQueries: mocks.refetchQueries }),
|
|
54
|
+
}));
|
|
55
|
+
|
|
44
56
|
function firePointerEvent(
|
|
45
57
|
target: Window | Document | Node | Element,
|
|
46
58
|
type: string,
|
|
@@ -168,7 +180,10 @@ beforeEach(() => {
|
|
|
168
180
|
overwritten: false,
|
|
169
181
|
});
|
|
170
182
|
mocks.refetchBrowse.mockResolvedValue(undefined);
|
|
183
|
+
mocks.refetchQueries.mockResolvedValue(undefined);
|
|
184
|
+
useWorkspaceProjectTreeStore.setState({ trees: {} });
|
|
171
185
|
useChatThreadStore.getState().setSnapshot({
|
|
186
|
+
workspaceExplorerOpen: false,
|
|
172
187
|
workspaceExplorerWidth: CHAT_WORKSPACE_EXPLORER_DEFAULT_WIDTH,
|
|
173
188
|
});
|
|
174
189
|
});
|
|
@@ -474,7 +489,7 @@ it('creates a project folder from the root toolbar and refreshes the tree', asyn
|
|
|
474
489
|
parentPath: '/Users/peiwang/Projects/nextbot',
|
|
475
490
|
name: 'research',
|
|
476
491
|
});
|
|
477
|
-
expect(mocks.
|
|
492
|
+
expect(mocks.refetchQueries).toHaveBeenCalled();
|
|
478
493
|
expect(document.activeElement).toBe(screen.getByRole('button', { name: 'research' }));
|
|
479
494
|
expect(mocks.scrollIntoView).toHaveBeenCalledTimes(2);
|
|
480
495
|
});
|
|
@@ -563,7 +578,7 @@ it('uploads multiple project files from the root actions menu', async () => {
|
|
|
563
578
|
files: [file],
|
|
564
579
|
overwrite: undefined,
|
|
565
580
|
});
|
|
566
|
-
expect(mocks.
|
|
581
|
+
expect(mocks.refetchQueries).toHaveBeenCalled();
|
|
567
582
|
});
|
|
568
583
|
});
|
|
569
584
|
|
|
@@ -593,11 +608,83 @@ it('requires destructive confirmation before deleting a project file', async ()
|
|
|
593
608
|
path: '/private/resolved-worktree/package.json',
|
|
594
609
|
});
|
|
595
610
|
expect(mocks.removeWorkspacePath).toHaveBeenCalledWith('/private/resolved-worktree/package.json');
|
|
596
|
-
expect(mocks.
|
|
611
|
+
expect(mocks.refetchQueries).toHaveBeenCalled();
|
|
597
612
|
});
|
|
598
613
|
});
|
|
599
614
|
|
|
600
|
-
it('
|
|
615
|
+
it('refreshes the root and every active expanded directory query', async () => {
|
|
616
|
+
const user = userEvent.setup();
|
|
617
|
+
render(
|
|
618
|
+
<ChatSessionWorkspacePanelContent
|
|
619
|
+
activeSelection={{ kind: 'project-files' }}
|
|
620
|
+
childSessionTabs={[]}
|
|
621
|
+
filePreviewRefreshVersion={0}
|
|
622
|
+
sessionKey="parent-1"
|
|
623
|
+
sessionCronJobs={[]}
|
|
624
|
+
sessionProjectRoot="/Users/peiwang/Projects/nextbot"
|
|
625
|
+
sessionWorkingDir="/Users/peiwang/Projects/nextbot"
|
|
626
|
+
/>,
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
await user.click(screen.getByRole('button', { name: 'src' }));
|
|
630
|
+
await user.click(screen.getByRole('button', { name: 'Refresh project files' }));
|
|
631
|
+
|
|
632
|
+
expect(mocks.refetchQueries).toHaveBeenCalledTimes(1);
|
|
633
|
+
const request = mocks.refetchQueries.mock.calls[0]?.[0] as {
|
|
634
|
+
predicate: (query: { queryKey: readonly unknown[] }) => boolean;
|
|
635
|
+
type: string;
|
|
636
|
+
};
|
|
637
|
+
expect(request.type).toBe('active');
|
|
638
|
+
expect(request.predicate({ queryKey: ['server-path-browse', '/Users/peiwang/Projects/nextbot', '', true] })).toBe(true);
|
|
639
|
+
expect(request.predicate({ queryKey: ['server-path-browse', '/Users/peiwang/Projects/nextbot/src', '', true] })).toBe(true);
|
|
640
|
+
expect(request.predicate({ queryKey: ['server-path-browse', '/tmp/another-project', '', true] })).toBe(false);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
it('collapses all persisted directories in one action', async () => {
|
|
644
|
+
const user = userEvent.setup();
|
|
645
|
+
render(
|
|
646
|
+
<ChatSessionWorkspacePanelContent
|
|
647
|
+
activeSelection={{ kind: 'project-files' }}
|
|
648
|
+
childSessionTabs={[]}
|
|
649
|
+
filePreviewRefreshVersion={0}
|
|
650
|
+
sessionKey="parent-1"
|
|
651
|
+
sessionCronJobs={[]}
|
|
652
|
+
sessionProjectRoot="/Users/peiwang/Projects/nextbot"
|
|
653
|
+
sessionWorkingDir="/Users/peiwang/Projects/nextbot"
|
|
654
|
+
/>,
|
|
655
|
+
);
|
|
656
|
+
|
|
657
|
+
const sourceDirectory = screen.getByRole('treeitem', { name: 'Open directory: src' });
|
|
658
|
+
await user.click(screen.getByRole('button', { name: 'src' }));
|
|
659
|
+
expect(sourceDirectory.getAttribute('aria-expanded')).toBe('true');
|
|
660
|
+
await user.click(screen.getByRole('button', { name: 'Collapse all' }));
|
|
661
|
+
expect(sourceDirectory.getAttribute('aria-expanded')).toBe('false');
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it('restores expansion and scroll from project view state after remounting', async () => {
|
|
665
|
+
const user = userEvent.setup();
|
|
666
|
+
const props = {
|
|
667
|
+
activeSelection: { kind: 'project-files' as const },
|
|
668
|
+
childSessionTabs: [],
|
|
669
|
+
filePreviewRefreshVersion: 0,
|
|
670
|
+
sessionKey: 'parent-1',
|
|
671
|
+
sessionCronJobs: [],
|
|
672
|
+
sessionProjectRoot: '/Users/peiwang/Projects/nextbot',
|
|
673
|
+
sessionWorkingDir: '/Users/peiwang/Projects/nextbot',
|
|
674
|
+
};
|
|
675
|
+
const first = render(<ChatSessionWorkspacePanelContent {...props} />);
|
|
676
|
+
await user.click(screen.getByRole('button', { name: 'src' }));
|
|
677
|
+
const firstTree = screen.getByRole('tree', { name: 'Project files' });
|
|
678
|
+
firstTree.scrollTop = 144;
|
|
679
|
+
fireEvent.scroll(firstTree);
|
|
680
|
+
first.unmount();
|
|
681
|
+
|
|
682
|
+
render(<ChatSessionWorkspacePanelContent {...props} />);
|
|
683
|
+
expect(screen.getAllByRole('treeitem', { name: 'Open directory: src' })[0]?.getAttribute('aria-expanded')).toBe('true');
|
|
684
|
+
expect(screen.getByRole('tree', { name: 'Project files' }).scrollTop).toBe(144);
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('selects and reveals the active file when it is opened outside the Explorer', async () => {
|
|
601
688
|
const user = userEvent.setup();
|
|
602
689
|
const projectFilesProps = {
|
|
603
690
|
activeSelection: { kind: 'project-files' as const },
|
|
@@ -609,24 +696,69 @@ it('preserves project tree expansion and scroll while visiting another workspace
|
|
|
609
696
|
sessionWorkingDir: '/Users/peiwang/Projects/nextbot',
|
|
610
697
|
};
|
|
611
698
|
const { rerender } = render(<ChatSessionWorkspacePanelContent {...projectFilesProps} />);
|
|
612
|
-
const
|
|
613
|
-
const
|
|
614
|
-
name: 'Open directory: src',
|
|
615
|
-
});
|
|
699
|
+
const sourceDirectory = screen.getByRole('treeitem', { name: 'Open directory: src' });
|
|
700
|
+
const packageEntry = screen.getByRole('treeitem', { name: 'Open file: package.json' });
|
|
616
701
|
await user.click(screen.getByRole('button', { name: 'src' }));
|
|
617
|
-
|
|
618
|
-
expect(sourceDirectory.getAttribute('aria-expanded')).toBe('true');
|
|
702
|
+
expect(sourceDirectory.getAttribute('aria-selected')).toBe('true');
|
|
619
703
|
|
|
620
|
-
rerender(
|
|
621
|
-
|
|
704
|
+
rerender(
|
|
705
|
+
<ChatSessionWorkspacePanelContent
|
|
706
|
+
{...projectFilesProps}
|
|
707
|
+
activeSelection={{
|
|
708
|
+
kind: 'file',
|
|
709
|
+
file: {
|
|
710
|
+
key: 'parent-1::preview::package.json',
|
|
711
|
+
parentSessionKey: 'parent-1',
|
|
712
|
+
path: 'package.json',
|
|
713
|
+
label: 'package.json',
|
|
714
|
+
viewMode: 'preview',
|
|
715
|
+
previewViewer: 'source',
|
|
716
|
+
},
|
|
717
|
+
}}
|
|
718
|
+
/>,
|
|
719
|
+
);
|
|
622
720
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
721
|
+
await waitFor(() => {
|
|
722
|
+
expect(packageEntry.getAttribute('aria-selected')).toBe('true');
|
|
723
|
+
expect(sourceDirectory.getAttribute('aria-selected')).toBe('false');
|
|
724
|
+
});
|
|
725
|
+
expect(mocks.scrollIntoView).toHaveBeenCalled();
|
|
726
|
+
expect(document.activeElement).not.toBe(screen.getByRole('button', { name: 'package.json' }));
|
|
627
727
|
});
|
|
628
728
|
|
|
629
|
-
it('
|
|
729
|
+
it('expands active-file ancestors like an auto-revealing Explorer', async () => {
|
|
730
|
+
useChatThreadStore.getState().setSnapshot({ workspaceExplorerOpen: true });
|
|
731
|
+
render(
|
|
732
|
+
<ChatSessionWorkspacePanelContent
|
|
733
|
+
activeSelection={{
|
|
734
|
+
kind: 'file',
|
|
735
|
+
file: {
|
|
736
|
+
key: 'parent-1::preview::src/index.ts',
|
|
737
|
+
parentSessionKey: 'parent-1',
|
|
738
|
+
path: '/Users/peiwang/Projects/nextbot/src/index.ts',
|
|
739
|
+
label: 'index.ts',
|
|
740
|
+
viewMode: 'preview',
|
|
741
|
+
previewViewer: 'source',
|
|
742
|
+
},
|
|
743
|
+
}}
|
|
744
|
+
childSessionTabs={[]}
|
|
745
|
+
filePreviewRefreshVersion={0}
|
|
746
|
+
sessionKey="parent-1"
|
|
747
|
+
sessionCronJobs={[]}
|
|
748
|
+
sessionProjectRoot="/Users/peiwang/Projects/nextbot"
|
|
749
|
+
sessionWorkingDir="/Users/peiwang/Projects/nextbot"
|
|
750
|
+
/>,
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
const sourceDirectory = within(screen.getByTestId('workspace-shared-explorer')).getAllByRole('treeitem', {
|
|
754
|
+
name: 'Open directory: src',
|
|
755
|
+
})[0];
|
|
756
|
+
await waitFor(() => {
|
|
757
|
+
expect(sourceDirectory.getAttribute('aria-expanded')).toBe('true');
|
|
758
|
+
});
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
it('keeps the file Explorer closed by default and reuses it after an explicit open', () => {
|
|
630
762
|
const projectFilesProps = {
|
|
631
763
|
activeSelection: { kind: 'project-files' as const },
|
|
632
764
|
childSessionTabs: [],
|
|
@@ -659,6 +791,9 @@ it('reuses the Explorer beside a file and persists a dragged compact width', ()
|
|
|
659
791
|
const explorer = screen.getByTestId('workspace-shared-explorer');
|
|
660
792
|
const breadcrumbs = screen.getByTestId('workspace-file-breadcrumbs');
|
|
661
793
|
const toggle = screen.getByTestId('workspace-explorer-toggle');
|
|
794
|
+
expect(explorer.getAttribute('aria-hidden')).toBe('true');
|
|
795
|
+
fireEvent.click(toggle);
|
|
796
|
+
expect(useChatThreadStore.getState().snapshot.workspaceExplorerOpen).toBe(true);
|
|
662
797
|
expect(screen.getByRole('tree', { name: 'Project files' })).toBe(tree);
|
|
663
798
|
expect(explorer.getAttribute('data-mode')).toBe('side');
|
|
664
799
|
expect(explorer.style.width).toBe('224px');
|
|
@@ -674,7 +809,7 @@ it('reuses the Explorer beside a file and persists a dragged compact width', ()
|
|
|
674
809
|
expect(mocks.setWorkspaceExplorerWidth).toHaveBeenCalledWith(300);
|
|
675
810
|
});
|
|
676
811
|
|
|
677
|
-
it('uses an overlay only below the compact threshold and
|
|
812
|
+
it('uses an overlay only below the compact threshold and persists closing it without unmounting', () => {
|
|
678
813
|
HTMLElement.prototype.getBoundingClientRect = () => ({
|
|
679
814
|
bottom: 600,
|
|
680
815
|
height: 600,
|
|
@@ -686,6 +821,7 @@ it('uses an overlay only below the compact threshold and closes it without unmou
|
|
|
686
821
|
y: 0,
|
|
687
822
|
toJSON: () => ({}),
|
|
688
823
|
});
|
|
824
|
+
useChatThreadStore.getState().setSnapshot({ workspaceExplorerOpen: true });
|
|
689
825
|
render(
|
|
690
826
|
<ChatSessionWorkspacePanelContent
|
|
691
827
|
activeSelection={{
|
|
@@ -714,6 +850,7 @@ it('uses an overlay only below the compact threshold and closes it without unmou
|
|
|
714
850
|
expect(screen.queryByTestId('workspace-explorer-resize-handle')).toBeNull();
|
|
715
851
|
|
|
716
852
|
fireEvent.click(screen.getByTestId('workspace-explorer-scrim'));
|
|
853
|
+
expect(useChatThreadStore.getState().snapshot.workspaceExplorerOpen).toBe(false);
|
|
717
854
|
expect(explorer.getAttribute('aria-hidden')).toBe('true');
|
|
718
855
|
expect(tree.isConnected).toBe(true);
|
|
719
856
|
});
|
|
@@ -22,14 +22,18 @@ vi.mock("@/shared/hooks/use-server-path-browse", () => ({
|
|
|
22
22
|
useServerPathBrowse: () => ({ data: null, error: null, isLoading: false }),
|
|
23
23
|
}));
|
|
24
24
|
|
|
25
|
-
vi.mock("@nextclaw/agent-chat-ui", () =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}))
|
|
25
|
+
vi.mock("@nextclaw/agent-chat-ui", async (importOriginal) => {
|
|
26
|
+
const actual = await importOriginal();
|
|
27
|
+
return {
|
|
28
|
+
...(actual as object),
|
|
29
|
+
ChatMessageMarkdown: ({ text }: { text: string }) => <div>{text}</div>,
|
|
30
|
+
FileOperationCodeSurface: ({ block }: { block: ChatFileOperationBlockViewModel }) => (
|
|
31
|
+
<div data-testid="json-source-preview">
|
|
32
|
+
{block.lines.map(({ text }, index) => <span key={index}>{text}{"\n"}</span>)}
|
|
33
|
+
</div>
|
|
34
|
+
),
|
|
35
|
+
};
|
|
36
|
+
});
|
|
33
37
|
|
|
34
38
|
it("supports the first text selection in a JSON preview", async () => {
|
|
35
39
|
const onTextExcerptAdd = vi.fn();
|
package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo, type ReactNode } from 'react';
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
2
3
|
import type { ChatFileOpenActionViewModel } from '@nextclaw/agent-chat-ui';
|
|
3
4
|
import { ChevronsUp, Copy, FilePlus2, FolderPlus, LocateFixed, Upload, RefreshCw } from 'lucide-react';
|
|
4
5
|
import { toast } from 'sonner';
|
|
@@ -10,6 +11,10 @@ import {
|
|
|
10
11
|
} from '@/features/chat/features/workspace/components/project-files/workspace-directory-tree';
|
|
11
12
|
import { WorkspaceNewFolderTreeItem } from '@/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item';
|
|
12
13
|
import { WorkspaceProjectFilesToolbar } from '@/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar';
|
|
14
|
+
import {
|
|
15
|
+
isWorkspaceProjectBrowseQuery,
|
|
16
|
+
WorkspaceProjectTree,
|
|
17
|
+
} from '@/features/chat/features/workspace/components/project-files/workspace-project-tree-view';
|
|
13
18
|
import {
|
|
14
19
|
useWorkspaceProjectFilesController,
|
|
15
20
|
type RefreshDirectory,
|
|
@@ -18,12 +23,18 @@ import {
|
|
|
18
23
|
} from '@/features/chat/features/workspace/hooks/use-workspace-file-actions';
|
|
19
24
|
import { ContextMenu, type ContextMenuGroup } from '@/shared/components/ui/context-menu/context-menu';
|
|
20
25
|
import { useConfirmDialog } from '@/shared/hooks/use-confirm-dialog';
|
|
26
|
+
import { useServerPathWatch } from '@/shared/hooks/use-server-path-watch';
|
|
21
27
|
import type { useServerPathBrowse } from '@/shared/hooks/use-server-path-browse';
|
|
22
28
|
import type { ServerPathEntryView } from '@/shared/lib/api';
|
|
23
29
|
import { hostCapabilityManager } from '@/shared/lib/host-capabilities';
|
|
24
30
|
import { t } from '@/shared/lib/i18n';
|
|
31
|
+
import {
|
|
32
|
+
normalizeWorkspaceProjectTreeRootKey,
|
|
33
|
+
useWorkspaceProjectTreeStore,
|
|
34
|
+
} from '@/features/chat/features/workspace/stores/workspace-project-tree.store';
|
|
25
35
|
|
|
26
36
|
type ChatSessionWorkspaceDirectoryBrowserProps = {
|
|
37
|
+
activeRelativePath?: string | null;
|
|
27
38
|
browseQuery: ReturnType<typeof useServerPathBrowse>;
|
|
28
39
|
onFileOpen: (action: ChatFileOpenActionViewModel) => void;
|
|
29
40
|
sessionKey?: string | null;
|
|
@@ -31,13 +42,15 @@ type ChatSessionWorkspaceDirectoryBrowserProps = {
|
|
|
31
42
|
showRoot?: boolean;
|
|
32
43
|
};
|
|
33
44
|
|
|
45
|
+
const EMPTY_EXPANDED_PATHS: readonly string[] = [];
|
|
46
|
+
|
|
34
47
|
function readPathName(path: string): string {
|
|
35
48
|
return path.split(/[\\/]/).filter(Boolean).pop() ?? path;
|
|
36
49
|
}
|
|
37
50
|
|
|
38
51
|
function WorkspaceDirectoryEntries({
|
|
52
|
+
activeRelativePath,
|
|
39
53
|
busy,
|
|
40
|
-
collapseVersion,
|
|
41
54
|
createTarget,
|
|
42
55
|
entries,
|
|
43
56
|
fallbackParentTarget,
|
|
@@ -58,9 +71,10 @@ function WorkspaceDirectoryEntries({
|
|
|
58
71
|
revealPath,
|
|
59
72
|
selectedPath,
|
|
60
73
|
showRoot,
|
|
74
|
+
treeRootKey,
|
|
61
75
|
}: {
|
|
76
|
+
activeRelativePath: string | null;
|
|
62
77
|
busy: boolean;
|
|
63
|
-
collapseVersion: number;
|
|
64
78
|
createTarget: WorkspaceDirectoryActionTarget | null;
|
|
65
79
|
entries: readonly ServerPathEntryView[];
|
|
66
80
|
fallbackParentTarget: WorkspaceDirectoryActionTarget;
|
|
@@ -81,16 +95,17 @@ function WorkspaceDirectoryEntries({
|
|
|
81
95
|
revealPath: string | null;
|
|
82
96
|
selectedPath: string | null;
|
|
83
97
|
showRoot: boolean;
|
|
98
|
+
treeRootKey: string | null;
|
|
84
99
|
}) {
|
|
85
100
|
if (entries.length === 0) {
|
|
86
101
|
return <div className="px-4 py-8 text-center text-xs text-gray-400">{t('chatWorkspaceDirectoryEmpty')}</div>;
|
|
87
102
|
}
|
|
88
103
|
return entries.map((entry) => (
|
|
89
104
|
<WorkspaceDirectoryTreeEntry
|
|
105
|
+
activeRelativePath={activeRelativePath}
|
|
90
106
|
key={entry.path}
|
|
91
107
|
browseParentRefresh={refresh}
|
|
92
108
|
busy={busy}
|
|
93
|
-
collapseVersion={collapseVersion}
|
|
94
109
|
createTarget={createTarget}
|
|
95
110
|
entry={entry}
|
|
96
111
|
level={showRoot ? 1 : 0}
|
|
@@ -109,6 +124,7 @@ function WorkspaceDirectoryEntries({
|
|
|
109
124
|
renderCreateFolder={renderCreateFolder}
|
|
110
125
|
revealPath={revealPath}
|
|
111
126
|
selectedPath={selectedPath}
|
|
127
|
+
treeRootKey={treeRootKey}
|
|
112
128
|
/>
|
|
113
129
|
));
|
|
114
130
|
}
|
|
@@ -203,46 +219,8 @@ function buildRootContextMenuGroups({
|
|
|
203
219
|
];
|
|
204
220
|
}
|
|
205
221
|
|
|
206
|
-
function WorkspaceProjectTree({
|
|
207
|
-
children,
|
|
208
|
-
currentPath,
|
|
209
|
-
onBlankContext,
|
|
210
|
-
onContextMenu,
|
|
211
|
-
rootDraft,
|
|
212
|
-
showRoot,
|
|
213
|
-
}: {
|
|
214
|
-
children: ReactNode;
|
|
215
|
-
currentPath: string | null;
|
|
216
|
-
onBlankContext: () => void;
|
|
217
|
-
onContextMenu?: MouseEventHandler<HTMLDivElement>;
|
|
218
|
-
rootDraft: ReactNode;
|
|
219
|
-
showRoot: boolean;
|
|
220
|
-
}) {
|
|
221
|
-
return (
|
|
222
|
-
<div
|
|
223
|
-
data-testid="workspace-directory-browser"
|
|
224
|
-
role="tree"
|
|
225
|
-
tabIndex={-1}
|
|
226
|
-
aria-label={t('chatWorkspaceProjectFiles')}
|
|
227
|
-
className="min-h-0 flex-1 overflow-auto py-1 custom-scrollbar"
|
|
228
|
-
onContextMenu={(event) => {
|
|
229
|
-
if (!(event.target as HTMLElement).closest('[data-workspace-tree-entry]')) onBlankContext();
|
|
230
|
-
onContextMenu?.(event);
|
|
231
|
-
}}
|
|
232
|
-
>
|
|
233
|
-
{showRoot && currentPath ? (
|
|
234
|
-
<>
|
|
235
|
-
{rootDraft}
|
|
236
|
-
{children}
|
|
237
|
-
</>
|
|
238
|
-
) : (
|
|
239
|
-
children
|
|
240
|
-
)}
|
|
241
|
-
</div>
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
222
|
function WorkspaceDirectoryBrowserReady({
|
|
223
|
+
activeRelativePath,
|
|
246
224
|
browseQuery,
|
|
247
225
|
ConfirmDialog,
|
|
248
226
|
controller,
|
|
@@ -254,6 +232,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
254
232
|
rootPath,
|
|
255
233
|
showRoot,
|
|
256
234
|
}: {
|
|
235
|
+
activeRelativePath: string | null;
|
|
257
236
|
browseQuery: ReturnType<typeof useServerPathBrowse>;
|
|
258
237
|
ConfirmDialog: () => ReactNode;
|
|
259
238
|
controller: ReturnType<typeof useWorkspaceProjectFilesController>;
|
|
@@ -265,33 +244,43 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
265
244
|
rootPath: string | null;
|
|
266
245
|
showRoot: boolean;
|
|
267
246
|
}) {
|
|
247
|
+
const queryClient = useQueryClient();
|
|
268
248
|
const {
|
|
269
|
-
actions,
|
|
270
249
|
cancelCreateFolder,
|
|
271
250
|
clearSelection,
|
|
272
251
|
completeReveal,
|
|
273
252
|
submitCreate,
|
|
274
|
-
createError,
|
|
275
|
-
createKind,
|
|
276
|
-
createName,
|
|
277
|
-
createTarget,
|
|
278
253
|
deleteEntry,
|
|
279
|
-
fileInputRef,
|
|
280
254
|
openCreateFile,
|
|
281
255
|
openCreateFolder,
|
|
282
256
|
requestUpload,
|
|
283
257
|
renameEntry,
|
|
284
|
-
revealPath,
|
|
285
258
|
selectEntry,
|
|
286
|
-
selectedCreateTarget,
|
|
287
|
-
selectedPath,
|
|
288
259
|
setCreateError,
|
|
289
260
|
setCreateName,
|
|
290
261
|
uploadFiles,
|
|
291
|
-
} = controller;
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
|
|
262
|
+
} = controller.actions;
|
|
263
|
+
const { fileInputRef } = controller.refs;
|
|
264
|
+
const {
|
|
265
|
+
createError,
|
|
266
|
+
createKind,
|
|
267
|
+
createName,
|
|
268
|
+
createTarget,
|
|
269
|
+
pendingAction,
|
|
270
|
+
revealPath,
|
|
271
|
+
selectedCreateTarget,
|
|
272
|
+
selectedPath,
|
|
273
|
+
} = controller.state;
|
|
274
|
+
const busy = pendingAction !== null;
|
|
275
|
+
const treeRootKey = normalizeWorkspaceProjectTreeRootKey(rootPath);
|
|
276
|
+
const collapseAll = useWorkspaceProjectTreeStore((state) => state.collapseAll);
|
|
277
|
+
const rootRefresh = () =>
|
|
278
|
+
rootPath
|
|
279
|
+
? queryClient.refetchQueries({
|
|
280
|
+
predicate: (query) => isWorkspaceProjectBrowseQuery(query.queryKey, rootPath),
|
|
281
|
+
type: 'active',
|
|
282
|
+
})
|
|
283
|
+
: browseQuery.refetch();
|
|
295
284
|
const rootTarget: WorkspaceDirectoryActionTarget | null = rootPath
|
|
296
285
|
? { label: rootLabel, path: rootPath, refresh: rootRefresh }
|
|
297
286
|
: null;
|
|
@@ -300,7 +289,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
300
289
|
<WorkspaceNewFolderTreeItem
|
|
301
290
|
error={createError}
|
|
302
291
|
kind={createKind}
|
|
303
|
-
isCreating={
|
|
292
|
+
isCreating={pendingAction === 'create-directory' || pendingAction === 'create-file'}
|
|
304
293
|
level={level}
|
|
305
294
|
name={createName}
|
|
306
295
|
onCancel={cancelCreateFolder}
|
|
@@ -318,8 +307,8 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
318
307
|
};
|
|
319
308
|
const treeEntries = (
|
|
320
309
|
<WorkspaceDirectoryEntries
|
|
310
|
+
activeRelativePath={activeRelativePath}
|
|
321
311
|
busy={busy}
|
|
322
|
-
collapseVersion={collapseVersion}
|
|
323
312
|
createTarget={createTarget}
|
|
324
313
|
entries={entries}
|
|
325
314
|
fallbackParentTarget={fallbackParentTarget}
|
|
@@ -340,6 +329,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
340
329
|
revealPath={revealPath}
|
|
341
330
|
selectedPath={selectedPath}
|
|
342
331
|
showRoot={false}
|
|
332
|
+
treeRootKey={treeRootKey || null}
|
|
343
333
|
/>
|
|
344
334
|
);
|
|
345
335
|
const tree = (
|
|
@@ -355,10 +345,12 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
355
345
|
const rootMenuGroups = rootTarget
|
|
356
346
|
? buildRootContextMenuGroups({
|
|
357
347
|
busy,
|
|
358
|
-
onCollapseAll: () =>
|
|
348
|
+
onCollapseAll: () => {
|
|
349
|
+
if (treeRootKey) collapseAll(treeRootKey);
|
|
350
|
+
},
|
|
359
351
|
onCreateFile: () => openCreateFile(rootTarget),
|
|
360
352
|
onCreateFolder: () => openCreateFolder(rootTarget),
|
|
361
|
-
onRefresh: () => void
|
|
353
|
+
onRefresh: () => void rootRefresh(),
|
|
362
354
|
onRevealPath,
|
|
363
355
|
onUpload: () => requestUpload(rootTarget),
|
|
364
356
|
target: rootTarget,
|
|
@@ -376,10 +368,12 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
376
368
|
<WorkspaceProjectFilesToolbar
|
|
377
369
|
disabled={busy}
|
|
378
370
|
rootLabel={rootLabel}
|
|
379
|
-
onCollapseAll={() =>
|
|
371
|
+
onCollapseAll={() => {
|
|
372
|
+
if (treeRootKey) collapseAll(treeRootKey);
|
|
373
|
+
}}
|
|
380
374
|
onNewFile={() => openCreateFile(toolbarTarget)}
|
|
381
375
|
onNewFolder={() => openCreateFolder(toolbarTarget)}
|
|
382
|
-
onRefresh={() => void
|
|
376
|
+
onRefresh={() => void rootRefresh()}
|
|
383
377
|
/>
|
|
384
378
|
) : null}
|
|
385
379
|
{rootPath ? (
|
|
@@ -406,6 +400,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
406
400
|
}
|
|
407
401
|
|
|
408
402
|
export function ChatSessionWorkspaceDirectoryBrowser({
|
|
403
|
+
activeRelativePath = null,
|
|
409
404
|
browseQuery,
|
|
410
405
|
onFileOpen,
|
|
411
406
|
sessionKey,
|
|
@@ -417,8 +412,30 @@ export function ChatSessionWorkspaceDirectoryBrowser({
|
|
|
417
412
|
const entries = browseQuery.data?.entries ?? [];
|
|
418
413
|
const errorMessage = readBrowseError(browseQuery);
|
|
419
414
|
const rootPath = showRoot ? (browseQuery.data?.currentPath ?? null) : null;
|
|
415
|
+
const treeRootKey = normalizeWorkspaceProjectTreeRootKey(rootPath);
|
|
416
|
+
const expandedPaths = useWorkspaceProjectTreeStore((state) =>
|
|
417
|
+
treeRootKey ? (state.trees[treeRootKey]?.expandedPaths ?? EMPTY_EXPANDED_PATHS) : EMPTY_EXPANDED_PATHS,
|
|
418
|
+
);
|
|
419
|
+
const watchedDirectories = useMemo(() => {
|
|
420
|
+
if (!rootPath) return [];
|
|
421
|
+
const separator = rootPath.includes('\\') && !rootPath.includes('/') ? '\\' : '/';
|
|
422
|
+
const normalizedRoot = rootPath.replace(/[\\/]+$/g, '');
|
|
423
|
+
const expandedPathSet = new Set(expandedPaths);
|
|
424
|
+
const visibleExpandedPaths = expandedPaths.filter((relativePath) => {
|
|
425
|
+
const segments = relativePath.split('/');
|
|
426
|
+
return segments.slice(0, -1).every((_, index) => expandedPathSet.has(segments.slice(0, index + 1).join('/')));
|
|
427
|
+
});
|
|
428
|
+
return [
|
|
429
|
+
rootPath,
|
|
430
|
+
...visibleExpandedPaths.map(
|
|
431
|
+
(relativePath) => `${normalizedRoot}${separator}${relativePath.replace(/[\\/]+/g, separator)}`,
|
|
432
|
+
),
|
|
433
|
+
];
|
|
434
|
+
}, [expandedPaths, rootPath]);
|
|
435
|
+
useServerPathWatch(watchedDirectories);
|
|
420
436
|
const rootLabel = rootPath ? readPathName(rootPath) : '';
|
|
421
437
|
const controller = useWorkspaceProjectFilesController({
|
|
438
|
+
activeRelativePath,
|
|
422
439
|
confirm,
|
|
423
440
|
onEntryDeleted: presenter.chatThreadManager.removeWorkspacePath,
|
|
424
441
|
onEntryRenamed: presenter.chatThreadManager.renameWorkspacePath,
|
|
@@ -457,6 +474,7 @@ export function ChatSessionWorkspaceDirectoryBrowser({
|
|
|
457
474
|
}
|
|
458
475
|
return (
|
|
459
476
|
<WorkspaceDirectoryBrowserReady
|
|
477
|
+
activeRelativePath={activeRelativePath}
|
|
460
478
|
browseQuery={browseQuery}
|
|
461
479
|
ConfirmDialog={ConfirmDialog}
|
|
462
480
|
controller={controller}
|
package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from '@/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils';
|
|
25
25
|
import { useWorkspaceExplorerLayout } from '@/features/chat/features/workspace/hooks/use-workspace-explorer-layout';
|
|
26
26
|
import { t } from '@/shared/lib/i18n';
|
|
27
|
+
import { resolveWorkspaceRelativePath } from '@/shared/lib/session-project';
|
|
27
28
|
import { cn } from '@/shared/lib/utils';
|
|
28
29
|
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
29
30
|
|
|
@@ -175,11 +176,13 @@ function WorkspaceChildSessions({ childSessionTabs }: { childSessionTabs: readon
|
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
function WorkspaceProjectFiles({
|
|
179
|
+
activePath,
|
|
178
180
|
onFileOpen,
|
|
179
181
|
projectRoot,
|
|
180
182
|
sessionKey,
|
|
181
183
|
workingDir,
|
|
182
184
|
}: {
|
|
185
|
+
activePath: string | null;
|
|
183
186
|
onFileOpen?: (action: ChatFileOpenActionViewModel) => void;
|
|
184
187
|
projectRoot: string | null;
|
|
185
188
|
sessionKey: string | null;
|
|
@@ -203,6 +206,9 @@ function WorkspaceProjectFiles({
|
|
|
203
206
|
|
|
204
207
|
return (
|
|
205
208
|
<ChatSessionWorkspaceDirectoryBrowser
|
|
209
|
+
activeRelativePath={
|
|
210
|
+
activePath ? resolveWorkspaceRelativePath({ path: activePath, sessionProjectRoot: rootPath }) : null
|
|
211
|
+
}
|
|
206
212
|
key={rootPath}
|
|
207
213
|
browseQuery={browseQuery}
|
|
208
214
|
onFileOpen={onFileOpen ?? presenter.chatThreadManager.openFilePreview}
|
|
@@ -384,7 +390,7 @@ export function ChatSessionWorkspacePanelContent({
|
|
|
384
390
|
onResizeStart,
|
|
385
391
|
setExplorerOpen,
|
|
386
392
|
showExplorer,
|
|
387
|
-
} = useWorkspaceExplorerLayout({ fileActive, projectFilesActive
|
|
393
|
+
} = useWorkspaceExplorerLayout({ fileActive, projectFilesActive });
|
|
388
394
|
|
|
389
395
|
return (
|
|
390
396
|
<div
|
|
@@ -414,6 +420,7 @@ export function ChatSessionWorkspacePanelContent({
|
|
|
414
420
|
aria-hidden={!showExplorer}
|
|
415
421
|
>
|
|
416
422
|
<WorkspaceProjectFiles
|
|
423
|
+
activePath={fileActive ? activeSelection.file.path : null}
|
|
417
424
|
onFileOpen={(action) => {
|
|
418
425
|
if (compact) setExplorerOpen(false);
|
|
419
426
|
presenter.chatThreadManager.openFilePreview(action);
|
|
@@ -445,7 +452,7 @@ export function ChatSessionWorkspacePanelContent({
|
|
|
445
452
|
fileActive
|
|
446
453
|
? {
|
|
447
454
|
open: explorerOpen,
|
|
448
|
-
onToggle: () => setExplorerOpen(
|
|
455
|
+
onToggle: () => setExplorerOpen(!explorerOpen),
|
|
449
456
|
}
|
|
450
457
|
: undefined
|
|
451
458
|
}
|