@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.
Files changed (314) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/assets/abnfDiagram-VRR7QNED-BYpK0F5F.js +1 -0
  3. package/dist/assets/aiden0z-pptx-renderer.es-D87ywFdC.js +94 -0
  4. package/dist/assets/api-IlX_CbwU.js +13 -0
  5. package/dist/assets/app-presenter-provider-Bbl_MVbg.js +106 -0
  6. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
  7. package/dist/assets/appearance-settings-page-80fLa4-9.js +1 -0
  8. package/dist/assets/arc-DFELHWM2.js +1 -0
  9. package/dist/assets/architecture-TIHT7OUA-ClwVFq-K.js +1 -0
  10. package/dist/assets/architectureDiagram-ZJ3FMSHR-CvRhdovL.js +36 -0
  11. package/dist/assets/array-BqYdCIE6.js +1 -0
  12. package/dist/assets/blockDiagram-677ZJIJ3-DVYNkbR_.js +132 -0
  13. package/dist/assets/{book-open-C3mJGwiy.js → book-open-CN7Shpij.js} +1 -1
  14. package/dist/assets/c4Diagram-LMCZKHZV-B1w-iwRe.js +10 -0
  15. package/dist/assets/channel-BEHOSFc5.js +1 -0
  16. package/dist/assets/channels-list-page-R7M6pzp6.js +8 -0
  17. package/dist/assets/chat-page-152YuwfU.js +1 -0
  18. package/dist/assets/chunk-2Q5K7J3B-DrIhesSX.js +1 -0
  19. package/dist/assets/chunk-32BRIVSS-kG3lg0bC.js +1 -0
  20. package/dist/assets/chunk-52WLFC77-BLeB7iGk.js +10 -0
  21. package/dist/assets/chunk-5FCAYU7R-BQga1Rr7.js +1 -0
  22. package/dist/assets/chunk-5HE753X5-DU81hkcF.js +1 -0
  23. package/dist/assets/chunk-5JV3BV7I-C2bAx0m7.js +1 -0
  24. package/dist/assets/chunk-5TONJI2A-BExIIgWY.js +2 -0
  25. package/dist/assets/chunk-5VM5RSS4-C3XB05yh.js +15 -0
  26. package/dist/assets/chunk-7BUUIJ7U-JiyRtrGu.js +1 -0
  27. package/dist/assets/chunk-BIQX33UG-BZRV20pI.js +1 -0
  28. package/dist/assets/chunk-C7G6YPKG-AsyDSQ9j.js +1 -0
  29. package/dist/assets/chunk-CQNSW5MT-iN-fiXVA.js +1 -0
  30. package/dist/assets/chunk-CYSBUYHQ-DhC_TRzI.js +1 -0
  31. package/dist/assets/chunk-DseTPa7n.js +1 -0
  32. package/dist/assets/chunk-EMLP6XTP-QFLK8R6d.js +1 -0
  33. package/dist/assets/chunk-EX3LRPZG-DzUwhkCz.js +231 -0
  34. package/dist/assets/chunk-FWX5IMBZ-DFelpZBy.js +2 -0
  35. package/dist/assets/chunk-HOUHSVGY-BMPwFEwN.js +1 -0
  36. package/dist/assets/chunk-ICXQ74PX-DH8NJMok.js +2 -0
  37. package/dist/assets/chunk-JG7HCLWE-D-95AsO4.js +2 -0
  38. package/dist/assets/chunk-JWPE2WC7-DIaTv8kx.js +1 -0
  39. package/dist/assets/chunk-KEIR6QF5-A3jEqwzn.js +161 -0
  40. package/dist/assets/chunk-MOJQB5TN-BPFLzWgj.js +88 -0
  41. package/dist/assets/chunk-MOZMSUNE-DR_fzxG0.js +1 -0
  42. package/dist/assets/chunk-OGEWGWER-TIcEoPPH.js +1 -0
  43. package/dist/assets/chunk-OSBZ3O6U-BALNvSfG.js +1 -0
  44. package/dist/assets/chunk-PUDLZKDR-I-EXhf_k.js +156 -0
  45. package/dist/assets/chunk-Q4XR5HBZ-uvIGstBS.js +70 -0
  46. package/dist/assets/chunk-QBLGF6JB-r-TjLdxa.js +1 -0
  47. package/dist/assets/chunk-R7FJI6CG-N-1LDgvy.js +1 -0
  48. package/dist/assets/chunk-RYQCIY6F-jxNASx65.js +1 -0
  49. package/dist/assets/chunk-U6XO7XAA-Cphbuc7q.js +2 -0
  50. package/dist/assets/chunk-V7JOEXUC-BLEuBf1s.js +206 -0
  51. package/dist/assets/chunk-VAUOI2AC-Dpcz6BhT.js +1 -0
  52. package/dist/assets/chunk-VR4S4FIN-BAUbR0ke.js +1 -0
  53. package/dist/assets/chunk-WYO6CB5R-Do6SJrnY.js +127 -0
  54. package/dist/assets/chunk-XXDRQBXY-C2QjjwYX.js +1 -0
  55. package/dist/assets/chunk-Y2CYZVJY-BGrd8tLy.js +1 -0
  56. package/dist/assets/chunk-YOTPTUD7-CQqvMTCr.js +1 -0
  57. package/dist/assets/chunk-ZGVPDNZ5-B7kWWaXv.js +62 -0
  58. package/dist/assets/chunk-ZIRB5QZD-DTU0cDNh.js +32 -0
  59. package/dist/assets/classDiagram-OUVF2IWQ-DESMaY3_.js +1 -0
  60. package/dist/assets/classDiagram-v2-EOCWNBFH-DwOlByYH.js +1 -0
  61. package/dist/assets/config-split-page-BlfvfmTm.js +1 -0
  62. package/dist/assets/confirm-dialog-Dt8Kdbgp.js +5 -0
  63. package/dist/assets/cose-bilkent-JH36ORCC-B9LrtV-q.js +1 -0
  64. package/dist/assets/cynefin-VYW2F7L2-CzjeeOq9.js +1 -0
  65. package/dist/assets/cynefinDiagram-TSTJHNR4-BfjvW4su.js +62 -0
  66. package/dist/assets/cytoscape.esm-CRW8q92n.js +321 -0
  67. package/dist/assets/dagre-DkiXZKkL.js +1 -0
  68. package/dist/assets/dagre-VKFMJZFB-B1pQKQSY.js +4 -0
  69. package/dist/assets/defaultLocale-Cdv9x6q7.js +1 -0
  70. package/dist/assets/desktop-update-config-DreMJu9z.js +1 -0
  71. package/dist/assets/diagram-FQU43EPY-cB4EZdaP.js +3 -0
  72. package/dist/assets/diagram-G47NLZAW-CtW8im1B.js +24 -0
  73. package/dist/assets/diagram-NH7WQ7WH-BDCtrCCm.js +24 -0
  74. package/dist/assets/diagram-OA4YK3LP-DEMJ42Gt.js +30 -0
  75. package/dist/assets/diagram-WEI45ONY-CdCcxSYU.js +41 -0
  76. package/dist/assets/dist-D5ycbwCo.js +41 -0
  77. package/dist/assets/dist-dw-gAfM_.js +1 -0
  78. package/dist/assets/doc-browser-C9u7N9vH.js +1 -0
  79. package/dist/assets/doc-browser-DJQ5XPsi2.js +1 -0
  80. package/dist/assets/doc-browser-context-CCdW9TJf.js +1 -0
  81. package/dist/assets/docx-preview-zis3U0Fa.js +20 -0
  82. package/dist/assets/download-CyPgglKr.js +1 -0
  83. package/dist/assets/ebnfDiagram-CCIWWBDH-DBZETBwE.js +1 -0
  84. package/dist/assets/erDiagram-Q63AITRT-y2zDXprP.js +85 -0
  85. package/dist/assets/eventmodeling-45OFAUF4-C38BqG8w.js +1 -0
  86. package/dist/assets/{external-link-CU0kzzIP.js → external-link-BahW1sl3.js} +1 -1
  87. package/dist/assets/eye-D8gGXMkD.js +1 -0
  88. package/dist/assets/flowDiagram-23GEKE2U-BoKk8RRq.js +1 -0
  89. package/dist/assets/folder-DGWqFDvE.js +1 -0
  90. package/dist/assets/{form-actions-BvCp_0lS.js → form-actions-D2imZLnU.js} +1 -1
  91. package/dist/assets/ganttDiagram-NO4QXBWP-D2DP344e.js +292 -0
  92. package/dist/assets/gitGraph-TEB2WS4Q-IsQHHJuS.js +1 -0
  93. package/dist/assets/gitGraphDiagram-IHSO6WYX-D37uiwA2.js +106 -0
  94. package/dist/assets/graphlib-BcNFQr5y.js +1 -0
  95. package/dist/assets/index-0av6WO9-.css +1 -0
  96. package/dist/assets/index-CT0iYlxV.js +2 -0
  97. package/dist/assets/info-DKCQHKI2-ofy2qlHI.js +1 -0
  98. package/dist/assets/infoDiagram-FWYZ7A6U-CG-WAIRi.js +2 -0
  99. package/dist/assets/init-D8TjIqfm.js +1 -0
  100. package/dist/assets/ishikawaDiagram-FXEZZL3T-WeCTnW0f.js +70 -0
  101. package/dist/assets/journeyDiagram-5HDEW3XC-DUFBW9Td.js +139 -0
  102. package/dist/assets/jszip.min-CP5uPNQa.js +2 -0
  103. package/dist/assets/kanban-definition-HUTT4EX6-B0lxgMpg.js +89 -0
  104. package/dist/assets/katex-wEmrEFTg.js +257 -0
  105. package/dist/assets/line-B78frP_c.js +1 -0
  106. package/dist/assets/linear-C6lVEcb2.js +1 -0
  107. package/dist/assets/loader-circle-DtKek-qG.js +1 -0
  108. package/dist/assets/logo-badge-CuPetu-v.js +1 -0
  109. package/dist/assets/map-Bdri5UL5.js +1 -0
  110. package/dist/assets/mcp-marketplace-page-4qMwFDpz.js +1 -0
  111. package/dist/assets/mcp-marketplace-page-BbxN5aZF.js +9 -0
  112. package/dist/assets/mermaid-parser.core-Cue18vLo.js +4 -0
  113. package/dist/assets/mermaid.core-CXwWRh5i.js +11 -0
  114. package/dist/assets/mindmap-definition-LN4V7U3C-CFxz0P0-.js +96 -0
  115. package/dist/assets/model-config-page-DiJcvBML.js +1 -0
  116. package/dist/assets/ordinal-Cbd8t4LB.js +1 -0
  117. package/dist/assets/packet-7NZHBO7P-Rfopfa1o.js +1 -0
  118. package/dist/assets/path-DzBnMI1r.js +1 -0
  119. package/dist/assets/pegDiagram-2B236MQR-B_Qt9zyT.js +1 -0
  120. package/dist/assets/pie-RZYD4A2V-CJR1xKEv.js +1 -0
  121. package/dist/assets/pieDiagram-ENE6RG2P-CRQdSuwS.js +39 -0
  122. package/dist/assets/plus-BwgE-Zwf.js +1 -0
  123. package/dist/assets/popover-Btp7KVc3.js +1 -0
  124. package/dist/assets/preload-helper-D4M6sveU.js +1 -0
  125. package/dist/assets/provider-models-BoUhFo9R.js +1 -0
  126. package/dist/assets/provider-scoped-model-input-DZMtoAJG.js +1 -0
  127. package/dist/assets/providers-config-page-DfiWveEF.js +1 -0
  128. package/dist/assets/quadrantDiagram-ABIIQ3AL-D5kPpttq.js +7 -0
  129. package/dist/assets/radar-I7S5WNFK-CDg8Z-1r.js +1 -0
  130. package/dist/assets/railroad-3IZDKUUU-BHnNmjxO.js +1 -0
  131. package/dist/assets/railroad-abnf-AHOZXSZD-DGtNcusW.js +1 -0
  132. package/dist/assets/railroad-ebnf-EBAXGLYW-BRFtsQmm.js +1 -0
  133. package/dist/assets/railroad-peg-LSFZ7HO6-Bj5IypCA.js +1 -0
  134. package/dist/assets/railroadDiagram-RFXS5EU6-DGh_TGlQ.js +1 -0
  135. package/dist/assets/react-BY-U3h3t.js +8 -0
  136. package/dist/assets/{refresh-cw-CILd1vAP.js → refresh-cw-Cme5qFej.js} +1 -1
  137. package/dist/assets/remote-BaVECEZw.js +1 -0
  138. package/dist/assets/requirementDiagram-TGXJPOKE-EmFph0H_.js +84 -0
  139. package/dist/assets/rotate-cw-CMRZxIkH.js +1 -0
  140. package/dist/assets/rough.esm-wJ1d3nQl.js +1 -0
  141. package/dist/assets/runtime-config-page-wygwvMB4.js +1 -0
  142. package/dist/assets/sankeyDiagram-HTMAVEWB-BXWB5Ugi.js +40 -0
  143. package/dist/assets/{save-ByJqcPTP.js → save-DNg2yJTS.js} +1 -1
  144. package/dist/assets/{search-DVIV6pfD.js → search-3ykfrAFt.js} +1 -1
  145. package/dist/assets/search-config-page-DrVKa_Ls.js +1 -0
  146. package/dist/assets/secrets-config-page-B39uQ5kF.js +3 -0
  147. package/dist/assets/security-config-BPzet76z.js +1 -0
  148. package/dist/assets/select-B5EecXJt.js +1 -0
  149. package/dist/assets/sequenceDiagram-DBY2YBRQ-ClKnO7v0.js +162 -0
  150. package/dist/assets/setting-row-Qv1Ps79v.js +1 -0
  151. package/dist/assets/{settings-2-CH5shGg_.js → settings-2-D-3um9Az.js} +1 -1
  152. package/dist/assets/sizeCapture-X5ZJPWSS-DSo-t5ou.js +1 -0
  153. package/dist/assets/{skeleton-DeX1FKw7.js → skeleton-BgkzQd4U.js} +1 -1
  154. package/dist/assets/src-Dad2ZbCt.js +1 -0
  155. package/dist/assets/stateDiagram-2N3HPSRC-BvAalBfz.js +1 -0
  156. package/dist/assets/stateDiagram-v2-6OUMAXLB-CfMU38yc.js +1 -0
  157. package/dist/assets/swimlanes-5IMT3BWC-DdVqVa1a.js +2 -0
  158. package/dist/assets/swimlanesDiagram-G3AALYLV-D9Zb9X57.js +8 -0
  159. package/dist/assets/tabs-BVD8gp3y.js +1 -0
  160. package/dist/assets/tag-chip-0qn-f3Bo.js +1 -0
  161. package/dist/assets/timeline-definition-FHXFAJF6-D4ar8IQY.js +120 -0
  162. package/dist/assets/trash-2-cnsMppRC.js +1 -0
  163. package/dist/assets/treeView-QDETBFTQ-Uy7M0WvH.js +1 -0
  164. package/dist/assets/treemap-6X3UGDF4-BJfGV7KX.js +1 -0
  165. package/dist/assets/use-config-D6yx0lb0.js +1 -0
  166. package/dist/assets/use-confirm-dialog-C_o0eQeH.js +1 -0
  167. package/dist/assets/use-viewport-layout-BWav4KCL.js +1 -0
  168. package/dist/assets/vennDiagram-L72KCM5P-CDXJ_i3p.js +34 -0
  169. package/dist/assets/wardley-OPB4EBWU-q263iF3K.js +1 -0
  170. package/dist/assets/wardleyDiagram-EHGQE667-D-dSuT_7.js +78 -0
  171. package/dist/assets/x-B3o1dWR5.js +1 -0
  172. package/dist/assets/xlsx-DUqJhg5u.js +64 -0
  173. package/dist/assets/xychartDiagram-FW5EYKEG-C9JCzsZF.js +7 -0
  174. package/dist/index.html +35 -28
  175. package/package.json +11 -6
  176. package/src/features/chat/components/chat-popover-content.tsx +1 -0
  177. package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +13 -0
  178. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +21 -11
  179. package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +2 -2
  180. package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +28 -1
  181. package/src/features/chat/components/conversation/chat-conversation-content.tsx +5 -4
  182. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +9 -18
  183. package/src/features/chat/components/conversation/chat-conversation-track.tsx +35 -0
  184. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +2 -0
  185. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +7 -7
  186. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +3 -14
  187. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +20 -1
  188. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +97 -65
  189. package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +43 -0
  190. package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +14 -10
  191. package/src/features/chat/features/input/utils/__tests__/chat-input-bar.utils.test.ts +51 -0
  192. package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +61 -21
  193. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +42 -10
  194. package/src/features/chat/features/message/components/chat-inline-file-preview.tsx +80 -0
  195. package/src/features/chat/features/message/components/chat-message-list.container.tsx +66 -56
  196. package/src/features/chat/features/message/utils/__tests__/chat-message-file-operation.utils.test.ts +30 -0
  197. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +2 -0
  198. package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +37 -0
  199. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +4 -3
  200. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +3 -8
  201. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +65 -20
  202. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +26 -28
  203. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
  204. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +3 -3
  205. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +3 -3
  206. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
  207. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +424 -129
  208. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +113 -2
  209. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +3 -1
  210. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +197 -44
  211. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +9 -3
  212. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +13 -22
  213. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +96 -194
  214. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +239 -1
  215. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +61 -7
  216. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +34 -8
  217. package/src/features/chat/features/workspace/components/file-content-preview/use-workspace-file-buffer.ts +42 -0
  218. package/src/features/chat/features/workspace/components/file-content-preview/workspace-document-preview-state.tsx +18 -0
  219. package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.css +89 -0
  220. package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.tsx +87 -0
  221. package/src/features/chat/features/workspace/components/file-content-preview/workspace-presentation-preview.tsx +82 -0
  222. package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +180 -0
  223. package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +191 -0
  224. package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +1 -4
  225. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +157 -13
  226. package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +151 -2
  227. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +17 -0
  228. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +66 -0
  229. package/src/features/chat/features/workspace/utils/chat-workspace-file-viewer.utils.ts +49 -0
  230. package/src/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils.ts +13 -0
  231. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +196 -43
  232. package/src/features/chat/index.ts +1 -0
  233. package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +101 -0
  234. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +48 -60
  235. package/src/features/chat/managers/chat-session-list.manager.ts +1 -0
  236. package/src/features/chat/managers/chat-thread.manager.ts +137 -162
  237. package/src/features/chat/pages/ncp-chat-page.tsx +1 -2
  238. package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +87 -1
  239. package/src/features/chat/stores/chat-message-layout.store.test.ts +37 -0
  240. package/src/features/chat/stores/chat-message-layout.store.ts +41 -0
  241. package/src/features/chat/stores/chat-thread.store.ts +77 -40
  242. package/src/features/chat/types/chat-input-bar.types.ts +2 -0
  243. package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +25 -8
  244. package/src/features/settings/pages/appearance-settings-page.tsx +92 -13
  245. package/src/index.css +36 -2
  246. package/src/shared/components/__tests__/file-type-icon.test.tsx +61 -0
  247. package/src/shared/components/common/__tests__/brand-header.test.tsx +17 -7
  248. package/src/shared/components/common/brand-header.tsx +34 -34
  249. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +19 -0
  250. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +16 -0
  251. package/src/shared/components/doc-browser/doc-browser-context.tsx +1 -0
  252. package/src/shared/components/doc-browser/doc-browser.tsx +11 -3
  253. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +5 -0
  254. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +6 -1
  255. package/src/shared/components/doc-browser/types/doc-browser.types.ts +2 -0
  256. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +11 -0
  257. package/src/shared/components/file-type-icon.tsx +272 -0
  258. package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +22 -0
  259. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +17 -2
  260. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +38 -0
  261. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +82 -2
  262. package/src/shared/hooks/use-server-path-read.ts +10 -5
  263. package/src/shared/lib/api/__tests__/server-path.utils.test.ts +28 -0
  264. package/src/shared/lib/api/types.ts +3 -3
  265. package/src/shared/lib/api/utils/server-path.utils.ts +20 -20
  266. package/src/shared/lib/i18n/locales/en-US/chat.json +25 -1
  267. package/src/shared/lib/i18n/locales/en-US/core.json +6 -0
  268. package/src/shared/lib/i18n/locales/zh-CN/chat.json +25 -1
  269. package/src/shared/lib/i18n/locales/zh-CN/core.json +6 -0
  270. package/src/shared/lib/session-project/__tests__/workspace-file-breadcrumb.test.ts +1 -4
  271. package/src/shared/lib/session-project/workspace-file-breadcrumb.utils.ts +1 -18
  272. package/dist/assets/api-iNBpppzj.js +0 -13
  273. package/dist/assets/appearance-settings-page-DMffQFR3.js +0 -1
  274. package/dist/assets/channels-list-page-CCtp0BRS.js +0 -8
  275. package/dist/assets/chat-page-H5a0dWvO.js +0 -1
  276. package/dist/assets/config-split-page-CrOJgB-Y.js +0 -1
  277. package/dist/assets/confirm-dialog-Chv50USy.js +0 -5
  278. package/dist/assets/desktop-update-config-KzTuXRf_.js +0 -1
  279. package/dist/assets/dist-BunzmC4B.js +0 -1
  280. package/dist/assets/dist-ChmGwvtK.js +0 -1
  281. package/dist/assets/doc-browser-DNRL4Zvd.js +0 -1
  282. package/dist/assets/doc-browser-Dg0pmkOg.js +0 -1
  283. package/dist/assets/doc-browser-context-BHY-0FSD.js +0 -1
  284. package/dist/assets/es2015-DQZ5JWwK.js +0 -41
  285. package/dist/assets/i18n-provider-Cu8XyZb_.js +0 -1
  286. package/dist/assets/index-CzfBdvK1.css +0 -1
  287. package/dist/assets/index-DGqHne1Q.js +0 -104
  288. package/dist/assets/loader-circle-CDSFuzmk.js +0 -1
  289. package/dist/assets/mcp-marketplace-page-BeEQK0DL.js +0 -9
  290. package/dist/assets/mcp-marketplace-page-D6idOTLp.js +0 -1
  291. package/dist/assets/model-config-page-bNNo-XyG.js +0 -1
  292. package/dist/assets/plus-D4DsdLN-.js +0 -1
  293. package/dist/assets/provider-scoped-model-input-IlgQCsoT.js +0 -1
  294. package/dist/assets/providers-config-page-wLo6CAJw.js +0 -1
  295. package/dist/assets/react-BPIsQIlO.js +0 -8
  296. package/dist/assets/remote-uKEYp7AR.js +0 -1
  297. package/dist/assets/rotate-cw-wPFPg1kH.js +0 -1
  298. package/dist/assets/runtime-config-page-DDn1sP4G.js +0 -1
  299. package/dist/assets/search-config-page-B-Cf4iiB.js +0 -1
  300. package/dist/assets/secrets-config-page-DPKsY8Iw.js +0 -3
  301. package/dist/assets/security-config-e9SSBlKr.js +0 -1
  302. package/dist/assets/select-BdgczSNw.js +0 -1
  303. package/dist/assets/setting-row-BkTVUTKx.js +0 -1
  304. package/dist/assets/side-dock-BsBvcJ9i.js +0 -3
  305. package/dist/assets/switch-Cv8Ekb3x.js +0 -1
  306. package/dist/assets/tag-chip-RB9uKcoC.js +0 -1
  307. package/dist/assets/tooltip-oQlEN-l6.js +0 -1
  308. package/dist/assets/use-config-l3W7y8Qz.js +0 -1
  309. package/dist/assets/use-confirm-dialog-BAxaVOJI.js +0 -1
  310. package/dist/assets/x-BBMffEN0.js +0 -1
  311. package/src/features/chat/components/layout/__tests__/chat-sidebar-utility-menu.test.tsx +0 -55
  312. /package/dist/assets/{config-hints-C_iP1zl_.js → config-hints-LxG80Uj5.js} +0 -0
  313. /package/dist/assets/{host-capabilities-9bB_998Z.js → host-capabilities-CFbAfrrA.js} +0 -0
  314. /package/dist/assets/{middleware-BILWbJE4.js → middleware-CAXxl-af.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { fireEvent, render, screen } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
2
3
  import { afterEach, describe, expect, it, vi } from "vitest";
3
4
  import {
4
5
  CompactTabStrip,
@@ -126,4 +127,41 @@ describe("CompactTabStrip", () => {
126
127
  expect(onClose).toHaveBeenCalledTimes(1);
127
128
  expect(onSelect).not.toHaveBeenCalled();
128
129
  });
130
+
131
+ it("opens a tab action menu without selecting the tab or restoring stale focus after an action", async () => {
132
+ const user = userEvent.setup();
133
+ const onAction = vi.fn();
134
+ const onSelect = vi.fn();
135
+
136
+ render(
137
+ <CompactTabStrip
138
+ tabs={[
139
+ {
140
+ key: "source-tab",
141
+ label: "index.html",
142
+ active: true,
143
+ menuLabel: "File actions",
144
+ menuActions: [
145
+ {
146
+ key: "preview",
147
+ icon: <span />,
148
+ label: "Open preview",
149
+ onClick: onAction,
150
+ },
151
+ ],
152
+ onSelect,
153
+ },
154
+ ]}
155
+ actions={[]}
156
+ />,
157
+ );
158
+
159
+ const menuTrigger = screen.getByRole("button", { name: "File actions" });
160
+ await user.click(menuTrigger);
161
+ await user.click(screen.getByRole("menuitem", { name: "Open preview" }));
162
+
163
+ expect(onAction).toHaveBeenCalledTimes(1);
164
+ expect(onSelect).not.toHaveBeenCalled();
165
+ expect(document.activeElement).not.toBe(menuTrigger);
166
+ });
129
167
  });
