@nextclaw/ui 0.15.10 → 0.15.12

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 (360) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/assets/{abnfDiagram-VRR7QNED-BYpK0F5F.js → abnfDiagram-VRR7QNED-M4g_AyR8.js} +1 -1
  3. package/dist/assets/{aiden0z-pptx-renderer.es-D87ywFdC.js → aiden0z-pptx-renderer.es-Bd99vut2.js} +1 -1
  4. package/dist/assets/api-Bw1oLhwf.js +13 -0
  5. package/dist/assets/app-presenter-provider-DSN90VJw.js +106 -0
  6. package/dist/assets/appearance-settings-page-BDpels6a.js +1 -0
  7. package/dist/assets/{arc-DFELHWM2.js → arc-IO7WNWOB.js} +1 -1
  8. package/dist/assets/architecture-TIHT7OUA-Cii4JyA2.js +1 -0
  9. package/dist/assets/{architectureDiagram-ZJ3FMSHR-CvRhdovL.js → architectureDiagram-ZJ3FMSHR-Dc-lvdUh.js} +1 -1
  10. package/dist/assets/{blockDiagram-677ZJIJ3-DVYNkbR_.js → blockDiagram-677ZJIJ3-CcsoWpIY.js} +1 -1
  11. package/dist/assets/{book-open-w3160PZf.js → book-open-D-oLp0QJ.js} +1 -1
  12. package/dist/assets/{c4Diagram-LMCZKHZV-B1w-iwRe.js → c4Diagram-LMCZKHZV-Bsrtg6b2.js} +1 -1
  13. package/dist/assets/card-CA3ozZwW.js +1 -0
  14. package/dist/assets/channel-BSKkTPe8.js +1 -0
  15. package/dist/assets/channels-list-page-B44EWctT.js +8 -0
  16. package/dist/assets/chat-page-CH8ypOKO.js +1 -0
  17. package/dist/assets/chunk-2Q5K7J3B-CDMOR1xZ.js +1 -0
  18. package/dist/assets/{chunk-32BRIVSS-kG3lg0bC.js → chunk-32BRIVSS-Bt08t8oG.js} +1 -1
  19. package/dist/assets/{chunk-52WLFC77-BLeB7iGk.js → chunk-52WLFC77-Ddx68Xzx.js} +1 -1
  20. package/dist/assets/{chunk-5FCAYU7R-BQga1Rr7.js → chunk-5FCAYU7R-B7p9_q55.js} +1 -1
  21. package/dist/assets/{chunk-5HE753X5-DU81hkcF.js → chunk-5HE753X5-D52KvdTm.js} +1 -1
  22. package/dist/assets/{chunk-5JV3BV7I-C2bAx0m7.js → chunk-5JV3BV7I-C329h8nI.js} +1 -1
  23. package/dist/assets/{chunk-5TONJI2A-BExIIgWY.js → chunk-5TONJI2A-BZyUBxWt.js} +1 -1
  24. package/dist/assets/{chunk-5VM5RSS4-C3XB05yh.js → chunk-5VM5RSS4-BUiYXZmu.js} +1 -1
  25. package/dist/assets/{chunk-7BUUIJ7U-JiyRtrGu.js → chunk-7BUUIJ7U-B7o-mn4r.js} +1 -1
  26. package/dist/assets/{chunk-BIQX33UG-BZRV20pI.js → chunk-BIQX33UG-Bey9GoRP.js} +1 -1
  27. package/dist/assets/{chunk-C7G6YPKG-AsyDSQ9j.js → chunk-C7G6YPKG-C6tosszM.js} +1 -1
  28. package/dist/assets/{chunk-CQNSW5MT-iN-fiXVA.js → chunk-CQNSW5MT-BNrdkgGQ.js} +1 -1
  29. package/dist/assets/{chunk-CYSBUYHQ-DhC_TRzI.js → chunk-CYSBUYHQ-DHODFeyB.js} +1 -1
  30. package/dist/assets/{chunk-EMLP6XTP-QFLK8R6d.js → chunk-EMLP6XTP-BcmLjrcq.js} +1 -1
  31. package/dist/assets/{chunk-EX3LRPZG-DzUwhkCz.js → chunk-EX3LRPZG-r-_eEtJI.js} +1 -1
  32. package/dist/assets/{chunk-FWX5IMBZ-DFelpZBy.js → chunk-FWX5IMBZ-DOObDWbf.js} +2 -2
  33. package/dist/assets/{chunk-HOUHSVGY-BMPwFEwN.js → chunk-HOUHSVGY-Bd0FnbWZ.js} +1 -1
  34. package/dist/assets/{chunk-ICXQ74PX-DH8NJMok.js → chunk-ICXQ74PX-ntNwAm4_.js} +1 -1
  35. package/dist/assets/{chunk-JG7HCLWE-D-95AsO4.js → chunk-JG7HCLWE-YtRpblZN.js} +1 -1
  36. package/dist/assets/{chunk-JWPE2WC7-DIaTv8kx.js → chunk-JWPE2WC7-De5-D9ta.js} +1 -1
  37. package/dist/assets/{chunk-MOJQB5TN-BPFLzWgj.js → chunk-MOJQB5TN-CdvKhyp2.js} +1 -1
  38. package/dist/assets/{chunk-MOZMSUNE-DR_fzxG0.js → chunk-MOZMSUNE-DJMMN_lu.js} +1 -1
  39. package/dist/assets/{chunk-OGEWGWER-TIcEoPPH.js → chunk-OGEWGWER-DOFWVw3O.js} +1 -1
  40. package/dist/assets/{chunk-OSBZ3O6U-BALNvSfG.js → chunk-OSBZ3O6U-DZkrIN9r.js} +1 -1
  41. package/dist/assets/{chunk-PUDLZKDR-I-EXhf_k.js → chunk-PUDLZKDR-D1wma2Yf.js} +1 -1
  42. package/dist/assets/{chunk-Q4XR5HBZ-uvIGstBS.js → chunk-Q4XR5HBZ-CjPy94Lz.js} +1 -1
  43. package/dist/assets/{chunk-QBLGF6JB-r-TjLdxa.js → chunk-QBLGF6JB-Hy1bEgS-.js} +1 -1
  44. package/dist/assets/{chunk-R7FJI6CG-N-1LDgvy.js → chunk-R7FJI6CG-CUPIHyh-.js} +1 -1
  45. package/dist/assets/{chunk-RYQCIY6F-jxNASx65.js → chunk-RYQCIY6F-D5Ua4pcv.js} +1 -1
  46. package/dist/assets/{chunk-U6XO7XAA-Cphbuc7q.js → chunk-U6XO7XAA-DaUQcqb7.js} +1 -1
  47. package/dist/assets/{chunk-V7JOEXUC-BLEuBf1s.js → chunk-V7JOEXUC-DX2zLfQe.js} +1 -1
  48. package/dist/assets/chunk-VAUOI2AC-BRvqNW76.js +1 -0
  49. package/dist/assets/{chunk-VR4S4FIN-BAUbR0ke.js → chunk-VR4S4FIN-CFA-WQik.js} +1 -1
  50. package/dist/assets/{chunk-WYO6CB5R-Do6SJrnY.js → chunk-WYO6CB5R-Bk2HeDvJ.js} +2 -2
  51. package/dist/assets/chunk-XXDRQBXY-CwX_mqJ3.js +1 -0
  52. package/dist/assets/{chunk-YOTPTUD7-CQqvMTCr.js → chunk-YOTPTUD7-DUG4FpBN.js} +1 -1
  53. package/dist/assets/{chunk-ZGVPDNZ5-B7kWWaXv.js → chunk-ZGVPDNZ5-70JdIGo0.js} +1 -1
  54. package/dist/assets/{chunk-ZIRB5QZD-DTU0cDNh.js → chunk-ZIRB5QZD-XZdgBt5L.js} +1 -1
  55. package/dist/assets/classDiagram-OUVF2IWQ-RzbGxG77.js +1 -0
  56. package/dist/assets/classDiagram-v2-EOCWNBFH-C_gWB7WT.js +1 -0
  57. package/dist/assets/config-split-page-DskB5yAV.js +1 -0
  58. package/dist/assets/confirm-dialog-BRQpFnvD.js +5 -0
  59. package/dist/assets/{cose-bilkent-JH36ORCC-B9LrtV-q.js → cose-bilkent-JH36ORCC-B-PQoGX-.js} +1 -1
  60. package/dist/assets/cynefin-VYW2F7L2-fSLIS0X3.js +1 -0
  61. package/dist/assets/{cynefinDiagram-TSTJHNR4-BfjvW4su.js → cynefinDiagram-TSTJHNR4-BoLCPEM0.js} +1 -1
  62. package/dist/assets/{dagre-DkiXZKkL.js → dagre-D7Ie4eXr.js} +1 -1
  63. package/dist/assets/{dagre-VKFMJZFB-B1pQKQSY.js → dagre-VKFMJZFB-CKRrwZA-.js} +1 -1
  64. package/dist/assets/desktop-update-config-se0OEu06.js +1 -0
  65. package/dist/assets/{diagram-FQU43EPY-cB4EZdaP.js → diagram-FQU43EPY-CASL1J3_.js} +1 -1
  66. package/dist/assets/{diagram-G47NLZAW-CtW8im1B.js → diagram-G47NLZAW-CvLPBIzf.js} +1 -1
  67. package/dist/assets/{diagram-NH7WQ7WH-BDCtrCCm.js → diagram-NH7WQ7WH-Ba6fGdYP.js} +1 -1
  68. package/dist/assets/{diagram-OA4YK3LP-DEMJ42Gt.js → diagram-OA4YK3LP-DkpfgEjM.js} +1 -1
  69. package/dist/assets/{diagram-WEI45ONY-CdCcxSYU.js → diagram-WEI45ONY-BP5UMVsN.js} +1 -1
  70. package/dist/assets/{dist-DEJlYi0E.js → dist-f6aZEsu8.js} +1 -1
  71. package/dist/assets/doc-browser-BRiAfy_N.js +1 -0
  72. package/dist/assets/doc-browser-DW7afLXs.js +1 -0
  73. package/dist/assets/{doc-browser-context-CpvHiuQG.js → doc-browser-context-DhTa-zP_.js} +1 -1
  74. package/dist/assets/{docx-preview-zis3U0Fa.js → docx-preview-D0tp3a9T.js} +1 -1
  75. package/dist/assets/{ebnfDiagram-CCIWWBDH-DBZETBwE.js → ebnfDiagram-CCIWWBDH-TJKbUcmc.js} +1 -1
  76. package/dist/assets/{erDiagram-Q63AITRT-y2zDXprP.js → erDiagram-Q63AITRT-DzGPKkKH.js} +1 -1
  77. package/dist/assets/eventmodeling-45OFAUF4-XVcQGgha.js +1 -0
  78. package/dist/assets/eye-DMGpISEo.js +1 -0
  79. package/dist/assets/flowDiagram-23GEKE2U-BiFSctqz.js +1 -0
  80. package/dist/assets/{form-actions-5OsDRt0g.js → form-actions-SgP78YnZ.js} +1 -1
  81. package/dist/assets/{ganttDiagram-NO4QXBWP-D2DP344e.js → ganttDiagram-NO4QXBWP-JhJzsGp2.js} +1 -1
  82. package/dist/assets/gitGraph-TEB2WS4Q-C014uXqS.js +1 -0
  83. package/dist/assets/{gitGraphDiagram-IHSO6WYX-D37uiwA2.js → gitGraphDiagram-IHSO6WYX-DZ1CKMj8.js} +1 -1
  84. package/dist/assets/index-B2YF-7Yw.css +1 -0
  85. package/dist/assets/index-CBD4zQ_A.js +2 -0
  86. package/dist/assets/info-DKCQHKI2-CQ2qjGhU.js +1 -0
  87. package/dist/assets/{infoDiagram-FWYZ7A6U-CG-WAIRi.js → infoDiagram-FWYZ7A6U-BNXNKfRQ.js} +1 -1
  88. package/dist/assets/{ishikawaDiagram-FXEZZL3T-WeCTnW0f.js → ishikawaDiagram-FXEZZL3T-DoiEfjNw.js} +1 -1
  89. package/dist/assets/{journeyDiagram-5HDEW3XC-DUFBW9Td.js → journeyDiagram-5HDEW3XC-D6oK2HSy.js} +1 -1
  90. package/dist/assets/{kanban-definition-HUTT4EX6-B0lxgMpg.js → kanban-definition-HUTT4EX6-B2UnLOH-.js} +1 -1
  91. package/dist/assets/{line-B78frP_c.js → line-BM7PoxY5.js} +1 -1
  92. package/dist/assets/{linear-C6lVEcb2.js → linear-B3DiqMjk.js} +1 -1
  93. package/dist/assets/loader-circle-DEQ2CflP.js +1 -0
  94. package/dist/assets/{logo-badge-TdPa95AC.js → logo-badge-BZnxuJYW.js} +1 -1
  95. package/dist/assets/{map-Bdri5UL5.js → map-BAAdHTqR.js} +1 -1
  96. package/dist/assets/mcp-marketplace-page-B8eWiT9H.js +1 -0
  97. package/dist/assets/{mcp-marketplace-page-cm3ifaKu.js → mcp-marketplace-page-Dm08nf11.js} +2 -2
  98. package/dist/assets/{mermaid-parser.core-Cue18vLo.js → mermaid-parser.core-BeMviefY.js} +2 -2
  99. package/dist/assets/{mermaid.core-CXwWRh5i.js → mermaid.core-D0Q77r9I.js} +3 -3
  100. package/dist/assets/{mindmap-definition-LN4V7U3C-CFxz0P0-.js → mindmap-definition-LN4V7U3C-BQ7r7bR8.js} +1 -1
  101. package/dist/assets/model-config-page-k_tCjGlK.js +1 -0
  102. package/dist/assets/navigation-link-CJ3fpUBN.js +1 -0
  103. package/dist/assets/{ordinal-Cbd8t4LB.js → ordinal-Bt2N4IkA.js} +1 -1
  104. package/dist/assets/packet-7NZHBO7P-6IFyydij.js +1 -0
  105. package/dist/assets/{pegDiagram-2B236MQR-B_Qt9zyT.js → pegDiagram-2B236MQR-B-C9-LGz.js} +1 -1
  106. package/dist/assets/pie-RZYD4A2V-spXQC_wr.js +1 -0
  107. package/dist/assets/{pieDiagram-ENE6RG2P-CRQdSuwS.js → pieDiagram-ENE6RG2P-CtirZLtn.js} +1 -1
  108. package/dist/assets/plus-9_9Q74qc.js +1 -0
  109. package/dist/assets/{popover-EulxhA0q.js → popover-Cq_oB7HI.js} +1 -1
  110. package/dist/assets/provider-scoped-model-input-Cwv5zw0Z.js +1 -0
  111. package/dist/assets/providers-config-page-D82jX13I.js +1 -0
  112. package/dist/assets/{quadrantDiagram-ABIIQ3AL-D5kPpttq.js → quadrantDiagram-ABIIQ3AL-DiBWAzDU.js} +1 -1
  113. package/dist/assets/radar-I7S5WNFK-DWVA8lvY.js +1 -0
  114. package/dist/assets/railroad-3IZDKUUU-Ce51u8y1.js +1 -0
  115. package/dist/assets/railroad-abnf-AHOZXSZD-D7i7cqI_.js +1 -0
  116. package/dist/assets/railroad-ebnf-EBAXGLYW-BEg2hcPs.js +1 -0
  117. package/dist/assets/railroad-peg-LSFZ7HO6-CxROSzbi.js +1 -0
  118. package/dist/assets/{railroadDiagram-RFXS5EU6-DGh_TGlQ.js → railroadDiagram-RFXS5EU6-CP6b3PBI.js} +1 -1
  119. package/dist/assets/{react-Bb0EYsLS.js → react-BjpVlGAu.js} +1 -1
  120. package/dist/assets/{refresh-cw-CexL11m1.js → refresh-cw-CYyWovQ1.js} +1 -1
  121. package/dist/assets/remote-C2MGMI2j.js +1 -0
  122. package/dist/assets/{requirementDiagram-TGXJPOKE-EmFph0H_.js → requirementDiagram-TGXJPOKE-D8YV0-Jz.js} +1 -1
  123. package/dist/assets/rotate-cw-BkGMTudQ.js +1 -0
  124. package/dist/assets/runtime-config-page-OS6ZT2b0.js +1 -0
  125. package/dist/assets/{sankeyDiagram-HTMAVEWB-BXWB5Ugi.js → sankeyDiagram-HTMAVEWB-C2vA4ojE.js} +1 -1
  126. package/dist/assets/{save-DtccrZld.js → save-B0V_M-kz.js} +1 -1
  127. package/dist/assets/search-config-page-IzK1hMQX.js +1 -0
  128. package/dist/assets/{search-BArc_WOX.js → search-vFYD1SOf.js} +1 -1
  129. package/dist/assets/secrets-config-page-Cm3IXYpK.js +3 -0
  130. package/dist/assets/security-config-DfzQ8txL.js +1 -0
  131. package/dist/assets/{select-C9FB0jlt.js → select-BAYdPRVG.js} +1 -1
  132. package/dist/assets/{sequenceDiagram-DBY2YBRQ-ClKnO7v0.js → sequenceDiagram-DBY2YBRQ-B9LBmpUo.js} +1 -1
  133. package/dist/assets/settings-2-QX-FHs_i.js +1 -0
  134. package/dist/assets/{sizeCapture-X5ZJPWSS-DSo-t5ou.js → sizeCapture-X5ZJPWSS-9UIfya9-.js} +1 -1
  135. package/dist/assets/skeleton-2eczb2co.js +1 -0
  136. package/dist/assets/{src-Dad2ZbCt.js → src-DKf77Yzo.js} +1 -1
  137. package/dist/assets/{stateDiagram-2N3HPSRC-BvAalBfz.js → stateDiagram-2N3HPSRC-oTW44vds.js} +1 -1
  138. package/dist/assets/stateDiagram-v2-6OUMAXLB-Bui4RXQK.js +1 -0
  139. package/dist/assets/{swimlanes-5IMT3BWC-DdVqVa1a.js → swimlanes-5IMT3BWC-Cf7lcsay.js} +2 -2
  140. package/dist/assets/swimlanesDiagram-G3AALYLV-DTwUsCBz.js +8 -0
  141. package/dist/assets/{tabs-D_mjyOOf.js → tabs-Ddprun22.js} +1 -1
  142. package/dist/assets/{tag-chip-C011rd9q.js → tag-chip-C9SLhljq.js} +1 -1
  143. package/dist/assets/{timeline-definition-FHXFAJF6-D4ar8IQY.js → timeline-definition-FHXFAJF6-DoCuWKDJ.js} +1 -1
  144. package/dist/assets/{trash-2-bDhfsO1O.js → trash-2-CODUwc31.js} +1 -1
  145. package/dist/assets/treeView-QDETBFTQ-D5zsTiuL.js +1 -0
  146. package/dist/assets/treemap-6X3UGDF4-CR3dxqNs.js +1 -0
  147. package/dist/assets/{use-config-BNrlfEck.js → use-config-C5OKT3lk.js} +1 -1
  148. package/dist/assets/use-confirm-dialog-B_ZW-WgC.js +1 -0
  149. package/dist/assets/{use-viewport-layout-P0q6Nt_N.js → use-viewport-layout-OtzTlg5U.js} +1 -1
  150. package/dist/assets/{vennDiagram-L72KCM5P-CDXJ_i3p.js → vennDiagram-L72KCM5P-CpU0pzGe.js} +1 -1
  151. package/dist/assets/wardley-OPB4EBWU-LatRT_Lx.js +1 -0
  152. package/dist/assets/{wardleyDiagram-EHGQE667-D-dSuT_7.js → wardleyDiagram-EHGQE667-CkN6nn6-.js} +1 -1
  153. package/dist/assets/x-Cbfpb-Zm.js +1 -0
  154. package/dist/assets/{xychartDiagram-FW5EYKEG-C9JCzsZF.js → xychartDiagram-FW5EYKEG-DATpapm2.js} +1 -1
  155. package/dist/index.html +31 -32
  156. package/dist/runtime-icons/opencode.svg +16 -0
  157. package/package.json +10 -9
  158. package/public/runtime-icons/opencode.svg +16 -0
  159. package/src/app/components/layout/__tests__/settings-entry-page.test.tsx +6 -4
  160. package/src/app/components/layout/__tests__/sidebar.layout.test.tsx +24 -12
  161. package/src/app/components/layout/sidebar-items.tsx +11 -2
  162. package/src/app/components/layout/sidebar.tsx +33 -234
  163. package/src/app/configs/app-navigation.config.ts +10 -24
  164. package/src/app/index.tsx +0 -5
  165. package/src/features/channels/components/config/channel-form.tsx +26 -26
  166. package/src/features/channels/components/config/weixin-channel-auth-section.tsx +6 -7
  167. package/src/features/channels/pages/__tests__/channels-list-page.test.tsx +2 -2
  168. package/src/features/channels/pages/channels-list-page.tsx +33 -32
  169. package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +68 -7
  170. package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +27 -0
  171. package/src/features/chat/components/conversation/__tests__/chat-conversation-panel.test.tsx +0 -8
  172. package/src/features/chat/components/conversation/chat-conversation-content.tsx +65 -21
  173. package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +36 -12
  174. package/src/features/chat/components/conversation/chat-conversation-panel.tsx +0 -7
  175. package/src/features/chat/components/layout/__tests__/chat-sidebar-toolbar.test.tsx +0 -1
  176. package/src/features/chat/components/layout/__tests__/chat-sidebar.test.tsx +17 -8
  177. package/src/features/chat/components/layout/chat-page-shell.tsx +2 -2
  178. package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -23
  179. package/src/features/chat/components/layout/chat-sidebar.tsx +3 -12
  180. package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +155 -93
  181. package/src/features/chat/features/conversation/components/session-conversation-area.tsx +126 -93
  182. package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +8 -0
  183. package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +27 -13
  184. package/src/features/chat/features/message/components/__tests__/chat-inline-file-preview.test.tsx +15 -9
  185. package/src/features/chat/features/message/components/__tests__/chat-inline-panel-app-card.test.tsx +127 -49
  186. package/src/features/chat/features/message/components/__tests__/chat-message-list.container.test.tsx +186 -20
  187. package/src/features/chat/features/message/components/chat-inline-content-surface.tsx +55 -0
  188. package/src/features/chat/features/message/components/chat-inline-file-preview.tsx +49 -71
  189. package/src/features/chat/features/message/components/chat-inline-panel-app-card.tsx +65 -55
  190. package/src/features/chat/features/message/components/chat-message-list.container.tsx +275 -267
  191. package/src/features/chat/features/message/hooks/__tests__/use-chat-message-virtualizer.test.tsx +163 -0
  192. package/src/features/chat/features/message/hooks/use-chat-message-virtualizer.ts +68 -0
  193. package/src/features/chat/features/message/utils/__tests__/chat-message-execution-summary.utils.test.ts +200 -0
  194. package/src/features/chat/features/message/utils/__tests__/chat-message-texts.utils.test.ts +14 -1
  195. package/src/features/chat/features/message/utils/__tests__/chat-message.utils.test.ts +33 -0
  196. package/src/features/chat/features/message/utils/chat-inline-panel-app-card.utils.ts +24 -9
  197. package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +173 -0
  198. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +43 -0
  199. package/src/features/chat/features/message/utils/chat-message-timeline.utils.ts +194 -0
  200. package/src/features/chat/features/message/utils/chat-message.utils.ts +5 -0
  201. package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-session-conversation.test.tsx +151 -13
  202. package/src/features/chat/features/ncp/hooks/use-ncp-session-conversation.ts +44 -70
  203. package/src/features/chat/features/ncp/hooks/use-ncp-session-message-history.ts +197 -0
  204. package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +21 -3
  205. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +7 -7
  206. package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +2 -2
  207. package/src/features/chat/features/session/components/session-context-icon.tsx +1 -1
  208. package/src/features/chat/features/session-type/components/__tests__/chat-session-type-option-item.test.tsx +5 -1
  209. package/src/features/chat/features/session-type/components/chat-session-type-option-item.tsx +1 -1
  210. package/src/features/chat/features/workspace/components/__tests__/workspace-file-content-preview.test.tsx +32 -10
  211. package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +5 -15
  212. package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +62 -9
  213. package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +6 -1
  214. package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +1 -25
  215. package/src/features/chat/managers/__tests__/chat-session-list.manager.test.ts +190 -109
  216. package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +9 -10
  217. package/src/features/chat/managers/chat-session-list.manager.ts +68 -27
  218. package/src/features/cron/components/__tests__/cron-config.test.tsx +260 -0
  219. package/src/features/cron/components/cron-config.tsx +392 -388
  220. package/src/features/cron/components/cron-job-detail-dialog.tsx +210 -0
  221. package/src/features/cron/components/cron-job-row.tsx +271 -0
  222. package/src/features/cron/components/cron-task-discovery.tsx +152 -0
  223. package/src/features/cron/hooks/use-cron-jobs.ts +3 -1
  224. package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +3 -2
  225. package/src/features/marketplace/components/marketplace-external-skill-source-action.tsx +8 -6
  226. package/src/features/marketplace/components/mcp/mcp-marketplace-page.tsx +26 -40
  227. package/src/features/pwa/components/pwa-install-entry.tsx +45 -58
  228. package/src/features/remote/components/remote-access-page.tsx +128 -208
  229. package/src/features/settings/components/config/provider-auth-section.tsx +32 -17
  230. package/src/features/settings/components/config/provider-form.tsx +6 -6
  231. package/src/features/settings/components/config/provider-models-section.tsx +52 -46
  232. package/src/features/settings/components/config/secrets-config-form.tsx +78 -84
  233. package/src/features/settings/index.ts +0 -1
  234. package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +35 -1
  235. package/src/features/settings/pages/__tests__/model-config-page.test.tsx +18 -1
  236. package/src/features/settings/pages/__tests__/search-config-page.test.tsx +8 -0
  237. package/src/features/settings/pages/__tests__/secrets-config-page.test.tsx +18 -17
  238. package/src/features/settings/pages/appearance-settings-page.tsx +87 -64
  239. package/src/features/settings/pages/model-config-page.tsx +75 -70
  240. package/src/features/settings/pages/providers-config-page.tsx +107 -73
  241. package/src/features/settings/pages/search-config-page.tsx +159 -152
  242. package/src/features/settings/pages/secrets-config-page.tsx +6 -1
  243. package/src/features/system-status/components/config/runtime-agent-list-card.tsx +23 -22
  244. package/src/features/system-status/components/config/runtime-binding-list-card.tsx +23 -22
  245. package/src/features/system-status/components/config/runtime-config-editor.tsx +17 -7
  246. package/src/features/system-status/components/config/runtime-config-overview.tsx +0 -3
  247. package/src/features/system-status/components/config/runtime-entry-list-card.tsx +24 -23
  248. package/src/features/system-status/components/config/runtime-settings-card.tsx +59 -52
  249. package/src/features/system-status/components/desktop-update-config.tsx +117 -112
  250. package/src/features/system-status/components/runtime-control-card.tsx +62 -59
  251. package/src/features/system-status/components/runtime-presence-card.tsx +79 -98
  252. package/src/features/system-status/components/runtime-security-card.tsx +74 -62
  253. package/src/features/system-status/components/security-config.tsx +3 -4
  254. package/src/features/system-status/pages/runtime-config-page.tsx +6 -1
  255. package/src/platforms/desktop/components/desktop-app-shell.tsx +1 -1
  256. package/src/platforms/mobile/components/mobile-settings-shell.tsx +2 -2
  257. package/src/shared/components/__tests__/config-split-page.test.tsx +15 -3
  258. package/src/shared/components/__tests__/settings-page.test.tsx +31 -0
  259. package/src/shared/components/actions/__tests__/navigation-link.test.tsx +47 -0
  260. package/src/shared/components/actions/navigation-link.tsx +116 -0
  261. package/src/shared/components/common/__tests__/brand-header.test.tsx +5 -5
  262. package/src/shared/components/common/__tests__/searchable-model-input.test.tsx +24 -0
  263. package/src/shared/components/common/brand-header.tsx +12 -10
  264. package/src/shared/components/common/searchable-model-input.tsx +9 -10
  265. package/src/shared/components/config-split-page.tsx +70 -65
  266. package/src/shared/components/doc-browser/doc-browser-panel-parts.tsx +6 -7
  267. package/src/shared/components/settings/setting-row.tsx +61 -30
  268. package/src/shared/components/settings/settings-page.tsx +34 -0
  269. package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +23 -2
  270. package/src/shared/components/ui/actions/icon-action-button.tsx +9 -2
  271. package/src/shared/components/ui/overlays/sheet.tsx +142 -0
  272. package/src/shared/lib/api/ncp-session.types.ts +8 -2
  273. package/src/shared/lib/api/types.ts +22 -1
  274. package/src/shared/lib/api/utils/config.utils.ts +2 -1
  275. package/src/shared/lib/api/utils/ncp-session.utils.ts +25 -11
  276. package/src/shared/lib/i18n/locales/en-US/chat.json +31 -1
  277. package/src/shared/lib/i18n/locales/en-US/core.json +3 -3
  278. package/src/shared/lib/i18n/locales/en-US/cron.json +87 -17
  279. package/src/shared/lib/i18n/locales/zh-CN/chat.json +33 -3
  280. package/src/shared/lib/i18n/locales/zh-CN/core.json +6 -6
  281. package/src/shared/lib/i18n/locales/zh-CN/cron.json +80 -10
  282. package/src/shared/lib/transport/__tests__/remote.transport.test.ts +16 -4
  283. package/dist/assets/api-D0U10BcF.js +0 -13
  284. package/dist/assets/app-presenter-provider-Dffdm_Ek.js +0 -106
  285. package/dist/assets/appearance-settings-page-sfusZc2d.js +0 -1
  286. package/dist/assets/architecture-TIHT7OUA-ClwVFq-K.js +0 -1
  287. package/dist/assets/channel-BEHOSFc5.js +0 -1
  288. package/dist/assets/channels-list-page-Dkfe87Zq.js +0 -8
  289. package/dist/assets/chat-page-CeapbQnG.js +0 -1
  290. package/dist/assets/chunk-2Q5K7J3B-DrIhesSX.js +0 -1
  291. package/dist/assets/chunk-VAUOI2AC-Dpcz6BhT.js +0 -1
  292. package/dist/assets/chunk-XXDRQBXY-C2QjjwYX.js +0 -1
  293. package/dist/assets/classDiagram-OUVF2IWQ-DESMaY3_.js +0 -1
  294. package/dist/assets/classDiagram-v2-EOCWNBFH-DwOlByYH.js +0 -1
  295. package/dist/assets/config-split-page-CnQI8cKT.js +0 -1
  296. package/dist/assets/confirm-dialog-RZUWA_j9.js +0 -5
  297. package/dist/assets/cynefin-VYW2F7L2-CzjeeOq9.js +0 -1
  298. package/dist/assets/desktop-update-config-CbSYQMYz.js +0 -1
  299. package/dist/assets/doc-browser-DwXHr-mm.js +0 -1
  300. package/dist/assets/doc-browser-jVTq8iY_2.js +0 -1
  301. package/dist/assets/download-BP7ZxrwI.js +0 -1
  302. package/dist/assets/eventmodeling-45OFAUF4-C38BqG8w.js +0 -1
  303. package/dist/assets/external-link-DvHCEe3h.js +0 -1
  304. package/dist/assets/eye-C--6dxv_.js +0 -1
  305. package/dist/assets/flowDiagram-23GEKE2U-BoKk8RRq.js +0 -1
  306. package/dist/assets/folder-BfeO1zCY.js +0 -1
  307. package/dist/assets/gitGraph-TEB2WS4Q-IsQHHJuS.js +0 -1
  308. package/dist/assets/index-BlKbckX4.css +0 -1
  309. package/dist/assets/index-DoZR11Nh.js +0 -2
  310. package/dist/assets/info-DKCQHKI2-ofy2qlHI.js +0 -1
  311. package/dist/assets/loader-circle-BWdgwVnn.js +0 -1
  312. package/dist/assets/mcp-marketplace-page-XnRWiC8c.js +0 -1
  313. package/dist/assets/model-config-page-CXnqSbSI.js +0 -1
  314. package/dist/assets/packet-7NZHBO7P-Rfopfa1o.js +0 -1
  315. package/dist/assets/pie-RZYD4A2V-CJR1xKEv.js +0 -1
  316. package/dist/assets/plus-BeApS21t.js +0 -1
  317. package/dist/assets/provider-scoped-model-input-ll_Btc9h.js +0 -1
  318. package/dist/assets/providers-config-page-Bcuhqkdl.js +0 -1
  319. package/dist/assets/radar-I7S5WNFK-CDg8Z-1r.js +0 -1
  320. package/dist/assets/railroad-3IZDKUUU-BHnNmjxO.js +0 -1
  321. package/dist/assets/railroad-abnf-AHOZXSZD-DGtNcusW.js +0 -1
  322. package/dist/assets/railroad-ebnf-EBAXGLYW-BRFtsQmm.js +0 -1
  323. package/dist/assets/railroad-peg-LSFZ7HO6-Bj5IypCA.js +0 -1
  324. package/dist/assets/remote-CqKpuOP9.js +0 -1
  325. package/dist/assets/rotate-cw-DHXoiqFB.js +0 -1
  326. package/dist/assets/runtime-config-page-D-Aqxizs.js +0 -1
  327. package/dist/assets/search-config-page-XTKf5rc0.js +0 -1
  328. package/dist/assets/secrets-config-page-Cx-qptcj.js +0 -3
  329. package/dist/assets/security-config-DWGFM2u9.js +0 -1
  330. package/dist/assets/setting-row-DFvioO2a.js +0 -1
  331. package/dist/assets/settings-2-RMWqf-ey.js +0 -1
  332. package/dist/assets/skeleton-DQ5WhuDG.js +0 -1
  333. package/dist/assets/stateDiagram-v2-6OUMAXLB-CfMU38yc.js +0 -1
  334. package/dist/assets/swimlanesDiagram-G3AALYLV-D9Zb9X57.js +0 -8
  335. package/dist/assets/treeView-QDETBFTQ-Uy7M0WvH.js +0 -1
  336. package/dist/assets/treemap-6X3UGDF4-BJfGV7KX.js +0 -1
  337. package/dist/assets/use-confirm-dialog-CTNA1PC0.js +0 -1
  338. package/dist/assets/wardley-OPB4EBWU-q263iF3K.js +0 -1
  339. package/dist/assets/x-qvh05iyu.js +0 -1
  340. package/src/features/chat/components/conversation/chat-conversation-skeleton.tsx +0 -86
  341. package/src/features/settings/pages/__tests__/language-settings-page.test.tsx +0 -36
  342. package/src/features/settings/pages/language-settings-page.tsx +0 -56
  343. package/src/shared/components/actions/action-link.tsx +0 -49
  344. /package/dist/assets/{array-BqYdCIE6.js → array-CAkJT3no.js} +0 -0
  345. /package/dist/assets/{chunk-KEIR6QF5-A3jEqwzn.js → chunk-KEIR6QF5-BgdDoWEH.js} +0 -0
  346. /package/dist/assets/{chunk-Y2CYZVJY-BGrd8tLy.js → chunk-Y2CYZVJY-pTllD0P3.js} +0 -0
  347. /package/dist/assets/{config-hints-LxG80Uj5.js → config-hints-S3g-UVZb.js} +0 -0
  348. /package/dist/assets/{cytoscape.esm-CRW8q92n.js → cytoscape.esm-DmURt-5G.js} +0 -0
  349. /package/dist/assets/{defaultLocale-Cdv9x6q7.js → defaultLocale-BKy_KP3O.js} +0 -0
  350. /package/dist/assets/{dist-dw-gAfM_.js → dist-IgNNB7K9.js} +0 -0
  351. /package/dist/assets/{graphlib-BcNFQr5y.js → graphlib-xw_TBHyH.js} +0 -0
  352. /package/dist/assets/{host-capabilities-CFbAfrrA.js → host-capabilities-B-TtABsP.js} +0 -0
  353. /package/dist/assets/{init-D8TjIqfm.js → init-C9xlLIAu.js} +0 -0
  354. /package/dist/assets/{jszip.min-CP5uPNQa.js → jszip.min-Das2IAnb.js} +0 -0
  355. /package/dist/assets/{katex-wEmrEFTg.js → katex-DSy1eD2d.js} +0 -0
  356. /package/dist/assets/{middleware-CAXxl-af.js → middleware-Df-a4x-q.js} +0 -0
  357. /package/dist/assets/{path-DzBnMI1r.js → path-DB0USYHi.js} +0 -0
  358. /package/dist/assets/{provider-models-BoUhFo9R.js → provider-models-CXUgDxGR.js} +0 -0
  359. /package/dist/assets/{rough.esm-wJ1d3nQl.js → rough.esm-B1B52ZQS.js} +0 -0
  360. /package/dist/assets/{xlsx-DUqJhg5u.js → xlsx-DfjC_iml.js} +0 -0
