@nextclaw/ui 0.15.2 → 0.15.4

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 (212) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/assets/aiden0z-pptx-renderer.es-Bd99vut2.js +94 -0
  3. package/dist/assets/api-BOXOrpcJ.js +13 -0
  4. package/dist/assets/app-presenter-provider-CkHLbvZQ.js +106 -0
  5. package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
  6. package/dist/assets/appearance-settings-page-fLIJbx1C.js +1 -0
  7. package/dist/assets/{book-open-Ba2f7YiG.js → book-open-DWUjS6aW.js} +1 -1
  8. package/dist/assets/channels-list-page-CvCTJraa.js +8 -0
  9. package/dist/assets/chat-page-B42UUIFR.js +1 -0
  10. package/dist/assets/chunk-DseTPa7n.js +1 -0
  11. package/dist/assets/config-split-page-DBgt9S8b.js +1 -0
  12. package/dist/assets/confirm-dialog-GSXIvoRU.js +5 -0
  13. package/dist/assets/desktop-update-config-7bmNeWIC.js +1 -0
  14. package/dist/assets/dist-DC7f4TJH.js +41 -0
  15. package/dist/assets/doc-browser-CgdoLUT92.js +1 -0
  16. package/dist/assets/doc-browser-D0monHjG.js +1 -0
  17. package/dist/assets/doc-browser-context-CGwEOhBy.js +1 -0
  18. package/dist/assets/docx-preview-eFH9DRsS.js +20 -0
  19. package/dist/assets/download-DiP9zx-J.js +1 -0
  20. package/dist/assets/{external-link-DxuPaDoK.js → external-link-C6ZeSPef.js} +1 -1
  21. package/dist/assets/eye-suvKmtwn.js +1 -0
  22. package/dist/assets/folder-CMELbQGG.js +1 -0
  23. package/dist/assets/{form-actions-BztL7P_T.js → form-actions-CUAzpNe_.js} +1 -1
  24. package/dist/assets/index-BFeNDQ4R.css +1 -0
  25. package/dist/assets/index-D_6U-M94.js +2 -0
  26. package/dist/assets/jszip.min-Das2IAnb.js +2 -0
  27. package/dist/assets/loader-circle-tYHStefV.js +1 -0
  28. package/dist/assets/logo-badge-Cu5UGH_4.js +1 -0
  29. package/dist/assets/mcp-marketplace-page-BUzHDwW6.js +9 -0
  30. package/dist/assets/mcp-marketplace-page-ohUAdfqJ.js +1 -0
  31. package/dist/assets/model-config-page-CWP6pyBm.js +1 -0
  32. package/dist/assets/plus-tywizkeY.js +1 -0
  33. package/dist/assets/popover-DImguRok.js +1 -0
  34. package/dist/assets/provider-models-C_yOh6DE.js +1 -0
  35. package/dist/assets/provider-scoped-model-input-CE7p4SbJ.js +1 -0
  36. package/dist/assets/providers-config-page-BKPo8SjH.js +1 -0
  37. package/dist/assets/react-5sjAT_6d.js +8 -0
  38. package/dist/assets/{refresh-cw-eT8BF-8B.js → refresh-cw-CHLBzWWj.js} +1 -1
  39. package/dist/assets/remote-DXJryUxB.js +1 -0
  40. package/dist/assets/rotate-cw-BefO5brU.js +1 -0
  41. package/dist/assets/runtime-config-page-1Axv4QGu.js +1 -0
  42. package/dist/assets/{save-Cb2g0BOi.js → save-BABzyrjB.js} +1 -1
  43. package/dist/assets/{search-BcHjwdsb.js → search-BTqxG3ZG.js} +1 -1
  44. package/dist/assets/search-config-page-BkKKmxmS.js +1 -0
  45. package/dist/assets/secrets-config-page-CWJMyu-k.js +3 -0
  46. package/dist/assets/security-config-DeQUIXfi.js +1 -0
  47. package/dist/assets/select-TYZDBNmq.js +1 -0
  48. package/dist/assets/setting-row-DR23Z_5I.js +1 -0
  49. package/dist/assets/{settings-2-2DWauOjY.js → settings-2-D8WWcBnw.js} +1 -1
  50. package/dist/assets/{skeleton-P5oM14E1.js → skeleton-CloHeg0S.js} +1 -1
  51. package/dist/assets/tabs-CX-ckWoo.js +1 -0
  52. package/dist/assets/tag-chip-mCc23Rhb.js +1 -0
  53. package/dist/assets/trash-2-SAW1Z4Po.js +1 -0
  54. package/dist/assets/use-config-BucdaK23.js +1 -0
  55. package/dist/assets/use-confirm-dialog-C95F6sT1.js +1 -0
  56. package/dist/assets/use-viewport-layout-C6m3Nte7.js +1 -0
  57. package/dist/assets/x-DtCPHwCu.js +1 -0
  58. package/dist/assets/xlsx-B6zVt1RK.js +64 -0
  59. package/dist/index.html +34 -28
  60. package/package.json +14 -9
  61. package/src/app/components/layout/sidebar-items.tsx +3 -3
  62. package/src/app/components/layout/sidebar-rail.styles.ts +2 -2
  63. package/src/app/components/layout/sidebar.tsx +1 -1
  64. package/src/app/styles/design-system.css +17 -4
  65. package/src/features/chat/components/__tests__/chat-popover-content.test.tsx +41 -0
  66. package/src/features/chat/components/chat-popover-content.tsx +26 -0
  67. package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +13 -0
  68. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +21 -11
  69. package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +2 -2
  70. package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +28 -1
  71. package/src/features/chat/components/conversation/chat-conversation-content.tsx +5 -4
  72. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +9 -18
  73. package/src/features/chat/components/conversation/chat-conversation-track.tsx +35 -0
  74. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +1 -0
  75. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +7 -7
  76. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +4 -15
  77. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +20 -1
  78. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +69 -54
  79. package/src/features/chat/features/conversation/components/session-queued-input-rows.tsx +1 -1
  80. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +62 -1
  81. package/src/features/chat/features/message/components/chat-message-list.container.tsx +63 -2
  82. package/src/features/chat/features/message/utils/__tests__/chat-message-file-operation.utils.test.ts +30 -0
  83. package/src/features/chat/features/message/utils/__tests__/chat-message-process-summary.utils.test.ts +11 -1
  84. package/src/features/chat/features/message/utils/__tests__/chat-message-texts.utils.test.ts +23 -0
  85. package/src/features/chat/features/message/utils/chat-message-process-summary.utils.ts +5 -0
  86. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +138 -0
  87. package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +37 -0
  88. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +5 -4
  89. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +3 -8
  90. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +65 -20
  91. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +26 -28
  92. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
  93. package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +5 -5
  94. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +4 -4
  95. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +4 -4
  96. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +463 -99
  97. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +113 -2
  98. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +1 -0
  99. package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +197 -44
  100. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +11 -5
  101. package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +8 -6
  102. package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +99 -67
  103. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +239 -1
  104. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +56 -6
  105. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +29 -7
  106. package/src/features/chat/features/workspace/components/file-content-preview/use-workspace-file-buffer.ts +42 -0
  107. package/src/features/chat/features/workspace/components/file-content-preview/workspace-document-preview-state.tsx +18 -0
  108. package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.css +89 -0
  109. package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.tsx +87 -0
  110. package/src/features/chat/features/workspace/components/file-content-preview/workspace-presentation-preview.tsx +82 -0
  111. package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +180 -0
  112. package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +191 -0
  113. package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +1 -4
  114. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +53 -10
  115. package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +68 -2
  116. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +21 -0
  117. package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +63 -0
  118. package/src/features/chat/features/workspace/utils/chat-workspace-file-viewer.utils.ts +49 -0
  119. package/src/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils.ts +13 -0
  120. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +120 -38
  121. package/src/features/chat/index.ts +1 -0
  122. package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +76 -0
  123. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +44 -60
  124. package/src/features/chat/managers/chat-thread.manager.ts +123 -124
  125. package/src/features/chat/pages/ncp-chat-page.tsx +1 -2
  126. package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +78 -1
  127. package/src/features/chat/stores/chat-message-layout.store.test.ts +37 -0
  128. package/src/features/chat/stores/chat-message-layout.store.ts +41 -0
  129. package/src/features/chat/stores/chat-thread.store.ts +73 -13
  130. package/src/features/cron/components/cron-config.tsx +63 -80
  131. package/src/features/marketplace/components/detail-doc/__tests__/marketplace-detail-doc.test.tsx +44 -6
  132. package/src/features/marketplace/components/marketplace-detail-doc.tsx +8 -4
  133. package/src/features/marketplace/components/marketplace-page-parts.tsx +1 -1
  134. package/src/features/marketplace/hooks/use-marketplace-detail-doc-entry.ts +84 -0
  135. package/src/features/panel-apps/components/panel-apps-list.tsx +2 -2
  136. package/src/features/right-panel-resources/components/right-panel-resource-home-page.tsx +1 -1
  137. package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +25 -8
  138. package/src/features/settings/pages/appearance-settings-page.tsx +92 -13
  139. package/src/features/side-dock/components/side-dock.tsx +3 -3
  140. package/src/index.css +275 -15
  141. package/src/shared/components/__tests__/file-type-icon.test.tsx +61 -0
  142. package/src/shared/components/actions/action-link.tsx +1 -1
  143. package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +19 -0
  144. package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +16 -0
  145. package/src/shared/components/doc-browser/doc-browser-context.tsx +1 -0
  146. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +1 -1
  147. package/src/shared/components/doc-browser/doc-browser.tsx +11 -3
  148. package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +5 -0
  149. package/src/shared/components/doc-browser/stores/doc-browser.store.ts +6 -1
  150. package/src/shared/components/doc-browser/types/doc-browser.types.ts +2 -0
  151. package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +11 -0
  152. package/src/shared/components/file-type-icon.tsx +272 -0
  153. package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +22 -0
  154. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +17 -2
  155. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  156. package/src/shared/components/ui/button.tsx +1 -1
  157. package/src/shared/components/ui/dialog.tsx +1 -1
  158. package/src/shared/components/ui/input.tsx +1 -1
  159. package/src/shared/components/ui/select.tsx +1 -1
  160. package/src/shared/components/ui/switch.tsx +1 -1
  161. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +38 -0
  162. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +82 -2
  163. package/src/shared/components/ui/tabs.tsx +1 -1
  164. package/src/shared/components/ui/textarea.tsx +1 -1
  165. package/src/shared/lib/api/__tests__/server-path.utils.test.ts +28 -0
  166. package/src/shared/lib/api/utils/server-path.utils.ts +19 -20
  167. package/src/shared/lib/i18n/locales/en-US/chat.json +99 -0
  168. package/src/shared/lib/i18n/locales/en-US/core.json +6 -0
  169. package/src/shared/lib/i18n/locales/zh-CN/chat.json +99 -0
  170. package/src/shared/lib/i18n/locales/zh-CN/core.json +6 -0
  171. package/dist/assets/api-B7Qigvtm.js +0 -13
  172. package/dist/assets/appearance-settings-page-CuE0Iiqj.js +0 -1
  173. package/dist/assets/channels-list-page-CTsM6TcP.js +0 -8
  174. package/dist/assets/chat-page-C_5dcuE3.js +0 -1
  175. package/dist/assets/config-split-page-Fbb4PtTf.js +0 -1
  176. package/dist/assets/confirm-dialog-D2EG3nqE.js +0 -5
  177. package/dist/assets/desktop-update-config-BGR3HUi1.js +0 -1
  178. package/dist/assets/dist-7JTjycxE.js +0 -1
  179. package/dist/assets/dist-wXLhk4hl.js +0 -1
  180. package/dist/assets/doc-browser-bHyXnxlj.js +0 -1
  181. package/dist/assets/doc-browser-context-CYAGm5d5.js +0 -1
  182. package/dist/assets/doc-browser-gTrQ3jCF.js +0 -1
  183. package/dist/assets/es2015-j1SRCIX5.js +0 -41
  184. package/dist/assets/i18n-provider-B4oMxOFx.js +0 -1
  185. package/dist/assets/index-CvrvblgX.css +0 -1
  186. package/dist/assets/index-Obd4JYU2.js +0 -104
  187. package/dist/assets/loader-circle-CdzgK4eH.js +0 -1
  188. package/dist/assets/mcp-marketplace-page-Bt7CuOoq.js +0 -9
  189. package/dist/assets/mcp-marketplace-page-Ck3t78_n.js +0 -1
  190. package/dist/assets/model-config-page-DeKk9gvE.js +0 -1
  191. package/dist/assets/plus-Bx7wQbhG.js +0 -1
  192. package/dist/assets/provider-scoped-model-input-DsH2LF1q.js +0 -1
  193. package/dist/assets/providers-config-page-BFnGp68F.js +0 -1
  194. package/dist/assets/react-UirzUuST.js +0 -8
  195. package/dist/assets/remote-CDkHZtA8.js +0 -1
  196. package/dist/assets/rotate-cw-1JqxHTuw.js +0 -1
  197. package/dist/assets/runtime-config-page-BelAqiNG.js +0 -1
  198. package/dist/assets/search-config-page-zPm6--Ig.js +0 -1
  199. package/dist/assets/secrets-config-page-Cxyp-KuQ.js +0 -3
  200. package/dist/assets/security-config-B_gCq9fn.js +0 -1
  201. package/dist/assets/select-CdSEOwVM.js +0 -1
  202. package/dist/assets/setting-row-CTAtGexr.js +0 -1
  203. package/dist/assets/side-dock-DPvakJ0a.js +0 -3
  204. package/dist/assets/switch-BU_UEULb.js +0 -1
  205. package/dist/assets/tag-chip-D-WsKoT1.js +0 -1
  206. package/dist/assets/tooltip-CjkOaHW7.js +0 -1
  207. package/dist/assets/use-config--hx5oxQn.js +0 -1
  208. package/dist/assets/use-confirm-dialog-CD9a_SK1.js +0 -1
  209. package/dist/assets/x-DT5x45JU.js +0 -1
  210. /package/dist/assets/{config-hints-C_iP1zl_.js → config-hints-fDrYfl0l.js} +0 -0
  211. /package/dist/assets/{host-capabilities-9bB_998Z.js → host-capabilities-zZvY9U63.js} +0 -0
  212. /package/dist/assets/{middleware-BILWbJE4.js → middleware-BLMHv9YF.js} +0 -0