@@ -1,6 +1,11 @@
1
1
  import * as React from "react";
2
- import { X } from "lucide-react";
2
+ import { MoreVertical, X } from "lucide-react";
3
3
  import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
4
+ import {
5
+ Popover,
6
+ PopoverContent,
7
+ PopoverTrigger,
8
+ } from "@/shared/components/ui/popover";
4
9
  import {
5
10
  Tooltip,
6
11
  TooltipContent,
@@ -15,10 +20,13 @@ export type CompactTabStripTab = {
15
20
  active: boolean;
16
21
  tooltip?: string | null;
17
22
  leadingIcon?: React.ReactNode;
23
+ labelClassName?: string;
18
24
  badge?: React.ReactNode;
19
25
  unreadIndicator?: React.ReactNode;
20
26
  closeLabel?: string;
21
27
  closePlacement?: "leading-hover" | "trailing";
28
+ menuLabel?: string;
29
+ menuActions?: readonly CompactTabStripAction[];
22
30
  onSelect: () => void;
23
31
  onClose?: () => void;
24
32
  };
@@ -55,6 +63,77 @@ function closeCompactTab(event: React.MouseEvent<HTMLButtonElement>, onClose: ()
55
63
  onClose();
56
64
  }
57
65
 
66
+ function CompactTabMenu({ tab }: { tab: CompactTabStripTab }) {
67
+ const [open, setOpen] = React.useState(false);
68
+ const restoreTriggerFocus = React.useRef(true);
69
+ if (!tab.menuActions?.length) {
70
+ return null;
71
+ }
72
+
73
+ const menuLabel = tab.menuLabel ?? tab.label;
74
+ return (
75
+ <Popover
76
+ open={open}
77
+ onOpenChange={(nextOpen) => {
78
+ if (nextOpen) {
79
+ restoreTriggerFocus.current = true;
80
+ }
81
+ setOpen(nextOpen);
82
+ }}
83
+ >
84
+ <div
85
+ className={cn(
86
+ "-ml-1.5 flex w-0 shrink-0 overflow-hidden opacity-0 transition-[width,margin,opacity] group-hover:ml-0 group-hover:w-5 group-hover:opacity-100 group-focus-within:ml-0 group-focus-within:w-5 group-focus-within:opacity-100",
87
+ open ? "ml-0 w-5 opacity-100" : null,
88
+ )}
89
+ >
90
+ <PopoverTrigger asChild>
91
+ <button
92
+ type="button"
93
+ aria-label={menuLabel}
94
+ onClick={(event) => event.stopPropagation()}
95
+ className="inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-700 focus-visible:bg-gray-200 focus-visible:text-gray-700 focus-visible:outline-none"
96
+ >
97
+ <MoreVertical className="h-3.5 w-3.5" />
98
+ </button>
99
+ </PopoverTrigger>
100
+ </div>
101
+ <PopoverContent
102
+ align="end"
103
+ className="w-40 rounded-xl p-1.5"
104
+ onClick={(event) => event.stopPropagation()}
105
+ onCloseAutoFocus={(event) => {
106
+ if (!restoreTriggerFocus.current) {
107
+ event.preventDefault();
108
+ }
109
+ }}
110
+ >
111
+ <div role="menu" aria-label={menuLabel}>
112
+ {tab.menuActions.map((action) => (
113
+ <button
114
+ key={action.key}
115
+ type="button"
116
+ role="menuitem"
117
+ disabled={action.disabled}
118
+ className="flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-xs text-gray-700 transition-colors hover:bg-gray-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:cursor-not-allowed disabled:opacity-45"
119
+ onClick={() => {
120
+ restoreTriggerFocus.current = false;
121
+ setOpen(false);
122
+ action.onClick();
123
+ }}
124
+ >
125
+ <span className="inline-flex h-4 w-4 shrink-0 items-center justify-center">
126
+ {action.icon}
127
+ </span>
128
+ <span>{action.label}</span>
129
+ </button>
130
+ ))}
131
+ </div>
132
+ </PopoverContent>
133
+ </Popover>
134
+ );
135
+ }
136
+
58
137
  function CompactTabLabelButton({
59
138
  labelClassName,
60
139
  tab,
@@ -77,7 +156,7 @@ function CompactTabLabelButton({
77
156
  {leadingIcon}
78
157
  </span>
79
158
  ) : null}
80
- <span className={cn("min-w-0 truncate text-[12px] font-medium", labelClassName)}>
159
+ <span className={cn("min-w-0 truncate text-[12px] font-medium", labelClassName, tab.labelClassName)}>
81
160
  {tab.label}
82
161
  </span>
83
162
  {tab.badge}
@@ -145,6 +224,7 @@ function CompactTabItem({
145
224
  </button>
146
225
  ) : null}
147
226
  <CompactTabLabelButton tab={tab} labelClassName={labelClassName} />
227
+ <CompactTabMenu tab={tab} />
148
228
  {tab.onClose && tab.closePlacement !== "leading-hover" ? (
149
229
  <IconActionButton
150
230
  size="sm"
@@ -4,27 +4,32 @@ import { fetchServerPathRead } from '@/shared/lib/api';
4
4
  export function buildServerPathReadQueryKey(params: {
5
5
  path?: string | null;
6
6
  basePath?: string | null;
7
+ line?: number | null;
7
8
  }) {
8
- return ['server-path-read', params.path?.trim() ?? '', params.basePath ?? null] as const;
9
+ return ['server-path-read', params.path?.trim() ?? '', params.basePath ?? null, params.line ?? null] as const;
9
10
  }
10
11
 
11
12
  export function useServerPathRead(params: {
12
13
  path?: string | null;
13
14
  basePath?: string | null;
15
+ line?: number | null;
14
16
  enabled?: boolean;
15
17
  }) {
16
- const normalizedPath = params.path?.trim() ?? '';
18
+ const { basePath, enabled = true, line, path } = params;
19
+ const normalizedPath = path?.trim() ?? '';
17
20
  return useQuery({
18
21
  queryKey: buildServerPathReadQueryKey({
19
22
  path: normalizedPath,
20
- basePath: params.basePath,
23
+ basePath,
24
+ line,
21
25
  }),
22
26
  queryFn: () =>
23
27
  fetchServerPathRead({
24
28
  path: normalizedPath,
25
- basePath: params.basePath,
29
+ basePath,
30
+ line,
26
31
  }),
27
- enabled: (params.enabled ?? true) && normalizedPath.length > 0,
32
+ enabled: enabled && normalizedPath.length > 0,
28
33
  staleTime: 0,
29
34
  });
30
35
  }
@@ -0,0 +1,28 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildServerPathContentUrl } from "@/shared/lib/api/utils/server-path.utils";
3
+
4
+ describe("buildServerPathContentUrl", () => {
5
+ it("uses the query content route for absolute files", () => {
6
+ expect(buildServerPathContentUrl("/tmp/logo.svg")).toContain(
7
+ "/api/server-paths/content?path=%2Ftmp%2Flogo.svg",
8
+ );
9
+ });
10
+
11
+ it("uses the same query content route for Windows files", () => {
12
+ expect(buildServerPathContentUrl("C:\\Users\\me\\logo.svg")).toContain(
13
+ "path=C%3A%5CUsers%5Cme%5Clogo.svg",
14
+ );
15
+ });
16
+
17
+ it("builds a base-path content URL for relative Markdown images", () => {
18
+ const url = buildServerPathContentUrl("assets/logo.svg", "/tmp/project");
19
+
20
+ expect(url).toContain("/api/server-paths/content?");
21
+ expect(url).toContain("path=assets%2Flogo.svg");
22
+ expect(url).toContain("basePath=%2Ftmp%2Fproject");
23
+ });
24
+
25
+ it("rejects relative content paths when no base path is available", () => {
26
+ expect(buildServerPathContentUrl("assets/logo.svg", null)).toBeNull();
27
+ });
28
+ });
@@ -316,8 +316,8 @@ export type SessionSkillEntryView = {
316
316
  ref: string;
317
317
  name: string;
318
318
  path: string;
319
- scope: 'builtin' | 'project' | 'workspace';
320
- source: 'builtin' | 'project' | 'workspace';
319
+ scope: 'builtin' | 'global' | 'project' | 'workspace';
320
+ source: 'builtin' | 'global' | 'project' | 'workspace';
321
321
  available: boolean;
322
322
  description?: string;
323
323
  descriptionZh?: string;
@@ -367,7 +367,7 @@ export type ServerPathBrowseView = {
367
367
  entries: ServerPathEntryView[];
368
368
  };
369
369
 
370
- export type ServerPathReadView = { requestedPath: string; resolvedPath: string; kind: "text" | "markdown" | "binary"; sizeBytes: number; truncated: boolean; text?: string; languageHint?: string | null };
370
+ export type ServerPathReadView = { requestedPath: string; resolvedPath: string; kind: "text" | "markdown" | "binary"; sizeBytes: number; startLine?: number; truncated: boolean; text?: string; languageHint?: string | null };
371
371
 
372
372
  export type PanelAppEntryView = {
373
373
  id: string;
@@ -3,17 +3,6 @@ import { nextclawClient } from '@/shared/lib/api/managers/client.manager';
3
3
  import type { ServerPathBrowseView, ServerPathReadView } from '@/shared/lib/api/types';
4
4
 
5
5
  const SERVER_PATH_CONTENT_BASE_PATH = '/api/server-paths/content';
6
- const SERVER_PATH_CONTENT_ABSOLUTE_SCOPE = '__abs__';
7
- const SERVER_PATH_CONTENT_WINDOWS_SCOPE = '__win__';
8
-
9
- function encodeServerPathSegments(path: string): string {
10
- return path
11
- .replace(/\\/g, '/')
12
- .split('/')
13
- .filter(Boolean)
14
- .map((segment) => encodeURIComponent(segment))
15
- .join('/');
16
- }
17
6
 
18
7
  export async function fetchServerPathBrowse(params?: {
19
8
  path?: string | null;
@@ -26,18 +15,29 @@ export async function fetchServerPathBrowse(params?: {
26
15
  export async function fetchServerPathRead(params: {
27
16
  path: string;
28
17
  basePath?: string | null;
18
+ line?: number | null;
29
19
  }): Promise<ServerPathReadView> {
30
20
  return await nextclawClient.serverPaths.read(params);
31
21
  }
32
22
 
33
- export function buildServerPathContentUrl(resolvedPath: string): string {
34
- const normalizedPath = resolvedPath.trim();
35
- if (/^[a-z]:[\\/]/i.test(normalizedPath)) {
36
- const [drive, ...segments] = normalizedPath.replace(/\\/g, '/').split('/');
37
- return `${API_BASE}${SERVER_PATH_CONTENT_BASE_PATH}/${SERVER_PATH_CONTENT_WINDOWS_SCOPE}/${encodeURIComponent(drive)}/${segments
38
- .filter(Boolean)
39
- .map((segment) => encodeURIComponent(segment))
40
- .join('/')}`;
23
+ export function buildServerPathContentUrl(path: string): string;
24
+ export function buildServerPathContentUrl(
25
+ path: string,
26
+ basePath: string | null,
27
+ ): string | null;
28
+ export function buildServerPathContentUrl(
29
+ path: string,
30
+ basePath?: string | null,
31
+ ): string | null {
32
+ const normalizedPath = path.trim();
33
+ const isAbsolute = normalizedPath.startsWith("/") || /^[a-z]:[\\/]/i.test(normalizedPath);
34
+ const normalizedBasePath = basePath?.trim() ?? "";
35
+ if (!isAbsolute && !normalizedBasePath) {
36
+ return null;
37
+ }
38
+ const query = new URLSearchParams({ path: normalizedPath });
39
+ if (normalizedBasePath) {
40
+ query.set("basePath", normalizedBasePath);
41
41
  }
42
- return `${API_BASE}${SERVER_PATH_CONTENT_BASE_PATH}/${SERVER_PATH_CONTENT_ABSOLUTE_SCOPE}/${encodeServerPathSegments(normalizedPath)}`;
42
+ return `${API_BASE}${SERVER_PATH_CONTENT_BASE_PATH}?${query.toString()}`;
43
43
  }
@@ -37,6 +37,8 @@
37
37
  "chatBackToParent": "Back to parent",
38
38
  "chatSessionOpenChildSessions": "View child sessions",
39
39
  "chatSessionOpenCronJobs": "View session cron jobs",
40
+ "chatSessionOpenWorkspace": "Open session workspace",
41
+ "chatSessionCloseWorkspace": "Close session workspace",
40
42
  "chatChildSessionLoading": "Loading child session…",
41
43
  "chatChildSessionEmpty": "No child session messages yet.",
42
44
  "chatWorkspaceBack": "Back in workspace",
@@ -45,13 +47,25 @@
45
47
  "chatWorkspaceMaximizePanel": "Maximize workspace panel",
46
48
  "chatWorkspaceRestorePanel": "Restore workspace panel",
47
49
  "chatWorkspaceClosePanel": "Close workspace panel",
50
+ "chatWorkspaceOverview": "Overview",
51
+ "chatWorkspaceOverviewDescription": "Open this session's related conversations, scheduled work, and project files.",
52
+ "chatWorkspaceChildSessionsDescription": "Review the child sessions created from this conversation.",
53
+ "chatWorkspaceChildSessionsEmpty": "No child sessions yet.",
54
+ "chatWorkspaceSessionCronJobsDescription": "Review scheduled tasks associated with this session.",
55
+ "chatWorkspaceProjectFiles": "Project files",
56
+ "chatWorkspaceProjectFilesDescription": "Browse files from this session's project directory.",
57
+ "chatWorkspaceProjectFilesUnavailable": "This session does not have a project directory yet.",
48
58
  "chatWorkspaceSideChatDraftTitle": "Side chat",
49
59
  "chatWorkspaceSideChatDraftSubtitle": "This draft will inherit the parent session context when you send the first message.",
50
60
  "chatWorkspaceChildSessions": "Child sessions",
51
61
  "chatWorkspaceOpenFiles": "Open files",
52
62
  "chatWorkspacePreview": "Preview",
63
+ "chatWorkspaceOpenPreview": "Open preview",
64
+ "chatWorkspaceOpenSource": "Open source",
65
+ "chatWorkspaceFileMoreActions": "File actions",
53
66
  "chatWorkspaceDiff": "Diff",
54
67
  "chatWorkspaceCloseFile": "Close file",
68
+ "chatWorkspaceCloseTab": "Close tab",
55
69
  "chatWorkspaceLoadingPreview": "Loading preview…",
56
70
  "chatWorkspaceLoadingFile": "Loading file…",
57
71
  "chatWorkspaceLoadingDirectory": "Loading directory…",
@@ -60,7 +74,9 @@
60
74
  "chatWorkspaceDirectoryEmpty": "This directory is empty.",
61
75
  "chatWorkspaceDirectoryLoadFailed": "Failed to load directory",
62
76
  "chatWorkspacePreviewUnsupported": "This file is not supported in the sidebar preview yet.",
63
- "chatWorkspacePreviewUnsupportedHint": "Formats like Word, Excel, and archives can’t be rendered in the sidebar. Download and open them with a local app.",
77
+ "chatWorkspacePreviewUnsupportedHint": "Legacy Word or PowerPoint files, archives, and other unsupported formats can be downloaded and opened with a local app.",
78
+ "chatWorkspacePreviewFailed": "The file could not be previewed. You can still download it and open it with a local app.",
79
+ "chatWorkspaceSpreadsheetPreviewTruncated": "This workbook is large. The preview shows up to 500 rows and 100 columns.",
64
80
  "chatWorkspacePreviewDownload": "Download file",
65
81
  "chatWorkspacePreviewOpenExternally": "Open with system app",
66
82
  "chatWorkspacePreviewEmpty": "No file content is available for preview.",
@@ -186,8 +202,13 @@
186
202
  "chatPanelAppReferenceFile": "File",
187
203
  "chatPanelAppReferenceNoDescription": "No panel app description",
188
204
  "chatSkillScopeBuiltin": "Built-in",
205
+ "chatSkillScopeGlobal": "Global",
189
206
  "chatSkillScopeProject": "Project",
190
207
  "chatSkillScopeWorkspace": "Workspace",
208
+ "chatSkillGroupBuiltin": "Built-in skills",
209
+ "chatSkillGroupGlobal": "Global skills",
210
+ "chatSkillGroupProject": "Project skills",
211
+ "chatSkillGroupWorkspace": "NextClaw skills",
191
212
  "chatPickerRecent": "Recent",
192
213
  "chatPickerFavoriteModels": "Favorites",
193
214
  "chatPickerRecentModels": "Recent",
@@ -239,6 +260,7 @@
239
260
  "chatSessionProjectCleared": "Project directory cleared",
240
261
  "chatSessionErrorTitle": "Something went wrong",
241
262
  "chatSendFailed": "Failed to send message",
263
+ "chatErrorDetails": "Details",
242
264
  "chatRoleUser": "You",
243
265
  "chatRoleAssistant": "Assistant",
244
266
  "chatRoleTool": "Tool",
@@ -280,6 +302,8 @@
280
302
  "chatCodeCopied": "Copied",
281
303
  "chatMessageCopy": "Copy",
282
304
  "chatMessageCopied": "Copied",
305
+ "chatMermaidDiagram": "Diagram",
306
+ "chatMermaidRenderError": "Diagram could not be rendered; showing source instead",
283
307
  "chatSidebarNewTask": "New Task",
284
308
  "chatSidebarSearchPlaceholder": "Search conversations...",
285
309
  "chatSidebarScheduledTasks": "Scheduled Tasks",
@@ -14,6 +14,12 @@
14
14
  "settingsGroupBasic": "Basic Configuration",
15
15
  "settingsGroupAdvanced": "Advanced Configuration",
16
16
  "appearance": "Appearance",
17
+ "chatMessageLayoutTitle": "Message layout",
18
+ "chatMessageLayoutDescription": "Choose how chat messages are displayed.",
19
+ "chatMessageLayoutCard": "Cards",
20
+ "chatMessageLayoutCardDescription": "Show user and AI messages in separate cards.",
21
+ "chatMessageLayoutFlat": "Flat",
22
+ "chatMessageLayoutFlatDescription": "Keep user bubbles while showing AI identity and content in a flat layout.",
17
23
  "settingsMenu": "Settings menu",
18
24
  "sidebarCollapse": "Collapse sidebar",
19
25
  "sidebarExpand": "Expand sidebar",
@@ -37,6 +37,8 @@
37
37
  "chatBackToParent": "返回父会话",
38
38
  "chatSessionOpenChildSessions": "查看子会话",
39
39
  "chatSessionOpenCronJobs": "查看本会话定时任务",
40
+ "chatSessionOpenWorkspace": "打开会话工作台",
41
+ "chatSessionCloseWorkspace": "收起会话工作台",
40
42
  "chatChildSessionLoading": "正在加载子会话…",
41
43
  "chatChildSessionEmpty": "子会话还没有消息。",
42
44
  "chatWorkspaceBack": "工作区后退",
@@ -45,13 +47,25 @@
45
47
  "chatWorkspaceMaximizePanel": "最大化工作区侧栏",
46
48
  "chatWorkspaceRestorePanel": "还原工作区侧栏",
47
49
  "chatWorkspaceClosePanel": "关闭工作区侧栏",
50
+ "chatWorkspaceOverview": "概览",
51
+ "chatWorkspaceOverviewDescription": "查看与当前会话相关的子会话、定时任务和项目文件。",
52
+ "chatWorkspaceChildSessionsDescription": "查看从当前会话创建的子会话。",
53
+ "chatWorkspaceChildSessionsEmpty": "当前还没有子会话。",
54
+ "chatWorkspaceSessionCronJobsDescription": "查看与当前会话关联的定时任务。",
55
+ "chatWorkspaceProjectFiles": "项目文件",
56
+ "chatWorkspaceProjectFilesDescription": "浏览当前会话项目目录中的文件。",
57
+ "chatWorkspaceProjectFilesUnavailable": "当前会话还没有项目目录。",
48
58
  "chatWorkspaceSideChatDraftTitle": "Side chat",
49
59
  "chatWorkspaceSideChatDraftSubtitle": "发送第一条消息后,会继承父会话上下文并创建真实 child 会话。",
50
60
  "chatWorkspaceChildSessions": "子会话",
51
61
  "chatWorkspaceOpenFiles": "打开的文件",
52
62
  "chatWorkspacePreview": "预览",
63
+ "chatWorkspaceOpenPreview": "打开预览",
64
+ "chatWorkspaceOpenSource": "打开源码",
65
+ "chatWorkspaceFileMoreActions": "文件操作",
53
66
  "chatWorkspaceDiff": "Diff",
54
67
  "chatWorkspaceCloseFile": "关闭文件",
68
+ "chatWorkspaceCloseTab": "关闭标签页",
55
69
  "chatWorkspaceLoadingPreview": "正在加载预览…",
56
70
  "chatWorkspaceLoadingFile": "正在加载文件…",
57
71
  "chatWorkspaceLoadingDirectory": "正在加载目录…",
@@ -60,7 +74,9 @@
60
74
  "chatWorkspaceDirectoryEmpty": "这个目录为空。",
61
75
  "chatWorkspaceDirectoryLoadFailed": "读取目录失败",
62
76
  "chatWorkspacePreviewUnsupported": "该文件暂不支持在侧栏预览。",
63
- "chatWorkspacePreviewUnsupportedHint": "Word、Excel、压缩包等格式无法在侧栏内直接渲染版式。你可以下载后用本机应用打开。",
77
+ "chatWorkspacePreviewUnsupportedHint": "旧版 Word、PowerPoint、压缩包等暂不支持的格式,可以下载后用本机应用打开。",
78
+ "chatWorkspacePreviewFailed": "文件预览失败。你仍可以下载后用本机应用打开。",
79
+ "chatWorkspaceSpreadsheetPreviewTruncated": "工作簿较大,当前最多显示 500 行和 100 列。",
64
80
  "chatWorkspacePreviewDownload": "下载文件",
65
81
  "chatWorkspacePreviewOpenExternally": "用系统应用打开",
66
82
  "chatWorkspacePreviewEmpty": "当前没有可显示的文件内容。",
@@ -186,8 +202,13 @@
186
202
  "chatPanelAppReferenceFile": "文件",
187
203
  "chatPanelAppReferenceNoDescription": "暂无面板应用描述",
188
204
  "chatSkillScopeBuiltin": "内建",
205
+ "chatSkillScopeGlobal": "全局",
189
206
  "chatSkillScopeProject": "项目",
190
207
  "chatSkillScopeWorkspace": "工作区",
208
+ "chatSkillGroupBuiltin": "内建技能",
209
+ "chatSkillGroupGlobal": "全局技能",
210
+ "chatSkillGroupProject": "项目技能",
211
+ "chatSkillGroupWorkspace": "NextClaw 技能",
191
212
  "chatPickerRecent": "最近使用",
192
213
  "chatPickerFavoriteModels": "收藏模型",
193
214
  "chatPickerRecentModels": "最近选择",
@@ -239,6 +260,7 @@
239
260
  "chatSessionProjectCleared": "项目目录已清除",
240
261
  "chatSessionErrorTitle": "出错了",
241
262
  "chatSendFailed": "发送消息失败",
263
+ "chatErrorDetails": "查看详情",
242
264
  "chatRoleUser": "你",
243
265
  "chatRoleAssistant": "助手",
244
266
  "chatRoleTool": "工具",
@@ -280,6 +302,8 @@
280
302
  "chatCodeCopied": "已复制",
281
303
  "chatMessageCopy": "复制",
282
304
  "chatMessageCopied": "已复制",
305
+ "chatMermaidDiagram": "图表",
306
+ "chatMermaidRenderError": "图表无法渲染,已显示源代码",
283
307
  "chatSidebarNewTask": "新任务",
284
308
  "chatSidebarSearchPlaceholder": "搜索对话...",
285
309
  "chatSidebarScheduledTasks": "定时任务",
@@ -14,6 +14,12 @@
14
14
  "settingsGroupBasic": "基础配置",
15
15
  "settingsGroupAdvanced": "高级配置",
16
16
  "appearance": "外观",
17
+ "chatMessageLayoutTitle": "消息布局",
18
+ "chatMessageLayoutDescription": "选择聊天消息的展示方式。",
19
+ "chatMessageLayoutCard": "卡片式",
20
+ "chatMessageLayoutCardDescription": "用户与 AI 消息都使用独立卡片展示。",
21
+ "chatMessageLayoutFlat": "平铺式",
22
+ "chatMessageLayoutFlatDescription": "用户消息保留气泡,AI 消息以头像、名称和正文平铺展示。",
17
23
  "settingsMenu": "设置菜单",
18
24
  "sidebarCollapse": "收起侧边栏",
19
25
  "sidebarExpand": "展开侧边栏",
@@ -80,16 +80,13 @@ describe("buildWorkspaceFileBreadcrumb", () => {
80
80
  ]);
81
81
  });
82
82
 
83
- it("attaches line metadata for the workspace breadcrumb bar", () => {
83
+ it("keeps truncation status separate from path segments", () => {
84
84
  const breadcrumb = buildWorkspaceFileBreadcrumb({
85
85
  path: "README.md",
86
86
  sessionProjectRoot: "/Users/demo/project-alpha",
87
- line: 12,
88
- column: 4,
89
87
  truncated: true,
90
88
  });
91
89
 
92
- expect(breadcrumb.locationLabel).toBe("L12:4");
93
90
  expect(breadcrumb.truncated).toBe(true);
94
91
  expect(breadcrumb.segments[0]?.label).toBe("project-alpha");
95
92
  expect(breadcrumb.segments[1]?.label).toBe("README.md");
@@ -11,7 +11,6 @@ export type WorkspaceFileBreadcrumbSegmentViewModel = {
11
11
 
12
12
  export type WorkspaceFileBreadcrumbViewModel = {
13
13
  fullPath: string;
14
- locationLabel: string | null;
15
14
  truncated: boolean;
16
15
  segments: WorkspaceFileBreadcrumbSegmentViewModel[];
17
16
  };
@@ -153,28 +152,13 @@ function buildSegmentsFromLabels(params: {
153
152
  return leading ? [leading, ...items] : items;
154
153
  }
155
154
 
156
- function buildLocationLabel(params: {
157
- line?: number | null;
158
- column?: number | null;
159
- }): string | null {
160
- const { column, line } = params;
161
-
162
- if (typeof line !== "number") {
163
- return null;
164
- }
165
-
166
- return `L${line}${typeof column === "number" ? `:${column}` : ""}`;
167
- }
168
-
169
155
  export function buildWorkspaceFileBreadcrumb(params: {
170
156
  path: string;
171
157
  kind?: "file" | "directory";
172
158
  sessionProjectRoot: string | null;
173
- line?: number | null;
174
- column?: number | null;
175
159
  truncated: boolean;
176
160
  }): WorkspaceFileBreadcrumbViewModel {
177
- const { column, kind = "file", line, path, sessionProjectRoot, truncated } = params;
161
+ const { kind = "file", path, sessionProjectRoot, truncated } = params;
178
162
  const fullPath = path.trim();
179
163
  const relativeSegments =
180
164
  sessionProjectRoot?.trim() && fullPath
@@ -239,7 +223,6 @@ export function buildWorkspaceFileBreadcrumb(params: {
239
223
 
240
224
  return {
241
225
  fullPath,
242
- locationLabel: buildLocationLabel({ line, column }),
243
226
  truncated,
244
227
  segments,
245
228
  };