@@ -1,10 +1,10 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- import type * as SharedApi from '@/shared/lib/api';
3
- import { ChatSessionListManager } from '@/features/chat/managers/chat-session-list.manager';
4
- import { useChatSessionListStore } from '@/features/chat/stores/chat-session-list.store';
5
- import { useChatThreadStore } from '@/features/chat/stores/chat-thread.store';
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import type * as SharedApi from "@/shared/lib/api";
3
+ import { ChatSessionListManager } from "@/features/chat/managers/chat-session-list.manager";
4
+ import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
5
+ import { useChatThreadStore } from "@/features/chat/stores/chat-thread.store";
6
6
 
7
- const chatSessionListModeStorageKey = 'nextclaw.chat.session-list.mode';
7
+ const chatSessionListModeStorageKey = "nextclaw.chat.session-list.mode";
8
8
  const persistStorage = new Map<string, unknown>();
9
9
 
10
10
  function createLocalStoragePersistStorage() {
@@ -23,7 +23,7 @@ const mocks = vi.hoisted(() => ({
23
23
  updateNcpSession: vi.fn(),
24
24
  }));
25
25
 
26
- vi.mock('@/shared/lib/api', async (importOriginal) => {
26
+ vi.mock("@/shared/lib/api", async (importOriginal) => {
27
27
  const actual = await importOriginal<typeof SharedApi>();
28
28
  return {
29
29
  ...actual,
@@ -33,40 +33,44 @@ vi.mock('@/shared/lib/api', async (importOriginal) => {
33
33
 
34
34
  function resetChatSessionListManagerState() {
35
35
  persistStorage.clear();
36
- useChatSessionListStore.persist.setOptions({ storage: createLocalStoragePersistStorage() as never });
37
- useChatThreadStore.persist.setOptions({ storage: createLocalStoragePersistStorage() as never });
36
+ useChatSessionListStore.persist.setOptions({
37
+ storage: createLocalStoragePersistStorage() as never,
38
+ });
39
+ useChatThreadStore.persist.setOptions({
40
+ storage: createLocalStoragePersistStorage() as never,
41
+ });
38
42
  mocks.updateNcpSession.mockReset();
39
43
  mocks.updateNcpSession.mockResolvedValue({});
40
44
  useChatSessionListStore.setState({
41
45
  optimisticReadAtBySessionKey: {},
42
46
  snapshot: {
43
47
  ...useChatSessionListStore.getState().snapshot,
44
- selectedSessionKey: 'session-1',
45
- listMode: 'time-first',
48
+ selectedSessionKey: "session-1",
49
+ listMode: "time-first",
46
50
  pinnedSessionKeys: [],
47
51
  pinnedProjectRoots: [],
48
52
  collapsedProjectRoots: [],
49
- }
53
+ },
50
54
  });
51
55
  useChatThreadStore.setState({
52
56
  snapshot: {
53
57
  ...useChatThreadStore.getState().snapshot,
54
- workspacePanelParentKey: 'session-1',
55
- activeWorkspacePanelKind: 'child-session',
56
- activeChildSessionKey: 'child-session-1',
58
+ workspacePanelParentKey: "session-1",
59
+ activeWorkspacePanelKind: "child-session",
60
+ activeChildSessionKey: "child-session-1",
57
61
  activeWorkspaceFileKey: null,
58
62
  workspaceNavigationHistory: [
59
- { kind: 'child-session', key: 'child-session-1' },
63
+ { kind: "child-session", key: "child-session-1" },
60
64
  ],
61
65
  workspaceNavigationHistoryIndex: 0,
62
66
  },
63
67
  });
64
68
  }
65
69
 
66
- describe('ChatSessionListManager draft and selection flow', () => {
70
+ describe("ChatSessionListManager draft and selection flow", () => {
67
71
  beforeEach(resetChatSessionListManagerState);
68
72
 
69
- it('applies the requested session type when creating a session', () => {
73
+ it("applies the requested session type when creating a session", () => {
70
74
  const uiManager = {
71
75
  goToChatRoot: vi.fn(),
72
76
  navigateTo: vi.fn(),
@@ -75,23 +79,28 @@ describe('ChatSessionListManager draft and selection flow', () => {
75
79
  } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
76
80
 
77
81
  const manager = new ChatSessionListManager(uiManager);
78
- manager.createSession('codex');
82
+ manager.createSession({ sessionType: "codex" });
79
83
 
80
- expect(uiManager.navigateTo).toHaveBeenCalledWith('/chat/draft', {
84
+ expect(uiManager.navigateTo).toHaveBeenCalledWith("/chat/draft", {
81
85
  replace: true,
82
86
  state: {
83
87
  chatDraft: {
84
- sessionType: 'codex',
88
+ sessionType: "codex",
85
89
  projectRoot: null,
90
+ prompt: null,
86
91
  },
87
92
  },
88
93
  });
89
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBeNull();
94
+ expect(
95
+ useChatSessionListStore.getState().snapshot.selectedSessionKey,
96
+ ).toBeNull();
90
97
  expect(useChatThreadStore.getState().snapshot.sessionKey).toBeNull();
91
- expect(useChatThreadStore.getState().snapshot.hasSubmittedDraftMessage).toBe(false);
98
+ expect(
99
+ useChatThreadStore.getState().snapshot.hasSubmittedDraftMessage,
100
+ ).toBe(false);
92
101
  });
93
102
 
94
- it('starts an agent draft chat through one owner state transition', () => {
103
+ it("starts an agent draft chat through one owner state transition", () => {
95
104
  const uiManager = {
96
105
  goToChatRoot: vi.fn(),
97
106
  navigateTo: vi.fn(),
@@ -100,24 +109,31 @@ describe('ChatSessionListManager draft and selection flow', () => {
100
109
  } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
101
110
 
102
111
  const manager = new ChatSessionListManager(uiManager);
103
- manager.startAgentDraftChat('researcher', 'codex');
112
+ manager.startAgentDraftChat("researcher", "codex");
104
113
 
105
- expect(uiManager.navigateTo).toHaveBeenCalledWith('/chat/draft', {
114
+ expect(uiManager.navigateTo).toHaveBeenCalledWith("/chat/draft", {
106
115
  replace: true,
107
116
  state: {
108
117
  chatDraft: {
109
- sessionType: 'codex',
118
+ sessionType: "codex",
110
119
  projectRoot: null,
120
+ prompt: null,
111
121
  },
112
122
  },
113
123
  });
114
- expect(useChatSessionListStore.getState().snapshot.selectedAgentId).toBe('researcher');
115
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBeNull();
124
+ expect(useChatSessionListStore.getState().snapshot.selectedAgentId).toBe(
125
+ "researcher",
126
+ );
127
+ expect(
128
+ useChatSessionListStore.getState().snapshot.selectedSessionKey,
129
+ ).toBeNull();
116
130
  expect(useChatThreadStore.getState().snapshot.sessionKey).toBeNull();
117
- expect(useChatThreadStore.getState().snapshot.hasSubmittedDraftMessage).toBe(false);
131
+ expect(
132
+ useChatThreadStore.getState().snapshot.hasSubmittedDraftMessage,
133
+ ).toBe(false);
118
134
  });
119
135
 
120
- it('hydrates the draft project root when creating a session inside a project group', () => {
136
+ it("hydrates the draft project root when creating a session inside a project group", () => {
121
137
  const uiManager = {
122
138
  goToChatRoot: vi.fn(),
123
139
  navigateTo: vi.fn(),
@@ -126,20 +142,47 @@ describe('ChatSessionListManager draft and selection flow', () => {
126
142
  } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
127
143
 
128
144
  const manager = new ChatSessionListManager(uiManager);
129
- manager.createSession('native', '/tmp/project-alpha');
145
+ manager.createSession({
146
+ projectRoot: "/tmp/project-alpha",
147
+ sessionType: "native",
148
+ });
130
149
 
131
- expect(uiManager.navigateTo).toHaveBeenCalledWith('/chat/draft', {
150
+ expect(uiManager.navigateTo).toHaveBeenCalledWith("/chat/draft", {
132
151
  replace: true,
133
152
  state: {
134
153
  chatDraft: {
135
- sessionType: 'native',
136
- projectRoot: '/tmp/project-alpha',
154
+ sessionType: "native",
155
+ projectRoot: "/tmp/project-alpha",
156
+ prompt: null,
157
+ },
158
+ },
159
+ });
160
+ });
161
+
162
+ it("carries an initial prompt through the draft route state", () => {
163
+ const uiManager = {
164
+ goToChatRoot: vi.fn(),
165
+ navigateTo: vi.fn(),
166
+ goToSession: vi.fn(),
167
+ isAtChatRoot: vi.fn(() => false),
168
+ } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
169
+
170
+ const manager = new ChatSessionListManager(uiManager);
171
+ manager.createSession({ prompt: " 每天整理项目风险 " });
172
+
173
+ expect(uiManager.navigateTo).toHaveBeenCalledWith("/chat/draft", {
174
+ replace: false,
175
+ state: {
176
+ chatDraft: {
177
+ sessionType: "native",
178
+ projectRoot: null,
179
+ prompt: "每天整理项目风险",
137
180
  },
138
181
  },
139
182
  });
140
183
  });
141
184
 
142
- it('does not eagerly replace the old selected session before the route finishes switching', () => {
185
+ it("does not eagerly replace the old selected session before the route finishes switching", () => {
143
186
  const uiManager = {
144
187
  goToChatRoot: vi.fn(),
145
188
  navigateTo: vi.fn(),
@@ -148,13 +191,21 @@ describe('ChatSessionListManager draft and selection flow', () => {
148
191
  } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
149
192
 
150
193
  const manager = new ChatSessionListManager(uiManager);
151
- manager.createSession('native', '/tmp/project-alpha');
194
+ manager.createSession({
195
+ projectRoot: "/tmp/project-alpha",
196
+ sessionType: "native",
197
+ });
152
198
 
153
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBeNull();
154
- expect(uiManager.navigateTo).toHaveBeenCalledWith('/chat/draft', expect.any(Object));
199
+ expect(
200
+ useChatSessionListStore.getState().snapshot.selectedSessionKey,
201
+ ).toBeNull();
202
+ expect(uiManager.navigateTo).toHaveBeenCalledWith(
203
+ "/chat/draft",
204
+ expect.any(Object),
205
+ );
155
206
  });
156
207
 
157
- it('delegates existing-session selection to routing while preserving workspace panel state', () => {
208
+ it("delegates existing-session selection to routing while preserving workspace panel state", () => {
158
209
  const uiManager = {
159
210
  goToChatRoot: vi.fn(),
160
211
  navigateTo: vi.fn(),
@@ -163,157 +214,187 @@ describe('ChatSessionListManager draft and selection flow', () => {
163
214
  } as unknown as ConstructorParameters<typeof ChatSessionListManager>[0];
164
215
 
165
216
  const manager = new ChatSessionListManager(uiManager);
166
- manager.selectSession('session-2');
167
-
168
- expect(uiManager.goToSession).toHaveBeenCalledWith('session-2');
169
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBe('session-1');
170
- expect(useChatThreadStore.getState().snapshot.workspacePanelParentKey).toBe('session-1');
171
- expect(useChatThreadStore.getState().snapshot.activeWorkspacePanelKind).toBe('child-session');
172
- expect(useChatThreadStore.getState().snapshot.activeChildSessionKey).toBe('child-session-1');
173
- expect(useChatThreadStore.getState().snapshot.activeWorkspaceFileKey).toBeNull();
217
+ manager.selectSession("session-2");
218
+
219
+ expect(uiManager.goToSession).toHaveBeenCalledWith("session-2");
220
+ expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBe(
221
+ "session-1",
222
+ );
223
+ expect(useChatThreadStore.getState().snapshot.workspacePanelParentKey).toBe(
224
+ "session-1",
225
+ );
226
+ expect(
227
+ useChatThreadStore.getState().snapshot.activeWorkspacePanelKind,
228
+ ).toBe("child-session");
229
+ expect(useChatThreadStore.getState().snapshot.activeChildSessionKey).toBe(
230
+ "child-session-1",
231
+ );
232
+ expect(
233
+ useChatThreadStore.getState().snapshot.activeWorkspaceFileKey,
234
+ ).toBeNull();
174
235
  });
175
236
  });
176
237
 
177
- describe('ChatSessionListManager list preference and read state', () => {
238
+ describe("ChatSessionListManager list preference and read state", () => {
178
239
  beforeEach(resetChatSessionListManagerState);
179
240
 
180
- it('updates the sidebar list mode without touching other session list state', () => {
181
- const uiManager = {} as ConstructorParameters<typeof ChatSessionListManager>[0];
241
+ it("updates the sidebar list mode without touching other session list state", () => {
242
+ const uiManager = {} as ConstructorParameters<
243
+ typeof ChatSessionListManager
244
+ >[0];
182
245
 
183
246
  const manager = new ChatSessionListManager(uiManager);
184
- manager.setListMode('project-first');
247
+ manager.setListMode("project-first");
185
248
 
186
- expect(useChatSessionListStore.getState().snapshot.listMode).toBe('project-first');
187
- expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBe('session-1');
249
+ expect(useChatSessionListStore.getState().snapshot.listMode).toBe(
250
+ "project-first",
251
+ );
252
+ expect(useChatSessionListStore.getState().snapshot.selectedSessionKey).toBe(
253
+ "session-1",
254
+ );
188
255
  expect(persistStorage.get(chatSessionListModeStorageKey)).toMatchObject({
189
256
  state: {
190
257
  snapshot: {
191
- listMode: 'project-first'
192
- }
193
- }
258
+ listMode: "project-first",
259
+ },
260
+ },
194
261
  });
195
262
  });
196
263
 
197
- it('persists session and project list preferences through the list owner', () => {
264
+ it("persists session and project list preferences through the list owner", () => {
198
265
  const manager = new ChatSessionListManager(
199
- {} as ConstructorParameters<typeof ChatSessionListManager>[0]
266
+ {} as ConstructorParameters<typeof ChatSessionListManager>[0],
200
267
  );
201
268
 
202
- manager.toggleSessionPinned('session-2');
203
- manager.toggleProjectPinned('/tmp/project-alpha');
204
- manager.toggleProjectCollapsed('/tmp/project-alpha');
269
+ manager.toggleSessionPinned("session-2");
270
+ manager.toggleProjectPinned("/tmp/project-alpha");
271
+ manager.toggleProjectCollapsed("/tmp/project-alpha");
205
272
 
206
273
  expect(useChatSessionListStore.getState().snapshot).toMatchObject({
207
- pinnedSessionKeys: ['session-2'],
208
- pinnedProjectRoots: ['/tmp/project-alpha'],
209
- collapsedProjectRoots: ['/tmp/project-alpha'],
274
+ pinnedSessionKeys: ["session-2"],
275
+ pinnedProjectRoots: ["/tmp/project-alpha"],
276
+ collapsedProjectRoots: ["/tmp/project-alpha"],
210
277
  });
211
278
  expect(persistStorage.get(chatSessionListModeStorageKey)).toMatchObject({
212
279
  state: {
213
280
  snapshot: {
214
- pinnedSessionKeys: ['session-2'],
215
- pinnedProjectRoots: ['/tmp/project-alpha'],
216
- collapsedProjectRoots: ['/tmp/project-alpha'],
281
+ pinnedSessionKeys: ["session-2"],
282
+ pinnedProjectRoots: ["/tmp/project-alpha"],
283
+ collapsedProjectRoots: ["/tmp/project-alpha"],
217
284
  },
218
285
  },
219
286
  });
220
287
  });
221
288
 
222
- it('marks a session as read through the session list owner boundary', () => {
289
+ it("marks a session as read through the session list owner boundary", () => {
223
290
  const manager = new ChatSessionListManager(
224
- {} as ConstructorParameters<typeof ChatSessionListManager>[0]
291
+ {} as ConstructorParameters<typeof ChatSessionListManager>[0],
225
292
  );
226
293
 
227
- manager.markSessionRead('session-2', '2026-04-10T10:00:00.000Z');
294
+ manager.markSessionRead("session-2", "2026-04-10T10:00:00.000Z");
228
295
 
229
- expect(useChatSessionListStore.getState().optimisticReadAtBySessionKey['session-2']).toBe(
230
- '2026-04-10T10:00:00.000Z'
231
- );
232
- expect(mocks.updateNcpSession).toHaveBeenCalledWith('session-2', {
233
- uiReadAt: '2026-04-10T10:00:00.000Z'
296
+ expect(
297
+ useChatSessionListStore.getState().optimisticReadAtBySessionKey[
298
+ "session-2"
299
+ ],
300
+ ).toBe("2026-04-10T10:00:00.000Z");
301
+ expect(mocks.updateNcpSession).toHaveBeenCalledWith("session-2", {
302
+ uiReadAt: "2026-04-10T10:00:00.000Z",
234
303
  });
235
304
  });
236
305
 
237
- it('skips persisting read state when the backend already has the same watermark', () => {
306
+ it("skips persisting read state when the backend already has the same watermark", () => {
238
307
  const manager = new ChatSessionListManager(
239
- {} as ConstructorParameters<typeof ChatSessionListManager>[0]
308
+ {} as ConstructorParameters<typeof ChatSessionListManager>[0],
240
309
  );
241
310
 
242
311
  manager.markSessionRead(
243
- 'session-2',
244
- '2026-04-10T10:00:00.000Z',
245
- '2026-04-10T10:00:00.000Z'
312
+ "session-2",
313
+ "2026-04-10T10:00:00.000Z",
314
+ "2026-04-10T10:00:00.000Z",
246
315
  );
247
316
 
248
- expect(useChatSessionListStore.getState().optimisticReadAtBySessionKey['session-2']).toBeUndefined();
317
+ expect(
318
+ useChatSessionListStore.getState().optimisticReadAtBySessionKey[
319
+ "session-2"
320
+ ],
321
+ ).toBeUndefined();
249
322
  expect(mocks.updateNcpSession).not.toHaveBeenCalled();
250
323
  });
251
324
 
252
- it('marks a visible workspace child session as read through the session list owner', () => {
325
+ it("marks a visible workspace child session as read through the session list owner", () => {
253
326
  const manager = new ChatSessionListManager(
254
- {} as ConstructorParameters<typeof ChatSessionListManager>[0]
327
+ {} as ConstructorParameters<typeof ChatSessionListManager>[0],
255
328
  );
256
329
 
257
330
  manager.markVisibleWorkspaceChildRead({
258
- sessionKey: 'child-session-1',
259
- lastMessageAt: '2026-04-10T10:00:00.000Z',
331
+ sessionKey: "child-session-1",
332
+ lastMessageAt: "2026-04-10T10:00:00.000Z",
260
333
  readAt: null,
261
- runStatus: 'completed',
334
+ runStatus: "completed",
262
335
  });
263
336
 
264
- expect(useChatSessionListStore.getState().optimisticReadAtBySessionKey['child-session-1']).toBe(
265
- '2026-04-10T10:00:00.000Z'
266
- );
267
- expect(mocks.updateNcpSession).toHaveBeenCalledWith('child-session-1', {
268
- uiReadAt: '2026-04-10T10:00:00.000Z'
337
+ expect(
338
+ useChatSessionListStore.getState().optimisticReadAtBySessionKey[
339
+ "child-session-1"
340
+ ],
341
+ ).toBe("2026-04-10T10:00:00.000Z");
342
+ expect(mocks.updateNcpSession).toHaveBeenCalledWith("child-session-1", {
343
+ uiReadAt: "2026-04-10T10:00:00.000Z",
269
344
  });
270
345
  });
271
346
 
272
- it('keeps running workspace child sessions unread until they settle', () => {
347
+ it("keeps running workspace child sessions unread until they settle", () => {
273
348
  const manager = new ChatSessionListManager(
274
- {} as ConstructorParameters<typeof ChatSessionListManager>[0]
349
+ {} as ConstructorParameters<typeof ChatSessionListManager>[0],
275
350
  );
276
351
 
277
352
  manager.markVisibleWorkspaceChildRead({
278
- sessionKey: 'child-session-1',
279
- lastMessageAt: '2026-04-10T10:00:00.000Z',
353
+ sessionKey: "child-session-1",
354
+ lastMessageAt: "2026-04-10T10:00:00.000Z",
280
355
  readAt: null,
281
- runStatus: 'running',
356
+ runStatus: "running",
282
357
  });
283
358
 
284
- expect(useChatSessionListStore.getState().optimisticReadAtBySessionKey['child-session-1']).toBeUndefined();
359
+ expect(
360
+ useChatSessionListStore.getState().optimisticReadAtBySessionKey[
361
+ "child-session-1"
362
+ ],
363
+ ).toBeUndefined();
285
364
  expect(mocks.updateNcpSession).not.toHaveBeenCalled();
286
365
  });
287
-
288
366
  });
289
367
 
290
- describe('ChatSessionListStore persistence', () => {
368
+ describe("ChatSessionListStore persistence", () => {
291
369
  beforeEach(() => {
292
370
  persistStorage.clear();
293
- useChatSessionListStore.persist.setOptions({ storage: createLocalStoragePersistStorage() as never });
371
+ useChatSessionListStore.persist.setOptions({
372
+ storage: createLocalStoragePersistStorage() as never,
373
+ });
294
374
  useChatSessionListStore.setState({
295
375
  snapshot: {
296
376
  ...useChatSessionListStore.getState().snapshot,
297
- listMode: 'time-first',
377
+ listMode: "time-first",
298
378
  pinnedSessionKeys: [],
299
379
  pinnedProjectRoots: [],
300
380
  collapsedProjectRoots: [],
301
- }
381
+ },
302
382
  });
303
383
  });
304
384
 
305
- it('falls back to time-first when the persisted sidebar list mode is invalid', () => {
385
+ it("falls back to time-first when the persisted sidebar list mode is invalid", () => {
306
386
  useChatSessionListStore.persist.setOptions({
307
387
  storage: {
308
- getItem: () => ({ state: { snapshot: { listMode: 'sideways' } } }),
388
+ getItem: () => ({ state: { snapshot: { listMode: "sideways" } } }),
309
389
  setItem: vi.fn(),
310
- removeItem: vi.fn()
311
- }
390
+ removeItem: vi.fn(),
391
+ },
312
392
  });
313
393
 
314
394
  useChatSessionListStore.persist.rehydrate();
315
395
 
316
- expect(useChatSessionListStore.getState().snapshot.listMode).toBe('time-first');
396
+ expect(useChatSessionListStore.getState().snapshot.listMode).toBe(
397
+ "time-first",
398
+ );
317
399
  });
318
-
319
400
  });
@@ -75,7 +75,7 @@ describe('ChatThreadManager workspace pages', () => {
75
75
  });
76
76
  });
77
77
 
78
- it('closes a workspace page, restores overview, and reopens the page on demand', () => {
78
+ it('does not close fixed workspace pages', () => {
79
79
  const manager = new ChatThreadManager(
80
80
  createUiManager(),
81
81
  {} as ConstructorParameters<typeof ChatThreadManager>[1],
@@ -83,19 +83,18 @@ describe('ChatThreadManager workspace pages', () => {
83
83
 
84
84
  manager.openWorkspaceOverview('parent-session-1');
85
85
  manager.openProjectFiles('parent-session-1');
86
- manager.closeWorkspaceTab({ kind: 'project-files' });
86
+ for (const kind of ['child-sessions', 'cron', 'project-files'] as const) {
87
+ manager.closeWorkspaceTab({ kind });
88
+ }
87
89
 
88
- expect(useChatThreadStore.getState().snapshot).toMatchObject({
89
- activeWorkspacePanelKind: 'overview',
90
- closedWorkspaceTabEntries: [{ kind: 'project-files' }],
91
- workspaceNavigationHistory: [{ kind: 'overview' }],
92
- workspaceNavigationHistoryIndex: 0,
93
- });
94
-
95
- manager.openProjectFiles('parent-session-1');
96
90
  expect(useChatThreadStore.getState().snapshot).toMatchObject({
97
91
  activeWorkspacePanelKind: 'project-files',
98
92
  closedWorkspaceTabEntries: [],
93
+ workspaceNavigationHistory: [
94
+ { kind: 'overview' },
95
+ { kind: 'project-files' },
96
+ ],
97
+ workspaceNavigationHistoryIndex: 1,
99
98
  });
100
99
  });
101
100
  });