@nextclaw/ui 0.14.1 → 0.14.3

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 (224) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/assets/{api-DPcvCLfa.js → api-BP_8IaxB.js} +7 -7
  3. package/dist/assets/channels-list-page-DEh5Jjqx.js +8 -0
  4. package/dist/assets/chat-page-BRB0N5WW.js +105 -0
  5. package/dist/assets/config-split-page-CRhlZ_pH.js +1 -0
  6. package/dist/assets/{confirm-dialog-CWh5FfK2.js → confirm-dialog-DsivFJ4r.js} +2 -2
  7. package/dist/assets/{desktop-update-config-DsRhBizi.js → desktop-update-config-B0w9p2ep.js} +1 -1
  8. package/dist/assets/{dist-DPrgcEC0.js → dist-CikkhOlq.js} +1 -1
  9. package/dist/assets/{dist-DsE4OsSS.js → dist-PVA_xL1D.js} +1 -1
  10. package/dist/assets/doc-browser-BoNJ7-tE.js +1 -0
  11. package/dist/assets/doc-browser-CdJ_d4ik.js +1 -0
  12. package/dist/assets/doc-browser-context-MTw4EvKd.js +1 -0
  13. package/dist/assets/{ellipsis-B81FStLm.js → ellipsis-y6vDtq4M.js} +1 -1
  14. package/dist/assets/{external-link-C_dmG-WJ.js → external-link-DVJIQf_G.js} +1 -1
  15. package/dist/assets/index-BiE-K8-q.css +1 -0
  16. package/dist/assets/index-D9BAE_L_.js +105 -0
  17. package/dist/assets/mcp-marketplace-page-B1SZNY5m.js +40 -0
  18. package/dist/assets/mcp-marketplace-page-Cq_Tw42T.js +1 -0
  19. package/dist/assets/middleware-CkFT3R4v.js +1 -0
  20. package/dist/assets/model-config-page-DotaTUHb.js +1 -0
  21. package/dist/assets/plus-BbZqquJe.js +1 -0
  22. package/dist/assets/provider-scoped-model-input-DsFRuWJH.js +1 -0
  23. package/dist/assets/providers-config-page-DW4tQSLN.js +1 -0
  24. package/dist/assets/{react-sZz5HSCm.js → react-VNqT5Zp7.js} +1 -1
  25. package/dist/assets/remote-B8TiUfwW.js +1 -0
  26. package/dist/assets/rotate-cw-DjHDTkCv.js +1 -0
  27. package/dist/assets/runtime-config-page-S6ErRHR8.js +1 -0
  28. package/dist/assets/{save-MzjoiHri.js → save-BOJ477H-.js} +1 -1
  29. package/dist/assets/{search-B29dE4GN.js → search-BEti5beA.js} +1 -1
  30. package/dist/assets/{search-config-page-Dl5sZzob.js → search-config-page-DGj5am03.js} +1 -1
  31. package/dist/assets/{secrets-config-page-C_l-IFCK.js → secrets-config-page--IzrIOid.js} +2 -2
  32. package/dist/assets/{select-BKmh05hd.js → select-hoj8dK4K.js} +2 -2
  33. package/dist/assets/{tag-chip-BS_7Ueom.js → tag-chip-T8-h-die.js} +1 -1
  34. package/dist/assets/use-config-CjRV2hwL.js +1 -0
  35. package/dist/assets/x-D9PXs_xP.js +1 -0
  36. package/dist/index.html +70 -19
  37. package/index.html +55 -5
  38. package/package.json +9 -9
  39. package/src/app/components/app-presenter-provider.tsx +11 -2
  40. package/src/app/components/layout/__tests__/app-layout.test.tsx +11 -2
  41. package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +110 -79
  42. package/src/app/components/layout/app-layout.tsx +18 -4
  43. package/src/app/components/layout/header.tsx +3 -3
  44. package/src/app/components/layout/page-layout.tsx +2 -2
  45. package/src/app/components/layout/runtime-status-entry.tsx +7 -7
  46. package/src/app/components/layout/sidebar-items.tsx +194 -71
  47. package/src/app/components/layout/sidebar-rail.styles.ts +15 -0
  48. package/src/app/components/layout/sidebar.tsx +340 -83
  49. package/src/app/managers/viewport-layout.manager.ts +10 -0
  50. package/src/app/stores/viewport-layout.store.ts +39 -3
  51. package/src/app/styles/design-system.css +388 -26
  52. package/src/app/test/vitest-setup.ts +31 -0
  53. package/src/features/agents/components/__tests__/agents-page.test.tsx +62 -39
  54. package/src/features/agents/components/agents-page.tsx +10 -6
  55. package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +3 -3
  56. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +145 -0
  57. package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +4 -2
  58. package/src/features/chat/components/conversation/__tests__/chat-conversation-panel.test.tsx +69 -762
  59. package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +132 -0
  60. package/src/features/chat/components/conversation/chat-conversation-content.tsx +22 -15
  61. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +15 -16
  62. package/src/features/chat/components/conversation/chat-conversation-header.tsx +7 -6
  63. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +19 -19
  64. package/src/features/chat/components/conversation/chat-conversation-skeleton.tsx +13 -13
  65. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +10 -4
  66. package/src/features/chat/components/layout/__tests__/chat-sidebar-read-state.test.tsx +52 -11
  67. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +18 -16
  68. package/src/features/chat/components/layout/chat-page-shell.tsx +1 -1
  69. package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +247 -0
  70. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +93 -20
  71. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +93 -36
  72. package/src/features/chat/components/layout/chat-sidebar.tsx +60 -93
  73. package/src/features/chat/components/providers/chat-presenter.provider.tsx +0 -6
  74. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +225 -0
  75. package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +199 -0
  76. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +308 -0
  77. package/src/features/chat/features/conversation/components/session-conversation-input.tsx +439 -0
  78. package/src/features/chat/features/conversation/hooks/use-session-conversation-controller.ts +194 -0
  79. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-attachments.ts +66 -0
  80. package/src/features/chat/features/{input/hooks/use-chat-input-bar-query-state.ts → conversation/hooks/use-session-conversation-input-query.ts} +51 -20
  81. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +281 -0
  82. package/src/features/chat/features/conversation/utils/session-conversation-input-toolbar.utils.ts +158 -0
  83. package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +56 -0
  84. package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +117 -0
  85. package/src/features/chat/features/input/input-surface-plugins/__tests__/panel-app-reference-plugin.test.ts +77 -0
  86. package/src/features/chat/features/input/input-surface-plugins/__tests__/slash-command-plugin.test.ts +108 -0
  87. package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +10 -0
  88. package/src/features/chat/features/input/input-surface-plugins/input-surface-search.utils.ts +108 -0
  89. package/src/features/chat/features/input/input-surface-plugins/panel-app-reference-plugin.utils.ts +108 -0
  90. package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +161 -0
  91. package/src/features/chat/features/input/utils/__tests__/chat-composer-state.utils.test.ts +22 -1
  92. package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +26 -13
  93. package/src/features/chat/features/input/utils/__tests__/ncp-chat-input-availability.utils.test.ts +7 -28
  94. package/src/features/chat/features/input/utils/chat-composer-state.utils.ts +6 -0
  95. package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +26 -51
  96. package/src/features/chat/features/input/utils/chat-input-bar.utils.ts +2 -0
  97. package/src/features/chat/features/input/utils/ncp-chat-input-availability.utils.ts +5 -6
  98. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +47 -12
  99. package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +7 -7
  100. package/src/features/chat/features/message/components/chat-message-list.container.tsx +99 -18
  101. package/src/features/chat/features/message/utils/__tests__/chat-message.utils.test.ts +31 -12
  102. package/src/features/chat/features/message/utils/chat-message-markdown-part.utils.ts +38 -0
  103. package/src/features/chat/features/message/utils/chat-message-part.utils.ts +1 -1
  104. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +7 -7
  105. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +6 -6
  106. package/src/features/chat/features/session/components/session-context-icon.tsx +2 -2
  107. package/src/features/chat/features/session/components/session-header/__tests__/chat-session-project-badge.test.tsx +2 -2
  108. package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +1 -1
  109. package/src/features/chat/features/session/components/session-header/chat-session-header-menu-item.tsx +1 -1
  110. package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
  111. package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
  112. package/src/features/chat/features/session/components/session-run-badge.tsx +1 -1
  113. package/src/features/chat/features/session/hooks/__tests__/use-chat-session-project.test.tsx +3 -30
  114. package/src/features/chat/features/session/hooks/use-chat-session-project.ts +0 -5
  115. package/src/features/chat/features/session/utils/chat-run-metadata.utils.ts +8 -0
  116. package/src/features/chat/features/session-type/components/__tests__/chat-session-type-menu.test.tsx +2 -2
  117. package/src/features/chat/features/session-type/components/__tests__/chat-session-type-option-item.test.tsx +2 -0
  118. package/src/features/chat/features/session-type/components/chat-session-type-menu.tsx +2 -2
  119. package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +2 -2
  120. package/src/features/chat/features/session-type/hooks/use-chat-session-type-state.ts +10 -2
  121. package/src/features/chat/features/welcome/components/__tests__/chat-conversation-welcome.test.tsx +49 -31
  122. package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +2 -9
  123. package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +21 -10
  124. package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +3 -3
  125. package/src/features/chat/features/welcome/components/chat-welcome-capability-grid.tsx +4 -4
  126. package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +14 -19
  127. package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +5 -5
  128. package/src/features/chat/features/welcome/components/chat-welcome.tsx +6 -6
  129. package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-project-options.utils.test.ts +6 -8
  130. package/src/features/chat/features/welcome/utils/chat-welcome-project-options.utils.ts +1 -16
  131. package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +54 -0
  132. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +44 -76
  133. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +5 -1
  134. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +7 -1
  135. package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +40 -31
  136. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +59 -1
  137. package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +109 -0
  138. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +44 -4
  139. package/src/features/chat/index.ts +0 -1
  140. package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +51 -99
  141. package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +135 -21
  142. package/src/features/chat/managers/chat-session-list.manager.ts +12 -43
  143. package/src/features/chat/managers/chat-thread.manager.ts +108 -34
  144. package/src/features/chat/pages/__tests__/ncp-chat-page.test.ts +48 -1
  145. package/src/features/chat/pages/__tests__/ncp-chat-page.test.tsx +72 -0
  146. package/src/features/chat/pages/ncp-chat-page.tsx +0 -122
  147. package/src/features/chat/presenters/chat.presenter.ts +2 -19
  148. package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +31 -0
  149. package/src/features/chat/stores/chat-thread.store.ts +42 -26
  150. package/src/features/panel-apps/components/panel-app-list-item.tsx +8 -8
  151. package/src/features/panel-apps/components/panel-app-toolbar.tsx +4 -4
  152. package/src/features/panel-apps/components/panel-apps-list.tsx +20 -20
  153. package/src/features/panel-apps/hooks/use-panel-apps.ts +2 -1
  154. package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +70 -6
  155. package/src/features/pwa/managers/pwa-shell-theme.manager.ts +10 -5
  156. package/src/features/service-apps/components/service-action-authorization-dialog.tsx +8 -8
  157. package/src/features/service-apps/components/service-apps-panel.tsx +24 -24
  158. package/src/features/settings/components/config/provider-advanced-settings-section.tsx +5 -5
  159. package/src/features/settings/components/config/provider-auth-section.tsx +7 -7
  160. package/src/features/settings/components/config/provider-form.tsx +10 -10
  161. package/src/features/settings/components/config/provider-models-section.tsx +16 -16
  162. package/src/features/settings/components/config/provider-pill-selector.tsx +1 -1
  163. package/src/features/settings/pages/providers-config-page.tsx +17 -17
  164. package/src/platforms/desktop/components/__tests__/desktop-app-shell.test.tsx +50 -10
  165. package/src/platforms/desktop/components/desktop-app-shell.tsx +34 -10
  166. package/src/platforms/desktop/components/desktop-window-chrome.tsx +41 -16
  167. package/src/shared/components/config-split-page.tsx +11 -11
  168. package/src/shared/components/doc-browser/doc-browser-home-page.tsx +2 -2
  169. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +4 -4
  170. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +4 -4
  171. package/src/shared/components/doc-browser/doc-browser.tsx +3 -3
  172. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +1 -1
  173. package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
  174. package/src/shared/components/ui/button.tsx +4 -4
  175. package/src/shared/components/ui/card.tsx +4 -4
  176. package/src/shared/components/ui/dialog.tsx +5 -5
  177. package/src/shared/components/ui/input.tsx +1 -1
  178. package/src/shared/components/ui/label.tsx +1 -1
  179. package/src/shared/components/ui/popover.tsx +1 -1
  180. package/src/shared/components/ui/select.tsx +3 -3
  181. package/src/shared/components/ui/switch.tsx +3 -3
  182. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +24 -1
  183. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +8 -4
  184. package/src/shared/components/ui/tabs.tsx +4 -4
  185. package/src/shared/components/ui/textarea.tsx +1 -1
  186. package/src/shared/lib/i18n/locales/en-US/chat.json +20 -2
  187. package/src/shared/lib/i18n/locales/en-US/core.json +9 -2
  188. package/src/shared/lib/i18n/locales/zh-CN/chat.json +20 -2
  189. package/src/shared/lib/i18n/locales/zh-CN/core.json +9 -2
  190. package/src/shared/lib/theme/index.ts +94 -52
  191. package/src/shared/lib/ui-document-title/__tests__/ui-document-title.test.ts +49 -0
  192. package/src/shared/lib/ui-document-title/index.ts +50 -21
  193. package/dist/assets/channels-list-page-D6jtziu4.js +0 -8
  194. package/dist/assets/chat-page-BBnNJoKG.js +0 -105
  195. package/dist/assets/config-split-page-BCJhqdK9.js +0 -1
  196. package/dist/assets/doc-browser-C8xOF_9F.js +0 -1
  197. package/dist/assets/doc-browser-DgQedeAn.js +0 -1
  198. package/dist/assets/doc-browser-context-B46tQGmO.js +0 -1
  199. package/dist/assets/index-7o1WdUbU.js +0 -103
  200. package/dist/assets/index-DQWmEWzk.css +0 -1
  201. package/dist/assets/mcp-marketplace-page-CWZN7ohK.js +0 -1
  202. package/dist/assets/mcp-marketplace-page-Dzull_4-.js +0 -40
  203. package/dist/assets/model-config-page-Cv0O3BIj.js +0 -1
  204. package/dist/assets/plus-Bnt56oqG.js +0 -1
  205. package/dist/assets/provider-scoped-model-input-Duuh7i3h.js +0 -1
  206. package/dist/assets/providers-config-page-CPDz0Lxc.js +0 -1
  207. package/dist/assets/remote-B0LMs8u7.js +0 -1
  208. package/dist/assets/rotate-cw-BfyG_KEF.js +0 -1
  209. package/dist/assets/runtime-config-page-q0fvv8ME.js +0 -1
  210. package/dist/assets/use-config-DZkBWIdL.js +0 -1
  211. package/dist/assets/x-CW2KO-Hz.js +0 -1
  212. package/src/features/chat/components/conversation/chat-conversation-alerts.tsx +0 -37
  213. package/src/features/chat/features/input/components/__tests__/chat-attachment-upload-limit.test.ts +0 -38
  214. package/src/features/chat/features/input/components/chat-input-bar.container.tsx +0 -496
  215. package/src/features/chat/features/message/utils/chat-message-inline-content.utils.ts +0 -95
  216. package/src/features/chat/managers/__tests__/chat-input.manager.test.ts +0 -448
  217. package/src/features/chat/managers/__tests__/chat-run-snapshot.manager.test.ts +0 -129
  218. package/src/features/chat/managers/__tests__/chat-run.manager.test.ts +0 -236
  219. package/src/features/chat/managers/__tests__/chat-session-preference-sync.manager.test.ts +0 -219
  220. package/src/features/chat/managers/chat-input.manager.ts +0 -430
  221. package/src/features/chat/managers/chat-run.manager.ts +0 -110
  222. package/src/features/chat/managers/chat-session-preference-sync.manager.ts +0 -142
  223. package/src/features/chat/stores/chat-input.store.ts +0 -104
  224. /package/dist/assets/{config-hints-CTqBnCDp.js → config-hints-BkYBc7z0.js} +0 -0
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * NextClaw Design System
3
- * Warm minimalist palette inspired by YouWare + YouMind
4
- * Warm amber brand, warm neutral grays, refined details
3
+ * Quiet workbench palettes.
4
+ * Neutral surfaces carry the UI; accent colors only mark actions and focus.
5
5
  */