package/dist/index.html CHANGED
@@ -186,34 +186,40 @@
186
186
  })();
187
187
  </script>
188
188
  <title>NextClaw</title>
189
- <script type="module" crossorigin src="/assets/index-Obd4JYU2.js"></script>
190
- <link rel="modulepreload" crossorigin href="/assets/react-UirzUuST.js">
191
- <link rel="modulepreload" crossorigin href="/assets/dist-7JTjycxE.js">
192
- <link rel="modulepreload" crossorigin href="/assets/dist-wXLhk4hl.js">
193
- <link rel="modulepreload" crossorigin href="/assets/tooltip-CjkOaHW7.js">
194
- <link rel="modulepreload" crossorigin href="/assets/book-open-Ba2f7YiG.js">
195
- <link rel="modulepreload" crossorigin href="/assets/plus-Bx7wQbhG.js">
196
- <link rel="modulepreload" crossorigin href="/assets/x-DT5x45JU.js">
197
- <link rel="modulepreload" crossorigin href="/assets/middleware-BILWbJE4.js">
198
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-CYAGm5d5.js">
199
- <link rel="modulepreload" crossorigin href="/assets/es2015-j1SRCIX5.js">
200
- <link rel="modulepreload" crossorigin href="/assets/switch-BU_UEULb.js">
201
- <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-D2EG3nqE.js">
202
- <link rel="modulepreload" crossorigin href="/assets/use-confirm-dialog-CD9a_SK1.js">
203
- <link rel="modulepreload" crossorigin href="/assets/host-capabilities-9bB_998Z.js">
204
- <link rel="modulepreload" crossorigin href="/assets/side-dock-DPvakJ0a.js">
205
- <link rel="modulepreload" crossorigin href="/assets/select-CdSEOwVM.js">
206
- <link rel="modulepreload" crossorigin href="/assets/api-B7Qigvtm.js">
207
- <link rel="modulepreload" crossorigin href="/assets/search-BcHjwdsb.js">
208
- <link rel="modulepreload" crossorigin href="/assets/external-link-DxuPaDoK.js">
209
- <link rel="modulepreload" crossorigin href="/assets/refresh-cw-eT8BF-8B.js">
210
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-bHyXnxlj.js">
211
- <link rel="modulepreload" crossorigin href="/assets/i18n-provider-B4oMxOFx.js">
212
- <link rel="modulepreload" crossorigin href="/assets/loader-circle-CdzgK4eH.js">
213
- <link rel="modulepreload" crossorigin href="/assets/skeleton-P5oM14E1.js">
214
- <link rel="modulepreload" crossorigin href="/assets/tag-chip-D-WsKoT1.js">
215
- <link rel="modulepreload" crossorigin href="/assets/mcp-marketplace-page-Bt7CuOoq.js">
216
- <link rel="stylesheet" crossorigin href="/assets/index-CvrvblgX.css">
189
+ <script type="module" crossorigin src="/assets/index-D_6U-M94.js"></script>
190
+ <link rel="modulepreload" crossorigin href="/assets/chunk-DseTPa7n.js">
191
+ <link rel="modulepreload" crossorigin href="/assets/react-5sjAT_6d.js">
192
+ <link rel="modulepreload" crossorigin href="/assets/dist-DC7f4TJH.js">
193
+ <link rel="modulepreload" crossorigin href="/assets/select-TYZDBNmq.js">
194
+ <link rel="modulepreload" crossorigin href="/assets/popover-DImguRok.js">
195
+ <link rel="modulepreload" crossorigin href="/assets/api-BOXOrpcJ.js">
196
+ <link rel="modulepreload" crossorigin href="/assets/x-DtCPHwCu.js">
197
+ <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-GSXIvoRU.js">
198
+ <link rel="modulepreload" crossorigin href="/assets/search-BTqxG3ZG.js">
199
+ <link rel="modulepreload" crossorigin href="/assets/external-link-C6ZeSPef.js">
200
+ <link rel="modulepreload" crossorigin href="/assets/plus-tywizkeY.js">
201
+ <link rel="modulepreload" crossorigin href="/assets/refresh-cw-CHLBzWWj.js">
202
+ <link rel="modulepreload" crossorigin href="/assets/middleware-BLMHv9YF.js">
203
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-CGwEOhBy.js">
204
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-D0monHjG.js">
205
+ <link rel="modulepreload" crossorigin href="/assets/book-open-DWUjS6aW.js">
206
+ <link rel="modulepreload" crossorigin href="/assets/use-confirm-dialog-C95F6sT1.js">
207
+ <link rel="modulepreload" crossorigin href="/assets/download-DiP9zx-J.js">
208
+ <link rel="modulepreload" crossorigin href="/assets/eye-suvKmtwn.js">
209
+ <link rel="modulepreload" crossorigin href="/assets/folder-CMELbQGG.js">
210
+ <link rel="modulepreload" crossorigin href="/assets/tabs-CX-ckWoo.js">
211
+ <link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-C6m3Nte7.js">
212
+ <link rel="modulepreload" crossorigin href="/assets/loader-circle-tYHStefV.js">
213
+ <link rel="modulepreload" crossorigin href="/assets/skeleton-CloHeg0S.js">
214
+ <link rel="modulepreload" crossorigin href="/assets/trash-2-SAW1Z4Po.js">
215
+ <link rel="modulepreload" crossorigin href="/assets/logo-badge-Cu5UGH_4.js">
216
+ <link rel="modulepreload" crossorigin href="/assets/host-capabilities-zZvY9U63.js">
217
+ <link rel="modulepreload" crossorigin href="/assets/provider-models-C_yOh6DE.js">
218
+ <link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-CkHLbvZQ.js">
219
+ <link rel="modulepreload" crossorigin href="/assets/tag-chip-mCc23Rhb.js">
220
+ <link rel="modulepreload" crossorigin href="/assets/mcp-marketplace-page-BUzHDwW6.js">
221
+ <link rel="stylesheet" crossorigin href="/assets/app-presenter-provider-D3BuuOyZ.css">
222
+ <link rel="stylesheet" crossorigin href="/assets/index-BFeNDQ4R.css">
217
223
  </head>
