@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,21 +1,234 @@
1
- import { MessageSquarePlus } from "lucide-react";
1
+ import type { ReactNode } from "react";
2
+ import {
3
+ AlarmClock,
4
+ ChevronRight,
5
+ FolderTree,
6
+ GitBranch,
7
+ MessageSquarePlus,
8
+ } from "lucide-react";
2
9
  import type { CronJobView } from "@/shared/lib/api";
3
10
  import { usePresenter } from "@/features/chat/components/providers/chat-presenter.provider";
4
11
  import { SessionConversationArea } from "@/features/chat/features/conversation/components/session-conversation-area";
5
12
  import { ChatSessionWorkspaceFilePreview } from "@/features/chat/features/workspace/components/chat-session-workspace-file-preview";
13
+ import { ChatSessionWorkspaceDirectoryBrowser } from "@/features/chat/features/workspace/components/chat-session-workspace-directory-browser";
6
14
  import { SessionCronJobContent } from "@/features/chat/features/workspace/components/session-cron-job-content";
7
15
  import type { ResolvedChildSessionTab } from "@/features/chat/features/ncp/hooks/use-ncp-child-session-tabs-view";
8
16
  import type { WorkspaceSelection } from "@/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils";
17
+ import { useServerPathBrowse } from "@/shared/hooks/use-server-path-browse";
9
18
  import { t } from "@/shared/lib/i18n";
19
+ import { cn } from "@/shared/lib/utils";
10
20
 
11
21
  type ChatSessionWorkspacePanelContentProps = {
12
22
  activeSelection: WorkspaceSelection;
23
+ childSessionTabs: readonly ResolvedChildSessionTab[];
13
24
  filePreviewRefreshVersion: number;
25
+ sessionKey: string | null;
14
26
  sessionCronJobs: readonly CronJobView[];
15
27
  sessionProjectRoot: string | null;
16
28
  sessionWorkingDir: string | null;
17
29
  };
18
30
 