6
6
 
7
7
  @layer base {
8
8
  :root {
9
9
  /* ========================================
10
- BRAND COLORS (Olive Green)
10
+ BRAND COLORS (Natural Olive)
11
11
  ======================================== */
12
12
  --brand-50: 94 20% 95%;
13
13
  --brand-100: 94 20% 90%;
@@ -140,7 +140,7 @@
140
140
  --radius-full: 9999px;
141
141
 
142
142
  /* ========================================
143
- SHADOWS (Warmer tint)
143
+ SHADOWS (Natural warm tint)
144
144
  ======================================== */
145
145
  --shadow-xs: 0 1px 2px 0 rgb(30 20 10 / 0.04);
146
146
  --shadow-sm: 0 1px 3px 0 rgb(30 20 10 / 0.06), 0 1px 2px -1px rgb(30 20 10 / 0.04);
@@ -207,29 +207,175 @@
207
207
  }
208
208
  }
209
209
 
210
+ @layer base {
211
+ :root[data-theme="minimal"] {
212
+ /* ========================================
213
+ BRAND COLORS (Minimal Ink)
214
+ ======================================== */
215
+ --brand-50: 0 0% 98%;
216
+ --brand-100: 0 0% 96%;
217
+ --brand-200: 0 0% 90%;
218
+ --brand-300: 0 0% 80%;
219
+ --brand-400: 0 0% 64%;
220
+ --brand-500: 0 0% 9%;
221
+ --brand-600: 0 0% 5%;
222
+ --brand-700: 0 0% 0%;
223
+ --brand-800: 0 0% 4%;
224
+ --brand-900: 0 0% 2%;
225
+
226
+ /* ========================================
227
+ NEUTRAL COLORS (Clean Gray / Ink scale)
228
+ ======================================== */
229
+ --gray-50: 0 0% 100%;
230
+ --gray-100: 0 0% 98%;
231
+ --gray-200: 0 0% 96%;
232
+ --gray-300: 0 0% 90%;
233
+ --gray-400: 0 0% 74%;
234
+ --gray-500: 0 0% 45%;
235
+ --gray-600: 0 0% 32%;
236
+ --gray-700: 0 0% 20%;
237
+ --gray-800: 0 0% 9%;
238
+ --gray-900: 0 0% 4%;
239
+
240
+ /* Semantic Colors */
241
+ --background: var(--gray-50);
242
+ --background-secondary: var(--gray-100);
243
+ --background-tertiary: var(--gray-200);
244
+ --foreground: var(--gray-800);
245
+ --foreground-secondary: var(--gray-700);
246
+ --foreground-tertiary: var(--gray-500);
247
+ --foreground-muted: var(--gray-400);
248
+ --primary: var(--brand-500);
249
+ --primary-hover: var(--brand-600);
250
+ --primary-active: var(--brand-700);
251
+ --secondary: var(--gray-100);
252
+ --secondary-hover: var(--gray-200);
253
+ --secondary-foreground: var(--gray-800);
254
+ --accent: 0 0% 96%;
255
+ --accent-foreground: var(--brand-700);
256
+ --muted: var(--gray-100);
257
+ --muted-foreground: var(--gray-500);
258
+ --card: 0 0% 100%;
259
+ --card-foreground: var(--gray-800);
260
+ --card-border: 0 0% 90%;
261
+ --popover: 0 0% 100%;
262
+ --popover-foreground: var(--gray-800);
263
+ --border: 0 0% 90%;
264
+ --border-hover: 0 0% 81%;
265
+ --border-active: var(--brand-500);
266
+ --input: 0 0% 100%;
267
+ --input-border: 0 0% 90%;
268
+ --input-focus: var(--brand-500);
269
+ --ring: var(--brand-500);
270
+ --ring-offset: var(--gray-50);
271
+
272
+ /* Shadows (minimal neutral tint) */
273
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.03);
274
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.05), 0 1px 2px -1px rgb(0 0 0 / 0.04);
275
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.05), 0 2px 4px -2px rgb(0 0 0 / 0.04);
276
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.06), 0 4px 6px -4px rgb(0 0 0 / 0.04);
277
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.08), 0 8px 10px -6px rgb(0 0 0 / 0.04);
278
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.14);
279
+ --shadow-card: 0 0 8px 0 rgba(0, 0, 0, 0.04);
280
+ --shadow-card-hover: 0 0 16px 0 rgba(0, 0, 0, 0.06);
281
+ }
282
+ }
283
+
284
+ @layer base {
285
+ :root[data-theme="warm"] {
286
+ /* ========================================
287
+ BRAND COLORS (Paper Taupe)
288
+ ======================================== */
289
+ --brand-50: 36 35% 94%;
290
+ --brand-100: 35 32% 90%;
291
+ --brand-200: 34 26% 82%;
292
+ --brand-300: 32 20% 70%;
293
+ --brand-400: 30 16% 56%;
294
+ --brand-500: 28 15% 42%;
295
+ --brand-600: 27 16% 34%;
296
+ --brand-700: 25 18% 28%;
297
+ --brand-800: 24 20% 20%;
298
+ --brand-900: 23 24% 13%;
299
+
300
+ /* ========================================
301
+ NEUTRAL COLORS (Warm Paper / Ink scale)
302
+ ======================================== */
303
+ --gray-50: 40 38% 97%;
304
+ --gray-100: 39 30% 94%;
305
+ --gray-200: 36 24% 87%;
306
+ --gray-300: 34 18% 78%;
307
+ --gray-400: 32 10% 60%;
308
+ --gray-500: 30 9% 46%;
309
+ --gray-600: 28 10% 36%;
310
+ --gray-700: 26 14% 27%;
311
+ --gray-800: 24 18% 18%;
312
+ --gray-900: 22 24% 11%;
313
+
314
+ /* Semantic Colors */
315
+ --background: var(--gray-50);
316
+ --background-secondary: var(--gray-100);
317
+ --background-tertiary: var(--gray-200);
318
+ --foreground: var(--gray-800);
319
+ --foreground-secondary: var(--gray-700);
320
+ --foreground-tertiary: var(--gray-500);
321
+ --foreground-muted: var(--gray-400);
322
+ --primary: var(--brand-500);
323
+ --primary-hover: var(--brand-600);
324
+ --primary-active: var(--brand-700);
325
+ --secondary: var(--gray-100);
326
+ --secondary-hover: var(--gray-200);
327
+ --secondary-foreground: var(--gray-800);
328
+ --accent: 38 30% 91%;
329
+ --accent-foreground: var(--brand-700);
330
+ --muted: var(--gray-100);
331
+ --muted-foreground: var(--gray-500);
332
+ --card: 40 48% 98%;
333
+ --card-foreground: var(--gray-800);
334
+ --card-border: 34 22% 84%;
335
+ --popover: 40 48% 98%;
336
+ --popover-foreground: var(--gray-800);
337
+ --border: 34 22% 84%;
338
+ --border-hover: 32 20% 73%;
339
+ --border-active: var(--brand-500);
340
+ --input: 40 48% 98%;
341
+ --input-border: 34 22% 84%;
342
+ --input-focus: var(--brand-500);
343
+ --ring: var(--brand-500);
344
+ --ring-offset: var(--gray-50);
345
+
346
+ /* Shadows (warmer tint) */
347
+ --shadow-xs: 0 1px 2px 0 rgb(30 20 10 / 0.04);
348
+ --shadow-sm: 0 1px 3px 0 rgb(30 20 10 / 0.06), 0 1px 2px -1px rgb(30 20 10 / 0.04);
349
+ --shadow-md: 0 4px 6px -1px rgb(30 20 10 / 0.06), 0 2px 4px -2px rgb(30 20 10 / 0.04);
350
+ --shadow-lg: 0 10px 15px -3px rgb(30 20 10 / 0.06), 0 4px 6px -4px rgb(30 20 10 / 0.04);
351
+ --shadow-xl: 0 20px 25px -5px rgb(30 20 10 / 0.08), 0 8px 10px -6px rgb(30 20 10 / 0.04);
352
+ --shadow-2xl: 0 25px 50px -12px rgb(30 20 10 / 0.15);
353
+ }
354
+ }
355
+
210
356
  @layer base {
211
357
  :root[data-theme="cool"] {
212
358
  /* ========================================
213
- BRAND COLORS (Cool Blue)
359
+ BRAND COLORS (Mist Blue)
214
360
  ======================================== */
215
- --brand-50: 214 100% 97%;
216
- --brand-100: 214 95% 93%;
217
- --brand-200: 213 97% 87%;
218
- --brand-300: 212 96% 78%;
219
- --brand-400: 213 94% 68%;
220
- --brand-500: 217 91% 60%;
221
- --brand-600: 221 83% 53%;
222
- --brand-700: 224 76% 48%;
223
- --brand-800: 226 71% 40%;
224
- --brand-900: 224 64% 33%;
361
+ --brand-50: 210 48% 96%;
362
+ --brand-100: 211 42% 92%;
363
+ --brand-200: 212 36% 84%;
364
+ --brand-300: 212 32% 72%;
365
+ --brand-400: 213 30% 60%;
366
+ --brand-500: 214 35% 48%;
367
+ --brand-600: 214 36% 42%;
368
+ --brand-700: 215 38% 34%;
369
+ --brand-800: 216 40% 26%;
370
+ --brand-900: 218 42% 18%;
225
371
 
226
372
  /* ========================================
227
373
  NEUTRAL COLORS (Cool Slate)
228
374
  ======================================== */
229
- --gray-50: 210 20% 98%;
230
- --gray-100: 220 14% 96%;
231
- --gray-200: 220 13% 91%;
232
- --gray-300: 216 12% 84%;
375
+ --gray-50: 210 32% 98%;
376
+ --gray-100: 210 24% 96%;
377
+ --gray-200: 214 18% 90%;
378
+ --gray-300: 216 14% 82%;
233
379
  --gray-400: 218 11% 65%;
234
380
  --gray-500: 220 9% 46%;
235
381
  --gray-600: 215 14% 34%;
@@ -255,16 +401,16 @@
255
401
  --accent-foreground: var(--brand-700);
256
402
  --muted: var(--gray-100);
257
403
  --muted-foreground: var(--gray-500);
258
- --card: 0 0% 100%;
404
+ --card: 210 36% 99%;
259
405
  --card-foreground: var(--gray-800);
260
- --card-border: var(--gray-200);
261
- --popover: 0 0% 100%;
406
+ --card-border: 214 22% 87%;
407
+ --popover: 210 36% 99%;
262
408
  --popover-foreground: var(--gray-800);
263
- --border: var(--gray-200);
264
- --border-hover: var(--gray-300);
409
+ --border: 214 22% 87%;
410
+ --border-hover: 215 17% 76%;
265
411
  --border-active: var(--brand-500);
266
- --input: 0 0% 100%;
267
- --input-border: var(--gray-200);
412
+ --input: 210 36% 99%;
413
+ --input-border: 214 22% 87%;
268
414
  --input-focus: var(--brand-500);
269
415
  --ring: var(--brand-500);
270
416
  --ring-offset: var(--gray-50);
@@ -279,6 +425,222 @@
279
425
  }
280
426
  }
