@nextclaw/ui 0.15.3 → 0.15.5
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 +38 -0
- package/dist/assets/abnfDiagram-VRR7QNED-BYpK0F5F.js +1 -0
- package/dist/assets/aiden0z-pptx-renderer.es-D87ywFdC.js +94 -0
- package/dist/assets/api-IlX_CbwU.js +13 -0
- package/dist/assets/app-presenter-provider-Bbl_MVbg.js +106 -0
- package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
- package/dist/assets/appearance-settings-page-80fLa4-9.js +1 -0
- package/dist/assets/arc-DFELHWM2.js +1 -0
- package/dist/assets/architecture-TIHT7OUA-ClwVFq-K.js +1 -0
- package/dist/assets/architectureDiagram-ZJ3FMSHR-CvRhdovL.js +36 -0
- package/dist/assets/array-BqYdCIE6.js +1 -0
- package/dist/assets/blockDiagram-677ZJIJ3-DVYNkbR_.js +132 -0
- package/dist/assets/{book-open-C3mJGwiy.js → book-open-CN7Shpij.js} +1 -1
- package/dist/assets/c4Diagram-LMCZKHZV-B1w-iwRe.js +10 -0
- package/dist/assets/channel-BEHOSFc5.js +1 -0
- package/dist/assets/channels-list-page-R7M6pzp6.js +8 -0
- package/dist/assets/chat-page-152YuwfU.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-DrIhesSX.js +1 -0
- package/dist/assets/chunk-32BRIVSS-kG3lg0bC.js +1 -0
- package/dist/assets/chunk-52WLFC77-BLeB7iGk.js +10 -0
- package/dist/assets/chunk-5FCAYU7R-BQga1Rr7.js +1 -0
- package/dist/assets/chunk-5HE753X5-DU81hkcF.js +1 -0
- package/dist/assets/chunk-5JV3BV7I-C2bAx0m7.js +1 -0
- package/dist/assets/chunk-5TONJI2A-BExIIgWY.js +2 -0
- package/dist/assets/chunk-5VM5RSS4-C3XB05yh.js +15 -0
- package/dist/assets/chunk-7BUUIJ7U-JiyRtrGu.js +1 -0
- package/dist/assets/chunk-BIQX33UG-BZRV20pI.js +1 -0
- package/dist/assets/chunk-C7G6YPKG-AsyDSQ9j.js +1 -0
- package/dist/assets/chunk-CQNSW5MT-iN-fiXVA.js +1 -0
- package/dist/assets/chunk-CYSBUYHQ-DhC_TRzI.js +1 -0
- package/dist/assets/chunk-DseTPa7n.js +1 -0
- package/dist/assets/chunk-EMLP6XTP-QFLK8R6d.js +1 -0
- package/dist/assets/chunk-EX3LRPZG-DzUwhkCz.js +231 -0
- package/dist/assets/chunk-FWX5IMBZ-DFelpZBy.js +2 -0
- package/dist/assets/chunk-HOUHSVGY-BMPwFEwN.js +1 -0
- package/dist/assets/chunk-ICXQ74PX-DH8NJMok.js +2 -0
- package/dist/assets/chunk-JG7HCLWE-D-95AsO4.js +2 -0
- package/dist/assets/chunk-JWPE2WC7-DIaTv8kx.js +1 -0
- package/dist/assets/chunk-KEIR6QF5-A3jEqwzn.js +161 -0
- package/dist/assets/chunk-MOJQB5TN-BPFLzWgj.js +88 -0
- package/dist/assets/chunk-MOZMSUNE-DR_fzxG0.js +1 -0
- package/dist/assets/chunk-OGEWGWER-TIcEoPPH.js +1 -0
- package/dist/assets/chunk-OSBZ3O6U-BALNvSfG.js +1 -0
- package/dist/assets/chunk-PUDLZKDR-I-EXhf_k.js +156 -0
- package/dist/assets/chunk-Q4XR5HBZ-uvIGstBS.js +70 -0
- package/dist/assets/chunk-QBLGF6JB-r-TjLdxa.js +1 -0
- package/dist/assets/chunk-R7FJI6CG-N-1LDgvy.js +1 -0
- package/dist/assets/chunk-RYQCIY6F-jxNASx65.js +1 -0
- package/dist/assets/chunk-U6XO7XAA-Cphbuc7q.js +2 -0
- package/dist/assets/chunk-V7JOEXUC-BLEuBf1s.js +206 -0
- package/dist/assets/chunk-VAUOI2AC-Dpcz6BhT.js +1 -0
- package/dist/assets/chunk-VR4S4FIN-BAUbR0ke.js +1 -0
- package/dist/assets/chunk-WYO6CB5R-Do6SJrnY.js +127 -0
- package/dist/assets/chunk-XXDRQBXY-C2QjjwYX.js +1 -0
- package/dist/assets/chunk-Y2CYZVJY-BGrd8tLy.js +1 -0
- package/dist/assets/chunk-YOTPTUD7-CQqvMTCr.js +1 -0
- package/dist/assets/chunk-ZGVPDNZ5-B7kWWaXv.js +62 -0
- package/dist/assets/chunk-ZIRB5QZD-DTU0cDNh.js +32 -0
- package/dist/assets/classDiagram-OUVF2IWQ-DESMaY3_.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-DwOlByYH.js +1 -0
- package/dist/assets/config-split-page-BlfvfmTm.js +1 -0
- package/dist/assets/confirm-dialog-Dt8Kdbgp.js +5 -0
- package/dist/assets/cose-bilkent-JH36ORCC-B9LrtV-q.js +1 -0
- package/dist/assets/cynefin-VYW2F7L2-CzjeeOq9.js +1 -0
- package/dist/assets/cynefinDiagram-TSTJHNR4-BfjvW4su.js +62 -0
- package/dist/assets/cytoscape.esm-CRW8q92n.js +321 -0
- package/dist/assets/dagre-DkiXZKkL.js +1 -0
- package/dist/assets/dagre-VKFMJZFB-B1pQKQSY.js +4 -0
- package/dist/assets/defaultLocale-Cdv9x6q7.js +1 -0
- package/dist/assets/desktop-update-config-DreMJu9z.js +1 -0
- package/dist/assets/diagram-FQU43EPY-cB4EZdaP.js +3 -0
- package/dist/assets/diagram-G47NLZAW-CtW8im1B.js +24 -0
- package/dist/assets/diagram-NH7WQ7WH-BDCtrCCm.js +24 -0
- package/dist/assets/diagram-OA4YK3LP-DEMJ42Gt.js +30 -0
- package/dist/assets/diagram-WEI45ONY-CdCcxSYU.js +41 -0
- package/dist/assets/dist-D5ycbwCo.js +41 -0
- package/dist/assets/dist-dw-gAfM_.js +1 -0
- package/dist/assets/doc-browser-C9u7N9vH.js +1 -0
- package/dist/assets/doc-browser-DJQ5XPsi2.js +1 -0
- package/dist/assets/doc-browser-context-CCdW9TJf.js +1 -0
- package/dist/assets/docx-preview-zis3U0Fa.js +20 -0
- package/dist/assets/download-CyPgglKr.js +1 -0
- package/dist/assets/ebnfDiagram-CCIWWBDH-DBZETBwE.js +1 -0
- package/dist/assets/erDiagram-Q63AITRT-y2zDXprP.js +85 -0
- package/dist/assets/eventmodeling-45OFAUF4-C38BqG8w.js +1 -0
- package/dist/assets/{external-link-CU0kzzIP.js → external-link-BahW1sl3.js} +1 -1
- package/dist/assets/eye-D8gGXMkD.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-BoKk8RRq.js +1 -0
- package/dist/assets/folder-DGWqFDvE.js +1 -0
- package/dist/assets/{form-actions-BvCp_0lS.js → form-actions-D2imZLnU.js} +1 -1
- package/dist/assets/ganttDiagram-NO4QXBWP-D2DP344e.js +292 -0
- package/dist/assets/gitGraph-TEB2WS4Q-IsQHHJuS.js +1 -0
- package/dist/assets/gitGraphDiagram-IHSO6WYX-D37uiwA2.js +106 -0
- package/dist/assets/graphlib-BcNFQr5y.js +1 -0
- package/dist/assets/index-0av6WO9-.css +1 -0
- package/dist/assets/index-CT0iYlxV.js +2 -0
- package/dist/assets/info-DKCQHKI2-ofy2qlHI.js +1 -0
- package/dist/assets/infoDiagram-FWYZ7A6U-CG-WAIRi.js +2 -0
- package/dist/assets/init-D8TjIqfm.js +1 -0
- package/dist/assets/ishikawaDiagram-FXEZZL3T-WeCTnW0f.js +70 -0
- package/dist/assets/journeyDiagram-5HDEW3XC-DUFBW9Td.js +139 -0
- package/dist/assets/jszip.min-CP5uPNQa.js +2 -0
- package/dist/assets/kanban-definition-HUTT4EX6-B0lxgMpg.js +89 -0
- package/dist/assets/katex-wEmrEFTg.js +257 -0
- package/dist/assets/line-B78frP_c.js +1 -0
- package/dist/assets/linear-C6lVEcb2.js +1 -0
- package/dist/assets/loader-circle-DtKek-qG.js +1 -0
- package/dist/assets/logo-badge-CuPetu-v.js +1 -0
- package/dist/assets/map-Bdri5UL5.js +1 -0
- package/dist/assets/mcp-marketplace-page-4qMwFDpz.js +1 -0
- package/dist/assets/mcp-marketplace-page-BbxN5aZF.js +9 -0
- package/dist/assets/mermaid-parser.core-Cue18vLo.js +4 -0
- package/dist/assets/mermaid.core-CXwWRh5i.js +11 -0
- package/dist/assets/mindmap-definition-LN4V7U3C-CFxz0P0-.js +96 -0
- package/dist/assets/model-config-page-DiJcvBML.js +1 -0
- package/dist/assets/ordinal-Cbd8t4LB.js +1 -0
- package/dist/assets/packet-7NZHBO7P-Rfopfa1o.js +1 -0
- package/dist/assets/path-DzBnMI1r.js +1 -0
- package/dist/assets/pegDiagram-2B236MQR-B_Qt9zyT.js +1 -0
- package/dist/assets/pie-RZYD4A2V-CJR1xKEv.js +1 -0
- package/dist/assets/pieDiagram-ENE6RG2P-CRQdSuwS.js +39 -0
- package/dist/assets/plus-BwgE-Zwf.js +1 -0
- package/dist/assets/popover-Btp7KVc3.js +1 -0
- package/dist/assets/preload-helper-D4M6sveU.js +1 -0
- package/dist/assets/provider-models-BoUhFo9R.js +1 -0
- package/dist/assets/provider-scoped-model-input-DZMtoAJG.js +1 -0
- package/dist/assets/providers-config-page-DfiWveEF.js +1 -0
- package/dist/assets/quadrantDiagram-ABIIQ3AL-D5kPpttq.js +7 -0
- package/dist/assets/radar-I7S5WNFK-CDg8Z-1r.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-BHnNmjxO.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-DGtNcusW.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-BRFtsQmm.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-Bj5IypCA.js +1 -0
- package/dist/assets/railroadDiagram-RFXS5EU6-DGh_TGlQ.js +1 -0
- package/dist/assets/react-BY-U3h3t.js +8 -0
- package/dist/assets/{refresh-cw-CILd1vAP.js → refresh-cw-Cme5qFej.js} +1 -1
- package/dist/assets/remote-BaVECEZw.js +1 -0
- package/dist/assets/requirementDiagram-TGXJPOKE-EmFph0H_.js +84 -0
- package/dist/assets/rotate-cw-CMRZxIkH.js +1 -0
- package/dist/assets/rough.esm-wJ1d3nQl.js +1 -0
- package/dist/assets/runtime-config-page-wygwvMB4.js +1 -0
- package/dist/assets/sankeyDiagram-HTMAVEWB-BXWB5Ugi.js +40 -0
- package/dist/assets/{save-ByJqcPTP.js → save-DNg2yJTS.js} +1 -1
- package/dist/assets/{search-DVIV6pfD.js → search-3ykfrAFt.js} +1 -1
- package/dist/assets/search-config-page-DrVKa_Ls.js +1 -0
- package/dist/assets/secrets-config-page-B39uQ5kF.js +3 -0
- package/dist/assets/security-config-BPzet76z.js +1 -0
- package/dist/assets/select-B5EecXJt.js +1 -0
- package/dist/assets/sequenceDiagram-DBY2YBRQ-ClKnO7v0.js +162 -0
- package/dist/assets/setting-row-Qv1Ps79v.js +1 -0
- package/dist/assets/{settings-2-CH5shGg_.js → settings-2-D-3um9Az.js} +1 -1
- package/dist/assets/sizeCapture-X5ZJPWSS-DSo-t5ou.js +1 -0
- package/dist/assets/{skeleton-DeX1FKw7.js → skeleton-BgkzQd4U.js} +1 -1
- package/dist/assets/src-Dad2ZbCt.js +1 -0
- package/dist/assets/stateDiagram-2N3HPSRC-BvAalBfz.js +1 -0
- package/dist/assets/stateDiagram-v2-6OUMAXLB-CfMU38yc.js +1 -0
- package/dist/assets/swimlanes-5IMT3BWC-DdVqVa1a.js +2 -0
- package/dist/assets/swimlanesDiagram-G3AALYLV-D9Zb9X57.js +8 -0
- package/dist/assets/tabs-BVD8gp3y.js +1 -0
- package/dist/assets/tag-chip-0qn-f3Bo.js +1 -0
- package/dist/assets/timeline-definition-FHXFAJF6-D4ar8IQY.js +120 -0
- package/dist/assets/trash-2-cnsMppRC.js +1 -0
- package/dist/assets/treeView-QDETBFTQ-Uy7M0WvH.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-BJfGV7KX.js +1 -0
- package/dist/assets/use-config-D6yx0lb0.js +1 -0
- package/dist/assets/use-confirm-dialog-C_o0eQeH.js +1 -0
- package/dist/assets/use-viewport-layout-BWav4KCL.js +1 -0
- package/dist/assets/vennDiagram-L72KCM5P-CDXJ_i3p.js +34 -0
- package/dist/assets/wardley-OPB4EBWU-q263iF3K.js +1 -0
- package/dist/assets/wardleyDiagram-EHGQE667-D-dSuT_7.js +78 -0
- package/dist/assets/x-B3o1dWR5.js +1 -0
- package/dist/assets/xlsx-DUqJhg5u.js +64 -0
- package/dist/assets/xychartDiagram-FW5EYKEG-C9JCzsZF.js +7 -0
- package/dist/index.html +35 -28
- package/package.json +11 -6
- package/src/features/chat/components/chat-popover-content.tsx +1 -0
- package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +13 -0
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +21 -11
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +2 -2
- package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +28 -1
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +5 -4
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +9 -18
- package/src/features/chat/components/conversation/chat-conversation-track.tsx +35 -0
- package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +2 -0
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +7 -7
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +3 -14
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +20 -1
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +97 -65
- package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +43 -0
- package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +14 -10
- package/src/features/chat/features/input/utils/__tests__/chat-input-bar.utils.test.ts +51 -0
- package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +61 -21
- package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +42 -10
- package/src/features/chat/features/message/components/chat-inline-file-preview.tsx +80 -0
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +66 -56
- package/src/features/chat/features/message/utils/__tests__/chat-message-file-operation.utils.test.ts +30 -0
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +2 -0
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +37 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +4 -3
- package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +3 -8
- package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +65 -20
- package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +26 -28
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
- package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +424 -129
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +113 -2
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +3 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +197 -44
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +9 -3
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +13 -22
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +96 -194
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +239 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +61 -7
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +34 -8
- package/src/features/chat/features/workspace/components/file-content-preview/use-workspace-file-buffer.ts +42 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-document-preview-state.tsx +18 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.css +89 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.tsx +87 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-presentation-preview.tsx +82 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +180 -0
- package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +191 -0
- package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +1 -4
- package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +157 -13
- package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +151 -2
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +17 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +66 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-viewer.utils.ts +49 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils.ts +13 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +196 -43
- package/src/features/chat/index.ts +1 -0
- package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +101 -0
- package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +48 -60
- package/src/features/chat/managers/chat-session-list.manager.ts +1 -0
- package/src/features/chat/managers/chat-thread.manager.ts +137 -162
- package/src/features/chat/pages/ncp-chat-page.tsx +1 -2
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +87 -1
- package/src/features/chat/stores/chat-message-layout.store.test.ts +37 -0
- package/src/features/chat/stores/chat-message-layout.store.ts +41 -0
- package/src/features/chat/stores/chat-thread.store.ts +77 -40
- package/src/features/chat/types/chat-input-bar.types.ts +2 -0
- package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +25 -8
- package/src/features/settings/pages/appearance-settings-page.tsx +92 -13
- package/src/index.css +36 -2
- package/src/shared/components/__tests__/file-type-icon.test.tsx +61 -0
- package/src/shared/components/common/__tests__/brand-header.test.tsx +17 -7
- package/src/shared/components/common/brand-header.tsx +34 -34
- package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +19 -0
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +16 -0
- package/src/shared/components/doc-browser/doc-browser-context.tsx +1 -0
- package/src/shared/components/doc-browser/doc-browser.tsx +11 -3
- package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +5 -0
- package/src/shared/components/doc-browser/stores/doc-browser.store.ts +6 -1
- package/src/shared/components/doc-browser/types/doc-browser.types.ts +2 -0
- package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +11 -0
- package/src/shared/components/file-type-icon.tsx +272 -0
- package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +22 -0
- package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +17 -2
- package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +38 -0
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +82 -2
- package/src/shared/hooks/use-server-path-read.ts +10 -5
- package/src/shared/lib/api/__tests__/server-path.utils.test.ts +28 -0
- package/src/shared/lib/api/types.ts +3 -3
- package/src/shared/lib/api/utils/server-path.utils.ts +20 -20
- package/src/shared/lib/i18n/locales/en-US/chat.json +25 -1
- package/src/shared/lib/i18n/locales/en-US/core.json +6 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +25 -1
- package/src/shared/lib/i18n/locales/zh-CN/core.json +6 -0
- package/src/shared/lib/session-project/__tests__/workspace-file-breadcrumb.test.ts +1 -4
- package/src/shared/lib/session-project/workspace-file-breadcrumb.utils.ts +1 -18
- package/dist/assets/api-iNBpppzj.js +0 -13
- package/dist/assets/appearance-settings-page-DMffQFR3.js +0 -1
- package/dist/assets/channels-list-page-CCtp0BRS.js +0 -8
- package/dist/assets/chat-page-H5a0dWvO.js +0 -1
- package/dist/assets/config-split-page-CrOJgB-Y.js +0 -1
- package/dist/assets/confirm-dialog-Chv50USy.js +0 -5
- package/dist/assets/desktop-update-config-KzTuXRf_.js +0 -1
- package/dist/assets/dist-BunzmC4B.js +0 -1
- package/dist/assets/dist-ChmGwvtK.js +0 -1
- package/dist/assets/doc-browser-DNRL4Zvd.js +0 -1
- package/dist/assets/doc-browser-Dg0pmkOg.js +0 -1
- package/dist/assets/doc-browser-context-BHY-0FSD.js +0 -1
- package/dist/assets/es2015-DQZ5JWwK.js +0 -41
- package/dist/assets/i18n-provider-Cu8XyZb_.js +0 -1
- package/dist/assets/index-CzfBdvK1.css +0 -1
- package/dist/assets/index-DGqHne1Q.js +0 -104
- package/dist/assets/loader-circle-CDSFuzmk.js +0 -1
- package/dist/assets/mcp-marketplace-page-BeEQK0DL.js +0 -9
- package/dist/assets/mcp-marketplace-page-D6idOTLp.js +0 -1
- package/dist/assets/model-config-page-bNNo-XyG.js +0 -1
- package/dist/assets/plus-D4DsdLN-.js +0 -1
- package/dist/assets/provider-scoped-model-input-IlgQCsoT.js +0 -1
- package/dist/assets/providers-config-page-wLo6CAJw.js +0 -1
- package/dist/assets/react-BPIsQIlO.js +0 -8
- package/dist/assets/remote-uKEYp7AR.js +0 -1
- package/dist/assets/rotate-cw-wPFPg1kH.js +0 -1
- package/dist/assets/runtime-config-page-DDn1sP4G.js +0 -1
- package/dist/assets/search-config-page-B-Cf4iiB.js +0 -1
- package/dist/assets/secrets-config-page-DPKsY8Iw.js +0 -3
- package/dist/assets/security-config-e9SSBlKr.js +0 -1
- package/dist/assets/select-BdgczSNw.js +0 -1
- package/dist/assets/setting-row-BkTVUTKx.js +0 -1
- package/dist/assets/side-dock-BsBvcJ9i.js +0 -3
- package/dist/assets/switch-Cv8Ekb3x.js +0 -1
- package/dist/assets/tag-chip-RB9uKcoC.js +0 -1
- package/dist/assets/tooltip-oQlEN-l6.js +0 -1
- package/dist/assets/use-config-l3W7y8Qz.js +0 -1
- package/dist/assets/use-confirm-dialog-BAxaVOJI.js +0 -1
- package/dist/assets/x-BBMffEN0.js +0 -1
- package/src/features/chat/components/layout/__tests__/chat-sidebar-utility-menu.test.tsx +0 -55
- /package/dist/assets/{config-hints-C_iP1zl_.js → config-hints-LxG80Uj5.js} +0 -0
- /package/dist/assets/{host-capabilities-9bB_998Z.js → host-capabilities-CFbAfrrA.js} +0 -0
- /package/dist/assets/{middleware-BILWbJE4.js → middleware-CAXxl-af.js} +0 -0
package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx
CHANGED
|
@@ -19,6 +19,7 @@ const captures = vi.hoisted(() => ({
|
|
|
19
19
|
openFilePreview: vi.fn(),
|
|
20
20
|
handleToolAction: vi.fn(),
|
|
21
21
|
showContent: vi.fn(),
|
|
22
|
+
filePreviewProps: [] as Array<{ showBreadcrumbs?: boolean }>,
|
|
22
23
|
}));
|
|
23
24
|
|
|
24
25
|
vi.mock("@nextclaw/agent-chat-ui", async (importOriginal) => {
|
|
@@ -61,12 +62,25 @@ vi.mock("@/shared/lib/i18n", () => ({
|
|
|
61
62
|
t: (key: string) => key,
|
|
62
63
|
}));
|
|
63
64
|
|
|
65
|
+
vi.mock(
|
|
66
|
+
"@/features/chat/features/workspace/components/chat-session-workspace-file-preview",
|
|
67
|
+
() => ({
|
|
68
|
+
ChatSessionWorkspaceFilePreview: (props: {
|
|
69
|
+
showBreadcrumbs?: boolean;
|
|
70
|
+
}) => {
|
|
71
|
+
captures.filePreviewProps.push(props);
|
|
72
|
+
return <div data-testid="inline-workspace-file-preview" />;
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
76
|
+
|
|
64
77
|
beforeEach(() => {
|
|
65
78
|
captures.renders = [];
|
|
66
79
|
captures.language = "en";
|
|
67
80
|
captures.openFilePreview.mockReset();
|
|
68
81
|
captures.handleToolAction.mockReset();
|
|
69
82
|
captures.showContent.mockReset();
|
|
83
|
+
captures.filePreviewProps = [];
|
|
70
84
|
});
|
|
71
85
|
|
|
72
86
|
it("reuses adapted message references when the source message object is unchanged", () => {
|
|
@@ -484,22 +498,40 @@ it("passes the inline panel app renderer to the shared chat UI", () => {
|
|
|
484
498
|
expect(captures.renders[captures.renders.length - 1]?.renderPanelAppCard).toEqual(expect.any(Function));
|
|
485
499
|
});
|
|
486
500
|
|
|
487
|
-
it("
|
|
501
|
+
it("renders inline file displays through the workspace file preview", () => {
|
|
488
502
|
render(<ChatMessageListContainer messages={[]} isSending={false} />);
|
|
489
503
|
|
|
490
504
|
const renderInlineDisplay =
|
|
491
505
|
captures.renders[captures.renders.length - 1]?.renderInlineDisplay;
|
|
492
506
|
|
|
493
507
|
expect(renderInlineDisplay).toEqual(expect.any(Function));
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
508
|
+
const rendered = renderInlineDisplay?.({
|
|
509
|
+
target: {
|
|
510
|
+
type: "file",
|
|
511
|
+
payload: { path: "preview.html", viewer: "rendered" },
|
|
512
|
+
},
|
|
513
|
+
title: "Preview",
|
|
514
|
+
description: "Rendered HTML",
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
if (!isValidElement<{ display?: unknown }>(rendered)) {
|
|
518
|
+
throw new Error("Expected inline file renderer to return a React element");
|
|
519
|
+
}
|
|
520
|
+
expect(rendered.props.display).toEqual({
|
|
521
|
+
target: {
|
|
522
|
+
type: "file",
|
|
523
|
+
payload: { path: "preview.html", viewer: "rendered" },
|
|
524
|
+
},
|
|
525
|
+
title: "Preview",
|
|
526
|
+
description: "Rendered HTML",
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
render(rendered);
|
|
530
|
+
|
|
531
|
+
expect(screen.getByText("Preview")).toBeTruthy();
|
|
532
|
+
expect(screen.getByText("preview.html")).toBeTruthy();
|
|
533
|
+
expect(screen.queryByText("Rendered HTML")).toBeNull();
|
|
534
|
+
expect(captures.filePreviewProps.at(-1)?.showBreadcrumbs).toBe(false);
|
|
503
535
|
});
|
|
504
536
|
|
|
505
537
|
it("keeps inline panel app displays expandable from the card header", () => {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ChatFileOpenActionViewModel,
|
|
3
|
+
ChatInlineDisplayViewModel,
|
|
4
|
+
} from "@nextclaw/agent-chat-ui";
|
|
5
|
+
import { FileText } from "lucide-react";
|
|
6
|
+
import { ChatSessionWorkspaceFilePreview } from "@/features/chat/features/workspace/components/chat-session-workspace-file-preview";
|
|
7
|
+
import { createWorkspaceFileTab } from "@/features/chat/features/workspace/utils/chat-workspace-file-tab.utils";
|
|
8
|
+
|
|
9
|
+
type ChatInlineFilePreviewProps = {
|
|
10
|
+
display: ChatInlineDisplayViewModel;
|
|
11
|
+
parentSessionKey: string | null;
|
|
12
|
+
sessionProjectRoot: string | null;
|
|
13
|
+
sessionWorkingDir: string | null;
|
|
14
|
+
onFileOpen: (action: ChatFileOpenActionViewModel) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function readFileName(path: string): string {
|
|
18
|
+
return path.split(/[\\/]/).filter(Boolean).pop() ?? path;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function ChatInlineFilePreview({
|
|
22
|
+
display,
|
|
23
|
+
parentSessionKey,
|
|
24
|
+
sessionProjectRoot,
|
|
25
|
+
sessionWorkingDir,
|
|
26
|
+
onFileOpen,
|
|
27
|
+
}: ChatInlineFilePreviewProps) {
|
|
28
|
+
if (display.target.type !== "file") {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const { path, line, column, viewer } = display.target.payload;
|
|
32
|
+
const file = createWorkspaceFileTab(
|
|
33
|
+
{
|
|
34
|
+
path,
|
|
35
|
+
label: display.title,
|
|
36
|
+
viewMode: "preview",
|
|
37
|
+
previewViewer: viewer,
|
|
38
|
+
line,
|
|
39
|
+
column,
|
|
40
|
+
},
|
|
41
|
+
parentSessionKey,
|
|
42
|
+
);
|
|
43
|
+
if (!file) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const title = display.title ?? readFileName(file.path);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<section
|
|
50
|
+
className="my-2 w-full max-w-[48rem] overflow-hidden rounded-lg border border-border bg-card shadow-sm"
|
|
51
|
+
data-chat-inline-file-preview="true"
|
|
52
|
+
data-chat-message-wide-content="true"
|
|
53
|
+
>
|
|
54
|
+
<header className="border-b border-border bg-muted/45 px-3 py-2">
|
|
55
|
+
<div className="flex min-w-0 items-center gap-2 text-xs font-medium text-foreground">
|
|
56
|
+
<FileText
|
|
57
|
+
className="h-3.5 w-3.5 shrink-0 text-muted-foreground"
|
|
58
|
+
aria-hidden
|
|
59
|
+
/>
|
|
60
|
+
<span className="truncate">{title}</span>
|
|
61
|
+
</div>
|
|
62
|
+
<p
|
|
63
|
+
className="mt-1 truncate font-mono text-[11px] font-normal text-muted-foreground"
|
|
64
|
+
title={file.path}
|
|
65
|
+
>
|
|
66
|
+
{file.path}
|
|
67
|
+
</p>
|
|
68
|
+
</header>
|
|
69
|
+
<div className="h-[420px] min-h-[240px] max-h-[min(60vh,420px)] overflow-hidden">
|
|
70
|
+
<ChatSessionWorkspaceFilePreview
|
|
71
|
+
file={file}
|
|
72
|
+
sessionProjectRoot={sessionProjectRoot}
|
|
73
|
+
sessionWorkingDir={sessionWorkingDir}
|
|
74
|
+
showBreadcrumbs={false}
|
|
75
|
+
onFileOpen={onFileOpen}
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
</section>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -4,13 +4,11 @@ import {
|
|
|
4
4
|
type ChatInlineDisplayViewModel,
|
|
5
5
|
type ChatInlineTokenViewModel,
|
|
6
6
|
type ChatMessageViewModel,
|
|
7
|
+
type ChatPanelAppCardViewModel,
|
|
7
8
|
ChatMessageList,
|
|
8
9
|
} from "@nextclaw/agent-chat-ui";
|
|
9
10
|
import { usePresenter } from "@/features/chat/components/providers/chat-presenter.provider";
|
|
10
|
-
import {
|
|
11
|
-
adaptChatMessage,
|
|
12
|
-
type ChatMessageSource,
|
|
13
|
-
} from "@/features/chat/features/message/utils/chat-message.utils";
|
|
11
|
+
import { adaptChatMessage, type ChatMessageSource } from "@/features/chat/features/message/utils/chat-message.utils";
|
|
14
12
|
import { buildChatMessageProcessSummary } from "@/features/chat/features/message/utils/chat-message-process-summary.utils";
|
|
15
13
|
import {
|
|
16
14
|
buildChatMessageAdapterTexts,
|
|
@@ -23,9 +21,14 @@ import {
|
|
|
23
21
|
type ContextCompactionTimelineView,
|
|
24
22
|
} from "@/features/chat/features/session/utils/ncp-session-context-metadata.utils";
|
|
25
23
|
import { AgentIdentityAvatar } from "@/shared/components/common/agent-identity";
|
|
24
|
+
import { ChatInlineFilePreview } from "@/features/chat/features/message/components/chat-inline-file-preview";
|
|
26
25
|
import { ChatInlinePanelAppCard } from "@/features/chat/features/message/components/chat-inline-panel-app-card";
|
|
27
26
|
import { useChatQueryStore } from "@/features/chat/stores/ncp-chat-query.store";
|
|
27
|
+
import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
|
|
28
|
+
import { useChatMessageLayoutStore } from "@/features/chat/stores/chat-message-layout.store";
|
|
29
|
+
import { useNcpChatSelectedSession } from "@/features/chat/features/ncp/hooks/use-ncp-chat-derived-state";
|
|
28
30
|
import { useI18n } from "@/app/components/i18n-provider";
|
|
31
|
+
import { buildServerPathContentUrl } from "@/shared/lib/api";
|
|
29
32
|
import { formatDateTime, t } from "@/shared/lib/i18n";
|
|
30
33
|
|
|
31
34
|
type ChatMessageListContainerProps = {
|
|
@@ -59,6 +62,9 @@ function renderChatInlineDisplay(display: ChatInlineDisplayViewModel) {
|
|
|
59
62
|
);
|
|
60
63
|
}
|
|
61
64
|
|
|
65
|
+
const renderChatToolAgent = (agentId: string) => <AgentIdentityAvatar agentId={agentId} className="h-4 w-4 shrink-0" />;
|
|
66
|
+
const renderChatPanelAppCard = (panelApp: ChatPanelAppCardViewModel) => <ChatInlinePanelAppCard panelApp={panelApp} />;
|
|
67
|
+
|
|
62
68
|
type ContextInheritanceTimelineView = {
|
|
63
69
|
sourceSessionId: string;
|
|
64
70
|
inheritedMessageCount: number;
|
|
@@ -85,11 +91,7 @@ type ChatTimelineItem =
|
|
|
85
91
|
inheritance: ContextInheritanceTimelineView;
|
|
86
92
|
};
|
|
87
93
|
|
|
88
|
-
function ChatContextCompactionDivider({
|
|
89
|
-
checkpoint,
|
|
90
|
-
}: {
|
|
91
|
-
checkpoint: ContextCompactionTimelineView;
|
|
92
|
-
}) {
|
|
94
|
+
function ChatContextCompactionDivider({ checkpoint }: { checkpoint: ContextCompactionTimelineView }) {
|
|
93
95
|
const title = [
|
|
94
96
|
`${t("chatContextCompactionCoveredMessages")}: ${checkpoint.coveredSessionMessageCount}`,
|
|
95
97
|
`${t("chatContextCompactionOriginalTokens")}: ${checkpoint.originalEstimatedTokens}`,
|
|
@@ -115,11 +117,7 @@ function ChatContextCompactionDivider({
|
|
|
115
117
|
);
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
function ChatContextInheritanceDivider({
|
|
119
|
-
inheritance,
|
|
120
|
-
}: {
|
|
121
|
-
inheritance: ContextInheritanceTimelineView;
|
|
122
|
-
}) {
|
|
120
|
+
function ChatContextInheritanceDivider({ inheritance }: { inheritance: ContextInheritanceTimelineView }) {
|
|
123
121
|
const title = [
|
|
124
122
|
`${t("chatContextInheritanceSourceSession")}: ${inheritance.sourceSessionId}`,
|
|
125
123
|
`${t("chatContextInheritanceMessages")}: ${inheritance.inheritedMessageCount}`,
|
|
@@ -141,20 +139,12 @@ function resolveCompactionBoundaryIndex(params: {
|
|
|
141
139
|
visibleRawMessages: readonly NcpMessage[];
|
|
142
140
|
rawMessageId: string;
|
|
143
141
|
}): number {
|
|
144
|
-
const {
|
|
145
|
-
|
|
146
|
-
rawMessages,
|
|
147
|
-
visibleRawMessages,
|
|
148
|
-
} = params;
|
|
149
|
-
const physicalIndex = rawMessages.findIndex(
|
|
150
|
-
(message) => message.id === rawMessageId,
|
|
151
|
-
);
|
|
142
|
+
const { rawMessageId, rawMessages, visibleRawMessages } = params;
|
|
143
|
+
const physicalIndex = rawMessages.findIndex((message) => message.id === rawMessageId);
|
|
152
144
|
if (physicalIndex < 0) {
|
|
153
145
|
return visibleRawMessages.length - 1;
|
|
154
146
|
}
|
|
155
|
-
const previousVisibleCount = rawMessages
|
|
156
|
-
.slice(0, physicalIndex)
|
|
157
|
-
.filter(isVisibleChatMessage).length;
|
|
147
|
+
const previousVisibleCount = rawMessages.slice(0, physicalIndex).filter(isVisibleChatMessage).length;
|
|
158
148
|
return previousVisibleCount - 1;
|
|
159
149
|
}
|
|
160
150
|
|
|
@@ -167,9 +157,7 @@ function isVisibleChatMessage(message: NcpMessage): boolean {
|
|
|
167
157
|
return !readContextCompactionTimeline(message) && !readInheritedSourceSessionId(message);
|
|
168
158
|
}
|
|
169
159
|
|
|
170
|
-
function resolveContextInheritanceBoundary(
|
|
171
|
-
messages: readonly NcpMessage[],
|
|
172
|
-
): ContextInheritanceTimelineBoundary | null {
|
|
160
|
+
function resolveContextInheritanceBoundary(messages: readonly NcpMessage[]): ContextInheritanceTimelineBoundary | null {
|
|
173
161
|
const boundaryIndex = messages.findIndex((message) => readInheritedSourceSessionId(message));
|
|
174
162
|
if (boundaryIndex < 0) {
|
|
175
163
|
return null;
|
|
@@ -181,7 +169,8 @@ function resolveContextInheritanceBoundary(
|
|
|
181
169
|
return {
|
|
182
170
|
boundaryIndex: messages.slice(0, boundaryIndex).filter(isVisibleChatMessage).length,
|
|
183
171
|
sourceSessionId,
|
|
184
|
-
inheritedMessageCount: messages.filter((message) => readInheritedSourceSessionId(message) === sourceSessionId)
|
|
172
|
+
inheritedMessageCount: messages.filter((message) => readInheritedSourceSessionId(message) === sourceSessionId)
|
|
173
|
+
.length,
|
|
185
174
|
};
|
|
186
175
|
}
|
|
187
176
|
|
|
@@ -196,8 +185,12 @@ function buildTimelineItems(params: {
|
|
|
196
185
|
checkpoint: readContextCompactionTimeline(message),
|
|
197
186
|
}))
|
|
198
187
|
.filter(
|
|
199
|
-
(
|
|
200
|
-
|
|
188
|
+
(
|
|
189
|
+
entry,
|
|
190
|
+
): entry is {
|
|
191
|
+
rawMessageId: string;
|
|
192
|
+
checkpoint: ContextCompactionTimelineView;
|
|
193
|
+
} => Boolean(entry.checkpoint),
|
|
201
194
|
)
|
|
202
195
|
.map((entry) => ({
|
|
203
196
|
key: entry.rawMessageId,
|
|
@@ -286,10 +279,36 @@ export function ChatMessageListContainer({
|
|
|
286
279
|
}: ChatMessageListContainerProps) {
|
|
287
280
|
const presenter = usePresenter();
|
|
288
281
|
const { language } = useI18n();
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
282
|
+
const messageLayout = useChatMessageLayoutStore((state) => state.layout);
|
|
283
|
+
const selectedSessionKey = useChatSessionListStore((state) => state.snapshot.selectedSessionKey);
|
|
284
|
+
const selectedSession = useNcpChatSelectedSession(selectedSessionKey);
|
|
285
|
+
const localFileBasePath = selectedSession?.workingDir ?? selectedSession?.projectRoot ?? null;
|
|
286
|
+
const renderInlineDisplayWithFiles = useCallback(
|
|
287
|
+
(display: ChatInlineDisplayViewModel) => {
|
|
288
|
+
const panelAppDisplay = renderChatInlineDisplay(display);
|
|
289
|
+
if (panelAppDisplay) {
|
|
290
|
+
return panelAppDisplay;
|
|
291
|
+
}
|
|
292
|
+
if (display.target.type === "file") {
|
|
293
|
+
return (
|
|
294
|
+
<ChatInlineFilePreview
|
|
295
|
+
display={display}
|
|
296
|
+
parentSessionKey={selectedSessionKey}
|
|
297
|
+
sessionProjectRoot={selectedSession?.projectRoot ?? null}
|
|
298
|
+
sessionWorkingDir={localFileBasePath}
|
|
299
|
+
onFileOpen={presenter.chatThreadManager.openFilePreview}
|
|
300
|
+
/>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
return undefined;
|
|
304
|
+
},
|
|
305
|
+
[localFileBasePath, presenter.chatThreadManager, selectedSession?.projectRoot, selectedSessionKey],
|
|
306
|
+
);
|
|
307
|
+
const resolveFileContentUrl = useCallback(
|
|
308
|
+
(action: { path: string }) => buildServerPathContentUrl(action.path, localFileBasePath),
|
|
309
|
+
[localFileBasePath],
|
|
292
310
|
);
|
|
311
|
+
const texts = useMemo(() => buildChatMessageAdapterTexts(language), [language]);
|
|
293
312
|
|
|
294
313
|
const messages = useMemo(() => {
|
|
295
314
|
const visibleRawMessages = rawMessages.filter(isVisibleChatMessage);
|
|
@@ -322,7 +341,11 @@ export function ChatMessageListContainer({
|
|
|
322
341
|
texts,
|
|
323
342
|
});
|
|
324
343
|
|
|
325
|
-
messageViewModelCache.set(message, {
|
|
344
|
+
messageViewModelCache.set(message, {
|
|
345
|
+
language,
|
|
346
|
+
processSummaryLabel,
|
|
347
|
+
viewModel,
|
|
348
|
+
});
|
|
326
349
|
return [viewModel];
|
|
327
350
|
});
|
|
328
351
|
}, [language, rawMessages, texts]);
|
|
@@ -330,20 +353,12 @@ export function ChatMessageListContainer({
|
|
|
330
353
|
const hasAssistantDraft = useMemo(
|
|
331
354
|
() =>
|
|
332
355
|
messages.some(
|
|
333
|
-
(message) =>
|
|
334
|
-
message.role === "assistant" &&
|
|
335
|
-
(message.status === "streaming" || message.status === "pending"),
|
|
356
|
+
(message) => message.role === "assistant" && (message.status === "streaming" || message.status === "pending"),
|
|
336
357
|
),
|
|
337
358
|
[messages],
|
|
338
359
|
);
|
|
339
|
-
const messageTexts = useMemo(
|
|
340
|
-
|
|
341
|
-
[language],
|
|
342
|
-
);
|
|
343
|
-
const timelineItems = useMemo(
|
|
344
|
-
() => buildTimelineItems({ rawMessages, messages }),
|
|
345
|
-
[messages, rawMessages],
|
|
346
|
-
);
|
|
360
|
+
const messageTexts = useMemo(() => buildChatMessageTexts(language), [language]);
|
|
361
|
+
const timelineItems = useMemo(() => buildTimelineItems({ rawMessages, messages }), [messages, rawMessages]);
|
|
347
362
|
const sessionSkillsQuery = useChatQueryStore((state) => state.snapshot.sessionSkillsQuery);
|
|
348
363
|
const handleInlineTokenClick = useCallback(
|
|
349
364
|
(token: ChatInlineTokenViewModel) => {
|
|
@@ -396,6 +411,7 @@ export function ChatMessageListContainer({
|
|
|
396
411
|
) : (
|
|
397
412
|
<ChatMessageList
|
|
398
413
|
key={item.key}
|
|
414
|
+
layout={messageLayout}
|
|
399
415
|
messages={item.messages}
|
|
400
416
|
isSending={index === timelineItems.length - 1 ? isSending : false}
|
|
401
417
|
hasAssistantDraft={hasAssistantDraft}
|
|
@@ -404,16 +420,10 @@ export function ChatMessageListContainer({
|
|
|
404
420
|
onFileOpen={presenter.chatThreadManager.openFilePreview}
|
|
405
421
|
onAttachmentOpen={handleAttachmentOpen}
|
|
406
422
|
onInlineTokenClick={handleInlineTokenClick}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
className="h-4 w-4 shrink-0"
|
|
412
|
-
/>
|
|
413
|
-
)}
|
|
414
|
-
renderPanelAppCard={(panelApp) => (
|
|
415
|
-
<ChatInlinePanelAppCard panelApp={panelApp} />
|
|
416
|
-
)}
|
|
423
|
+
resolveFileContentUrl={resolveFileContentUrl}
|
|
424
|
+
renderInlineDisplay={renderInlineDisplayWithFiles}
|
|
425
|
+
renderToolAgent={renderChatToolAgent}
|
|
426
|
+
renderPanelAppCard={renderChatPanelAppCard}
|
|
417
427
|
/>
|
|
418
428
|
),
|
|
419
429
|
)}
|
package/src/features/chat/features/message/utils/__tests__/chat-message-file-operation.utils.test.ts
CHANGED
|
@@ -63,6 +63,36 @@ it("builds edit-file previews from structured args before the tool finishes", ()
|
|
|
63
63
|
expect(editLines[1]).not.toHaveProperty("newLineNumber");
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
it("keeps incomplete edit-file arguments available before preview fields arrive", () => {
|
|
67
|
+
const partialArgs = '{"path":"src/app.ts","oldText":';
|
|
68
|
+
const adapted = adapt([
|
|
69
|
+
{
|
|
70
|
+
id: "assistant-partial-edit-input",
|
|
71
|
+
role: "assistant",
|
|
72
|
+
parts: [
|
|
73
|
+
{
|
|
74
|
+
type: "tool-invocation",
|
|
75
|
+
toolInvocation: {
|
|
76
|
+
status: ToolInvocationStatus.PARTIAL_CALL,
|
|
77
|
+
toolCallId: "edit-partial-1",
|
|
78
|
+
toolName: "edit_file",
|
|
79
|
+
args: partialArgs,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
] as unknown as ChatMessageSource[]);
|
|
85
|
+
|
|
86
|
+
expect(adapted[0]?.parts[0]).toMatchObject({
|
|
87
|
+
type: "tool-card",
|
|
88
|
+
card: {
|
|
89
|
+
toolName: "edit_file",
|
|
90
|
+
input: partialArgs,
|
|
91
|
+
statusTone: "running",
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
66
96
|
it("uses structured edit-file result line numbers after the tool finishes", () => {
|
|
67
97
|
const adapted = adapt([
|
|
68
98
|
{
|
|
@@ -106,6 +106,8 @@ export function buildChatMessageTexts(
|
|
|
106
106
|
copiedCodeLabel: t("chatCodeCopied"),
|
|
107
107
|
copyMessageLabel: t("chatMessageCopy"),
|
|
108
108
|
copiedMessageLabel: t("chatMessageCopied"),
|
|
109
|
+
mermaidDiagramLabel: t("chatMermaidDiagram"),
|
|
110
|
+
mermaidRenderErrorLabel: t("chatMermaidRenderError"),
|
|
109
111
|
typingLabel: t("chatTyping"),
|
|
110
112
|
reasoningCharacterCountTemplates: {
|
|
111
113
|
inProgress: t("chatReasoningInProgressCharacterCount"),
|
package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { expect, it, vi } from 'vitest';
|
|
3
|
+
import { ChatSidebarSessionItem } from '@/features/chat/features/session/components/chat-sidebar-session-item';
|
|
4
|
+
|
|
5
|
+
it('shows session actions only on hover or when an action owns focus', () => {
|
|
6
|
+
render(
|
|
7
|
+
<ChatSidebarSessionItem
|
|
8
|
+
sessionKey="session:current"
|
|
9
|
+
active
|
|
10
|
+
showUnreadDot={false}
|
|
11
|
+
context={{ icon: null, label: null }}
|
|
12
|
+
isPinned={false}
|
|
13
|
+
title="Current Task"
|
|
14
|
+
previewText="Preview"
|
|
15
|
+
trailingText="Now"
|
|
16
|
+
isEditing={false}
|
|
17
|
+
draftLabel="Current Task"
|
|
18
|
+
isSaving={false}
|
|
19
|
+
onSelect={vi.fn()}
|
|
20
|
+
onStartEditing={vi.fn()}
|
|
21
|
+
onDraftLabelChange={vi.fn()}
|
|
22
|
+
onSave={vi.fn()}
|
|
23
|
+
onCancel={vi.fn()}
|
|
24
|
+
onTogglePinned={vi.fn()}
|
|
25
|
+
/>,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
screen.getByText('Current Task').closest('button')?.focus();
|
|
29
|
+
const actions = screen.getByLabelText('Pin session').parentElement;
|
|
30
|
+
|
|
31
|
+
expect(actions?.className).toContain('opacity-0');
|
|
32
|
+
expect(actions?.className).toContain('group-hover/session:opacity-100');
|
|
33
|
+
expect(actions?.className).toContain('focus-within:opacity-100');
|
|
34
|
+
expect(actions?.className).not.toContain(
|
|
35
|
+
'group-focus-within/session:opacity-100',
|
|
36
|
+
);
|
|
37
|
+
});
|
|
@@ -2,7 +2,8 @@ import { useMemo, useState, type ReactNode } from 'react';
|
|
|
2
2
|
import { ChevronDown, ChevronRight, Folder, Pin, Plus } from 'lucide-react';
|
|
3
3
|
import { usePresenter } from '@/features/chat/components/providers/chat-presenter.provider';
|
|
4
4
|
import { ChatSessionTypeMenu } from "@/features/chat/features/session-type/components/chat-session-type-menu";
|
|
5
|
-
import { Popover,
|
|
5
|
+
import { Popover, PopoverTrigger } from '@/shared/components/ui/popover';
|
|
6
|
+
import { ChatPopoverContent } from '@/features/chat/components/chat-popover-content';
|
|
6
7
|
import { IconActionButton } from '@/shared/components/ui/actions/icon-action-button';
|
|
7
8
|
import type { ChatSessionTypeOption } from "@/features/chat/features/session-type/utils/chat-session-type.utils";
|
|
8
9
|
import type { NcpSessionListItemView } from '@/features/chat/features/ncp/hooks/use-ncp-session-list-view';
|
|
@@ -107,7 +108,7 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
|
|
|
107
108
|
label={actionLabel}
|
|
108
109
|
/>
|
|
109
110
|
</PopoverTrigger>
|
|
110
|
-
<
|
|
111
|
+
<ChatPopoverContent
|
|
111
112
|
align="end"
|
|
112
113
|
className="w-56 rounded-2xl border border-border bg-popover p-1.5 text-popover-foreground shadow-[0_24px_60px_-28px_rgba(15,23,42,0.38)]"
|
|
113
114
|
>
|
|
@@ -122,7 +123,7 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
|
|
|
122
123
|
setOpenProjectRoot(null);
|
|
123
124
|
}}
|
|
124
125
|
/>
|
|
125
|
-
</
|
|
126
|
+
</ChatPopoverContent>
|
|
126
127
|
</Popover>
|
|
127
128
|
) : (
|
|
128
129
|
<IconActionButton
|
|
@@ -169,12 +169,7 @@ function ChatSidebarSessionDisplayView({
|
|
|
169
169
|
event.stopPropagation();
|
|
170
170
|
onOpenChildSessions();
|
|
171
171
|
}}
|
|
172
|
-
className=
|
|
173
|
-
'absolute right-12 top-0 inline-flex h-6 items-center gap-1 rounded-md px-1.5 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-black/10 hover:text-foreground',
|
|
174
|
-
active
|
|
175
|
-
? 'opacity-100'
|
|
176
|
-
: 'opacity-0 group-hover/session:opacity-100 group-focus-within/session:opacity-100'
|
|
177
|
-
)}
|
|
172
|
+
className="pointer-events-none absolute right-12 top-0 inline-flex h-6 items-center gap-1 rounded-md px-1.5 text-[10px] font-medium text-muted-foreground opacity-0 transition-colors hover:bg-black/10 hover:text-foreground group-hover/session:pointer-events-auto group-hover/session:opacity-100 focus-visible:pointer-events-auto focus-visible:opacity-100"
|
|
178
173
|
aria-label={t('chatSessionOpenChildSessions')}
|
|
179
174
|
title={t('chatSessionOpenChildSessions')}
|
|
180
175
|
>
|
|
@@ -183,11 +178,11 @@ function ChatSidebarSessionDisplayView({
|
|
|
183
178
|
</button>
|
|
184
179
|
) : null}
|
|
185
180
|
{runStatus ? (
|
|
186
|
-
<span className="absolute right-0 top-0 inline-flex h-6 w-6 items-center justify-center transition-opacity group-hover/session:opacity-0
|
|
181
|
+
<span className="absolute right-0 top-0 inline-flex h-6 w-6 items-center justify-center transition-opacity group-hover/session:opacity-0">
|
|
187
182
|
<SessionRunBadge status={runStatus} />
|
|
188
183
|
</span>
|
|
189
184
|
) : null}
|
|
190
|
-
<div className="absolute right-0 top-0 flex h-6 items-center gap-0.5 opacity-0 transition-opacity group-hover/session:opacity-100
|
|
185
|
+
<div className="pointer-events-none absolute right-0 top-0 flex h-6 items-center gap-0.5 opacity-0 transition-opacity group-hover/session:pointer-events-auto group-hover/session:opacity-100 focus-within:pointer-events-auto focus-within:opacity-100">
|
|
191
186
|
<IconActionButton
|
|
192
187
|
size="sm"
|
|
193
188
|
tone="strong"
|