31
+ function WorkspaceOverviewEntry({
32
+ count,
33
+ description,
34
+ icon,
35
+ onClick,
36
+ title,
37
+ }: {
38
+ count?: number;
39
+ description: string;
40
+ icon: ReactNode;
41
+ onClick: () => void;
42
+ title: string;
43
+ }) {
44
+ return (
45
+ <button
46
+ type="button"
47
+ className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
48
+ onClick={onClick}
49
+ >
50
+ <span className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
51
+ {icon}
52
+ </span>
53
+ <span className="min-w-0 flex-1">
54
+ <span className="flex items-center gap-2 text-sm font-medium text-gray-900">
55
+ <span className="truncate">{title}</span>
56
+ {typeof count === "number" ? (
57
+ <span className="rounded-full bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold tabular-nums text-gray-500">
58
+ {count}
59
+ </span>
60
+ ) : null}
61
+ </span>
62
+ <span className="mt-0.5 block text-xs leading-5 text-gray-500">
63
+ {description}
64
+ </span>
65
+ </span>
66
+ <ChevronRight className="h-4 w-4 shrink-0 text-gray-300 transition-transform group-hover:translate-x-0.5 group-hover:text-gray-500" />
67
+ </button>
68
+ );
69
+ }
70
+
71
+ function WorkspaceOverview({
72
+ childSessionTabs,
73
+ sessionCronJobs,
74
+ sessionKey,
75
+ }: {
76
+ childSessionTabs: readonly ResolvedChildSessionTab[];
77
+ sessionCronJobs: readonly CronJobView[];
78
+ sessionKey: string | null;
79
+ }) {
80
+ const presenter = usePresenter();
81
+
82
+ return (
83
+ <div className="h-full overflow-auto bg-gray-50/45 px-4 py-5 custom-scrollbar">
84
+ <div className="mx-auto max-w-xl">
85
+ <h2 className="text-base font-semibold text-gray-900">
86
+ {t("chatWorkspaceOverview")}
87
+ </h2>
88
+ <p className="mt-1 text-xs leading-5 text-gray-500">
89
+ {t("chatWorkspaceOverviewDescription")}
90
+ </p>
91
+ <div className="mt-4 space-y-2">
92
+ <WorkspaceOverviewEntry
93
+ count={childSessionTabs.length}
94
+ description={t("chatWorkspaceChildSessionsDescription")}
95
+ icon={<GitBranch className="h-4 w-4" />}
96
+ title={t("chatWorkspaceChildSessions")}
97
+ onClick={() => {
98
+ if (sessionKey) {
99
+ presenter.chatThreadManager.openChildSessions(sessionKey);
100
+ }
101
+ }}
102
+ />
103
+ <WorkspaceOverviewEntry
104
+ count={sessionCronJobs.length}
105
+ description={t("chatWorkspaceSessionCronJobsDescription")}
106
+ icon={<AlarmClock className="h-4 w-4" />}
107
+ title={t("chatWorkspaceSessionCronJobs")}
108
+ onClick={() => {
109
+ if (sessionKey) {
110
+ presenter.chatThreadManager.openSessionCronPanel(sessionKey);
111
+ }
112
+ }}
113
+ />
114
+ <WorkspaceOverviewEntry
115
+ description={t("chatWorkspaceProjectFilesDescription")}
116
+ icon={<FolderTree className="h-4 w-4" />}
117
+ title={t("chatWorkspaceProjectFiles")}
118
+ onClick={() => {
119
+ if (sessionKey) {
120
+ presenter.chatThreadManager.openProjectFiles(sessionKey);
121
+ }
122
+ }}
123
+ />
124
+ </div>
125
+ </div>
126
+ </div>
127
+ );
128
+ }
129
+
130
+ function WorkspaceChildSessions({
131
+ childSessionTabs,
132
+ }: {
133
+ childSessionTabs: readonly ResolvedChildSessionTab[];
134
+ }) {
135
+ const presenter = usePresenter();
136
+
137
+ return (
138
+ <div className="h-full overflow-auto bg-gray-50/45 px-4 py-5 custom-scrollbar">
139
+ <div className="mx-auto max-w-xl">
140
+ <div className="flex items-center gap-2">
141
+ <h2 className="text-base font-semibold text-gray-900">
142
+ {t("chatWorkspaceChildSessions")}
143
+ </h2>
144
+ <span className="rounded-full bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold tabular-nums text-gray-500">
145
+ {childSessionTabs.length}
146
+ </span>
147
+ </div>
148
+ {childSessionTabs.length === 0 ? (
149
+ <div className="py-10 text-center text-sm text-gray-500">
150
+ {t("chatWorkspaceChildSessionsEmpty")}
151
+ </div>
152
+ ) : (
153
+ <div className="mt-4 space-y-2">
154
+ {childSessionTabs.map((tab) => (
155
+ <button
156
+ key={tab.sessionKey}
157
+ type="button"
158
+ className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
159
+ onClick={() =>
160
+ presenter.chatThreadManager.selectChildSessionDetail(
161
+ tab.sessionKey,
162
+ )
163
+ }
164
+ >
165
+ <span className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
166
+ <GitBranch className="h-4 w-4" />
167
+ </span>
168
+ <span className="min-w-0 flex-1">
169
+ <span className="block truncate text-sm font-medium text-gray-900">
170
+ {tab.title}
171
+ </span>
172
+ {tab.projectName || tab.sessionTypeLabel ? (
173
+ <span className="mt-0.5 block truncate text-xs text-gray-500">
174
+ {[tab.sessionTypeLabel, tab.projectName]
175
+ .filter(Boolean)
176
+ .join(" · ")}
177
+ </span>
178
+ ) : null}
179
+ </span>
180
+ <ChevronRight className="h-4 w-4 shrink-0 text-gray-300 transition-transform group-hover:translate-x-0.5 group-hover:text-gray-500" />
181
+ </button>
182
+ ))}
183
+ </div>
184
+ )}
185
+ </div>
186
+ </div>
187
+ );
188
+ }
189
+
190
+ function WorkspaceProjectFiles({
191
+ projectRoot,
192
+ workingDir,
193
+ }: {
194
+ projectRoot: string | null;
195
+ workingDir: string | null;
196
+ }) {
197
+ const presenter = usePresenter();
198
+ const rootPath = projectRoot ?? workingDir;
199
+ const browseQuery = useServerPathBrowse({
200
+ path: rootPath,
201
+ includeFiles: true,
202
+ enabled: Boolean(rootPath),
203
+ });
204
+
205
+ if (!rootPath) {
206
+ return (
207
+ <div className="flex h-full items-center justify-center px-6 text-center text-sm text-gray-500">
208
+ {t("chatWorkspaceProjectFilesUnavailable")}
209
+ </div>
210
+ );
211
+ }
212
+
213
+ return (
214
+ <ChatSessionWorkspaceDirectoryBrowser
215
+ browseQuery={browseQuery}
216
+ onFileOpen={presenter.chatThreadManager.openFilePreview}
217
+ renderStatus={({ text, tone = "muted" }) => (
218
+ <div
219
+ className={cn(
220
+ "flex h-full items-center justify-center px-6 text-center text-sm",
221
+ tone === "error" ? "text-rose-600" : "text-gray-500",
222
+ )}
223
+ >
224
+ {text}
225
+ </div>
226
+ )}
227
+ showRoot
228
+ />
229
+ );
230
+ }
231
+
19
232
  function ChildSessionMetaChip({ value }: { value: string }) {
20
233
  return (
21
234
  <span className="inline-flex max-w-full shrink-0 items-center rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-[10px] font-medium text-gray-600">
@@ -68,13 +281,38 @@ function WorkspaceSideChatDraftHeader() {
68
281
 
69
282
  export function ChatSessionWorkspacePanelContent({
70
283
  activeSelection,
284
+ childSessionTabs,
71
285
  filePreviewRefreshVersion,
286
+ sessionKey,
72
287
  sessionCronJobs,
73
288
  sessionProjectRoot,
74
289
  sessionWorkingDir,
75
290
  }: ChatSessionWorkspacePanelContentProps) {
76
291
  const presenter = usePresenter();
77
292
 
293
+ if (activeSelection.kind === "overview") {
294
+ return (
295
+ <WorkspaceOverview
296
+ childSessionTabs={childSessionTabs}
297
+ sessionCronJobs={sessionCronJobs}
298
+ sessionKey={sessionKey}
299
+ />
300
+ );
301
+ }
302
+
303
+ if (activeSelection.kind === "project-files") {
304
+ return (
305
+ <WorkspaceProjectFiles
306
+ projectRoot={sessionProjectRoot}
307
+ workingDir={sessionWorkingDir}
308
+ />
309
+ );
310
+ }
311
+
312
+ if (activeSelection.kind === "child-sessions") {
313
+ return <WorkspaceChildSessions childSessionTabs={childSessionTabs} />;
314
+ }
315
+
78
316
  if (activeSelection.kind === "side-chat-draft") {
79
317
  return (
80
318
  <>
@@ -2,7 +2,11 @@ import {
2
2
  AlarmClock,
3
3
  ArrowLeft,
4
4
  ArrowRight,
5
- FileCode2,
5
+ Code2,
6
+ Eye,
7
+ FolderTree,
8
+ GitBranch,
9
+ LayoutDashboard,
6
10
  Maximize2,
7
11
  MessageSquarePlus,
8
12
  MessageSquareText,
@@ -12,6 +16,7 @@ import {
12
16
  } from "lucide-react";
13
17
  import type { WorkspaceTabViewModel } from "@/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils";
14
18
  import { AgentIdentityAvatar } from "@/shared/components/common/agent-identity";
19
+ import { FileTypeIcon } from "@/shared/components/file-type-icon";
15
20
  import {
16
21
  CompactTabStrip,
17
22
  type CompactTabStripAction,
@@ -19,13 +24,29 @@ import {
19
24
  } from "@/shared/components/ui/tab-strip/compact-tab-strip";
20
25
  import { t } from "@/shared/lib/i18n";
21
26
 
22
- function WorkspaceTabIcon({ agentId, kind }: Pick<WorkspaceTabViewModel, "agentId" | "kind">) {
27
+ function WorkspaceTabIcon({
28
+ agentId,
29
+ fileName,
30
+ kind,
31
+ }: Pick<WorkspaceTabViewModel, "agentId" | "fileName" | "kind">) {
32
+ if (kind === "overview") {
33
+ return <LayoutDashboard className="h-3.5 w-3.5 shrink-0 text-gray-400" />;
34
+ }
35
+
36
+ if (kind === "child-sessions") {
37
+ return <GitBranch className="h-3.5 w-3.5 shrink-0 text-gray-400" />;
38
+ }
39
+
40
+ if (kind === "project-files") {
41
+ return <FolderTree className="h-3.5 w-3.5 shrink-0 text-gray-400" />;
42
+ }
43
+
23
44
  if (kind === "cron") {
24
45
  return <AlarmClock className="h-3.5 w-3.5 shrink-0 text-gray-400" />;
25
46
  }
26
47
 
27
48
  if (kind === "file") {
28
- return <FileCode2 className="h-3.5 w-3.5 shrink-0 text-gray-400" />;
49
+ return <FileTypeIcon fileName={fileName ?? ""} size="compact" />;
29
50
  }
30
51
 
31
52
  if (kind === "side-chat-draft") {
@@ -47,20 +68,53 @@ function buildCompactWorkspaceTabs(
47
68
  return tabs.map((tab) => ({
48
69
  key: tab.key,
49
70
  label: tab.title,
71
+ labelClassName: tab.isRenderedPreview ? "italic font-normal" : undefined,
50
72
  active: tab.active,
51
73
  tooltip: tab.tooltip,
52
- leadingIcon: <WorkspaceTabIcon kind={tab.kind} agentId={tab.agentId} />,
53
- badge:
54
- tab.kind === "file" && tab.viewMode === "diff" ? (
74
+ leadingIcon: (
75
+ <WorkspaceTabIcon
76
+ kind={tab.kind}
77
+ agentId={tab.agentId}
78
+ fileName={tab.fileName}
79
+ />
80
+ ),
81
+ badge: tab.kind === "file" && tab.viewMode === "diff" ? (
55
82
  <span className="shrink-0 rounded border border-amber-200 bg-amber-50 px-1 py-0 text-[9px] font-medium uppercase tracking-[0.08em] text-amber-700">
56
83
  {t("chatWorkspaceDiff")}
57
84
  </span>
58
85
  ) : null,
59
86
  unreadIndicator: tab.showUnreadDot ? <span aria-label={t("chatSessionUnread")} className="h-2 w-2 shrink-0 rounded-full bg-primary" /> : null,
60
- closeLabel: t("chatWorkspaceCloseFile"),
87
+ closeLabel: `${
88
+ tab.kind === "file"
89
+ ? t("chatWorkspaceCloseFile")
90
+ : t("chatWorkspaceCloseTab")
91
+ }: ${tab.title}`,
61
92
  closePlacement: "leading-hover",
62
93
  onSelect: tab.onSelect,
63
94
  onClose: tab.onClose,
95
+ menuLabel: t("chatWorkspaceFileMoreActions"),
96
+ menuActions: tab.kind === "file"
97
+ ? [
98
+ ...(tab.alternateViewerAction
99
+ ? [{
100
+ key: `viewer:${tab.alternateViewerAction.viewer}`,
101
+ icon: tab.alternateViewerAction.viewer === "rendered"
102
+ ? <Eye className="h-3.5 w-3.5" />
103
+ : <Code2 className="h-3.5 w-3.5" />,
104
+ label: tab.alternateViewerAction.label,
105
+ onClick: tab.alternateViewerAction.onSelect,
106
+ }]
107
+ : []),
108
+ ...(tab.onClose
109
+ ? [{
110
+ key: "close",
111
+ icon: <X className="h-3.5 w-3.5" />,
112
+ label: t("chatWorkspaceCloseFile"),
113
+ onClick: tab.onClose,
114
+ }]
115
+ : []),
116
+ ]
117
+ : undefined,
64
118
  }));
65
119
  }
66
120
 
@@ -3,8 +3,14 @@ import { useQueryClient } from "@tanstack/react-query";
3
3
  import type { CronJobView } from "@/shared/lib/api";
4
4
  import { useNcpChildSessionTabsView } from "@/features/chat/features/ncp/hooks/use-ncp-child-session-tabs-view";
5
5
  import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
6
+ import {
7
+ CHAT_WORKSPACE_PANEL_DEFAULT_WIDTH,
8
+ CHAT_WORKSPACE_PANEL_MAX_WIDTH,
9
+ CHAT_WORKSPACE_PANEL_MIN_WIDTH,
10
+ } from "@/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils";
6
11
  import type {
7
12
  ChatChildSessionTab,
13
+ ChatWorkspacePanelKind,
8
14
  ChatWorkspaceSideChatDraft,
9
15
  ChatWorkspaceNavigationEntry,
10
16
  ChatWorkspaceFileTab,
@@ -33,12 +39,14 @@ type ChatSessionWorkspacePanelProps = {
33
39
  activeSideChatDraft: ChatWorkspaceSideChatDraft | null;
34
40
  workspaceFileTabs: readonly ChatWorkspaceFileTab[];
35
41
  activeWorkspaceFileKey: string | null;
42
+ closedWorkspaceTabEntries: readonly ChatWorkspaceNavigationEntry[];
36
43
  workspaceNavigationHistory?: readonly ChatWorkspaceNavigationEntry[];
37
44
  workspaceNavigationHistoryIndex?: number;
38
- activePanelKind?: "child-session" | "side-chat-draft" | "file" | "cron" | null;
45
+ activePanelKind?: ChatWorkspacePanelKind | null;
39
46
  sessionCronJobs?: readonly CronJobView[];
40
47
  sessionProjectRoot: string | null;
41
48
  sessionWorkingDir: string | null;
49
+ workspacePanelWidth?: number;
42
50
  displayMode?: "docked" | "overlay";
43
51
  };
44
52
 
@@ -49,12 +57,14 @@ export function ChatSessionWorkspacePanel({
49
57
  activeSideChatDraft,
50
58
  workspaceFileTabs,
51
59
  activeWorkspaceFileKey,
60
+ closedWorkspaceTabEntries,
52
61
  workspaceNavigationHistory = [],
53
62
  workspaceNavigationHistoryIndex = 0,
54
63
  activePanelKind,
55
64
  sessionCronJobs = [],
56
65
  sessionProjectRoot,
57
66
  sessionWorkingDir,
67
+ workspacePanelWidth = CHAT_WORKSPACE_PANEL_DEFAULT_WIDTH,
58
68
  displayMode = "docked",
59
69
  }: ChatSessionWorkspacePanelProps) {
60
70
  const presenter = usePresenter();
@@ -72,7 +82,6 @@ export function ChatSessionWorkspacePanel({
72
82
  activePanelKind,
73
83
  childSessionTabs: resolvedChildTabs,
74
84
  workspaceFileTabs,
75
- sessionCronJobCount: sessionCronJobs.length,
76
85
  });
77
86
  const workspaceHistory = {
78
87
  entries: workspaceNavigationHistory,
@@ -88,13 +97,26 @@ export function ChatSessionWorkspacePanel({
88
97
  buildWorkspaceTabsViewModel({
89
98
  resolvedChildTabs,
90
99
  activeSideChatDraft,
100
+ closedWorkspaceTabEntries,
91
101
  workspaceFileTabs,
92
- sessionCronJobCount: sessionCronJobs.length,
93
102
  activeSelection,
94
103
  optimisticReadAtBySessionKey,
95
104
  onSelectSession: presenter.chatThreadManager.selectChildSessionDetail,
96
105
  onSelectFile: presenter.chatThreadManager.selectWorkspaceFile,
97
- onCloseFile: presenter.chatThreadManager.closeWorkspaceFile,
106
+ onOpenFileViewer: presenter.chatThreadManager.openWorkspaceFileViewer,
107
+ onCloseTab: presenter.chatThreadManager.closeWorkspaceTab,
108
+ onSelectOverview: () => {
109
+ if (sessionKey)
110
+ presenter.chatThreadManager.openWorkspaceOverview(sessionKey);
111
+ },
112
+ onSelectChildSessions: () => {
113
+ if (sessionKey)
114
+ presenter.chatThreadManager.openChildSessions(sessionKey);
115
+ },
116
+ onSelectProjectFiles: () => {
117
+ if (sessionKey)
118
+ presenter.chatThreadManager.openProjectFiles(sessionKey);
119
+ },
98
120
  onSelectCronJobs: () => {
99
121
  if (sessionKey)
100
122
  presenter.chatThreadManager.openSessionCronPanel(sessionKey);
@@ -103,12 +125,12 @@ export function ChatSessionWorkspacePanel({
103
125
  [
104
126
  activeSelection,
105
127
  activeSideChatDraft,
128
+ closedWorkspaceTabEntries,
106
129
  optimisticReadAtBySessionKey,
107
130
  presenter.chatThreadManager,
108
131
  resolvedChildTabs,
109
132
  sessionKey,
110
133
  workspaceFileTabs,
111
- sessionCronJobs.length,
112
134
  ],
113
135
  );
114
136
 
@@ -150,9 +172,11 @@ export function ChatSessionWorkspacePanel({
150
172
  : "hidden border-gray-200/70 bg-white/95 backdrop-blur-sm md:flex",
151
173
  isContainerMaximized ? "shadow-xl" : null,
152
174
  )}
153
- defaultWidth={480}
154
- minWidth={360}
155
- maxWidth={860}
175
+ defaultWidth={workspacePanelWidth}
176
+ width={workspacePanelWidth}
177
+ minWidth={CHAT_WORKSPACE_PANEL_MIN_WIDTH}
178
+ maxWidth={CHAT_WORKSPACE_PANEL_MAX_WIDTH}
179
+ onWidthCommit={presenter.chatThreadManager.setWorkspacePanelWidth}
156
180
  overlay={isOverlayPanel}
157
181
  overlayScope={isContainerMaximized ? "container" : "viewport"}
158
182
  >
@@ -175,7 +199,9 @@ export function ChatSessionWorkspacePanel({
175
199
  <div className="flex min-h-0 flex-1 flex-col bg-white">
176
200
  <ChatSessionWorkspacePanelContent
177
201
  activeSelection={activeSelection}
202
+ childSessionTabs={resolvedChildTabs}
178
203
  filePreviewRefreshVersion={filePreviewRefreshVersion}
204
+ sessionKey={sessionKey}
179
205
  sessionCronJobs={sessionCronJobs}
180
206
  sessionProjectRoot={sessionProjectRoot}
181
207
  sessionWorkingDir={sessionWorkingDir}
@@ -0,0 +1,42 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ type WorkspaceFileBufferState =
4
+ | { contentUrl: string; status: "ready"; data: ArrayBuffer }
5
+ | { contentUrl: string; status: "error"; data: null };
6
+
7
+ export function useWorkspaceFileBuffer(contentUrl: string): {
8
+ status: "loading" | "ready" | "error";
9
+ data: ArrayBuffer | null;
10
+ } {
11
+ const [state, setState] = useState<WorkspaceFileBufferState | null>(null);
12
+ const currentState = state?.contentUrl === contentUrl ? state : null;
13
+
14
+ useEffect(() => {
15
+ const abortController = new AbortController();
16
+ void fetch(contentUrl, { signal: abortController.signal })
17
+ .then((response) => {
18
+ if (!response.ok) {
19
+ throw new Error(`Unable to load document (${response.status}).`);
20
+ }
21
+ return response.arrayBuffer();
22
+ })
23
+ .then((data) => {
24
+ if (!abortController.signal.aborted) {
25
+ setState({ contentUrl, status: "ready", data });
26
+ }
27
+ })
28
+ .catch((error: unknown) => {
29
+ if (!abortController.signal.aborted) {
30
+ console.error("Failed to load workspace document", error);
31
+ setState({ contentUrl, status: "error", data: null });
32
+ }
33
+ });
34
+
35
+ return () => abortController.abort();
36
+ }, [contentUrl]);
37
+
38
+ return {
39
+ status: currentState?.status ?? "loading",
40
+ data: currentState?.data ?? null,
41
+ };
42
+ }
@@ -0,0 +1,18 @@
1
+ import { t } from "@/shared/lib/i18n";
2
+
3
+ export function WorkspaceDocumentPreviewState({
4
+ status,
5
+ }: {
6
+ status: "loading" | "ready" | "error";
7
+ }) {
8
+ if (status === "ready") {
9
+ return null;
10
+ }
11
+ return (
12
+ <div className="absolute inset-0 z-10 flex items-center justify-center bg-background/90 px-6 text-center text-sm text-muted-foreground">
13
+ {status === "loading"
14
+ ? t("chatWorkspaceLoadingPreview")
15
+ : t("chatWorkspacePreviewFailed")}
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,89 @@
1
+ .workspace-docx-preview {
2
+ container-type: inline-size;
3
+ }
4
+
5
+ .workspace-docx-preview .docx-wrapper {
6
+ gap: 1rem;
7
+ padding: 0 !important;
8
+ padding-bottom: 0 !important;
9
+ background: transparent !important;
10
+ }
11
+
12
+ .workspace-docx-preview .docx-wrapper > section.docx {
13
+ margin: 0 auto 1rem !important;
14
+ border: 1px solid rgb(0 0 0 / 8%);
15
+ border-radius: 4px;
16
+ box-shadow: 0 4px 18px rgb(0 0 0 / 12%) !important;
17
+ }
18
+
19
+ .workspace-docx-preview--reflow .docx-wrapper > section.docx {
20
+ width: 100% !important;
21
+ min-height: auto !important;
22
+ padding: clamp(1.5rem, 6cqw, 3.5rem) !important;
23
+ overflow: visible !important;
24
+ }
25
+
26
+ .workspace-docx-preview--reflow .docx-wrapper > section.docx > article {
27
+ min-width: 0;
28
+ }
29
+
30
+ .workspace-docx-preview--reflow .docx p {
31
+ line-height: 1.6 !important;
32
+ }
33
+
34
+ .workspace-docx-preview--reflow .docx p.docx_heading1 span {
35
+ min-height: 0 !important;
36
+ font-size: clamp(1.5rem, 6cqw, 2rem) !important;
37
+ line-height: 1.25 !important;
38
+ }
39
+
40
+ .workspace-docx-preview--reflow .docx p.docx_heading2 span {
41
+ min-height: 0 !important;
42
+ font-size: clamp(1.125rem, 4.5cqw, 1.375rem) !important;
43
+ line-height: 1.35 !important;
44
+ }
45
+
46
+ .workspace-docx-preview--reflow .docx table {
47
+ width: 100% !important;
48
+ margin: 0.75rem 0 1.25rem;
49
+ table-layout: auto !important;
50
+ }
51
+
52
+ .workspace-docx-preview--reflow .docx col {
53
+ width: auto !important;
54
+ }
55
+
56
+ .workspace-docx-preview--reflow .docx table td,
57
+ .workspace-docx-preview--reflow .docx table th {
58
+ padding: 0.45rem 0.55rem !important;
59
+ border-bottom: 1px solid rgb(0 0 0 / 9%);
60
+ }
61
+
62
+ .workspace-docx-preview--reflow .docx table tr:first-child > td,
63
+ .workspace-docx-preview--reflow .docx table tr:first-child > th {
64
+ background: rgb(0 0 0 / 4%);
65
+ font-weight: 600;
66
+ }
67
+
68
+ .workspace-docx-preview--reflow .docx table p {
69
+ min-height: 0;
70
+ margin: 0 !important;
71
+ }
72
+
73
+ .workspace-docx-preview--reflow .workspace-docx-wide-table {
74
+ max-width: 100%;
75
+ margin: 0.75rem 0 1.25rem;
76
+ overflow-x: auto;
77
+ scrollbar-width: thin;
78
+ }
79
+
80
+ .workspace-docx-preview--reflow .workspace-docx-wide-table table {
81
+ min-width: 36rem;
82
+ margin: 0;
83
+ font-size: 0.875rem;
84
+ }
85
+
86
+ .workspace-docx-preview--reflow .workspace-docx-wide-table td,
87
+ .workspace-docx-preview--reflow .workspace-docx-wide-table th {
88
+ white-space: nowrap;
89
+ }