@nextclaw/ui 0.13.13 → 0.14.0

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 (379) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/assets/{api-D0hARyyl.js → api-B50yVdT8.js} +7 -7
  3. package/dist/assets/app-presenter-provider-BI-ewLbO.js +3 -0
  4. package/dist/assets/arrow-left-BOCJyLbQ.js +1 -0
  5. package/dist/assets/{book-open-DmeQPqkd.js → book-open-Bd2Xbrrc.js} +1 -1
  6. package/dist/assets/channels-list-page-moJkpxtU.js +8 -0
  7. package/dist/assets/chat-page-CO27cl4v.js +105 -0
  8. package/dist/assets/config-split-page-CsQ2rIdq.js +1 -0
  9. package/dist/assets/{confirm-dialog-CTcaBp-8.js → confirm-dialog-DRSelLdI.js} +2 -2
  10. package/dist/assets/desktop-update-config-qa-SynOc.js +1 -0
  11. package/dist/assets/{dist-Di6EHp2x.js → dist-D19wiQwB.js} +1 -1
  12. package/dist/assets/{dist-C59BKqbX.js → dist-NZRV-BxD.js} +1 -1
  13. package/dist/assets/doc-browser-2ddUJCA0.js +1 -0
  14. package/dist/assets/doc-browser-BjHUczQb.js +1 -0
  15. package/dist/assets/doc-browser-context-C8KPbj-p.js +1 -0
  16. package/dist/assets/{ellipsis-hXUNwi63.js → ellipsis-BYy8TP0A.js} +1 -1
  17. package/dist/assets/{es2015-CJlVSTh-.js → es2015-BUIIKCNh.js} +1 -1
  18. package/dist/assets/{external-link-J0fCK-vu.js → external-link-528k6MDD.js} +1 -1
  19. package/dist/assets/index-CMNrRhnG.js +101 -0
  20. package/dist/assets/index-UTmTW1eU.css +1 -0
  21. package/dist/assets/{key-round-BzYZ0Nno.js → key-round-D3vD9dj7.js} +1 -1
  22. package/dist/assets/loader-circle-DV9TSRns.js +1 -0
  23. package/dist/assets/mcp-marketplace-page-CS5Lh3oA.js +1 -0
  24. package/dist/assets/mcp-marketplace-page-DEOMcWb0.js +40 -0
  25. package/dist/assets/model-config-page-BSc4o7pb.js +1 -0
  26. package/dist/assets/{notice-card-CD9Ok62G.js → notice-card-qqlbsOoR.js} +1 -1
  27. package/dist/assets/plus-Bf9qhPDO.js +1 -0
  28. package/dist/assets/{popover-CoBu3mbV.js → popover-BnmPOXe3.js} +1 -1
  29. package/dist/assets/provider-scoped-model-input-Ca56s475.js +1 -0
  30. package/dist/assets/providers-config-page-D8Kf4U3u.js +1 -0
  31. package/dist/assets/{react-C7HsxuKH.js → react-Dsotw5vM.js} +1 -1
  32. package/dist/assets/{refresh-cw-CVo4nWpq.js → refresh-cw-Bmx4wc9P.js} +1 -1
  33. package/dist/assets/remote-DNMEy_c4.js +1 -0
  34. package/dist/assets/rotate-cw-CL0sVBel.js +1 -0
  35. package/dist/assets/runtime-config-page-CUFtKr0U.js +1 -0
  36. package/dist/assets/{save-Z1QTovIt.js → save-CHDnDTok.js} +1 -1
  37. package/dist/assets/search-D7L-TCH-.js +1 -0
  38. package/dist/assets/search-config-page-CA3RVAef.js +1 -0
  39. package/dist/assets/secrets-config-page-95yaH1fa.js +3 -0
  40. package/dist/assets/{status-dot-C1-FKgvv.js → status-dot-Dm4h-bjn.js} +1 -1
  41. package/dist/assets/tabs-CJvw5Lqp.js +1 -0
  42. package/dist/assets/{tag-chip-3kpiMTST.js → tag-chip-Cr8GwpRE.js} +1 -1
  43. package/dist/assets/{tooltip-Bw-mXQAM.js → tooltip-Bxzi6aDL.js} +1 -1
  44. package/dist/assets/{trash-2-CmIwAJIT.js → trash-2-CSfX-BvU.js} +1 -1
  45. package/dist/assets/use-config-TzwzTgg0.js +1 -0
  46. package/dist/assets/x-fkIWvi07.js +1 -0
  47. package/dist/index.html +27 -27
  48. package/package.json +9 -8
  49. package/src/app/index.tsx +8 -4
  50. package/src/features/account/components/account-panel.tsx +1 -1
  51. package/src/features/account/hooks/{use-auth.test.ts → __tests__/use-auth.test.ts} +1 -1
  52. package/src/features/agents/components/{agents-page.test.tsx → __tests__/agents-page.test.tsx} +41 -2
  53. package/src/features/agents/components/agent-dialogs.tsx +2 -2
  54. package/src/features/agents/components/agents-page.tsx +1 -1
  55. package/src/features/channels/components/config/channel-form.tsx +1 -1
  56. package/src/features/channels/pages/channels-list-page.tsx +18 -15
  57. package/src/features/channels/utils/{channel-form-fields.utils.test.ts → __tests__/channel-form-fields.utils.test.ts} +1 -1
  58. package/src/features/chat/components/{chat-welcome.test.tsx → __tests__/chat-welcome.test.tsx} +1 -1
  59. package/src/features/chat/components/conversation/{chat-conversation-header.test.tsx → __tests__/chat-conversation-header.test.tsx} +25 -32
  60. package/src/features/chat/components/conversation/{chat-conversation-panel.test.tsx → __tests__/chat-conversation-panel.test.tsx} +132 -37
  61. package/src/features/chat/components/conversation/chat-conversation-alerts.tsx +37 -0
  62. package/src/features/chat/components/conversation/chat-conversation-content.tsx +91 -0
  63. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +151 -0
  64. package/src/features/chat/components/conversation/chat-conversation-header.tsx +26 -89
  65. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +13 -379
  66. package/src/features/chat/components/conversation/chat-conversation-parent-banner.tsx +16 -0
  67. package/src/features/chat/components/conversation/chat-conversation-skeleton.tsx +86 -0
  68. package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +42 -0
  69. package/src/features/chat/components/layout/{chat-page-shell.test.tsx → __tests__/chat-page-shell.test.tsx} +1 -1
  70. package/src/features/chat/components/layout/__tests__/chat-sidebar-read-state.test.tsx +167 -0
  71. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +834 -0
  72. package/src/features/chat/components/layout/chat-page-shell.tsx +11 -30
  73. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +33 -53
  74. package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +1 -1
  75. package/src/features/chat/components/layout/chat-sidebar.tsx +156 -202
  76. package/src/features/chat/components/providers/chat-presenter.provider.tsx +13 -46
  77. package/src/features/chat/{components/conversation → features/input/components/__tests__}/chat-attachment-upload-limit.test.ts +1 -1
  78. package/src/features/chat/{components/conversation → features/input/components}/chat-input-bar.container.tsx +133 -31
  79. package/src/features/chat/{hooks → features/input/hooks/__tests__}/use-chat-input-bar-controller.test.tsx +1 -1
  80. package/src/features/chat/{utils → features/input/utils/__tests__}/chat-composer-state.utils.test.ts +1 -1
  81. package/src/features/chat/{utils → features/input/utils/__tests__}/chat-inline-token.utils.test.ts +1 -1
  82. package/src/features/chat/{utils → features/input/utils/__tests__}/chat-input-bar.utils.test.ts +2 -2
  83. package/src/features/chat/{utils → features/input/utils/__tests__}/ncp-chat-input-availability.utils.test.ts +2 -1
  84. package/src/features/chat/{utils → features/input/utils}/ncp-chat-input-availability.utils.ts +6 -6
  85. package/src/features/chat/{components/conversation → features/message/components/__tests__}/chat-message-list.container.test.tsx +38 -3
  86. package/src/features/chat/{components/conversation → features/message/components}/chat-message-list.container.tsx +9 -13
  87. package/src/features/chat/{utils → features/message/utils/__tests__}/chat-message-invalid-tool-arguments.utils.test.ts +2 -2
  88. package/src/features/chat/{utils → features/message/utils/__tests__}/chat-message-session-spawn-tool-card.utils.test.ts +2 -2
  89. package/src/features/chat/features/message/utils/__tests__/chat-message-show-content-tool-card.utils.test.ts +54 -0
  90. package/src/features/chat/{utils → features/message/utils/__tests__}/chat-message-summary-truncation.utils.test.ts +2 -2
  91. package/src/features/chat/{utils → features/message/utils/__tests__}/chat-message-tool-agent-id.utils.test.ts +1 -1
  92. package/src/features/chat/{utils → features/message/utils/__tests__}/chat-message.utils.test.ts +2 -2
  93. package/src/features/chat/{utils → features/message/utils}/chat-message-inline-content.utils.ts +1 -1
  94. package/src/features/chat/{utils → features/message/utils}/chat-message-part.utils.ts +15 -2
  95. package/src/features/chat/{utils → features/message/utils}/chat-message-session-request-tool-card.utils.ts +1 -1
  96. package/src/features/chat/features/message/utils/chat-message-show-content-tool-card.utils.ts +165 -0
  97. package/src/features/chat/{utils → features/message/utils}/chat-message-tool-card.utils.ts +1 -1
  98. package/src/features/chat/{utils → features/message/utils}/chat-message.utils.ts +1 -1
  99. package/src/features/chat/features/ncp/hooks/__tests__/use-hydrated-ncp-agent.test.tsx +57 -0
  100. package/src/features/chat/{hooks → features/ncp/hooks/__tests__}/use-ncp-agent-runtime.test.tsx +2 -2
  101. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-chat-derived-state.test.tsx +22 -0
  102. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-chat-query-store-sync.test.tsx +101 -0
  103. package/src/features/chat/{hooks → features/ncp/hooks/__tests__}/use-ncp-session-conversation.test.tsx +1 -1
  104. package/src/features/chat/features/ncp/hooks/__tests__/use-ui-show-content-event.test.tsx +52 -0
  105. package/src/features/chat/features/ncp/hooks/use-ncp-chat-derived-state.ts +37 -0
  106. package/src/features/chat/features/ncp/hooks/use-ncp-chat-query-store-sync.ts +28 -0
  107. package/src/features/chat/{hooks → features/ncp/hooks}/use-ncp-child-session-tabs-view.ts +4 -4
  108. package/src/features/chat/{hooks → features/ncp/hooks}/use-ncp-session-conversation.ts +1 -1
  109. package/src/features/chat/{hooks → features/ncp/hooks}/use-ncp-session-list-view.ts +3 -3
  110. package/src/features/chat/features/ncp/hooks/use-ncp-session-queries.ts +32 -0
  111. package/src/features/chat/features/ncp/hooks/use-ui-show-content-event.ts +14 -0
  112. package/src/features/chat/features/ncp/utils/ncp-chat-query-derived.utils.ts +77 -0
  113. package/src/features/chat/{utils → features/runtime/utils/__tests__}/ncp-app-client-fetch.utils.test.ts +1 -1
  114. package/src/features/chat/{utils → features/runtime/utils/__tests__}/ncp-chat-runtime-availability.utils.test.ts +1 -1
  115. package/src/features/chat/{utils → features/runtime/utils}/chat-runtime.utils.ts +1 -1
  116. package/src/features/chat/{components → features/session/components}/chat-sidebar-project-groups.tsx +21 -42
  117. package/src/features/chat/{components/layout → features/session/components}/chat-sidebar-session-entry.tsx +40 -13
  118. package/src/features/chat/{components → features/session/components}/chat-sidebar-session-item.tsx +36 -44
  119. package/src/features/chat/features/session/components/chat-sidebar-session-list.tsx +78 -0
  120. package/src/features/chat/{components/session → features/session/components}/session-context-icon.tsx +1 -1
  121. package/src/features/chat/{components/conversation/session-header → features/session/components/session-header/__tests__}/chat-session-header-actions.test.tsx +3 -3
  122. package/src/features/chat/{components/conversation/session-header → features/session/components/session-header/__tests__}/chat-session-project-badge.test.tsx +3 -3
  123. package/src/features/chat/{components/conversation → features/session/components}/session-header/chat-session-header-actions.tsx +15 -27
  124. package/src/features/chat/{components/conversation → features/session/components}/session-header/chat-session-project-badge.tsx +1 -1
  125. package/src/features/chat/{hooks → features/session/hooks/__tests__}/use-chat-session-project.test.tsx +2 -2
  126. package/src/features/chat/{hooks → features/session/hooks/__tests__}/use-chat-session-update.test.tsx +1 -1
  127. package/src/features/chat/{hooks → features/session/hooks}/use-chat-session-project.ts +1 -1
  128. package/src/features/chat/{hooks → features/session/hooks}/use-chat-session-update.ts +17 -0
  129. package/src/features/chat/{hooks → features/session/hooks}/use-chat-sidebar-session-label-editor.ts +1 -1
  130. package/src/features/chat/{hooks → features/session/hooks}/use-selected-session-context-window-indicator.ts +1 -1
  131. package/src/features/chat/{utils → features/session/utils/__tests__}/chat-session-display.utils.test.ts +1 -1
  132. package/src/features/chat/{utils → features/session/utils/__tests__}/chat-session-route.utils.test.ts +1 -1
  133. package/src/features/chat/{utils → features/session/utils/__tests__}/ncp-session-adapter.utils.cancelled-tool.test.ts +2 -2
  134. package/src/features/chat/{utils → features/session/utils/__tests__}/ncp-session-adapter.utils.test.ts +2 -2
  135. package/src/features/chat/{utils → features/session/utils/__tests__}/session-context.utils.test.ts +1 -1
  136. package/src/features/chat/features/session/utils/chat-run-metadata.utils.ts +60 -0
  137. package/src/features/chat/{utils → features/session/utils}/chat-session-preference-governance.utils.ts +0 -128
  138. package/src/features/chat/features/session/utils/chat-sidebar-session-groups.utils.ts +144 -0
  139. package/src/features/chat/{components → features/session-type/components/__tests__}/chat-session-type-option-item.test.tsx +1 -1
  140. package/src/features/chat/{components → features/session-type/components}/chat-session-type-option-item.tsx +7 -16
  141. package/src/features/chat/features/session-type/components/chat-sidebar-create-menu.tsx +42 -0
  142. package/src/features/chat/{hooks → features/session-type/hooks/__tests__}/use-chat-session-type-state.test.tsx +1 -1
  143. package/src/features/chat/{hooks → features/session-type/hooks}/use-chat-session-type-state.ts +23 -94
  144. package/src/features/chat/features/session-type/utils/chat-session-type.utils.ts +105 -0
  145. package/src/features/chat/{components → features/workspace/components/__tests__}/chat-session-workspace-file-preview.test.tsx +1 -1
  146. package/src/features/chat/{components → features/workspace/components}/chat-session-workspace-file-preview.tsx +2 -2
  147. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +156 -0
  148. package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +84 -0
  149. package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +138 -0
  150. package/src/features/chat/{components/workspace → features/workspace/components}/session-cron-job-content.tsx +1 -1
  151. package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +63 -0
  152. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +103 -0
  153. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +183 -0
  154. package/src/features/chat/index.ts +16 -6
  155. package/src/features/chat/managers/__tests__/chat-input.manager.test.ts +355 -0
  156. package/src/features/chat/managers/__tests__/chat-query.manager.test.ts +39 -0
  157. package/src/features/chat/managers/__tests__/chat-run.manager.test.ts +202 -0
  158. package/src/features/chat/managers/{chat-session-list.manager.test.ts → __tests__/chat-session-list.manager.test.ts} +98 -78
  159. package/src/features/chat/managers/{chat-session-preference-sync.manager.test.ts → __tests__/chat-session-preference-sync.manager.test.ts} +1 -1
  160. package/src/features/chat/managers/{ncp-chat-thread.manager.test.ts → __tests__/chat-thread.manager.test.ts} +298 -45
  161. package/src/features/chat/managers/__tests__/chat-ui.manager.test.ts +126 -0
  162. package/src/features/chat/managers/{recent-selection.manager.test.ts → __tests__/recent-selection.manager.test.ts} +1 -1
  163. package/src/features/chat/managers/{ncp-chat-input.manager.ts → chat-input.manager.ts} +108 -35
  164. package/src/features/chat/managers/chat-query.manager.ts +48 -0
  165. package/src/features/chat/managers/chat-run.manager.ts +107 -0
  166. package/src/features/chat/managers/chat-session-list.manager.ts +45 -15
  167. package/src/features/chat/managers/chat-session-preference-sync.manager.ts +60 -5
  168. package/src/features/chat/managers/{ncp-chat-thread.manager.ts → chat-thread.manager.ts} +63 -36
  169. package/src/features/chat/managers/chat-ui.manager.ts +55 -9
  170. package/src/features/chat/pages/{ncp-chat-page.test.ts → __tests__/ncp-chat-page.test.ts} +49 -12
  171. package/src/features/chat/pages/ncp-chat-page.tsx +123 -399
  172. package/src/features/chat/presenters/chat.presenter.ts +39 -0
  173. package/src/features/chat/stores/chat-input.store.ts +5 -1
  174. package/src/features/chat/stores/chat-thread.store.ts +0 -19
  175. package/src/features/chat/stores/ncp-chat-query.store.ts +25 -0
  176. package/src/features/chat/types/chat-input.types.ts +1 -0
  177. package/src/features/chat/types/chat-message.types.ts +1 -0
  178. package/src/features/chat/types/chat-run.types.ts +41 -0
  179. package/src/{shared → features/cron}/components/cron-config.tsx +1 -1
  180. package/src/features/cron/hooks/use-cron-jobs.ts +58 -0
  181. package/src/features/cron/index.ts +7 -0
  182. package/src/features/marketplace/components/curated-shelves/marketplace-curated-shelves.tsx +15 -61
  183. package/src/features/marketplace/components/marketplace-external-skill-source-action.tsx +1 -1
  184. package/src/features/marketplace/components/marketplace-item-list-view.tsx +167 -0
  185. package/src/features/marketplace/components/marketplace-list-card.tsx +27 -31
  186. package/src/features/marketplace/components/marketplace-page-data.ts +0 -6
  187. package/src/features/marketplace/components/marketplace-page.tsx +105 -451
  188. package/src/features/marketplace/components/mcp/mcp-marketplace-card.tsx +1 -1
  189. package/src/features/marketplace/components/mcp/mcp-marketplace-dialogs.tsx +1 -1
  190. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +1 -1
  191. package/src/features/marketplace/hooks/use-marketplace-item-actions.ts +101 -0
  192. package/src/features/marketplace/hooks/use-marketplace-item-detail.ts +109 -0
  193. package/src/features/marketplace/hooks/use-marketplace-list-model.ts +160 -0
  194. package/src/features/marketplace/utils/{marketplace-installed-cache.utils.test.ts → __tests__/marketplace-installed-cache.utils.test.ts} +1 -1
  195. package/src/features/panel-apps/components/{panel-app-list-item.test.tsx → __tests__/panel-app-list-item.test.tsx} +1 -1
  196. package/src/features/panel-apps/components/{panel-app-toolbar.test.tsx → __tests__/panel-app-toolbar.test.tsx} +1 -1
  197. package/src/features/panel-apps/utils/{panel-app-view.utils.test.ts → __tests__/panel-app-view.utils.test.ts} +1 -1
  198. package/src/features/pwa/managers/{pwa-service-worker-cache.manager.test.ts → __tests__/pwa-service-worker-cache.manager.test.ts} +1 -1
  199. package/src/features/remote/components/remote-access-page.tsx +2 -2
  200. package/src/features/remote/services/{remote-access-feedback.service.test.ts → __tests__/remote-access-feedback.service.test.ts} +1 -1
  201. package/src/{shared → features/settings}/components/config/provider-form.tsx +5 -5
  202. package/src/{shared/components → features/settings/components/config}/provider-status-badge.tsx +1 -1
  203. package/src/{shared/components/model-config.test.tsx → features/settings/pages/__tests__/model-config-page.test.tsx} +40 -5
  204. package/src/{shared/components/config/providers-list.test.tsx → features/settings/pages/__tests__/providers-config-page.test.tsx} +48 -5
  205. package/src/{shared/components/search-config.test.tsx → features/settings/pages/__tests__/search-config-page.test.tsx} +3 -3
  206. package/src/{shared/components/config/secrets-config.test.tsx → features/settings/pages/__tests__/secrets-config-page.test.tsx} +3 -3
  207. package/src/{shared/components/model-config.tsx → features/settings/pages/model-config-page.tsx} +1 -1
  208. package/src/{shared/components/config/providers-list.tsx → features/settings/pages/providers-config-page.tsx} +3 -3
  209. package/src/{shared/components/search-config.tsx → features/settings/pages/search-config-page.tsx} +1 -1
  210. package/src/{shared/components/config/secrets-config.tsx → features/settings/pages/secrets-config-page.tsx} +2 -2
  211. package/src/{shared/components/config/provider-form-support.test.ts → features/settings/utils/__tests__/provider-form-support.utils.test.ts} +1 -1
  212. package/src/features/system-status/components/{runtime-control-card.test.tsx → __tests__/runtime-control-card.test.tsx} +1 -1
  213. package/src/features/system-status/components/{runtime-presence-card.test.tsx → __tests__/runtime-presence-card.test.tsx} +1 -1
  214. package/src/features/system-status/components/runtime-presence-card.tsx +2 -2
  215. package/src/features/system-status/managers/{system-status.manager.bootstrap-polling.test.ts → __tests__/system-status.manager.bootstrap-polling.test.ts} +1 -1
  216. package/src/features/system-status/managers/{system-status.manager.test.ts → __tests__/system-status.manager.test.ts} +1 -1
  217. package/src/features/system-status/utils/{system-status.utils.test.ts → __tests__/system-status.utils.test.ts} +1 -1
  218. package/src/shared/components/common/{agent-avatar.test.tsx → __tests__/agent-avatar.test.tsx} +1 -1
  219. package/src/shared/components/common/agent-identity/use-agent-identity.ts +3 -8
  220. package/src/shared/components/common/brand-header.tsx +1 -1
  221. package/src/shared/components/common/tag-input.tsx +1 -1
  222. package/src/shared/components/doc-browser/{doc-browser-context.test.tsx → __tests__/doc-browser-context.test.tsx} +1 -1
  223. package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +64 -161
  224. package/src/shared/components/doc-browser/doc-browser.tsx +4 -4
  225. package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +66 -0
  226. package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +11 -8
  227. package/src/shared/components/ui/actions/icon-action-button.tsx +53 -0
  228. package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +52 -0
  229. package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +228 -0
  230. package/src/shared/hooks/use-app-meta.ts +10 -0
  231. package/src/shared/hooks/use-config.ts +1 -148
  232. package/src/shared/lib/api/{ncp-session.test.ts → __tests__/ncp-session.test.ts} +3 -3
  233. package/src/shared/lib/api/{raw-client.test.ts → __tests__/raw-client.test.ts} +1 -1
  234. package/src/shared/lib/api/chat-session-type.types.ts +3 -0
  235. package/src/shared/lib/cadence/services/{adaptive-cadence.service.test.ts → __tests__/adaptive-cadence.service.test.ts} +1 -1
  236. package/src/shared/lib/i18n/locales/en-US/chat.json +2 -0
  237. package/src/shared/lib/i18n/locales/en-US/core.json +1 -0
  238. package/src/shared/lib/i18n/locales/zh-CN/chat.json +2 -0
  239. package/src/shared/lib/i18n/locales/zh-CN/core.json +1 -0
  240. package/src/shared/lib/i18n/locales/zh-CN/marketplace.json +1 -1
  241. package/src/shared/lib/i18n/runtime/{i18n-language-owner.test.ts → __tests__/i18n-language-owner.test.ts} +2 -2
  242. package/src/shared/lib/navigation-history/{navigation-history.utils.test.ts → __tests__/navigation-history.utils.test.ts} +1 -1
  243. package/src/shared/lib/provider-models/{index.test.ts → __tests__/index.test.ts} +1 -1
  244. package/src/shared/lib/transport/{app-client.test.ts → __tests__/app-client.test.ts} +3 -3
  245. package/src/shared/lib/transport/{remote.transport.test.ts → __tests__/remote.transport.test.ts} +1 -1
  246. package/src/shared/lib/transport/{sse-stream.test.ts → __tests__/sse-stream.test.ts} +1 -1
  247. package/tsconfig.json +2 -5
  248. package/vite.config.ts +4 -4
  249. package/vitest.config.ts +4 -0
  250. package/dist/assets/app-presenter-provider-C7EsUuEJ.js +0 -3
  251. package/dist/assets/arrow-left-CzSkR5L6.js +0 -1
  252. package/dist/assets/channels-list-page-B0yiiH01.js +0 -8
  253. package/dist/assets/chat-page-ChPjx_X9.js +0 -105
  254. package/dist/assets/config-split-page-BzfZSyAr.js +0 -1
  255. package/dist/assets/desktop-update-config-CExpdkqD.js +0 -1
  256. package/dist/assets/doc-browser-EZbnEcdk.js +0 -1
  257. package/dist/assets/doc-browser-XIwe1Tg-.js +0 -1
  258. package/dist/assets/doc-browser-context-BzEA1lm1.js +0 -1
  259. package/dist/assets/index-DfZTO6Pi.js +0 -101
  260. package/dist/assets/index-mIb_YMrc.css +0 -1
  261. package/dist/assets/loader-circle-BbdIlBbQ.js +0 -1
  262. package/dist/assets/mcp-marketplace-page-L22aCzHX.js +0 -40
  263. package/dist/assets/mcp-marketplace-page-f80Jmv37.js +0 -1
  264. package/dist/assets/model-config-DkD7vSQT.js +0 -1
  265. package/dist/assets/play-DHuSeKs8.js +0 -1
  266. package/dist/assets/plus-DrV685KC.js +0 -1
  267. package/dist/assets/provider-models-C9VRroK3.js +0 -1
  268. package/dist/assets/provider-scoped-model-input-DZlmTCJU.js +0 -1
  269. package/dist/assets/providers-list-CVkWiqIy.js +0 -1
  270. package/dist/assets/remote-Bznw9iji.js +0 -1
  271. package/dist/assets/rotate-cw-CXDpRO6D.js +0 -1
  272. package/dist/assets/runtime-config-page-5IycbIxs.js +0 -1
  273. package/dist/assets/search-8nY6PGm0.js +0 -1
  274. package/dist/assets/search-config-DEH80WkC.js +0 -1
  275. package/dist/assets/secrets-config-Gzo5nDJG.js +0 -3
  276. package/dist/assets/tabs-BqkKwx1R.js +0 -1
  277. package/dist/assets/tabs-custom-DOkaJZmt.js +0 -1
  278. package/dist/assets/x-CSRTOZnM.js +0 -1
  279. package/src/features/chat/components/chat-session-workspace-panel-nav.tsx +0 -264
  280. package/src/features/chat/components/chat-session-workspace-panel.tsx +0 -380
  281. package/src/features/chat/components/layout/chat-sidebar-read-state.test.tsx +0 -145
  282. package/src/features/chat/components/layout/chat-sidebar.test.tsx +0 -896
  283. package/src/features/chat/hooks/use-chat-session-label.ts +0 -18
  284. package/src/features/chat/hooks/use-hydrated-ncp-agent.test.tsx +0 -90
  285. package/src/features/chat/hooks/use-ncp-chat-derived-state.ts +0 -181
  286. package/src/features/chat/hooks/use-ncp-chat-page-data.test.tsx +0 -70
  287. package/src/features/chat/hooks/use-ncp-chat-page-data.ts +0 -260
  288. package/src/features/chat/managers/chat-stream-actions.manager.ts +0 -35
  289. package/src/features/chat/managers/ncp-chat-input.manager.test.ts +0 -232
  290. package/src/features/chat/managers/ncp-chat-presenter.manager.ts +0 -28
  291. package/src/features/chat/types/chat-stream.types.ts +0 -32
  292. package/src/features/chat/utils/chat-session-preference-governance.utils.test.tsx +0 -114
  293. package/src/features/marketplace/components/marketplace-catalog-grid.tsx +0 -132
  294. package/src/shared/components/resizable-right-panel/resizable-right-panel.test.tsx +0 -38
  295. package/src/shared/components/ui/config-card.tsx +0 -71
  296. package/src/shared/components/ui/highlight-card.tsx +0 -40
  297. package/src/shared/components/ui/tabs-custom.tsx +0 -49
  298. /package/dist/assets/{config-hints-fGnUjDe9.js → config-hints-Cl2XAhzV.js} +0 -0
  299. /package/dist/assets/{host-capabilities-DjiRQ0Q9.js → host-capabilities-9bB_998Z.js} +0 -0
  300. /package/src/{app.test.tsx → __tests__/app.test.tsx} +0 -0
  301. /package/src/app/components/layout/{app-layout.test.tsx → __tests__/app-layout.test.tsx} +0 -0
  302. /package/src/app/components/layout/{runtime-status-entry.test.tsx → __tests__/runtime-status-entry.test.tsx} +0 -0
  303. /package/src/app/components/layout/{settings-entry-page.test.tsx → __tests__/settings-entry-page.test.tsx} +0 -0
  304. /package/src/app/components/layout/{sidebar.layout.test.tsx → __tests__/sidebar.layout.test.tsx} +0 -0
  305. /package/src/features/channels/components/config/{channel-form.test.tsx → __tests__/channel-form.test.tsx} +0 -0
  306. /package/src/features/channels/components/config/{weixin-channel-auth-section.test.tsx → __tests__/weixin-channel-auth-section.test.tsx} +0 -0
  307. /package/src/features/channels/pages/{channels-list-page.test.tsx → __tests__/channels-list-page.test.tsx} +0 -0
  308. /package/src/features/chat/{hooks → features/input/hooks}/use-chat-input-bar-controller.ts +0 -0
  309. /package/src/features/chat/{utils → features/input/utils}/chat-composer-state.utils.ts +0 -0
  310. /package/src/features/chat/{utils → features/input/utils}/chat-inline-token.utils.ts +0 -0
  311. /package/src/features/chat/{utils → features/input/utils}/chat-input-bar.utils.ts +0 -0
  312. /package/src/features/chat/{utils → features/input/utils}/chat-input-toolbar.utils.ts +0 -0
  313. /package/src/features/chat/{utils → features/message/utils}/chat-message-core.utils.ts +0 -0
  314. /package/src/features/chat/{utils → features/message/utils}/chat-message-partial-json.utils.ts +0 -0
  315. /package/src/features/chat/{utils → features/message/utils}/chat-message-tool-agent-id.utils.ts +0 -0
  316. /package/src/features/chat/{utils → features/message/utils}/file-operation/card.utils.ts +0 -0
  317. /package/src/features/chat/{utils → features/message/utils}/file-operation/diff.utils.ts +0 -0
  318. /package/src/features/chat/{utils → features/message/utils}/file-operation/line-builder.utils.ts +0 -0
  319. /package/src/features/chat/{utils → features/message/utils}/file-operation/parsed-block.utils.ts +0 -0
  320. /package/src/features/chat/{utils → features/message/utils}/file-operation/record-readers.utils.ts +0 -0
  321. /package/src/features/chat/{utils → features/runtime/utils}/ncp-app-client-fetch.utils.ts +0 -0
  322. /package/src/features/chat/{utils → features/runtime/utils}/ncp-chat-runtime-availability.utils.ts +0 -0
  323. /package/src/features/chat/{components/conversation → features/session/components}/session-header/chat-session-header-menu-item.tsx +0 -0
  324. /package/src/features/chat/{components/conversation → features/session/components}/session-header/chat-session-project-dialog.tsx +0 -0
  325. /package/src/features/chat/{components/session → features/session/components}/session-run-badge.tsx +0 -0
  326. /package/src/features/chat/{utils → features/session/utils}/chat-context-window-indicator.utils.ts +0 -0
  327. /package/src/features/chat/{utils → features/session/utils}/chat-session-display.utils.ts +0 -0
  328. /package/src/features/chat/{utils → features/session/utils}/chat-session-route.utils.ts +0 -0
  329. /package/src/features/chat/{utils → features/session/utils}/ncp-session-adapter.utils.ts +0 -0
  330. /package/src/features/chat/{utils → features/session/utils}/ncp-session-context-metadata.utils.ts +0 -0
  331. /package/src/features/chat/{utils → features/session/utils}/session-context.utils.ts +0 -0
  332. /package/src/features/chat/{hooks → features/session-type/hooks}/use-ncp-chat-session-types.ts +0 -0
  333. /package/src/features/chat/{components/workspace → features/workspace/components}/chat-session-workspace-file-breadcrumbs.tsx +0 -0
  334. /package/src/features/chat/stores/{chat-thread.store.test.ts → __tests__/chat-thread.store.test.ts} +0 -0
  335. /package/src/features/marketplace/components/{marketplace-page-detail.test.tsx → __tests__/marketplace-page-detail.test.tsx} +0 -0
  336. /package/src/features/marketplace/components/{marketplace-page.test.tsx → __tests__/marketplace-page.test.tsx} +0 -0
  337. /package/src/features/marketplace/components/curated-shelves/{marketplace-curated-scene-route.test.tsx → __tests__/marketplace-curated-scene-route.test.tsx} +0 -0
  338. /package/src/features/marketplace/components/detail-doc/{marketplace-detail-doc.test.ts → __tests__/marketplace-detail-doc.test.ts} +0 -0
  339. /package/src/features/marketplace/components/mcp/{mcp-marketplace-page.test.tsx → __tests__/mcp-marketplace-page.test.tsx} +0 -0
  340. /package/src/features/marketplace/hooks/{use-marketplace.test.tsx → __tests__/use-marketplace.test.tsx} +0 -0
  341. /package/src/features/panel-apps/managers/{panel-app-bridge.manager.test.ts → __tests__/panel-app-bridge.manager.test.ts} +0 -0
  342. /package/src/features/panel-apps/utils/{panel-app-doc-browser.utils.test.ts → __tests__/panel-app-doc-browser.utils.test.ts} +0 -0
  343. /package/src/features/pwa/components/{pwa-install-entry.test.tsx → __tests__/pwa-install-entry.test.tsx} +0 -0
  344. /package/src/features/pwa/managers/{pwa-install.manager.test.ts → __tests__/pwa-install.manager.test.ts} +0 -0
  345. /package/src/features/pwa/managers/{pwa-shell-theme.manager.test.ts → __tests__/pwa-shell-theme.manager.test.ts} +0 -0
  346. /package/src/features/remote/components/{remote-access-page.test.tsx → __tests__/remote-access-page.test.tsx} +0 -0
  347. /package/src/features/right-panel-resources/utils/{right-panel-resource-route-resolver.utils.test.ts → __tests__/right-panel-resource-route-resolver.utils.test.ts} +0 -0
  348. /package/src/features/right-panel-resources/utils/{right-panel-resource-uri.utils.test.ts → __tests__/right-panel-resource-uri.utils.test.ts} +0 -0
  349. /package/src/features/service-apps/components/{service-apps-panel.test.tsx → __tests__/service-apps-panel.test.tsx} +0 -0
  350. /package/src/{shared/components → features/settings/components/config}/provider-advanced-settings-section.tsx +0 -0
  351. /package/src/{shared/components → features/settings/components/config}/provider-auth-section.tsx +0 -0
  352. /package/src/{shared → features/settings}/components/config/provider-models-section.tsx +0 -0
  353. /package/src/{shared/components → features/settings/components/config}/provider-pill-selector.tsx +0 -0
  354. /package/src/{shared → features/settings}/components/config/secrets-config-form.tsx +0 -0
  355. /package/src/features/settings/pages/{language-settings-page.test.tsx → __tests__/language-settings-page.test.tsx} +0 -0
  356. /package/src/{shared/components/config/provider-form-support.ts → features/settings/utils/provider-form-support.utils.ts} +0 -0
  357. /package/src/features/side-dock/components/{side-dock.test.tsx → __tests__/side-dock.test.tsx} +0 -0
  358. /package/src/features/side-dock/managers/{side-dock.manager.test.ts → __tests__/side-dock.manager.test.ts} +0 -0
  359. /package/src/features/side-dock/utils/{side-dock-item.utils.test.ts → __tests__/side-dock-item.utils.test.ts} +0 -0
  360. /package/src/features/system-status/components/{desktop-update-config.test.tsx → __tests__/desktop-update-config.test.tsx} +0 -0
  361. /package/src/features/system-status/pages/{runtime-config-page.test.tsx → __tests__/runtime-config-page.test.tsx} +0 -0
  362. /package/src/platforms/desktop/components/{desktop-app-shell.test.tsx → __tests__/desktop-app-shell.test.tsx} +0 -0
  363. /package/src/platforms/mobile/components/{mobile-app-shell.test.tsx → __tests__/mobile-app-shell.test.tsx} +0 -0
  364. /package/src/platforms/mobile/components/{mobile-bottom-nav.test.tsx → __tests__/mobile-bottom-nav.test.tsx} +0 -0
  365. /package/src/shared/components/{ui → actions}/action-link.tsx +0 -0
  366. /package/src/shared/components/common/{brand-header.test.tsx → __tests__/brand-header.test.tsx} +0 -0
  367. /package/src/shared/components/doc-browser/{doc-browser.test.tsx → __tests__/doc-browser.test.tsx} +0 -0
  368. /package/src/shared/components/{ui → feedback}/notice-card.tsx +0 -0
  369. /package/src/shared/components/path-picker/{server-path-picker-dialog.test.tsx → __tests__/server-path-picker-dialog.test.tsx} +0 -0
  370. /package/src/shared/components/{ui → settings}/setting-row.tsx +0 -0
  371. /package/src/shared/components/{ui → status}/status-dot.tsx +0 -0
  372. /package/src/shared/components/{ui → tags}/tag-chip.tsx +0 -0
  373. /package/src/shared/lib/api/{api-base.test.ts → __tests__/api-base.test.ts} +0 -0
  374. /package/src/shared/lib/api/{client.test.ts → __tests__/client.test.ts} +0 -0
  375. /package/src/shared/lib/api/{ncp-session-query-cache.utils.test.ts → __tests__/ncp-session-query-cache.utils.test.ts} +0 -0
  376. /package/src/shared/lib/app-resource-uri/{app-resource-uri.test.ts → __tests__/app-resource-uri.test.ts} +0 -0
  377. /package/src/shared/lib/host-capabilities/{host-capability.manager.test.ts → __tests__/host-capability.manager.test.ts} +0 -0
  378. /package/src/shared/lib/resource-uri/utils/{resource-uri-resolver.utils.test.ts → __tests__/resource-uri-resolver.utils.test.ts} +0 -0
  379. /package/src/shared/lib/session-project/{workspace-file-breadcrumb.test.ts → __tests__/workspace-file-breadcrumb.test.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
2
  import { appQueryClient } from '@/app-query-client';
3
- import { NcpChatThreadManager } from '@/features/chat/managers/ncp-chat-thread.manager';
3
+ import { ChatThreadManager } from '@/features/chat/managers/chat-thread.manager';
4
4
  import { useChatSessionListStore } from '@/features/chat/stores/chat-session-list.store';
5
5
  import { useChatThreadStore } from '@/features/chat/stores/chat-thread.store';
6
6
  import type * as SharedApi from '@/shared/lib/api';
@@ -49,19 +49,33 @@ beforeEach(() => {
49
49
  });
50
50
  });