218
224
 
219
225
  <body>
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@nextclaw/ui",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "dependencies": {
8
+ "@aiden0z/pptx-renderer": "1.2.4",
9
+ "@iconify/icons-vscode-icons": "^1.2.29",
10
+ "@iconify/react": "^6.0.2",
8
11
  "@radix-ui/react-dialog": "^1.1.2",
9
12
  "@radix-ui/react-label": "^2.1.0",
10
13
  "@radix-ui/react-popover": "^1.1.15",
@@ -16,6 +19,7 @@
16
19
  "@tanstack/react-query": "^5.59.20",
17
20
  "class-variance-authority": "^0.7.1",
18
21
  "clsx": "^2.1.1",
22
+ "docx-preview": "0.4.0",
19
23
  "lucide-react": "^0.462.0",
20
24
  "qrcode": "^1.5.4",
21
25
  "react": "^18.3.1",
@@ -26,16 +30,17 @@
26
30
  "rxjs": "^7.8.2",
27
31
  "sonner": "^1.7.1",
28
32
  "tailwind-merge": "^2.5.4",
33
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
29
34
  "zod": "^3.23.8",
30
35
  "zustand": "^5.0.2",
31
- "@nextclaw/client-sdk": "0.5.2",
32
- "@nextclaw/ncp": "0.7.2",
33
- "@nextclaw/ncp-http-agent-client": "0.4.2",
34
- "@nextclaw/ncp-toolkit": "0.6.2",
35
- "@nextclaw/shared": "0.4.2",
36
- "@nextclaw/agent-chat": "0.3.1",
37
- "@nextclaw/agent-chat-ui": "0.6.2",
38
- "@nextclaw/ncp-react": "0.5.2"
36
+ "@nextclaw/agent-chat-ui": "0.6.4",
37
+ "@nextclaw/client-sdk": "0.5.4",
38
+ "@nextclaw/ncp": "0.7.3",
39
+ "@nextclaw/ncp-react": "0.5.4",
40
+ "@nextclaw/ncp-toolkit": "0.6.4",
41
+ "@nextclaw/shared": "0.4.3",
42
+ "@nextclaw/agent-chat": "0.3.2",
43
+ "@nextclaw/ncp-http-agent-client": "0.4.3"
39
44
  },