281
427
 
428
+ @layer base {
429
+ :root[data-theme="dawn"] {
430
+ /* ========================================
431
+ BRAND COLORS (Dawn Clay)
432
+ ======================================== */
433
+ --brand-50: 352 34% 96%;
434
+ --brand-100: 352 30% 92%;
435
+ --brand-200: 352 25% 84%;
436
+ --brand-300: 352 22% 72%;
437
+ --brand-400: 351 22% 58%;
438
+ --brand-500: 350 24% 46%;
439
+ --brand-600: 350 25% 39%;
440
+ --brand-700: 349 26% 32%;
441
+ --brand-800: 348 28% 24%;
442
+ --brand-900: 347 30% 16%;
443
+
444
+ /* ========================================
445
+ NEUTRAL COLORS (Blush Paper)
446
+ ======================================== */
447
+ --gray-50: 24 38% 97%;
448
+ --gray-100: 20 30% 94%;
449
+ --gray-200: 18 22% 87%;
450
+ --gray-300: 17 18% 78%;
451
+ --gray-400: 16 10% 60%;
452
+ --gray-500: 15 9% 46%;
453
+ --gray-600: 12 10% 36%;
454
+ --gray-700: 10 13% 27%;
455
+ --gray-800: 8 16% 18%;
456
+ --gray-900: 6 20% 11%;
457
+
458
+ /* Semantic Colors */
459
+ --background: var(--gray-50);
460
+ --background-secondary: var(--gray-100);
461
+ --background-tertiary: var(--gray-200);
462
+ --foreground: var(--gray-800);
463
+ --foreground-secondary: var(--gray-700);
464
+ --foreground-tertiary: var(--gray-500);
465
+ --foreground-muted: var(--gray-400);
466
+ --primary: var(--brand-500);
467
+ --primary-hover: var(--brand-600);
468
+ --primary-active: var(--brand-700);
469
+ --secondary: var(--gray-100);
470
+ --secondary-hover: var(--gray-200);
471
+ --secondary-foreground: var(--gray-800);
472
+ --accent: 352 34% 94%;
473
+ --accent-foreground: var(--brand-700);
474
+ --muted: var(--gray-100);
475
+ --muted-foreground: var(--gray-500);
476
+ --card: 24 48% 98%;
477
+ --card-foreground: var(--gray-800);
478
+ --card-border: 18 22% 84%;
479
+ --popover: 24 48% 98%;
480
+ --popover-foreground: var(--gray-800);
481
+ --border: 18 22% 84%;
482
+ --border-hover: 16 20% 74%;
483
+ --border-active: var(--brand-500);
484
+ --input: 24 48% 98%;
485
+ --input-border: 18 22% 84%;
486
+ --input-focus: var(--brand-500);
487
+ --ring: var(--brand-500);
488
+ --ring-offset: var(--gray-50);
489
+
490
+ /* Shadows (clay tint) */
491
+ --shadow-xs: 0 1px 2px 0 rgb(64 40 36 / 0.04);
492
+ --shadow-sm: 0 1px 3px 0 rgb(64 40 36 / 0.06), 0 1px 2px -1px rgb(64 40 36 / 0.04);
493
+ --shadow-md: 0 4px 6px -1px rgb(64 40 36 / 0.06), 0 2px 4px -2px rgb(64 40 36 / 0.04);
494
+ --shadow-lg: 0 10px 15px -3px rgb(64 40 36 / 0.06), 0 4px 6px -4px rgb(64 40 36 / 0.04);
495
+ --shadow-xl: 0 20px 25px -5px rgb(64 40 36 / 0.08), 0 8px 10px -6px rgb(64 40 36 / 0.04);
496
+ --shadow-2xl: 0 25px 50px -12px rgb(64 40 36 / 0.14);
497
+ }
498
+ }
499
+
500
+ @layer base {
501
+ :root[data-theme="graphite"] {
502
+ /* ========================================
503
+ BRAND COLORS (Quiet Graphite)
504
+ ======================================== */
505
+ --brand-50: 220 12% 95%;
506
+ --brand-100: 220 10% 91%;
507
+ --brand-200: 220 9% 84%;
508
+ --brand-300: 220 8% 72%;
509
+ --brand-400: 220 7% 58%;
510
+ --brand-500: 220 9% 39%;
511
+ --brand-600: 220 10% 32%;
512
+ --brand-700: 220 12% 25%;
513
+ --brand-800: 220 14% 18%;
514
+ --brand-900: 220 18% 11%;
515
+
516
+ /* ========================================
517
+ NEUTRAL COLORS (Soft Monochrome)
518
+ ======================================== */
519
+ --gray-50: 48 10% 97%;
520
+ --gray-100: 45 8% 94%;
521
+ --gray-200: 42 7% 87%;
522
+ --gray-300: 38 6% 78%;
523
+ --gray-400: 34 5% 60%;
524
+ --gray-500: 30 4% 46%;
525
+ --gray-600: 28 5% 36%;
526
+ --gray-700: 25 7% 27%;
527
+ --gray-800: 220 11% 18%;
528
+ --gray-900: 220 18% 11%;
529
+
530
+ /* Semantic Colors */
531
+ --background: var(--gray-50);
532
+ --background-secondary: var(--gray-100);
533
+ --background-tertiary: var(--gray-200);
534
+ --foreground: var(--gray-800);
535
+ --foreground-secondary: var(--gray-700);
536
+ --foreground-tertiary: var(--gray-500);
537
+ --foreground-muted: var(--gray-400);
538
+ --primary: var(--brand-500);
539
+ --primary-hover: var(--brand-600);
540
+ --primary-active: var(--brand-700);
541
+ --secondary: var(--gray-100);
542
+ --secondary-hover: var(--gray-200);
543
+ --secondary-foreground: var(--gray-800);
544
+ --accent: 220 12% 92%;
545
+ --accent-foreground: var(--brand-700);
546
+ --muted: var(--gray-100);
547
+ --muted-foreground: var(--gray-500);
548
+ --card: 48 13% 99%;
549
+ --card-foreground: var(--gray-800);
550
+ --card-border: 42 7% 84%;
551
+ --popover: 48 13% 99%;
552
+ --popover-foreground: var(--gray-800);
553
+ --border: 42 7% 84%;
554
+ --border-hover: 38 6% 74%;
555
+ --border-active: var(--brand-500);
556
+ --input: 48 13% 99%;
557
+ --input-border: 42 7% 84%;
558
+ --input-focus: var(--brand-500);
559
+ --ring: var(--brand-500);
560
+ --ring-offset: var(--gray-50);
561
+
562
+ /* Shadows (neutral tint) */
563
+ --shadow-xs: 0 1px 2px 0 rgb(24 26 31 / 0.04);
564
+ --shadow-sm: 0 1px 3px 0 rgb(24 26 31 / 0.06), 0 1px 2px -1px rgb(24 26 31 / 0.04);
565
+ --shadow-md: 0 4px 6px -1px rgb(24 26 31 / 0.06), 0 2px 4px -2px rgb(24 26 31 / 0.04);
566
+ --shadow-lg: 0 10px 15px -3px rgb(24 26 31 / 0.06), 0 4px 6px -4px rgb(24 26 31 / 0.04);
567
+ --shadow-xl: 0 20px 25px -5px rgb(24 26 31 / 0.08), 0 8px 10px -6px rgb(24 26 31 / 0.04);
568
+ --shadow-2xl: 0 25px 50px -12px rgb(24 26 31 / 0.14);
569
+ }
570
+ }
571
+
572
+ @layer base {
573
+ :root[data-theme="probe"] {
574
+ /* ========================================
575
+ BRAND COLORS (Reference Ink)
576
+ ======================================== */
577
+ --brand-50: 210 16% 95%;
578
+ --brand-100: 210 14% 90%;
579
+ --brand-200: 210 12% 82%;
580
+ --brand-300: 210 11% 70%;
581
+ --brand-400: 210 12% 52%;
582
+ --brand-500: 210 14% 22%;
583
+ --brand-600: 210 16% 18%;
584
+ --brand-700: 210 18% 15%;
585
+ --brand-800: 210 20% 12%;
586
+ --brand-900: 210 24% 9%;
587
+
588
+ /* ========================================
589
+ NEUTRAL COLORS (Cream Paper / Ink)
590
+ ======================================== */
591
+ --gray-50: 42 83% 98%;
592
+ --gray-100: 41 80% 96%;
593
+ --gray-200: 38 48% 92%;
594
+ --gray-300: 38 24% 78%;
595
+ --gray-400: 180 2% 52%;
596
+ --gray-500: 213 6% 45%;
597
+ --gray-600: 213 6% 36%;
598
+ --gray-700: 213 6% 30%;
599
+ --gray-800: 207 28% 19%;
600
+ --gray-900: 210 30% 12%;
601
+
602
+ /* Semantic Colors */
603
+ --background: var(--gray-50);
604
+ --background-secondary: var(--gray-100);
605
+ --background-tertiary: var(--gray-200);
606
+ --foreground: var(--gray-800);
607
+ --foreground-secondary: var(--gray-700);
608
+ --foreground-tertiary: var(--gray-500);
609
+ --foreground-muted: var(--gray-400);
610
+ --primary: var(--brand-500);
611
+ --primary-hover: var(--brand-600);
612
+ --primary-active: var(--brand-700);
613
+ --secondary: var(--gray-100);
614
+ --secondary-hover: var(--gray-200);
615
+ --secondary-foreground: var(--gray-800);
616
+ --accent: 210 16% 92%;
617
+ --accent-foreground: var(--brand-700);
618
+ --muted: var(--gray-100);
619
+ --muted-foreground: var(--gray-500);
620
+ --card: 41 80% 96%;
621
+ --card-foreground: var(--gray-800);
622
+ --card-border: 38 26% 82%;
623
+ --popover: 42 83% 98%;
624
+ --popover-foreground: var(--gray-800);
625
+ --border: 38 26% 82%;
626
+ --border-hover: 210 14% 72%;
627
+ --border-active: var(--brand-500);
628
+ --input: 42 83% 98%;
629
+ --input-border: 38 26% 82%;
630
+ --input-focus: var(--brand-500);
631
+ --ring: var(--brand-500);
632
+ --ring-offset: var(--gray-50);
633
+
634
+ /* Shadows (ink / paper tint) */
635
+ --shadow-xs: 0 1px 2px 0 rgb(34 49 61 / 0.04);
636
+ --shadow-sm: 0 1px 3px 0 rgb(34 49 61 / 0.06), 0 1px 2px -1px rgb(34 49 61 / 0.04);
637
+ --shadow-md: 0 4px 6px -1px rgb(34 49 61 / 0.06), 0 2px 4px -2px rgb(34 49 61 / 0.04);
638
+ --shadow-lg: 0 10px 15px -3px rgb(34 49 61 / 0.06), 0 4px 6px -4px rgb(34 49 61 / 0.04);
639
+ --shadow-xl: 0 20px 25px -5px rgb(34 49 61 / 0.08), 0 8px 10px -6px rgb(34 49 61 / 0.04);
640
+ --shadow-2xl: 0 25px 50px -12px rgb(34 49 61 / 0.14);
641
+ }
642
+ }
643
+
282
644
  @layer utilities {
283
645
  /* ========================================
284
646
  UTILITY CLASSES
@@ -14,3 +14,34 @@ class MockResizeObserver {
14
14
  }
15
15
 
16
16
  vi.stubGlobal('ResizeObserver', MockResizeObserver);
17
+
18
+ class MemoryStorage implements Storage {
19
+ private readonly values = new Map<string, string>();
20
+
21
+ get length() {
22
+ return this.values.size;
23
+ }
24
+
25
+ clear = () => {
26
+ this.values.clear();
27
+ };
28
+
29
+ getItem = (key: string) => this.values.get(key) ?? null;
30
+
31
+ key = (index: number) => Array.from(this.values.keys())[index] ?? null;
32
+
33
+ removeItem = (key: string) => {
34
+ this.values.delete(key);
35
+ };
36
+
37
+ setItem = (key: string, value: string) => {
38
+ this.values.set(key, value);
39
+ };
40
+ }
41
+
42
+ if (typeof window !== 'undefined' && typeof window.localStorage?.getItem !== 'function') {
43
+ Object.defineProperty(window, 'localStorage', {
44
+ configurable: true,
45
+ value: new MemoryStorage()
46
+ });
47
+ }
@@ -1,13 +1,10 @@
1
1
  import { render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
  import { MemoryRouter } from "react-router-dom";
4
+ import type * as ReactRouterDom from "react-router-dom";
4
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
5
6
  import { AgentsPage } from "@/features/agents";
6
- import type * as ChatFeature from "@/features/chat";
7
7
  import {
8
- ChatPresenter,
9
- ChatPresenterProvider,
10
- useChatInputStore,
11
8
  useChatSessionListStore,
12
9
  useChatThreadStore,
13
10
  } from "@/features/chat";
@@ -17,6 +14,8 @@ const mocks = vi.hoisted(() => ({
17
14
  createAgent: vi.fn(),
18
15
  updateAgent: vi.fn(),
19
16
  deleteAgent: vi.fn(),
17
+ navigate: vi.fn(),
18
+ requestDraft: vi.fn(),
20
19
  sessionTypesQuery: {
21
20
  data: {
22
21
  defaultType: "native",
@@ -90,6 +89,35 @@ const mocks = vi.hoisted(() => ({
90
89
  },
91
90
  },
92
91
  }));
92
+ const persistStorage = new Map<string, unknown>();
93
+
94
+ function createPersistStorage() {
95
+ return {
96
+ getItem: (name: string) => persistStorage.get(name) ?? null,
97
+ setItem: (name: string, value: unknown) => {
98
+ persistStorage.set(name, value);
99
+ },
100
+ removeItem: (name: string) => {
101
+ persistStorage.delete(name);
102
+ },
103
+ };
104
+ }
105
+
106
+ vi.mock("react-router-dom", async (importOriginal) => {
107
+ const actual = await importOriginal<typeof ReactRouterDom>();
108
+ return {
109
+ ...actual,
110
+ useNavigate: () => mocks.navigate,
111
+ };
112
+ });
113
+
114
+ vi.mock("@/app/components/app-presenter-provider", () => ({
115
+ useAppPresenter: () => ({
116
+ chatDraftIntentManager: {
117
+ requestDraft: mocks.requestDraft,
118
+ },
119
+ }),
120
+ }));
93
121
 
94
122
  vi.mock("@/shared/hooks/use-agents", () => ({
95
123
  useAgents: () => mocks.agentsQuery,
@@ -147,35 +175,50 @@ vi.mock("@/shared/hooks/use-config", () => ({
147
175
  }),
148
176
  }));
149
177
 
150
- vi.mock("@/features/chat", async (importOriginal) => {
151
- const actual = await importOriginal<typeof ChatFeature>();
178
+ vi.mock("@/features/chat", async () => {
179
+ const sessionListStore = await import("@/features/chat/stores/chat-session-list.store");
180
+ const threadStore = await import("@/features/chat/stores/chat-thread.store");
181
+ const sessionTypeUtils = await import("@/features/chat/features/session-type/utils/chat-session-type.utils");
152
182
  return {
153
- ...actual,
183
+ ...sessionTypeUtils,
184
+ usePresenter: () => ({
185
+ chatSessionListManager: {
186
+ startAgentDraftChat: (agentId: string) => {
187
+ sessionListStore.useChatSessionListStore.getState().setSnapshot({
188
+ selectedAgentId: agentId,
189
+ selectedSessionKey: null,
190
+ });
191
+ threadStore.useChatThreadStore.getState().setSnapshot({
192
+ sessionKey: null,
193
+ });
194
+ },
195
+ },
196
+ }),
197
+ useChatSessionListStore: sessionListStore.useChatSessionListStore,
198
+ useChatThreadStore: threadStore.useChatThreadStore,
154
199
  useNcpChatSessionTypes: () => mocks.sessionTypesQuery,
155
200
  };
156
201
  });
157
202
 
158
203
  function renderAgentsPage() {
159
- const presenter = new ChatPresenter({
160
- docBrowserManager: {
161
- open: vi.fn(),
162
- },
163
- } as unknown as ConstructorParameters<typeof ChatPresenter>[0]);
164
204
  return render(
165
205
  <MemoryRouter>
166
- <ChatPresenterProvider presenter={presenter}>
167
- <AgentsPage />
168
- </ChatPresenterProvider>
206
+ <AgentsPage />
169
207
  </MemoryRouter>,
170
208
  );
171
209
  }
172
210
 
173
211
  describe("AgentsPage", () => {
174
212
  beforeEach(() => {
213
+ persistStorage.clear();
214
+ useChatSessionListStore.persist.setOptions({ storage: createPersistStorage() as never });
215
+ useChatThreadStore.persist.setOptions({ storage: createPersistStorage() as never });
175
216
  setLanguage("zh");
176
217
  mocks.createAgent.mockReset();
177
218
  mocks.updateAgent.mockReset();
178
219
  mocks.deleteAgent.mockReset();
220
+ mocks.navigate.mockReset();
221
+ mocks.requestDraft.mockReset();
179
222
  if (!HTMLElement.prototype.hasPointerCapture) {
180
223
  HTMLElement.prototype.hasPointerCapture = () => false;
181
224
  }
@@ -185,15 +228,6 @@ describe("AgentsPage", () => {
185
228
  if (!HTMLElement.prototype.releasePointerCapture) {
186
229
  HTMLElement.prototype.releasePointerCapture = () => {};
187
230
  }
188
- useChatInputStore.setState({
189
- snapshot: {
190
- ...useChatInputStore.getState().snapshot,
191
- draft: "",
192
- pendingSessionType: "native",
193
- pendingProjectRoot: "/tmp/demo-project",
194
- pendingProjectRootSessionKey: "draft-session",
195
- },
196
- });
197
231
  useChatSessionListStore.setState({
198
232
  snapshot: {
199
233
  ...useChatSessionListStore.getState().snapshot,
@@ -227,13 +261,9 @@ describe("AgentsPage", () => {
227
261
 
228
262
  await user.click(screen.getByRole("button", { name: "新增 Agent" }));
229
263
 
230
- expect(useChatSessionListStore.getState().snapshot.selectedAgentId).toBe(
231
- "main",
232
- );
233
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBeNull();
234
- expect(useChatThreadStore.getState().snapshot.sessionKey).toBeNull();
235
- expect(useChatInputStore.getState().snapshot.draft).toContain(
236
- "请直接创建一个默认示例 Agent,不要问我问题",
264
+ expect(mocks.navigate).toHaveBeenCalledWith("/chat");
265
+ expect(mocks.requestDraft).toHaveBeenCalledWith(
266
+ expect.stringContaining("请直接创建一个默认示例 Agent,不要问我问题"),
237
267
  );
238
268
  expect(mocks.createAgent).not.toHaveBeenCalled();
239
269
  expect(screen.queryByText("创建新的 Agent 身份")).toBeNull();
@@ -281,7 +311,7 @@ describe("AgentsPage", () => {
281
311
  });
282
312
  });
283
313
 
284
- it("starts a draft chat with the agent runtime as the pending session type", async () => {
314
+ it("starts a draft chat with the agent selected through the session list owner", async () => {
285
315
  const user = userEvent.setup();
286
316
 
287
317
  renderAgentsPage();
@@ -294,12 +324,5 @@ describe("AgentsPage", () => {
294
324
  );
295
325
  expect(sessionListSnapshot.selectedSessionKey).toBeNull();
296
326
  expect(useChatThreadStore.getState().snapshot.sessionKey).toBeNull();
297
- expect(useChatInputStore.getState().snapshot.pendingSessionType).toBe(
298
- "codex",
299
- );
300
- expect(useChatInputStore.getState().snapshot.pendingProjectRoot).toBeNull();
301
- expect(
302
- useChatInputStore.getState().snapshot.pendingProjectRootSessionKey,
303
- ).toBeNull();
304
327
  });
305
328
  });