51
51
 
52
- describe('NcpChatThreadManager', () => {
52
+ function createUiManager(
53
+ overrides: Record<string, unknown> = {},
54
+ ): ConstructorParameters<typeof ChatThreadManager>[0] {
55
+ return {
56
+ goToSession: vi.fn(),
57
+ goToChatRoot: vi.fn(),
58
+ goToProviders: vi.fn(),
59
+ confirm: vi.fn(),
60
+ isCompactViewport: vi.fn(() => false),
61
+ showContent: vi.fn().mockResolvedValue(undefined),
62
+ ...overrides,
63
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
64
+ }
65
+
66
+ describe('ChatThreadManager', () => {
53
67
  it('opens the child-session panel for the requested parent session and keeps focus on the chosen child', () => {
54
68
  const uiManager = {
55
69
  goToSession: vi.fn(),
56
70
  goToChatRoot: vi.fn(),
57
71
  goToProviders: vi.fn(),
58
72
  confirm: vi.fn(),
59
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
73
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
60
74
 
61
- const manager = new NcpChatThreadManager(
75
+ const manager = new ChatThreadManager(
62
76
  uiManager,
63
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
64
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
77
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
78
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
65
79
  );
66
80
 
67
81
  manager.openChildSessionPanel({
@@ -86,12 +100,12 @@ describe('NcpChatThreadManager', () => {
86
100
  goToChatRoot: vi.fn(),
87
101
  goToProviders: vi.fn(),
88
102
  confirm: vi.fn(),
89
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
103
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
90
104
 
91
- const manager = new NcpChatThreadManager(
105
+ const manager = new ChatThreadManager(
92
106
  uiManager,
93
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
94
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
107
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
108
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
95
109
  );
96
110
 
97
111
  manager.openChildSessionPanel({
@@ -108,12 +122,12 @@ describe('NcpChatThreadManager', () => {
108
122
  goToChatRoot: vi.fn(),
109
123
  goToProviders: vi.fn(),
110
124
  confirm: vi.fn(),
111
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
125
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
112
126
 
113
- const manager = new NcpChatThreadManager(
127
+ const manager = new ChatThreadManager(
114
128
  uiManager,
115
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
116
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
129
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
130
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
117
131
  );
118
132
 
119
133
  manager.openSessionCronPanel('parent-session-1');
@@ -139,12 +153,12 @@ describe('NcpChatThreadManager', () => {
139
153
  goToChatRoot: vi.fn(),
140
154
  goToProviders: vi.fn(),
141
155
  confirm: vi.fn(),
142
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
156
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
143
157
 
144
- const manager = new NcpChatThreadManager(
158
+ const manager = new ChatThreadManager(
145
159
  uiManager,
146
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
147
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
160
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
161
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
148
162
  );
149
163
 
150
164
  manager.openSessionCronPanel('parent-session-1');
@@ -158,12 +172,12 @@ describe('NcpChatThreadManager', () => {
158
172
  goToChatRoot: vi.fn(),
159
173
  goToProviders: vi.fn(),
160
174
  confirm: vi.fn(),
161
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
175
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
162
176
 
163
- const manager = new NcpChatThreadManager(
177
+ const manager = new ChatThreadManager(
164
178
  uiManager,
165
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
166
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
179
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
180
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
167
181
  );
168
182
 
169
183
  manager.openFilePreview({
@@ -196,18 +210,18 @@ describe('NcpChatThreadManager', () => {
196
210
  });
197
211
  });
198
212
 
199
- describe('NcpChatThreadManager workspace navigation', () => {
213
+ describe('ChatThreadManager workspace navigation', () => {
200
214
  it('navigates backward and forward through workspace selections', () => {
201
215
  const uiManager = {
202
216
  goToSession: vi.fn(),
203
217
  goToChatRoot: vi.fn(),
204
218
  goToProviders: vi.fn(),
205
219
  confirm: vi.fn(),
206
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
207
- const manager = new NcpChatThreadManager(
220
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
221
+ const manager = new ChatThreadManager(
208
222
  uiManager,
209
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
210
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
223
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
224
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
211
225
  );
212
226
 
213
227
  manager.openChildSessionPanel({
@@ -261,10 +275,10 @@ describe('NcpChatThreadManager workspace navigation', () => {
261
275
  },
262
276
  ],
263
277
  });
264
- const manager = new NcpChatThreadManager(
265
- { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0],
266
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
267
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
278
+ const manager = new ChatThreadManager(
279
+ { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof ChatThreadManager>[0],
280
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
281
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
268
282
  );
269
283
 
270
284
  manager.openChildSessionPanel({
@@ -287,10 +301,10 @@ describe('NcpChatThreadManager workspace navigation', () => {
287
301
  });
288
302
 
289
303
  it('removes a closed active file from workspace history and restores the previous entry', () => {
290
- const manager = new NcpChatThreadManager(
291
- { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0],
292
- {} as ConstructorParameters<typeof NcpChatThreadManager>[1],
293
- {} as ConstructorParameters<typeof NcpChatThreadManager>[2],
304
+ const manager = new ChatThreadManager(
305
+ { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof ChatThreadManager>[0],
306
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
307
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
294
308
  );
295
309
 
296
310
  manager.openChildSessionPanel({
@@ -316,7 +330,246 @@ describe('NcpChatThreadManager workspace navigation', () => {
316
330
  });
317
331
  });
318
332
 
319
- describe('NcpChatThreadManager deletion', () => {
333
+ describe('ChatThreadManager showContent', () => {
334
+ it('routes tool actions through the thread manager owner', async () => {
335
+ const uiManager = createUiManager({
336
+ goToSession: vi.fn(),
337
+ });
338
+ const manager = new ChatThreadManager(
339
+ uiManager,
340
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
341
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
342
+ );
343
+
344
+ await manager.handleToolAction({
345
+ kind: 'show-content',
346
+ label: 'Show content',
347
+ request: {
348
+ target: {
349
+ type: 'url',
350
+ payload: {
351
+ url: 'https://example.com/read',
352
+ },
353
+ },
354
+ title: 'Example URL',
355
+ },
356
+ });
357
+ await manager.handleToolAction({
358
+ kind: 'open-session',
359
+ sessionId: 'child-session-1',
360
+ sessionKind: 'session',
361
+ });
362
+
363
+ expect(uiManager.showContent).toHaveBeenCalledWith({
364
+ target: {
365
+ type: 'url',
366
+ payload: {
367
+ url: 'https://example.com/read',
368
+ },
369
+ },
370
+ title: 'Example URL',
371
+ });
372
+ expect(uiManager.goToSession).toHaveBeenCalledWith('child-session-1');
373
+ });
374
+
375
+ it('shows file content through the existing workspace file preview', async () => {
376
+ const manager = new ChatThreadManager(
377
+ { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof ChatThreadManager>[0],
378
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
379
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
380
+ );
381
+
382
+ await manager.handleToolAction({
383
+ kind: 'show-content',
384
+ label: 'Show content',
385
+ request: {
386
+ target: {
387
+ type: 'file',
388
+ payload: {
389
+ path: 'docs/example.md',
390
+ line: 5,
391
+ },
392
+ },
393
+ title: 'Example',
394
+ purpose: 'read',
395
+ },
396
+ });
397
+
398
+ expect(useChatThreadStore.getState().snapshot).toMatchObject({
399
+ activeWorkspacePanelKind: 'file',
400
+ activeWorkspaceFileKey: 'parent-session-1::preview::docs/example.md',
401
+ workspaceFileTabs: [
402
+ expect.objectContaining({
403
+ path: 'docs/example.md',
404
+ label: 'Example',
405
+ line: 5,
406
+ viewMode: 'preview',
407
+ }),
408
+ ],
409
+ });
410
+ });
411
+
412
+ it('shows URL and panel app content through DocBrowser', async () => {
413
+ const uiManager = createUiManager();
414
+ const manager = new ChatThreadManager(
415
+ uiManager,
416
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
417
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
418
+ );
419
+
420
+ await manager.handleToolAction({
421
+ kind: 'show-content',
422
+ label: 'Show content',
423
+ request: {
424
+ target: {
425
+ type: 'url',
426
+ payload: {
427
+ url: 'https://example.com/read',
428
+ },
429
+ },
430
+ title: 'Example URL',
431
+ },
432
+ });
433
+ await manager.handleToolAction({
434
+ kind: 'show-content',
435
+ label: 'Show content',
436
+ request: {
437
+ target: {
438
+ type: 'panel_app',
439
+ payload: {
440
+ appId: 'reader',
441
+ },
442
+ },
443
+ title: 'Reader',
444
+ },
445
+ });
446
+
447
+ expect(uiManager.showContent).toHaveBeenCalledWith({
448
+ target: {
449
+ type: 'url',
450
+ payload: {
451
+ url: 'https://example.com/read',
452
+ },
453
+ },
454
+ title: 'Example URL',
455
+ });
456
+ expect(uiManager.showContent).toHaveBeenCalledWith({
457
+ target: {
458
+ type: 'panel_app',
459
+ payload: {
460
+ appId: 'reader',
461
+ },
462
+ },
463
+ title: 'Reader',
464
+ });
465
+ });
466
+
467
+ it('handles ui.show-content events once through the same owner path', async () => {
468
+ const uiManager = createUiManager();
469
+ const manager = new ChatThreadManager(
470
+ uiManager,
471
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
472
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
473
+ );
474
+
475
+ await manager.handleUiShowContentEvent({
476
+ id: 'tool:call-show-content-1:show-content',
477
+ toolCallId: 'call-show-content-1',
478
+ target: {
479
+ type: 'url',
480
+ payload: {
481
+ url: 'https://example.com/read',
482
+ },
483
+ },
484
+ title: 'Example URL',
485
+ purpose: 'read',
486
+ });
487
+ await manager.handleUiShowContentEvent({
488
+ id: 'tool:call-show-content-1:show-content',
489
+ toolCallId: 'call-show-content-1',
490
+ target: {
491
+ type: 'url',
492
+ payload: {
493
+ url: 'https://example.com/read',
494
+ },
495
+ },
496
+ title: 'Example URL',
497
+ purpose: 'read',
498
+ });
499
+
500
+ expect(uiManager.showContent).toHaveBeenCalledTimes(1);
501
+ expect(uiManager.showContent).toHaveBeenCalledWith({
502
+ target: {
503
+ type: 'url',
504
+ payload: {
505
+ url: 'https://example.com/read',
506
+ },
507
+ },
508
+ title: 'Example URL',
509
+ });
510
+ });
511
+
512
+ it('delegates panel app content to the UI manager owner', async () => {
513
+ const uiManager = createUiManager();
514
+ const manager = new ChatThreadManager(
515
+ uiManager,
516
+ {} as ConstructorParameters<typeof ChatThreadManager>[1],
517
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
518
+ );
519
+
520
+ await manager.handleToolAction({
521
+ kind: 'show-content',
522
+ label: 'Show content',
523
+ request: {
524
+ target: {
525
+ type: 'panel_app',
526
+ payload: {
527
+ appId: 'encoded-reader',
528
+ },
529
+ },
530
+ title: 'Reader',
531
+ },
532
+ });
533
+
534
+ expect(uiManager.showContent).toHaveBeenCalledWith({
535
+ target: {
536
+ type: 'panel_app',
537
+ payload: {
538
+ appId: 'encoded-reader',
539
+ },
540
+ },
541
+ title: 'Reader',
542
+ });
543
+ });
544
+ });
545
+
546
+ describe('ChatThreadManager visible workspace selection', () => {
547
+ it('delegates visible child-session read state to the session list owner', () => {
548
+ const sessionListManager = {
549
+ markVisibleWorkspaceChildRead: vi.fn(),
550
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[1];
551
+ const manager = new ChatThreadManager(
552
+ { goToSession: vi.fn() } as unknown as ConstructorParameters<typeof ChatThreadManager>[0],
553
+ sessionListManager,
554
+ {} as ConstructorParameters<typeof ChatThreadManager>[2],
555
+ );
556
+ const tab = {
557
+ sessionKey: 'child-session-1',
558
+ lastMessageAt: '2026-04-10T10:00:00.000Z',
559
+ readAt: null,
560
+ runStatus: 'completed',
561
+ };
562
+
563
+ manager.syncVisibleWorkspaceSelection({ kind: 'child-session', tab });
564
+ manager.syncVisibleWorkspaceSelection({ kind: 'file' });
565
+ manager.syncVisibleWorkspaceSelection(null);
566
+
567
+ expect(sessionListManager.markVisibleWorkspaceChildRead).toHaveBeenCalledTimes(1);
568
+ expect(sessionListManager.markVisibleWorkspaceChildRead).toHaveBeenCalledWith(tab);
569
+ });
570
+ });
571
+
572
+ describe('ChatThreadManager deletion', () => {
320
573
  it('clears the selected thread state after deleting the current session', async () => {
321
574
  const removeQueries = vi.spyOn(appQueryClient, 'removeQueries').mockImplementation(async () => undefined);
322
575
  const uiManager = {
@@ -324,24 +577,24 @@ describe('NcpChatThreadManager deletion', () => {
324
577
  goToChatRoot: vi.fn(),
325
578
  goToProviders: vi.fn(),
326
579
  confirm: vi.fn(async () => true),
327
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[0];
580
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[0];
328
581
  const sessionListManager = {
329
582
  setSelectedSessionKey: vi.fn((value: string | null) => {
330
583
  useChatSessionListStore.getState().setSnapshot({
331
584
  selectedSessionKey: value,
332
585
  });
333
586
  }),
334
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[1];
335
- const streamActionsManager = {
336
- resetStreamState: vi.fn(),
337
- } as unknown as ConstructorParameters<typeof NcpChatThreadManager>[2];
338
- const manager = new NcpChatThreadManager(
587
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[1];
588
+ const chatRunManager = {
589
+ clearRunState: vi.fn(),
590
+ } as unknown as ConstructorParameters<typeof ChatThreadManager>[2];
591
+ const manager = new ChatThreadManager(
339
592
  uiManager,
340
593
  sessionListManager,
341
- streamActionsManager,
594
+ chatRunManager,
342
595
  );
343
596
 
344
- await (manager as unknown as { deleteCurrentSession: () => Promise<void> }).deleteCurrentSession();
597
+ await manager.deleteSession();
345
598
 
346
599
  expect(sessionListManager.setSelectedSessionKey).toHaveBeenCalledWith(null);
347
600
  expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBeNull();
@@ -357,7 +610,7 @@ describe('NcpChatThreadManager deletion', () => {
357
610
  workspaceNavigationHistory: [],
358
611
  workspaceNavigationHistoryIndex: 0,
359
612
  });
360
- expect(streamActionsManager.resetStreamState).toHaveBeenCalledTimes(1);
613
+ expect(chatRunManager.clearRunState).toHaveBeenCalledTimes(1);
361
614
  expect(deleteSummaryMock).toHaveBeenCalledWith(appQueryClient, 'parent-session-1');
362
615
  expect(removeQueries).toHaveBeenCalledWith({
363
616
  queryKey: ['ncp-session-messages', 'parent-session-1'],
@@ -0,0 +1,126 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { ChatUiManager } from '@/features/chat/managers/chat-ui.manager';
3
+ import type { PanelAppEntryView } from '@/shared/lib/api';
4
+ import type * as SharedApi from '@/shared/lib/api';
5
+
6
+ const { listPanelAppsMock } = vi.hoisted(() => ({
7
+ listPanelAppsMock: vi.fn(),
8
+ }));
9
+
10
+ vi.mock('@/shared/lib/api', async (importOriginal) => {
11
+ const actual = await importOriginal<typeof SharedApi>();
12
+ return {
13
+ ...actual,
14
+ nextclawClient: {
15
+ panelApps: {
16
+ listPanelApps: listPanelAppsMock,
17
+ },
18
+ },
19
+ };
20
+ });
21
+
22
+ function createDocBrowserManager() {
23
+ return {
24
+ open: vi.fn(),
25
+ openTarget: vi.fn(),
26
+ };
27
+ }
28
+
29
+ function createPanelAppEntry(overrides: Partial<PanelAppEntryView> = {}): PanelAppEntryView {
30
+ return {
31
+ appId: 'reader',
32
+ clientDeclared: false,
33
+ clientGranted: false,
34
+ contentPath: '/api/panel-apps/encoded-reader/content',
35
+ createdAt: '2026-06-09T00:00:00.000Z',
36
+ favorite: false,
37
+ fileName: 'reader.panel',
38
+ id: 'encoded-reader',
39
+ kind: 'folder',
40
+ openCount: 0,
41
+ sizeBytes: 1024,
42
+ title: 'Reader',
43
+ updatedAt: '2026-06-09T00:00:00.000Z',
44
+ ...overrides,
45
+ };
46
+ }
47
+
48
+ describe('ChatUiManager content display', () => {
49
+ beforeEach(() => {
50
+ listPanelAppsMock.mockReset();
51
+ listPanelAppsMock.mockResolvedValue({ entries: [] });
52
+ });
53
+
54
+ it('shows URL content through DocBrowser', async () => {
55
+ const docBrowserManager = createDocBrowserManager();
56
+ const manager = new ChatUiManager(
57
+ docBrowserManager as unknown as ConstructorParameters<typeof ChatUiManager>[0],
58
+ );
59
+
60
+ await manager.showContent({
61
+ target: {
62
+ type: 'url',
63
+ payload: {
64
+ url: 'https://example.com/read',
65
+ },
66
+ },
67
+ title: 'Example URL',
68
+ });
69
+
70
+ expect(docBrowserManager.open).toHaveBeenCalledWith('https://example.com/read', {
71
+ title: 'Example URL',
72
+ });
73
+ });
74
+
75
+ it('opens a listed panel app as a managed DocBrowser target', async () => {
76
+ listPanelAppsMock.mockResolvedValue({
77
+ entries: [createPanelAppEntry()],
78
+ });
79
+ const docBrowserManager = createDocBrowserManager();
80
+ const manager = new ChatUiManager(
81
+ docBrowserManager as unknown as ConstructorParameters<typeof ChatUiManager>[0],
82
+ );
83
+
84
+ await manager.showContent({
85
+ target: {
86
+ type: 'panel_app',
87
+ payload: {
88
+ appId: 'reader',
89
+ },
90
+ },
91
+ title: 'Reader',
92
+ });
93
+
94
+ expect(docBrowserManager.openTarget).toHaveBeenCalledWith({
95
+ dedupeKey: 'panel-app:encoded-reader',
96
+ historyPolicy: 'managed',
97
+ kind: 'panel-app',
98
+ resourceUri: 'nextclaw://panel-app/encoded-reader',
99
+ title: 'Reader',
100
+ url: '/api/panel-apps/encoded-reader/content',
101
+ }, {
102
+ title: 'Reader',
103
+ });
104
+ });
105
+
106
+ it('falls back to the panel app resource URI when no listed entry matches', async () => {
107
+ const docBrowserManager = createDocBrowserManager();
108
+ const manager = new ChatUiManager(
109
+ docBrowserManager as unknown as ConstructorParameters<typeof ChatUiManager>[0],
110
+ );
111
+
112
+ await manager.showContent({
113
+ target: {
114
+ type: 'panel_app',
115
+ payload: {
116
+ appId: 'encoded-reader',
117
+ },
118
+ },
119
+ title: 'Reader',
120
+ });
121
+
122
+ expect(docBrowserManager.open).toHaveBeenCalledWith('nextclaw://panel-app/encoded-reader', {
123
+ title: 'Reader',
124
+ });
125
+ });
126
+ });
@@ -1,4 +1,4 @@
1
- import { RecentSelectionManager } from './recent-selection.manager';
1
+ import { RecentSelectionManager } from '../recent-selection.manager';
2
2
 
3
3
  describe('RecentSelectionManager', () => {
4
4
  const storageKey = 'test.recent-selection-manager';