40
45
  "devDependencies": {
41
46
  "@testing-library/react": "^16.3.0",
@@ -110,7 +110,7 @@ export function SidebarNavLinkItem({
110
110
  aria-label={label}
111
111
  aria-current={isActive ? "page" : undefined}
112
112
  className={cn(
113
- "group flex w-full items-center rounded-xl font-medium transition-colors duration-base focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35",
113
+ "group flex w-full items-center rounded-xl font-medium transition-colors duration-base focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
114
114
  collapsed
115
115
  ? cn(SIDEBAR_RAIL_CONTROL_CLASS, "justify-center px-0 py-0")
116
116
  : tone.row,
@@ -213,7 +213,7 @@ export function SidebarActionItem({
213
213
  onClick={onClick}
214
214
  aria-label={label}
215
215
  className={cn(
216
- "group flex w-full items-center rounded-xl font-medium text-muted-foreground transition-colors duration-base hover:bg-gray-200/60 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35",
216
+ "group flex w-full items-center rounded-xl font-medium text-muted-foreground transition-colors duration-base hover:bg-gray-200/60 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
217
217
  collapsed
218
218
  ? cn(
219
219
  SIDEBAR_RAIL_CONTROL_CLASS,
@@ -287,7 +287,7 @@ export function SidebarSelectItem({
287
287
  <SelectTrigger
288
288
  aria-label={label}
289
289
  className={cn(
290
- "group h-auto w-full rounded-xl border-0 bg-transparent font-medium text-muted-foreground shadow-none hover:bg-gray-200/60 hover:text-gray-900 focus:ring-0 focus-visible:ring-2 focus-visible:ring-primary/35",
290
+ "group h-auto w-full rounded-xl border-0 bg-transparent font-medium text-muted-foreground shadow-none hover:bg-gray-200/60 hover:text-gray-900 focus:ring-0 focus-visible:ring-1 focus-visible:ring-border",
291
291
  collapsed
292
292
  ? cn(
293
293
  SIDEBAR_RAIL_CONTROL_CLASS,
@@ -9,9 +9,9 @@ export const SIDEBAR_SCROLL_EDGE_FADE_CLASS =
9
9
  "[mask-image:linear-gradient(to_bottom,black_calc(100%_-_28px),transparent)] [-webkit-mask-image:linear-gradient(to_bottom,black_calc(100%_-_28px),transparent)]";
10
10
 
11
11
  export const SIDEBAR_RAIL_SURFACE_CLASS =
12
- "text-muted-foreground transition-colors duration-base hover:bg-gray-200/60 hover:text-gray-900 active:bg-gray-200/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35";
12
+ "text-muted-foreground transition-colors duration-base hover:bg-gray-200/60 hover:text-gray-900 active:bg-gray-200/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border";
13
13
 
14
14
  export const SIDEBAR_RAIL_ACTIVE_SURFACE_CLASS = "bg-gray-200/80 text-gray-900";
15
15
 
16
16
  export const SIDEBAR_RAIL_PRIMARY_SURFACE_CLASS =
17
- "bg-primary/10 text-primary transition-colors duration-base hover:bg-primary/15 hover:text-primary-700 active:bg-primary/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35";
17
+ "bg-primary/10 text-primary transition-colors duration-base hover:bg-primary/15 hover:text-primary-700 active:bg-primary/20 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border";
@@ -133,7 +133,7 @@ function SettingsSidebarHeader({
133
133
  to="/chat"
134
134
  aria-label={t("backToMain")}
135
135
  className={cn(
136
- "group inline-flex min-w-0 items-center rounded-lg text-[12px] font-medium text-muted-foreground transition-colors hover:bg-gray-200/60 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35",
136
+ "group inline-flex min-w-0 items-center rounded-lg text-[12px] font-medium text-muted-foreground transition-colors hover:bg-gray-200/60 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border",
137
137
  isCollapsed
138
138
  ? cn(
139
139
  SIDEBAR_RAIL_CONTROL_CLASS,
@@ -364,6 +364,19 @@
364
364
  color: hsl(var(--gray-800));
365
365
  }
366
366
 
367
+ /* User bubble is light in work theme; keep clickable skill tokens as link-colored text. */
368
+ :root[data-theme="work"] .nextclaw-chat-message-user .nextclaw-chat-inline-token {
369
+ border-color: transparent;
370
+ background-color: transparent;
371
+ color: var(--md-link, #1f73c9);
372
+ box-shadow: none;
373
+ }
374
+
375
+ :root[data-theme="work"] .nextclaw-chat-message-user .nextclaw-chat-inline-token > span:first-child {
376
+ color: currentColor;
377
+ opacity: 0.8;
378
+ }
379
+
367
380
  }
368
381
 
369
382
  @layer base {
@@ -894,10 +907,10 @@
894
907
  -webkit-backdrop-filter: blur(12px);
895
908
  }
896
909
 
897
- /* Focus Ring */
910
+ /* Focus Ring — light inset-style ring, no offset box */
898
911
  .focus-ring {
899
- @apply focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2;
900
- --tw-ring-color: hsl(var(--ring));
901
- --tw-ring-offset-color: hsl(var(--ring-offset));
912
+ @apply focus:outline-none focus-visible:ring-1 focus-visible:ring-offset-0;
913
+ --tw-ring-color: hsl(var(--border));
914
+ --tw-ring-offset-color: transparent;
902
915
  }
903
916
  }
@@ -0,0 +1,41 @@
1
+ import { useState } from "react";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import { describe, expect, it } from "vitest";
4
+ import { ChatPopoverContent } from "@/features/chat/components/chat-popover-content";
5
+ import { Popover, PopoverTrigger } from "@/shared/components/ui/popover";
6
+
7
+ function ChatPopoverHarness() {
8
+ const [open, setOpen] = useState(true);
9
+ return (
10
+ <Popover open={open} onOpenChange={setOpen}>
11
+ <PopoverTrigger>Sessions</PopoverTrigger>
12
+ <ChatPopoverContent>Session search</ChatPopoverContent>
13
+ </Popover>
14
+ );
15
+ }
16
+
17
+ function appendComposerFocusTarget(): HTMLElement {
18
+ const shell = document.createElement("div");
19
+ shell.className = "nextclaw-chat-input-bar-shell";
20
+ const composer = document.createElement("div");
21
+ composer.setAttribute("contenteditable", "true");
22
+ composer.setAttribute("role", "textbox");
23
+ shell.appendChild(composer);
24
+ document.body.appendChild(shell);
25
+ return composer;
26
+ }
27
+
28
+ describe("ChatPopoverContent", () => {
29
+ it("keeps chat popovers open when the composer receives programmatic focus", () => {
30
+ const composer = appendComposerFocusTarget();
31
+ try {
32
+ render(<ChatPopoverHarness />);
33
+
34
+ fireEvent.focusIn(composer);
35
+
36
+ expect(screen.getByText("Session search")).toBeTruthy();
37
+ } finally {
38
+ composer.closest(".nextclaw-chat-input-bar-shell")?.remove();
39
+ }
40
+ });
41
+ });
@@ -0,0 +1,26 @@
1
+ import { forwardRef, type ComponentPropsWithoutRef, type ElementRef } from "react";
2
+ import { PopoverContent } from "@/shared/components/ui/popover";
3
+
4
+ function isChatComposerFocusTarget(target: EventTarget | null): boolean {
5
+ return target instanceof HTMLElement && Boolean(
6
+ target.closest('.nextclaw-chat-input-bar-shell [role="textbox"][contenteditable="true"]'),
7
+ );
8
+ }
9
+
10
+ export const ChatPopoverContent = forwardRef<
11
+ ElementRef<typeof PopoverContent>,
12
+ ComponentPropsWithoutRef<typeof PopoverContent>
13
+ >(function ChatPopoverContent({ onFocusOutside, ...props }, ref) {
14
+ return (
15
+ <PopoverContent
16
+ {...props}
17
+ ref={ref}
18
+ onFocusOutside={(event) => {
19
+ onFocusOutside?.(event);
20
+ if (!event.defaultPrevented && isChatComposerFocusTarget(event.detail.originalEvent.target)) {
21
+ event.preventDefault();
22
+ }
23
+ }}
24
+ />
25
+ );
26
+ });
@@ -3,6 +3,7 @@ import userEvent from "@testing-library/user-event";
3
3
  import type { NcpMessage } from "@nextclaw/ncp";
4
4
  import { beforeEach, expect, it, vi } from "vitest";
5
5
  import { ChatConversationContent } from "@/features/chat/components/conversation/chat-conversation-content";
6
+ import { useChatMessageLayoutStore } from "@/features/chat/stores/chat-message-layout.store";
6
7
 
7
8
  const captures = vi.hoisted(() => ({
8
9
  isAtBottom: true,
@@ -52,11 +53,23 @@ function renderContent(options: { bottomSlot?: React.ReactNode } = {}) {
52
53
  }
53
54
 
54
55
  beforeEach(() => {
56
+ useChatMessageLayoutStore.getState().setLayout("card");
55
57
  captures.isAtBottom = true;
56
58
  captures.onScroll.mockReset();
57
59
  captures.scrollToBottom.mockReset();
58
60
  });
59
61
 
62
+ it("uses the centered reading track in flat message layout", () => {
63
+ useChatMessageLayoutStore.getState().setLayout("flat");
64
+
65
+ renderContent();
66
+
67
+ const track = screen
68
+ .getByTestId("chat-message-list")
69
+ .closest('[data-chat-conversation-track="flat"]');
70
+ expect(track?.className).toContain("max-w-[min(52rem,100%)]");
71
+ });
72
+
60
73
  it("hides the scroll-to-bottom action while the conversation is already at the bottom", () => {
61
74
  renderContent();
62
75
 
@@ -13,8 +13,7 @@ import type { NcpSessionSummaryView, SessionEntryView } from "@/shared/lib/api";
13
13
 
14
14
  const mocks = vi.hoisted(() => ({
15
15
  deleteSession: vi.fn(),
16
- openChildSessionPanel: vi.fn(),
17
- openSessionCronPanel: vi.fn(),
16
+ toggleWorkspacePanel: vi.fn(),
18
17
  selectSession: vi.fn(),
19
18
  sessionItems: [] as NcpSessionListItemView[],
20
19
  isSessionListLoading: false,
@@ -24,8 +23,7 @@ vi.mock("@/features/chat/components/providers/chat-presenter.provider", () => ({
24
23
  usePresenter: () => ({
25
24
  chatThreadManager: {
26
25
  deleteSession: mocks.deleteSession,
27
- openChildSessionPanel: mocks.openChildSessionPanel,
28
- openSessionCronPanel: mocks.openSessionCronPanel,
26
+ toggleWorkspacePanel: mocks.toggleWorkspacePanel,
29
27
  },
30
28
  chatSessionListManager: {
31
29
  selectSession: mocks.selectSession,
@@ -120,8 +118,7 @@ function renderHeaderSection() {
120
118
  describe("ChatConversationHeaderSection", () => {
121
119
  beforeEach(() => {
122
120
  mocks.deleteSession.mockReset();
123
- mocks.openChildSessionPanel.mockReset();
124
- mocks.openSessionCronPanel.mockReset();
121
+ mocks.toggleWorkspacePanel.mockReset();
125
122
  mocks.selectSession.mockReset();
126
123
  mocks.isSessionListLoading = false;
127
124
  viewportLayoutManager.resetForTests();
@@ -195,16 +192,29 @@ describe("ChatConversationHeaderSection", () => {
195
192
  ];
196
193
  });
197
194
 
198
- it("shows the child-session entry from session query state before a tool card opens it", async () => {
195
+ it("opens the current session workspace overview from the header", async () => {
199
196
  const user = userEvent.setup();
200
197
 
201
198
  renderHeaderSection();
202
- await user.click(screen.getByRole("button", { name: "View child sessions" }));
199
+ await user.click(screen.getByRole("button", { name: "Open session workspace" }));
203
200
 
204
- expect(mocks.openChildSessionPanel).toHaveBeenCalledWith({
205
- parentSessionKey: "parent-session-1",
206
- activeChildSessionKey: "child-session-1",
201
+ expect(mocks.toggleWorkspacePanel).toHaveBeenCalledWith("parent-session-1");
202
+ });
203
+
204
+ it("shows the close workspace action while the current session panel is open", () => {
205
+ useChatThreadStore.setState({
206
+ snapshot: {
207
+ ...useChatThreadStore.getState().snapshot,
208
+ workspacePanelParentKey: "parent-session-1",
209
+ activeWorkspacePanelKind: "overview",
210
+ },
207
211
  });
212
+
213
+ renderHeaderSection();
214
+
215
+ expect(
216
+ screen.getByRole("button", { name: "Close session workspace" }),
217
+ ).toBeTruthy();
208
218
  });
209
219
 
210
220
  it("uses the collapsed desktop title as a session switcher", async () => {
@@ -51,8 +51,8 @@ describe("ChatConversationHeader", () => {
51
51
  sessionKey="session-1"
52
52
  canDeleteSession
53
53
  isDeletePending={false}
54
- childSessionCount={0}
55
- sessionCronJobCount={0}
54
+ isWorkspaceOpen={false}
55
+ onToggleWorkspace={vi.fn()}
56
56
  onDeleteSession={vi.fn()}
57
57
  />
58
58
  ),
@@ -14,16 +14,23 @@ vi.mock("@/features/chat/features/workspace/components/chat-session-workspace-pa
14
14
  ChatSessionWorkspacePanel: ({
15
15
  sessionProjectRoot,
16
16
  sessionWorkingDir,
17
+ workspacePanelWidth,
17
18
  }: {
18
19
  sessionProjectRoot: string | null;
19
20
  sessionWorkingDir: string | null;
21
+ workspacePanelWidth: number;
20
22
  }) => {
21
- mocks.panelProps({ sessionProjectRoot, sessionWorkingDir });
23
+ mocks.panelProps({
24
+ sessionProjectRoot,
25
+ sessionWorkingDir,
26
+ workspacePanelWidth,
27
+ });
22
28
  return (
23
29
  <div
24
30
  data-testid="workspace-panel"
25
31
  data-project-root={sessionProjectRoot ?? ""}
26
32
  data-working-dir={sessionWorkingDir ?? ""}
33
+ data-width={workspacePanelWidth}
27
34
  />
28
35
  );
29
36
  },
@@ -85,6 +92,7 @@ describe("ChatConversationWorkspaceSection", () => {
85
92
  workspaceNavigationHistoryIndex: 0,
86
93
  sessionProjectRoot: null,
87
94
  sessionWorkingDir: null,
95
+ workspacePanelWidth: 620,
88
96
  },
89
97
  });
90
98
  useChatQueryStore.setState({
@@ -122,11 +130,30 @@ describe("ChatConversationWorkspaceSection", () => {
122
130
  expect(panel.getAttribute("data-working-dir")).toBe(
123
131
  "/Users/peiwang/Projects/nextbot",
124
132
  );
133
+ expect(panel.getAttribute("data-width")).toBe("620");
125
134
  expect(mocks.panelProps).toHaveBeenCalledWith(
126
135
  expect.objectContaining({
127
136
  sessionProjectRoot: "/Users/peiwang/Projects/nextbot",
128
137
  sessionWorkingDir: "/Users/peiwang/Projects/nextbot",
138
+ workspacePanelWidth: 620,
129
139
  }),
130
140
  );
131
141
  });
142
+
143
+ it("renders an explicitly opened overview without requiring existing workspace resources", () => {
144
+ useChatThreadStore.getState().setSnapshot({
145
+ activeWorkspacePanelKind: "overview",
146
+ workspaceFileTabs: [],
147
+ activeWorkspaceFileKey: null,
148
+ });
149
+
150
+ render(
151
+ <ChatConversationWorkspaceSection
152
+ layoutMode="desktop"
153
+ sessionKey="session-1"
154
+ />,
155
+ );
156
+
157
+ expect(screen.getByTestId("workspace-panel")).toBeTruthy();
158
+ });
132
159
  });
@@ -3,6 +3,7 @@ import { useStickyBottomScroll } from "@nextclaw/agent-chat-ui";
3
3
  import type { NcpMessage } from "@nextclaw/ncp";
4
4
  import { ArrowDown } from "lucide-react";
5
5
  import { ChatMessageListContainer } from "@/features/chat/features/message/components/chat-message-list.container";
6
+ import { ChatConversationTrack } from "@/features/chat/components/conversation/chat-conversation-track";
6
7
  import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
7
8
  import { t } from "@/shared/lib/i18n";
8
9
 
@@ -60,17 +61,17 @@ export function ChatConversationContent({
60
61
  ) : (
61
62
  <>
62
63
  {hideEmptyHint || !hasMessages ? null : (
63
- <div className="mx-auto w-full max-w-[min(1120px,100%)] px-4 py-4 sm:px-6 sm:py-5">
64
+ <ChatConversationTrack className="py-4 sm:py-5">
64
65
  <ChatMessageListContainer
65
66
  messages={messages}
66
67
  isSending={hasMessages && isSending && isAwaitingAssistantOutput}
67
68
  />
68
- </div>
69
+ </ChatConversationTrack>
69
70
  )}
70
71
  {bottomSlot ? (
71
- <div className="mx-auto w-full max-w-[min(1120px,100%)] px-4 pb-4 sm:px-6 sm:pb-5">
72
+ <ChatConversationTrack className="pb-4 sm:pb-5">
72
73
  {bottomSlot}
73
- </div>
74
+ </ChatConversationTrack>
74
75
  ) : null}
75
76
  </>
76
77
  )}
@@ -5,7 +5,6 @@ import { ChatSessionProjectBadge } from "@/features/chat/features/session/compon
5
5
  import { ChatSessionTitleSwitcher } from "@/features/chat/features/session/components/session-header/chat-session-title-switcher";
6
6
  import { usePresenter } from "@/features/chat/components/providers/chat-presenter.provider";
7
7
  import { SessionContextIconNode } from "@/features/chat/features/session/components/session-context-icon";
8
- import { useChatConversationWorkspaceState } from "@/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state";
9
8
  import { useNcpChatSelectedSession } from "@/features/chat/features/ncp/hooks/use-ncp-chat-derived-state";
10
9
  import { sessionDisplayName } from "@/features/chat/features/session/utils/chat-session-display.utils";
11
10
  import {
@@ -59,8 +58,6 @@ export function ChatConversationHeaderSection({
59
58
  const sessionProjectName =
60
59
  selectedSession?.projectName ?? getSessionProjectName(sessionProjectRoot);
61
60
  const canDeleteSession = Boolean(selectedSession);
62
- const { childSessionTabs, sessionCronJobs } =
63
- useChatConversationWorkspaceState(snapshot, sessionKey);
64
61
  const shouldShowSessionHeader = Boolean(sessionKey || sessionTypeLabel);
65
62
  const sessionHeaderTitle =
66
63
  (selectedSession ? sessionDisplayName(selectedSession) : undefined) ||
@@ -72,20 +69,16 @@ export function ChatConversationHeaderSection({
72
69
  selectedSession?.agentId?.trim() ?? selectedAgentId?.trim() ?? "";
73
70
  const shouldShowHeaderAgentAvatar =
74
71
  normalizedAgentId.length > 0 && normalizedAgentId.toLowerCase() !== "main";
75
- const openChildSessions = () => {
72
+ const isWorkspaceOpen = Boolean(
73
+ sessionKey &&
74
+ snapshot.workspacePanelParentKey === sessionKey &&
75
+ snapshot.activeWorkspacePanelKind,
76
+ );
77
+ const toggleWorkspace = () => {
76
78
  if (!sessionKey) {
77
79
  return;
78
80
  }
79
- presenter.chatThreadManager.openChildSessionPanel({
80
- parentSessionKey: sessionKey,
81
- activeChildSessionKey: childSessionTabs[0]?.sessionKey ?? null,
82
- });
83
- };
84
- const openSessionCronJobs = () => {
85
- if (!sessionKey || sessionCronJobs.length === 0) {
86
- return;
87
- }
88
- presenter.chatThreadManager.openSessionCronPanel(sessionKey);
81
+ presenter.chatThreadManager.toggleWorkspacePanel(sessionKey);
89
82
  };
90
83
 
91
84
  return (
@@ -148,10 +141,8 @@ export function ChatConversationHeaderSection({
148
141
  isDeletePending={snapshot.isDeletePending}
149
142
  projectRoot={sessionProjectRoot}
150
143
  metadata={selectedSession?.metadata ?? null}
151
- childSessionCount={childSessionTabs.length}
152
- sessionCronJobCount={sessionCronJobs.length}
153
- onOpenChildSessions={openChildSessions}
154
- onOpenSessionCronJobs={openSessionCronJobs}
144
+ isWorkspaceOpen={isWorkspaceOpen}
145
+ onToggleWorkspace={toggleWorkspace}
155
146
  onDeleteSession={presenter.chatThreadManager.deleteSession}
156
147
  />
157
148
  ) : null
@@ -0,0 +1,35 @@
1
+ import type { ReactNode } from "react";
2
+ import { useChatMessageLayoutStore } from "@/features/chat/stores/chat-message-layout.store";
3
+ import { cn } from "@/shared/lib/utils";
4
+
5
+ type ChatConversationTrackProps = {
6
+ children: ReactNode;
7
+ className?: string;
8
+ width?: "messages" | "composer";
9
+ };
10
+
11
+ export function ChatConversationTrack({
12
+ children,
13
+ className,
14
+ width = "messages",
15
+ }: ChatConversationTrackProps) {
16
+ const layout = useChatMessageLayoutStore((state) => state.layout);
17
+
18
+ return (
19
+ <div
20
+ data-chat-conversation-track={layout}
21
+ data-chat-conversation-track-width={width}
22
+ className={cn(
23
+ "mx-auto w-full px-4 sm:px-6",
24
+ layout === "flat"
25
+ ? width === "composer"
26
+ ? "max-w-[min(54rem,100%)]"
27
+ : "max-w-[min(52rem,100%)]"
28
+ : "max-w-[min(1120px,100%)]",
29
+ className,
30
+ )}
31
+ >
32
+ {children}
33
+ </div>
34
+ );
35
+ }
@@ -42,6 +42,7 @@ export function ChatConversationWorkspaceSection({
42
42
  sessionWorkingDir={
43
43
  selectedSession?.workingDir ?? selectedSession?.projectRoot ?? null
44
44
  }
45
+ workspacePanelWidth={snapshot.workspacePanelWidth}
45
46
  displayMode={layoutMode === "mobile" ? "overlay" : "docked"}
46
47
  />
47
48
  );