@nextclaw/ui 0.26.5 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/.vite/manifest.json +1271 -1227
- package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-DmeCRAkd.js} +1 -1
- package/dist/assets/account-panel-BYxGT4m4.js +1 -0
- package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.js → aiden0z-pptx-renderer.es-ChX5DHqP.js} +1 -1
- package/dist/assets/api-CG22BskB.js +20 -0
- package/dist/assets/app-presenter-provider-CJFjhVYI.js +28 -0
- package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
- package/dist/assets/appearance-settings-page-BcXr0vHp.js +1 -0
- package/dist/assets/{arc-DBRedCax.js → arc-Cu6Ols44.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-DrNB0eLE.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-08rHt6DJ.js} +1 -1
- package/dist/assets/{book-open-Bcnn2_uV.js → book-open-ClbJmmxP.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CCVgRG-u.js} +1 -1
- package/dist/assets/{card-Cqs73hGI.js → card-BdC01NFF.js} +1 -1
- package/dist/assets/channel-BgpbPyEH.js +1 -0
- package/dist/assets/channels-list-page-BrIvJlop.js +8 -0
- package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-BeCaI-JN.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-ZXIcYPYs.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-DDwTPcy8.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-WygrMYPL.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-o8T3KZgk.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BKFbUT7J.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DYxCRV86.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CvSeJlKZ.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-BhH3RHCY.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-BTL0-xL3.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DWAU4QaD.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-B7ZBMXTx.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D92HvnHE.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-DfOGKwW8.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-DUuJUrXJ.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-i3MDyUY5.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-F_pmNX6t.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DygOelrU.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-BpiZMeRl.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-CV10sB1I.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-Cf1WZNm0.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-DuSw54VR.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-_rt_XKSZ.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-BFPaAGNW.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-GE0v_E5y.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-BK_FpnlJ.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-CpYh6rGo.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-htnxL_Cl.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-wDbE4BZ7.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DDRSVFTB.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-COdhHR1o.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-DPDGhyF6.js} +3 -3
- package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-D8ir9Nx5.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BuNKD836.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DyHzq8jH.js} +1 -1
- package/dist/assets/{circle-dashed-EY1ScSMe.js → circle-dashed-nDaMRmP-.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +1 -0
- package/dist/assets/{client-CH7w6yRV.js → client-DlFB5dW5.js} +1 -1
- package/dist/assets/config-split-page-C06fU9OQ.js +1 -0
- package/dist/assets/confirm-dialog-DpcmlXhd.js +1 -0
- package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
- package/dist/assets/context-menu-DKIEaY7f.js +211 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-B1I1_P6a.js} +1 -1
- package/dist/assets/{createLucideIcon-Cfo2ySi5.js → createLucideIcon-Lnt-4LMC.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DcOnhnCo.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-hAX89lg3.js} +1 -1
- package/dist/assets/{dagre-CrgsRasE.js → dagre-nSYhf9yY.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-BDYITStl.js → desktop-capabilities-page-DPORyZAu.js} +1 -1
- package/dist/assets/desktop-update-config-BMTeWZmn.js +1 -0
- package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-C1mRMD2k.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D2XBn5al.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-3LmRsmkC.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-CFWn-osC.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-BqNRbUvU.js} +1 -1
- package/dist/assets/dialog-BNXSPMX_.js +1 -0
- package/dist/assets/dist-Cuiqqp1O.js +41 -0
- package/dist/assets/doc-browser-CDEapjmj.js +1 -0
- package/dist/assets/{doc-browser-context-DwgG6wrz.js → doc-browser-context-0QDWYorh.js} +1 -1
- package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-CunAATyC.js} +1 -1
- package/dist/assets/{download-BoaKzDJk.js → download-f_sPcoLZ.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-CYb8IwqD.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-H47mUoeK.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +1 -0
- package/dist/assets/extensions-B-0xQz3L.js +1 -0
- package/dist/assets/external-link-CbVlnlNy.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +1 -0
- package/dist/assets/{form-actions-D9JWSFQu.js → form-actions-BoTqELHB.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-hSX45zfV.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-Br0UW2qg.js} +1 -1
- package/dist/assets/{i18n-Bm3Ov7Fy.js → i18n-B0V5NkFj.js} +2 -2
- package/dist/assets/inbox-Bna8iUy0.js +1 -0
- package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-DQmP_67w.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-BHAV2oes.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-CFHax4_d.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-B4ZA9rp5.js} +1 -1
- package/dist/assets/katex-BprZ-Wwb.js +1 -0
- package/dist/assets/{keyboard-shortcuts-settings-page-DZ8A1iLg.js → keyboard-shortcuts-settings-page-BluWKrSo.js} +1 -1
- package/dist/assets/{line-D_bHubTL.js → line-BboM0HLF.js} +1 -1
- package/dist/assets/{linear-ChlwuS5y.js → linear-4K_M1oYM.js} +1 -1
- package/dist/assets/login-page-BMHW0Hh0.js +1 -0
- package/dist/assets/{login-page-C-DvcG3L.js → login-page-JNr5JCEw.js} +1 -1
- package/dist/assets/main-BCX_Untx.css +1 -0
- package/dist/assets/main-C5kbmGUV.js +2 -0
- package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +1 -0
- package/dist/assets/{map-oGHTsIu8.js → map-26GpO1wn.js} +1 -1
- package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +1 -0
- package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-BTJFnvRC.js} +2 -2
- package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-B7ufoXgq.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-BHyru6KE.js} +1 -1
- package/dist/assets/model-config-page-C-wbM6Fe.js +1 -0
- package/dist/assets/{navigation-link-CjxNC8aT.js → navigation-link-DFLSVIut.js} +2 -2
- package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-BqFe2ePF.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +1 -0
- package/dist/assets/panel-app-CSQmm_7E.js +1 -0
- package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +1 -0
- package/dist/assets/panelStandalone-PuuMF65O.js +2 -0
- package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-PVTatU5j.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-CGc-QCc7.js} +1 -1
- package/dist/assets/plus-CywSlIbG.js +1 -0
- package/dist/assets/privacy-settings-page-CPdEiouE.js +1 -0
- package/dist/assets/projects-D_cd_t4G.js +1 -0
- package/dist/assets/provider-models-XRArsply.js +1 -0
- package/dist/assets/provider-scoped-model-input-C8JI-hus.js +1 -0
- package/dist/assets/providers-config-page-fyMlVgvq.js +1 -0
- package/dist/assets/puzzle-Bk3ud1KI.js +1 -0
- package/dist/assets/pwa-Cx6Fnox4.js +1 -0
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-DGL36riv.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-CyNwvhSb.js} +1 -1
- package/dist/assets/{refresh-cw-BlXDrVP0.js → refresh-cw-Ca2napNx.js} +1 -1
- package/dist/assets/remote-D5MBQNZE.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-C31NMKJ0.js} +1 -1
- package/dist/assets/{rotate-cw-ei6rPD6z.js → rotate-cw-DXg7sNUE.js} +1 -1
- package/dist/assets/runtime-config-page--ivCxBT4.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-CwrQ_7PA.js} +1 -1
- package/dist/assets/{save-DdF-bXgC.js → save-DNigywZ9.js} +1 -1
- package/dist/assets/search-U9C0oTQJ.js +1 -0
- package/dist/assets/search-config-page-Bdx_RR1q.js +1 -0
- package/dist/assets/secrets-config-page-CvMIcsfJ.js +3 -0
- package/dist/assets/security-config-CQmMqQ8v.js +1 -0
- package/dist/assets/select-DxwDeKUR.js +1 -0
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-EFD482_y.js} +1 -1
- package/dist/assets/service-apps-panel-CiYO1Be4.js +1 -0
- package/dist/assets/{settings-2-CrNhfInU.js → settings-2-BrBUdRoY.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-TDvULTE1.js} +1 -1
- package/dist/assets/{src-C8AUg09O.js → src-CI2AvEMj.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-JdPsIYHo.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +1 -0
- package/dist/assets/{status-dot-C3SRFEta.js → status-dot-BbGsrkIX.js} +1 -1
- package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BnxpKeK_.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +8 -0
- package/dist/assets/tag-chip-BDbxcf6P.js +1 -0
- package/dist/assets/theme-provider-D98XGa-c.js +1 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-2IL22-uC.js} +1 -1
- package/dist/assets/trash-2-DwSkRfeB.js +1 -0
- package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +1 -0
- package/dist/assets/{use-config-evzage09.js → use-config-D3cNzk2k.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-BYDjFlpt.js → use-desktop-capabilities-D7odgaTB.js} +1 -1
- package/dist/assets/use-viewport-layout-BANU5E1t.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-Cjf6n5Va.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-yv4qKbBO.js} +1 -1
- package/dist/assets/x-BqGj6_Vq.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-Bmp8Ck8X.js} +1 -1
- package/dist/index.html +43 -106
- package/dist/panel-standalone.html +18 -12
- package/index.html +15 -66
- package/package.json +4 -4
- package/src/app/styles/design-system.css +85 -1
- package/src/app/styles/island-theme.css +8 -6
- package/src/features/agents/components/agent-details-dialog.tsx +5 -3
- package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
- package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
- package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
- package/src/features/apps/components/app-document-access-section.tsx +17 -14
- package/src/features/apps/components/app-marketplace-catalog.tsx +66 -39
- package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
- package/src/features/apps/components/app-marketplace-detail.tsx +9 -6
- package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
- package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
- package/src/features/apps/components/app-package-card.tsx +224 -147
- package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
- package/src/features/apps/components/app-packages-panel.tsx +159 -144
- package/src/features/apps/components/apps-panel.tsx +40 -11
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
- package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
- package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +33 -0
- package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
- package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
- package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
- package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
- package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
- package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -7
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +5 -4
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
- package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
- package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +7 -4
- package/src/features/cron/components/cron-job-row.tsx +5 -4
- package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
- package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
- package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
- package/src/features/inbox/managers/inbox.manager.ts +18 -4
- package/src/features/inbox/pages/inbox-page.test.ts +4 -2
- package/src/features/inbox/pages/inbox-page.tsx +6 -5
- package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
- package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
- package/src/features/projects/components/work/project-work-items.tsx +1 -1
- package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
- package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
- package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
- package/src/features/right-panel-resources/components/page-resource-icon.tsx +15 -7
- package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +1 -1
- package/src/features/right-panel-resources/index.ts +3 -0
- package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +5 -0
- package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
- package/src/features/service-apps/components/service-action-row.tsx +4 -3
- package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
- package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
- package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
- package/src/features/settings/pages/providers-config-page.tsx +3 -2
- package/src/index.css +42 -8
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
- package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
- package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
- package/src/shared/components/ui/actions/action-feedback.ts +1 -8
- package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
- package/src/shared/components/ui/confirm-dialog.tsx +1 -2
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
- package/src/shared/components/ui/dialog.tsx +29 -7
- package/src/shared/components/ui/popover.tsx +14 -3
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -2
- package/src/shared/components/ui/tooltip.tsx +2 -1
- package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
- package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
- package/src/shared/components/workbench/workbench-surface.tsx +4 -1
- package/src/shared/lib/i18n/locales/en-US/chat.json +13 -7
- package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
- package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +13 -7
- package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
- package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
- package/src/shared/lib/theme/index.test.ts +28 -1
- package/src/shared/lib/theme/index.ts +14 -3
- package/dist/assets/account-panel-BAH7FW6z.js +0 -1
- package/dist/assets/api-DjiZvIa0.js +0 -20
- package/dist/assets/app-presenter-provider-CCRFsFYr.js +0 -232
- package/dist/assets/appearance-settings-page-CdP86QJ7.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
- package/dist/assets/channel-CpMstUPF.js +0 -1
- package/dist/assets/channels-list-page-5qGagKuE.js +0 -8
- package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
- package/dist/assets/config-split-page-CuEGQL8Z.js +0 -1
- package/dist/assets/confirm-dialog-CxfecBzO.js +0 -1
- package/dist/assets/context-menu-BsCj2fRs.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
- package/dist/assets/desktop-update-config-e-zhkJuS.js +0 -1
- package/dist/assets/dialog-QjQoKbIV.js +0 -5
- package/dist/assets/doc-browser-CLEdkH9z.js +0 -1
- package/dist/assets/es2015-Bp6cuSGh.js +0 -41
- package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
- package/dist/assets/extensions-CgShSIkd.js +0 -1
- package/dist/assets/eye-kisejBFH.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
- package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
- package/dist/assets/katex-B4FQSo9k.js +0 -1
- package/dist/assets/loader-circle-Bd1fTm-x.js +0 -1
- package/dist/assets/login-page-D99JjH9F.js +0 -1
- package/dist/assets/main-Bt5r6b21.js +0 -2
- package/dist/assets/main-DXd_aKJV.css +0 -1
- package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +0 -1
- package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +0 -1
- package/dist/assets/model-config-page-9NNf-mzK.js +0 -1
- package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
- package/dist/assets/panel-app-BYfQu_TS.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +0 -1
- package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
- package/dist/assets/panelStandalone-BaUzY8Wy.js +0 -2
- package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
- package/dist/assets/privacy-settings-page-CVMBFuak.js +0 -1
- package/dist/assets/projects-BEsU3box.js +0 -1
- package/dist/assets/provider-models-Dm-pmWAA.js +0 -1
- package/dist/assets/provider-scoped-model-input-CzrXg4cX.js +0 -1
- package/dist/assets/providers-config-page-839uUADZ.js +0 -1
- package/dist/assets/puzzle-BGvD2DPZ.js +0 -1
- package/dist/assets/pwa-DNNK_8E9.js +0 -1
- package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
- package/dist/assets/remote-B5qIuUbT.js +0 -1
- package/dist/assets/runtime-config-page-Bf-4JYxQ.js +0 -1
- package/dist/assets/search-config-page-C0qA3j-T.js +0 -1
- package/dist/assets/secrets-config-page-DxfZWpnk.js +0 -3
- package/dist/assets/security-config-CItfIQZ4.js +0 -1
- package/dist/assets/select-CWyjnar7.js +0 -1
- package/dist/assets/service-apps-panel-D3SOkRVv.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
- package/dist/assets/tag-chip-BIuavK2K.js +0 -1
- package/dist/assets/theme-provider-CWUz4yO9.js +0 -1
- package/dist/assets/trash-2-hAbJh9VZ.js +0 -1
- package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
- package/dist/assets/use-viewport-layout-D_9XWGDV.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
- package/dist/assets/x-ChPbNv39.js +0 -1
- package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
- /package/dist/assets/{array-BV9OtnO8.js → array-DstOKG9P.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-0TA8nwgf.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-rfGCG6pM.js} +0 -0
- /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-BfGoD7-o.js} +0 -0
- /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-DdIcNEda.js} +0 -0
- /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-CzXix2iJ.js} +0 -0
- /package/dist/assets/{dist-BVCSkfWY.js → dist-D5dwMwKA.js} +0 -0
- /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-BKOe0eFe.js} +0 -0
- /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-CnSVTaot.js} +0 -0
- /package/dist/assets/{init-BF6GH5oe.js → init-OCFb3zgY.js} +0 -0
- /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-B2uhSxvV.js} +0 -0
- /package/dist/assets/{katex-CsAM73R9.js → katex-dBrYsE7B.js} +0 -0
- /package/dist/assets/{middleware-B--6mAUM.js → middleware-CAXxl-af.js} +0 -0
- /package/dist/assets/{path-C56XkznJ.js → path-T5eoIRSJ.js} +0 -0
- /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
- /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-DmGXmZEB.js} +0 -0
- /package/dist/assets/{xlsx-sds5nUpL.js → xlsx-CoYacou7.js} +0 -0
package/src/features/chat/features/conversation/components/floating-session-conversation.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { PageResourceActionsMenu } from '@/features/right-panel-resources';
|
|
2
2
|
import { pageResourceFromTarget } from '@/features/right-panel-resources';
|
|
3
3
|
import { buildSessionPanelUrl } from '@/features/chat/features/session/utils/chat-session-route.utils';
|
|
4
|
-
import { MessageSquare } from 'lucide-react';
|
|
5
4
|
import { useNavigate } from 'react-router-dom';
|
|
6
5
|
import { getAppPresenter } from '@/app/presenters/app.presenter';
|
|
7
6
|
import { sessionSurfaceManager } from '@/features/chat/managers/session-surface.manager';
|
|
@@ -17,8 +16,8 @@ export function FloatingSessionConversation() {
|
|
|
17
16
|
const presenter = getAppPresenter();
|
|
18
17
|
if (!session) return null;
|
|
19
18
|
return <WorkbenchSurface id={SESSION_WORKBENCH_SURFACE} manager={presenter.workbenchSurfaceManager}
|
|
20
|
-
title={session.title}
|
|
21
|
-
|
|
19
|
+
title={session.title} testId="floating-session-conversation" focusOnOpen
|
|
20
|
+
moreActions={<PageResourceActionsMenu page={pageResourceFromTarget({ kind: 'chat-session', title: session.title, url: buildSessionPanelUrl(session.sessionKey), resourceUri: buildSessionPanelUrl(session.sessionKey), historyPolicy: 'none' })} />}
|
|
22
21
|
onClose={sessionSurfaceManager.close}
|
|
23
22
|
onPlace={() => sessionSurfaceManager.dock(session, presenter.docBrowserManager)}
|
|
24
23
|
onOpenMain={() => { navigate(buildSessionPath(session.sessionKey)); sessionSurfaceManager.close(); }}>
|
|
@@ -437,6 +437,7 @@ export function SessionConversationArea(props: SessionConversationAreaProps) {
|
|
|
437
437
|
onEditMessage={(payload) => controllerRef.current.editMessage(payload)}
|
|
438
438
|
welcomeSlot={
|
|
439
439
|
<ChatConversationWelcome
|
|
440
|
+
hasDraftContent={Boolean(inputSnapshot.text.trim() || inputSnapshot.attachments.length || inputSnapshot.selectedSkills.length)}
|
|
440
441
|
inputSlot={
|
|
441
442
|
<div className="space-y-2">
|
|
442
443
|
{renderInput("embedded", t("chatWelcomeInputPlaceholder"))}
|
|
@@ -198,4 +198,37 @@ describe('useSessionConversationInputState session preferences', () => {
|
|
|
198
198
|
rerender({ sessionKey: null });
|
|
199
199
|
expect(result.current.inputSnapshot.text).toBe('新会话草稿');
|
|
200
200
|
});
|
|
201
|
+
|
|
202
|
+
it('keeps a successfully cleared draft empty after switching away and back', () => {
|
|
203
|
+
const { result, rerender } = renderHook(
|
|
204
|
+
({ sessionKey }: { sessionKey: string }) =>
|
|
205
|
+
useSessionConversationInputState(null, sessionKey),
|
|
206
|
+
{ initialProps: { sessionKey: 'session-sent' } },
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
act(() => {
|
|
210
|
+
result.current.inputActions.syncComposer({
|
|
211
|
+
text: '已经发送的消息',
|
|
212
|
+
nodes: [],
|
|
213
|
+
selectedSkills: [],
|
|
214
|
+
skillRecords: [],
|
|
215
|
+
});
|
|
216
|
+
result.current.inputActions.resetComposer();
|
|
217
|
+
});
|
|
218
|
+
rerender({ sessionKey: 'session-unsent' });
|
|
219
|
+
act(() => {
|
|
220
|
+
result.current.inputActions.syncComposer({
|
|
221
|
+
text: '仍未发送的草稿',
|
|
222
|
+
nodes: [],
|
|
223
|
+
selectedSkills: [],
|
|
224
|
+
skillRecords: [],
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
rerender({ sessionKey: 'session-sent' });
|
|
229
|
+
expect(result.current.inputSnapshot.text).toBe('');
|
|
230
|
+
|
|
231
|
+
rerender({ sessionKey: 'session-unsent' });
|
|
232
|
+
expect(result.current.inputSnapshot.text).toBe('仍未发送的草稿');
|
|
233
|
+
});
|
|
201
234
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ChatMessageMoreActionsViewModel } from "@nextclaw/agent-chat-ui";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import { Braces } from "lucide-react";
|
|
2
4
|
import {
|
|
3
5
|
readNcpAiExecutionMetadata,
|
|
4
6
|
type NcpAiExecutionMetadata,
|
|
@@ -159,6 +161,7 @@ export function buildChatMessageExecutionPresentation(params: {
|
|
|
159
161
|
items: [
|
|
160
162
|
{
|
|
161
163
|
key: "ai-execution-metadata",
|
|
164
|
+
icon: createElement(Braces, { className: "h-4 w-4" }),
|
|
162
165
|
label: labels.viewMetadata,
|
|
163
166
|
dialog: {
|
|
164
167
|
title: labels.metadataTitle,
|
|
@@ -190,6 +190,7 @@ export function buildChatMessageTexts(
|
|
|
190
190
|
excerptCharacterCountTemplate: t("chatWorkspaceExcerptCharacterCount"),
|
|
191
191
|
mermaidDiagramLabel: t("chatMermaidDiagram"),
|
|
192
192
|
frontmatterLabel: t("chatMarkdownFrontmatter"),
|
|
193
|
+
detailsLabel: t("chatMarkdownDetails"),
|
|
193
194
|
mermaidExpandLabel: t("chatMermaidExpand"),
|
|
194
195
|
mermaidLoadingLabel: t("chatMermaidLoading"),
|
|
195
196
|
mermaidRenderErrorLabel: t("chatMermaidRenderError"),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ChatMessageMoreActionsViewModel } from "@nextclaw/agent-chat-ui";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import { Zap } from "lucide-react";
|
|
2
4
|
import {
|
|
3
5
|
readNcpAiExecutionMetadata,
|
|
4
6
|
readNcpRunTriggerMetadata,
|
|
@@ -106,6 +108,7 @@ export function buildChatMessageTriggerDetails(params: {
|
|
|
106
108
|
triggerLabel: labels.moreActions,
|
|
107
109
|
items: [{
|
|
108
110
|
key: "run-trigger-metadata",
|
|
111
|
+
icon: createElement(Zap, { className: "h-4 w-4" }),
|
|
109
112
|
label: labels.viewTrigger,
|
|
110
113
|
dialog: {
|
|
111
114
|
title: labels.title,
|
|
@@ -262,7 +262,7 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
|
|
|
262
262
|
onClick={(event) => event.stopPropagation()}
|
|
263
263
|
/>
|
|
264
264
|
</PopoverTrigger>
|
|
265
|
-
<ChatPopoverContent align="end"
|
|
265
|
+
<ChatPopoverContent align="end" variant="menu">
|
|
266
266
|
<ChatSessionHeaderMenuItem
|
|
267
267
|
icon={FolderMinus}
|
|
268
268
|
label={t("projectsRemoveFromList")}
|
|
@@ -29,7 +29,7 @@ export function ChatSessionMetadataDialog({
|
|
|
29
29
|
return (
|
|
30
30
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
31
31
|
<DialogContent className="max-w-2xl gap-0 overflow-hidden p-0">
|
|
32
|
-
<DialogHeader className="border-b border-border px-5 py-4
|
|
32
|
+
<DialogHeader className="border-b border-border px-5 py-4">
|
|
33
33
|
<DialogTitle className="text-base">{t('chatSessionMetadataDialogTitle')}</DialogTitle>
|
|
34
34
|
<DialogDescription className="sr-only">
|
|
35
35
|
{t('chatSessionMetadataDialogDescription')}
|
package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx
CHANGED
|
@@ -56,8 +56,8 @@ export function ChatSessionProjectBadge({
|
|
|
56
56
|
<PopoverTrigger asChild>
|
|
57
57
|
<button
|
|
58
58
|
type="button"
|
|
59
|
-
title={projectRoot
|
|
60
|
-
className="min-w-0 max-w-[
|
|
59
|
+
title={projectRoot ? `${projectName}\n${projectRoot}` : projectName}
|
|
60
|
+
className="min-w-0 max-w-[40%] shrink-0 rounded-full border border-border bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-60"
|
|
61
61
|
aria-label={t('chatSessionSetProject')}
|
|
62
62
|
disabled={isProjectPending}
|
|
63
63
|
>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
3
|
import { ChatWelcome } from '@/features/chat/features/welcome/components/chat-welcome';
|
|
4
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
5
|
+
import { buildSessionPath } from '@/features/chat/features/session/utils/chat-session-route.utils';
|
|
4
6
|
|
|
5
7
|
vi.mock(
|
|
6
8
|
'@/features/chat/features/session/components/session-header/chat-session-project-dialog',
|
|
@@ -18,12 +20,14 @@ function renderWelcome(
|
|
|
18
20
|
overrides: Partial<Parameters<typeof ChatWelcome>[0]> = {},
|
|
19
21
|
) {
|
|
20
22
|
return render(
|
|
23
|
+
<MemoryRouter>
|
|
21
24
|
<ChatWelcome
|
|
22
25
|
agents={[
|
|
23
26
|
{ id: 'main', displayName: 'Main' },
|
|
24
27
|
{ id: 'engineer', displayName: 'Engineer' },
|
|
25
28
|
]}
|
|
26
29
|
projectOptions={[]}
|
|
30
|
+
selectedProjectRoot="/tmp/project"
|
|
27
31
|
selectedAgentId="main"
|
|
28
32
|
selectedSessionType="native"
|
|
29
33
|
sessionTypeOptions={sessionTypeOptions}
|
|
@@ -31,11 +35,34 @@ function renderWelcome(
|
|
|
31
35
|
onSelectPrompt={vi.fn()}
|
|
32
36
|
onSelectSessionType={vi.fn()}
|
|
33
37
|
{...overrides}
|
|
34
|
-
|
|
38
|
+
/>
|
|
39
|
+
</MemoryRouter>,
|
|
35
40
|
);
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
describe('ChatWelcome', () => {
|
|
44
|
+
it('offers an open-ended starting point outside an explicit project', () => {
|
|
45
|
+
renderWelcome({ selectedProjectRoot: null });
|
|
46
|
+
expect(screen.getByRole('button', { name: 'Talk about how I’ve been' })).toBeTruthy();
|
|
47
|
+
expect(screen.queryByRole('button', { name: 'Move this project forward' })).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('links to the original session and can dismiss it without removing history', () => {
|
|
51
|
+
renderWelcome({ continuation: { sessionKey: 'session/one', title: 'A real conversation' } });
|
|
52
|
+
const link = screen.getByRole('link', { name: /A real conversation/ });
|
|
53
|
+
expect(link.getAttribute('href')).toBe(buildSessionPath('session/one'));
|
|
54
|
+
expect(screen.getByRole('button', { name: 'Talk about how I’ve been' })).toBeTruthy();
|
|
55
|
+
fireEvent.click(screen.getByRole('button', { name: 'Hide this conversation suggestion for now' }));
|
|
56
|
+
expect(screen.queryByRole('link')).toBeNull();
|
|
57
|
+
expect(screen.getByRole('button', { name: 'Move this project forward' })).toBeTruthy();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('hides starting suggestions while composing but keeps context controls available', () => {
|
|
61
|
+
renderWelcome({ hasDraftContent: true });
|
|
62
|
+
expect(screen.queryByRole('button', { name: 'Move this project forward' })).toBeNull();
|
|
63
|
+
expect(screen.getByRole('combobox', { name: 'Draft agent' })).toBeTruthy();
|
|
64
|
+
expect(screen.getByRole('button', { name: 'Choose session type' })).toBeTruthy();
|
|
65
|
+
});
|
|
39
66
|
it('renders a lightweight draft agent select and allows switching', () => {
|
|
40
67
|
const onSelectAgent = vi.fn();
|
|
41
68
|
|
|
@@ -53,12 +80,10 @@ describe('ChatWelcome', () => {
|
|
|
53
80
|
it('renders a single-purpose welcome surface with compact prompt suggestions', () => {
|
|
54
81
|
renderWelcome({ agents: [{ id: 'main', displayName: 'Main' }] });
|
|
55
82
|
|
|
56
|
-
expect(screen.getByRole('heading', { name: '
|
|
83
|
+
expect(screen.getByRole('heading', { name: 'Where shall we start today?' })).toBeTruthy();
|
|
57
84
|
expect(screen.queryByText(/Describe the goal/)).toBeNull();
|
|
58
85
|
expect(screen.getByRole('group', { name: 'Task context' })).toBeTruthy();
|
|
59
|
-
const suggestion = screen.getByRole('button', { name: '
|
|
60
|
-
expect(suggestion.className).toContain('rounded-full');
|
|
61
|
-
expect(suggestion.className).not.toContain('border');
|
|
86
|
+
const suggestion = screen.getByRole('button', { name: 'Move this project forward' });
|
|
62
87
|
expect(suggestion.parentElement?.className).toContain('flex-wrap');
|
|
63
88
|
});
|
|
64
89
|
|
|
@@ -67,7 +92,7 @@ describe('ChatWelcome', () => {
|
|
|
67
92
|
|
|
68
93
|
renderWelcome({ onSelectPrompt });
|
|
69
94
|
|
|
70
|
-
fireEvent.click(screen.getByRole('button', { name: '
|
|
95
|
+
fireEvent.click(screen.getByRole('button', { name: 'Move this project forward' }));
|
|
71
96
|
|
|
72
97
|
expect(onSelectPrompt).toHaveBeenCalledWith(
|
|
73
98
|
expect.stringContaining('next three concrete things'),
|
|
@@ -19,11 +19,13 @@ import { useAgents } from "@/shared/hooks/use-agents";
|
|
|
19
19
|
import { useProjects } from "@/shared/hooks/use-projects";
|
|
20
20
|
import type { NcpSessionSummaryView } from "@/shared/lib/api";
|
|
21
21
|
import { normalizeSessionProjectRootValue } from "@/shared/lib/session-project";
|
|
22
|
+
import { resolveChatWelcomeContinuation } from "@/features/chat/features/welcome/utils/chat-welcome-continuation.utils";
|
|
22
23
|
|
|
23
24
|
const EMPTY_NCP_SESSION_SUMMARIES: NcpSessionSummaryView[] = [];
|
|
24
25
|
|
|
25
26
|
type ChatConversationWelcomeProps = {
|
|
26
27
|
inputSlot: ReactNode;
|
|
28
|
+
hasDraftContent?: boolean;
|
|
27
29
|
pendingProjectRoot: string | null;
|
|
28
30
|
pendingSessionType: string;
|
|
29
31
|
selectedSessionTypeValue: string | null;
|
|
@@ -34,6 +36,7 @@ type ChatConversationWelcomeProps = {
|
|
|
34
36
|
|
|
35
37
|
export function ChatConversationWelcome({
|
|
36
38
|
inputSlot,
|
|
39
|
+
hasDraftContent = false,
|
|
37
40
|
pendingProjectRoot,
|
|
38
41
|
pendingSessionType,
|
|
39
42
|
selectedSessionTypeValue,
|
|
@@ -50,7 +53,9 @@ export function ChatConversationWelcome({
|
|
|
50
53
|
(state) => state.snapshot.configQuery?.data ?? null,
|
|
51
54
|
);
|
|
52
55
|
const sessionSummaries = useChatQueryStore(
|
|
53
|
-
(state) => state.snapshot.sessionsQuery?.
|
|
56
|
+
(state) => state.snapshot.sessionsQuery?.isSuccess
|
|
57
|
+
? state.snapshot.sessionsQuery.data?.sessions ?? EMPTY_NCP_SESSION_SUMMARIES
|
|
58
|
+
: EMPTY_NCP_SESSION_SUMMARIES,
|
|
54
59
|
);
|
|
55
60
|
const sessionTypesData = useChatQueryStore(
|
|
56
61
|
(state) => state.snapshot.sessionTypesQuery?.data ?? null,
|
|
@@ -104,6 +109,13 @@ export function ChatConversationWelcome({
|
|
|
104
109
|
agents={availableAgents}
|
|
105
110
|
defaultProjectRoot={defaultProjectRoot}
|
|
106
111
|
inputSlot={inputSlot}
|
|
112
|
+
hasDraftContent={hasDraftContent}
|
|
113
|
+
continuation={resolveChatWelcomeContinuation({
|
|
114
|
+
sessions: sessionSummaries,
|
|
115
|
+
projectRoot: selectedProjectRoot ?? defaultProjectRoot,
|
|
116
|
+
defaultProjectRoot,
|
|
117
|
+
agentId: draftAgentId,
|
|
118
|
+
})}
|
|
107
119
|
projectOptions={projectOptions}
|
|
108
120
|
selectedAgentId={draftAgentId}
|
|
109
121
|
selectedProjectRoot={selectedProjectRoot}
|
|
@@ -28,7 +28,7 @@ export function ChatWelcomeAgentPicker({
|
|
|
28
28
|
<Select value={selectedAgentId} onValueChange={onSelectAgent}>
|
|
29
29
|
<SelectTrigger
|
|
30
30
|
aria-label={t('chatDraftAgentTitle')}
|
|
31
|
-
className="h-
|
|
31
|
+
className="h-9 w-auto min-w-0 gap-1.5 rounded-lg border-0 bg-transparent px-2 py-1.5 text-sm font-medium text-foreground/80 shadow-none hover:bg-[var(--interaction-hover)] hover:text-foreground focus:ring-1 focus:ring-border"
|
|
32
32
|
>
|
|
33
33
|
<span className="sr-only">{t('chatDraftAgentTitle')}</span>
|
|
34
34
|
<div className="flex min-w-0 items-center gap-1.5">
|
|
@@ -43,7 +43,7 @@ export function ChatWelcomeProjectPicker({
|
|
|
43
43
|
<PopoverTrigger asChild>
|
|
44
44
|
<button
|
|
45
45
|
type="button"
|
|
46
|
-
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-
|
|
46
|
+
className="inline-flex h-9 min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left text-sm font-medium text-foreground/80 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
47
47
|
title={projectRoot ?? undefined}
|
|
48
48
|
aria-label={t('chatWelcomeProjectPickerLabel')}
|
|
49
49
|
disabled={!selectable || isSaving}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
import { ArrowUpRight, History, X } from 'lucide-react';
|
|
4
|
+
import { buildSessionPath } from '@/features/chat/features/session/utils/chat-session-route.utils';
|
|
5
|
+
import type { ChatWelcomeContinuation } from '@/features/chat/features/welcome/utils/chat-welcome-continuation.utils';
|
|
1
6
|
import { t } from '@/shared/lib/i18n';
|
|
2
7
|
|
|
3
8
|
const WELCOME_PROMPT_SUGGESTIONS = [
|
|
4
9
|
{
|
|
5
|
-
labelKey: '
|
|
6
|
-
promptKey: '
|
|
10
|
+
labelKey: 'chatWelcomeOpenStartLabel' as const,
|
|
11
|
+
promptKey: 'chatWelcomeOpenStartPrompt' as const,
|
|
7
12
|
},
|
|
8
13
|
{
|
|
9
14
|
labelKey: 'chatWelcomeSuggestion2Label' as const,
|
|
@@ -17,21 +22,59 @@ const WELCOME_PROMPT_SUGGESTIONS = [
|
|
|
17
22
|
|
|
18
23
|
export function ChatWelcomePromptSuggestions({
|
|
19
24
|
onSelectPrompt,
|
|
25
|
+
hasDraftContent = false,
|
|
26
|
+
hasProject = false,
|
|
27
|
+
continuation,
|
|
20
28
|
}: {
|
|
21
29
|
onSelectPrompt: (prompt: string) => void;
|
|
30
|
+
hasDraftContent?: boolean;
|
|
31
|
+
hasProject?: boolean;
|
|
32
|
+
continuation?: ChatWelcomeContinuation | null;
|
|
22
33
|
}) {
|
|
34
|
+
const [dismissedSessionKey, setDismissedSessionKey] = useState<string | null>(null);
|
|
35
|
+
const showContinuation = continuation && continuation.sessionKey !== dismissedSessionKey;
|
|
23
36
|
return (
|
|
24
|
-
<div className=
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
<div className={`mt-3 min-h-32 ${hasDraftContent ? 'invisible' : ''}`} aria-hidden={hasDraftContent || undefined}>
|
|
38
|
+
<div className="flex flex-wrap justify-center gap-x-2 gap-y-1">
|
|
39
|
+
{WELCOME_PROMPT_SUGGESTIONS.map((suggestion, index) => {
|
|
40
|
+
const projectStart = index === 2 && hasProject;
|
|
41
|
+
return (
|
|
42
|
+
<button
|
|
43
|
+
key={suggestion.labelKey}
|
|
44
|
+
type="button"
|
|
45
|
+
onClick={() => onSelectPrompt(t(projectStart ? 'chatWelcomeSuggestion1Prompt' : suggestion.promptKey))}
|
|
46
|
+
className="rounded-lg bg-muted/70 px-3 py-1.5 text-[13px] font-normal leading-5 text-foreground/80 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
47
|
+
>
|
|
48
|
+
{t(projectStart ? 'chatWelcomeSuggestion1Label' : suggestion.labelKey)}
|
|
49
|
+
</button>
|
|
50
|
+
);
|
|
51
|
+
})}
|
|
52
|
+
</div>
|
|
53
|
+
{continuation ? (
|
|
54
|
+
<div className={`mx-auto mt-5 flex min-w-0 max-w-lg items-center gap-1 border-t border-border/50 pt-3 ${showContinuation ? '' : 'invisible'}`} aria-hidden={!showContinuation || undefined}>
|
|
55
|
+
<Link
|
|
56
|
+
to={buildSessionPath(continuation.sessionKey)}
|
|
57
|
+
title={t('chatWelcomeContinueHint')}
|
|
58
|
+
className="flex min-w-0 flex-1 items-center gap-3 rounded-lg px-2 py-2 transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
59
|
+
>
|
|
60
|
+
<History aria-hidden="true" className="h-4 w-4 shrink-0 text-muted-foreground" />
|
|
61
|
+
<span className="min-w-0 flex-1">
|
|
62
|
+
<span className="block text-xs text-muted-foreground">{t('chatWelcomeContinueLabel')}</span>
|
|
63
|
+
<span className="mt-1 block truncate text-sm text-foreground">{continuation.title}</span>
|
|
64
|
+
</span>
|
|
65
|
+
<ArrowUpRight aria-hidden="true" className="h-4 w-4 shrink-0 text-muted-foreground" />
|
|
66
|
+
</Link>
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
aria-label={t('chatWelcomeDismissContinue')}
|
|
70
|
+
title={t('chatWelcomeDismissContinue')}
|
|
71
|
+
onClick={() => setDismissedSessionKey(continuation.sessionKey)}
|
|
72
|
+
className="mr-1 flex h-9 w-9 shrink-0 items-center justify-center rounded-lg text-muted-foreground hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
73
|
+
>
|
|
74
|
+
<X aria-hidden="true" className="h-3.5 w-3.5" />
|
|
75
|
+
</button>
|
|
76
|
+
</div>
|
|
77
|
+
) : null}
|
|
35
78
|
</div>
|
|
36
79
|
);
|
|
37
80
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Cpu, ChevronDown } from 'lucide-react';
|
|
3
3
|
import { SessionContextIconNode } from '@/features/chat/features/session/components/session-context-icon';
|
|
4
4
|
import { ChatSessionTypeOptionItem } from '@/features/chat/features/session-type/components/chat-session-type-option-item';
|
|
5
5
|
import type { ChatSessionTypeOption } from '@/features/chat/features/session-type/utils/chat-session-type.utils';
|
|
@@ -39,7 +39,7 @@ export function ChatWelcomeSessionTypePicker({
|
|
|
39
39
|
<PopoverTrigger asChild>
|
|
40
40
|
<button
|
|
41
41
|
type="button"
|
|
42
|
-
className="inline-flex min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left font-medium text-
|
|
42
|
+
className="inline-flex h-9 min-w-0 max-w-full items-center gap-1.5 rounded-lg px-2 py-1.5 text-left text-sm font-medium text-foreground/80 transition-colors hover:bg-[var(--interaction-hover)] hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border"
|
|
43
43
|
aria-label={t('chatWelcomeSessionTypePickerLabel')}
|
|
44
44
|
>
|
|
45
45
|
{selectedOption.icon?.src ? (
|
|
@@ -53,7 +53,7 @@ export function ChatWelcomeSessionTypePicker({
|
|
|
53
53
|
className="h-4 w-4"
|
|
54
54
|
/>
|
|
55
55
|
) : (
|
|
56
|
-
<
|
|
56
|
+
<Cpu className="h-3.5 w-3.5 shrink-0" />
|
|
57
57
|
)}
|
|
58
58
|
<span className="truncate">{selectedOption.label}</span>
|
|
59
59
|
<ChevronDown className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70" />
|
|
@@ -9,12 +9,15 @@ import type { ChatWelcomeProjectOption } from '@/features/chat/features/welcome/
|
|
|
9
9
|
import type { ChatSessionTypeOption } from '@/features/chat/features/session-type/utils/chat-session-type.utils';
|
|
10
10
|
import type { AgentProfileView } from '@/shared/lib/api';
|
|
11
11
|
import { t } from '@/shared/lib/i18n';
|
|
12
|
+
import type { ChatWelcomeContinuation } from '@/features/chat/features/welcome/utils/chat-welcome-continuation.utils';
|
|
12
13
|
|
|
13
14
|
type SessionTypeOption = ChatSessionTypeOption;
|
|
14
15
|
|
|
15
16
|
type ChatWelcomeProps = {
|
|
16
17
|
agents: AgentProfileView[];
|
|
17
18
|
inputSlot?: ReactNode;
|
|
19
|
+
hasDraftContent?: boolean;
|
|
20
|
+
continuation?: ChatWelcomeContinuation | null;
|
|
18
21
|
defaultProjectRoot?: string | null;
|
|
19
22
|
projectOptions: readonly ChatWelcomeProjectOption[];
|
|
20
23
|
selectedAgentId: string;
|
|
@@ -31,6 +34,8 @@ export function ChatWelcome({
|
|
|
31
34
|
agents,
|
|
32
35
|
defaultProjectRoot,
|
|
33
36
|
inputSlot,
|
|
37
|
+
hasDraftContent = false,
|
|
38
|
+
continuation,
|
|
34
39
|
projectOptions,
|
|
35
40
|
selectedAgentId,
|
|
36
41
|
selectedProjectRoot,
|
|
@@ -64,18 +69,18 @@ export function ChatWelcome({
|
|
|
64
69
|
<div className="flex min-h-full items-center justify-center px-4 py-10 sm:p-8">
|
|
65
70
|
<div className="w-full min-w-0 max-w-[min(680px,100%)]">
|
|
66
71
|
<div className="text-center">
|
|
67
|
-
<h2 className="text-2xl font-
|
|
72
|
+
<h2 className="text-2xl font-[number:var(--welcome-title-weight)] leading-tight text-[hsl(var(--welcome-title-foreground))] sm:text-[1.75rem]">
|
|
68
73
|
{t('chatWelcomeTitle')}
|
|
69
74
|
</h2>
|
|
70
75
|
</div>
|
|
71
76
|
|
|
72
77
|
{inputSlot ? <div className="mt-6">{inputSlot}</div> : null}
|
|
73
78
|
|
|
74
|
-
<div className="mt-
|
|
79
|
+
<div className="mt-1.5 flex justify-center px-1">
|
|
75
80
|
<div
|
|
76
81
|
role="group"
|
|
77
82
|
aria-label={t('chatWelcomeContextLabel')}
|
|
78
|
-
className="flex min-w-0 max-w-full flex-wrap items-center justify-center gap-
|
|
83
|
+
className="flex min-w-0 max-w-full flex-wrap items-center justify-center gap-x-1 gap-y-0.5 text-xs text-muted-foreground"
|
|
79
84
|
>
|
|
80
85
|
{onSelectProjectRoot ? (
|
|
81
86
|
<ChatWelcomeProjectPicker
|
|
@@ -101,7 +106,12 @@ export function ChatWelcome({
|
|
|
101
106
|
</div>
|
|
102
107
|
</div>
|
|
103
108
|
|
|
104
|
-
<ChatWelcomePromptSuggestions
|
|
109
|
+
<ChatWelcomePromptSuggestions
|
|
110
|
+
hasDraftContent={hasDraftContent}
|
|
111
|
+
hasProject={Boolean(selectedProjectRoot)}
|
|
112
|
+
continuation={continuation}
|
|
113
|
+
onSelectPrompt={onSelectPrompt}
|
|
114
|
+
/>
|
|
105
115
|
</div>
|
|
106
116
|
|
|
107
117
|
{onSelectProjectRoot ? (
|
package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import type { NcpSessionSummaryView } from '@/shared/lib/api';
|
|
3
|
+
import { resolveChatWelcomeContinuation } from '@/features/chat/features/welcome/utils/chat-welcome-continuation.utils';
|
|
4
|
+
|
|
5
|
+
const summary = (overrides: Partial<NcpSessionSummaryView> = {}): NcpSessionSummaryView => ({
|
|
6
|
+
sessionId: 'original', agentId: 'main', messageCount: 2,
|
|
7
|
+
updatedAt: '2026-09-16T10:00:00Z',
|
|
8
|
+
metadata: { label: 'Project plan', project_root: '/project' },
|
|
9
|
+
...overrides,
|
|
10
|
+
});
|
|
11
|
+
const resolve = (sessions: NcpSessionSummaryView[], projectRoot = '/project') =>
|
|
12
|
+
resolveChatWelcomeContinuation({ sessions, projectRoot, defaultProjectRoot: '/default', agentId: 'main' });
|
|
13
|
+
|
|
14
|
+
describe('resolveChatWelcomeContinuation', () => {
|
|
15
|
+
it('selects by message activity without changing source ordering', () => {
|
|
16
|
+
const sessions = [summary({ sessionId: 'old', lastMessageAt: '2026-09-10T10:00:00Z' }), summary()];
|
|
17
|
+
expect(resolve(sessions)?.sessionKey).toBe('original');
|
|
18
|
+
expect(sessions[0].sessionId).toBe('old');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('excludes other agents, projects, empty, untitled and child sessions', () => {
|
|
22
|
+
expect(resolve([
|
|
23
|
+
summary({ agentId: 'other' }), summary({ messageCount: 0 }),
|
|
24
|
+
summary({ metadata: { project_root: '/other', label: 'Other' } }),
|
|
25
|
+
summary({ metadata: { project_root: '/project' } }),
|
|
26
|
+
summary({ metadata: { project_root: '/project', label: 'Child', parentSessionId: 'parent' } }),
|
|
27
|
+
])).toBeNull();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('uses the default workspace for old sessions without project metadata', () => {
|
|
31
|
+
const sessions = [summary({ metadata: { label: 'Previous discussion' } })];
|
|
32
|
+
expect(resolve(sessions, '/default')?.title).toBe('Previous discussion');
|
|
33
|
+
expect(resolve(sessions)).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('respects a working directory when project metadata is absent', () => {
|
|
37
|
+
expect(resolve([summary({ metadata: { label: 'Working directory' }, workingDir: '/elsewhere' })])).toBeNull();
|
|
38
|
+
expect(resolve([])).toBeNull();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { adaptNcpSessionSummaries } from '@/features/chat/features/session/utils/ncp-session-adapter.utils';
|
|
2
|
+
import type { NcpSessionSummaryView } from '@/shared/lib/api';
|
|
3
|
+
|
|
4
|
+
export type ChatWelcomeContinuation = { sessionKey: string; title: string };
|
|
5
|
+
|
|
6
|
+
export function resolveChatWelcomeContinuation(params: {
|
|
7
|
+
sessions: readonly NcpSessionSummaryView[];
|
|
8
|
+
projectRoot: string | null;
|
|
9
|
+
defaultProjectRoot: string | null;
|
|
10
|
+
agentId: string;
|
|
11
|
+
}): ChatWelcomeContinuation | null {
|
|
12
|
+
const candidates = adaptNcpSessionSummaries([...params.sessions]).filter((session) =>
|
|
13
|
+
!session.isChildSession && session.messageCount > 0 && session.label?.trim() &&
|
|
14
|
+
(session.agentId ?? 'main') === params.agentId &&
|
|
15
|
+
(session.projectRoot ?? session.workingDir ?? params.defaultProjectRoot) === params.projectRoot,
|
|
16
|
+
);
|
|
17
|
+
const activityAt = (session: typeof candidates[number]) =>
|
|
18
|
+
Date.parse(session.lastMessageAt ?? session.updatedAt) || 0;
|
|
19
|
+
const recent = candidates.sort((a, b) => activityAt(b) - activityAt(a))[0];
|
|
20
|
+
return recent ? { sessionKey: recent.key, title: recent.label!.trim() } : null;
|
|
21
|
+
}
|
package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx
CHANGED
|
@@ -359,7 +359,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
359
359
|
|
|
360
360
|
const content = (
|
|
361
361
|
<div
|
|
362
|
-
className="flex h-full min-h-0 flex-col bg-
|
|
362
|
+
className="flex h-full min-h-0 flex-col bg-background"
|
|
363
363
|
onContextMenu={(event) => {
|
|
364
364
|
if (!(event.target as HTMLElement).closest('[data-workspace-tree-entry]')) clearSelection();
|
|
365
365
|
}}
|
package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx
CHANGED
|
@@ -44,11 +44,7 @@ function WorkspaceBreadcrumbSegmentButton({
|
|
|
44
44
|
aria-current={segment.isCurrent ? 'page' : undefined}
|
|
45
45
|
className={cn(
|
|
46
46
|
'inline-flex h-5 shrink-0 items-center gap-1 whitespace-nowrap rounded-sm px-1 text-[11px] leading-none transition-colors hover:bg-[var(--interaction-hover)] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border',
|
|
47
|
-
segment.
|
|
48
|
-
? 'bg-[var(--interaction-selection)] text-foreground hover:bg-[var(--interaction-selection)]'
|
|
49
|
-
: segment.isCurrent
|
|
50
|
-
? 'bg-gray-200/70 text-gray-900'
|
|
51
|
-
: 'text-gray-500',
|
|
47
|
+
segment.isCurrent ? 'font-medium text-foreground' : 'text-muted-foreground',
|
|
52
48
|
)}
|
|
53
49
|
disabled={!segment.browsePath}
|
|
54
50
|
>
|
|
@@ -115,7 +111,7 @@ export function ChatSessionWorkspaceFileBreadcrumbs({
|
|
|
115
111
|
<div
|
|
116
112
|
data-testid="workspace-file-breadcrumbs"
|
|
117
113
|
title={breadcrumb.fullPath}
|
|
118
|
-
className="flex h-
|
|
114
|
+
className="flex h-7 min-w-0 shrink-0 items-center border-b border-border/40 bg-muted text-foreground"
|
|
119
115
|
>
|
|
120
116
|
{leading ? <div className="flex h-full shrink-0 items-center pl-1 pr-0.5">{leading}</div> : null}
|
|
121
117
|
<div
|
|
@@ -128,7 +124,7 @@ export function ChatSessionWorkspaceFileBreadcrumbs({
|
|
|
128
124
|
<Fragment key={segment.key}>
|
|
129
125
|
<WorkspaceBreadcrumbSegmentButton segment={segment} onFileOpen={onFileOpen} />
|
|
130
126
|
{index < breadcrumb.segments.length - 1 ? (
|
|
131
|
-
<ChevronRight className="h-3 w-3 shrink-0 text-
|
|
127
|
+
<ChevronRight className="h-3 w-3 shrink-0 text-muted-foreground/65" />
|
|
132
128
|
) : null}
|
|
133
129
|
</Fragment>
|
|
134
130
|
))}
|
package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx
CHANGED
|
@@ -137,8 +137,8 @@ function WorkspaceFilePreviewStatus({ text, tone = 'muted' }: { text: string; to
|
|
|
137
137
|
return (
|
|
138
138
|
<div
|
|
139
139
|
className={cn(
|
|
140
|
-
'flex h-full items-center justify-center px-6 text-center text-sm',
|
|
141
|
-
tone === 'error' ? 'text-
|
|
140
|
+
'flex h-full items-center justify-center bg-background px-6 text-center text-sm',
|
|
141
|
+
tone === 'error' ? 'text-destructive' : 'text-muted-foreground',
|
|
142
142
|
)}
|
|
143
143
|
>
|
|
144
144
|
{text}
|
|
@@ -260,7 +260,7 @@ function WorkspacePreviewBody({
|
|
|
260
260
|
<div
|
|
261
261
|
ref={markdownScrollRef}
|
|
262
262
|
onScroll={onMarkdownScroll}
|
|
263
|
-
className="h-full overflow-auto custom-scrollbar px-5 py-4"
|
|
263
|
+
className="h-full overflow-auto bg-background text-foreground custom-scrollbar px-5 py-4"
|
|
264
264
|
>
|
|
265
265
|
<ChatMessageMarkdown
|
|
266
266
|
text={previewText}
|
|
@@ -269,6 +269,7 @@ function WorkspacePreviewBody({
|
|
|
269
269
|
copyCodeLabel: t('chatCodeCopy'),
|
|
270
270
|
copiedCodeLabel: t('chatCodeCopied'),
|
|
271
271
|
frontmatterLabel: t('chatMarkdownFrontmatter'),
|
|
272
|
+
detailsLabel: t('chatMarkdownDetails'),
|
|
272
273
|
}}
|
|
273
274
|
onFileOpen={onFileOpen}
|
|
274
275
|
resolveFileContentUrl={(action) => buildServerPathContentUrl(action.path, fileBasePath)}
|
|
@@ -429,7 +430,7 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
429
430
|
);
|
|
430
431
|
|
|
431
432
|
return (
|
|
432
|
-
<div className="flex h-full min-h-0 flex-col bg-
|
|
433
|
+
<div className="flex h-full min-h-0 flex-col bg-background">
|
|
433
434
|
{showBreadcrumbs ? (
|
|
434
435
|
<ChatSessionWorkspaceFileBreadcrumbs
|
|
435
436
|
breadcrumb={breadcrumb}
|