@nextclaw/ui 0.15.10 → 0.15.11

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 +34 -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-pbx14YAL.js +13 -0
  5. package/dist/assets/app-presenter-provider-Q6u2xBAn.js +106 -0
  6. package/dist/assets/appearance-settings-page-D9wJdf-0.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-DZyssdCc.js} +1 -1
  12. package/dist/assets/{c4Diagram-LMCZKHZV-B1w-iwRe.js → c4Diagram-LMCZKHZV-Bsrtg6b2.js} +1 -1
  13. package/dist/assets/card-D7l-gWkY.js +1 -0
  14. package/dist/assets/channel-BSKkTPe8.js +1 -0
  15. package/dist/assets/channels-list-page-B3qW3T-B.js +8 -0
  16. package/dist/assets/chat-page-DUI_Jm6r.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-DFEKStD7.js +1 -0
  58. package/dist/assets/confirm-dialog-7wpxfMCp.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-DP6IbxBO.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-B9UN0HrS.js} +1 -1
  71. package/dist/assets/doc-browser-D7klPMHs.js +1 -0
  72. package/dist/assets/{doc-browser-context-CpvHiuQG.js → doc-browser-context-Bw9m83Jp.js} +1 -1
  73. package/dist/assets/doc-browser-wgEeLkn1.js +1 -0
  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-IVMB0Rrz.js +1 -0
  79. package/dist/assets/flowDiagram-23GEKE2U-BiFSctqz.js +1 -0
  80. package/dist/assets/{form-actions-5OsDRt0g.js → form-actions-DrFAgO58.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-D297NGOb.js +2 -0
  85. package/dist/assets/index-DqZoodZL.css +1 -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-DDgFo4Kv.js +1 -0
  94. package/dist/assets/{logo-badge-TdPa95AC.js → logo-badge-DoZOVuPr.js} +1 -1
  95. package/dist/assets/{map-Bdri5UL5.js → map-BAAdHTqR.js} +1 -1
  96. package/dist/assets/mcp-marketplace-page-BtNExfMn.js +1 -0
  97. package/dist/assets/{mcp-marketplace-page-cm3ifaKu.js → mcp-marketplace-page-C151EGP-.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-BmfQzc52.js +1 -0
  102. package/dist/assets/navigation-link-CJw6FLOj.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-CYxLSfLh.js +1 -0
  109. package/dist/assets/{popover-EulxhA0q.js → popover-DitLJE6k.js} +1 -1
  110. package/dist/assets/provider-scoped-model-input-CuAtduIc.js +1 -0
  111. package/dist/assets/providers-config-page-CrmuY4DC.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-CTDaaQ9V.js} +1 -1
  120. package/dist/assets/{refresh-cw-CexL11m1.js → refresh-cw-E5qTlQY6.js} +1 -1
  121. package/dist/assets/remote-YzPpOPmK.js +1 -0
  122. package/dist/assets/{requirementDiagram-TGXJPOKE-EmFph0H_.js → requirementDiagram-TGXJPOKE-D8YV0-Jz.js} +1 -1
  123. package/dist/assets/rotate-cw-BXeiDT6C.js +1 -0
  124. package/dist/assets/runtime-config-page-1fPJJvo5.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-CTiZvAd2.js} +1 -1
  127. package/dist/assets/{search-BArc_WOX.js → search-CztGmpnR.js} +1 -1
  128. package/dist/assets/search-config-page-D3jVALZU.js +1 -0
  129. package/dist/assets/secrets-config-page-CxWLQCjZ.js +3 -0
  130. package/dist/assets/security-config-DEyj4WBh.js +1 -0
  131. package/dist/assets/{select-C9FB0jlt.js → select-BPVI2dQ_.js} +1 -1
  132. package/dist/assets/{sequenceDiagram-DBY2YBRQ-ClKnO7v0.js → sequenceDiagram-DBY2YBRQ-B9LBmpUo.js} +1 -1
  133. package/dist/assets/settings-2-Cd7QaBsq.js +1 -0
  134. package/dist/assets/{sizeCapture-X5ZJPWSS-DSo-t5ou.js → sizeCapture-X5ZJPWSS-9UIfya9-.js} +1 -1
  135. package/dist/assets/skeleton-CUpAXGoe.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-DrUmYwEQ.js} +1 -1
  142. package/dist/assets/{tag-chip-C011rd9q.js → tag-chip-CmViAZKK.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-DMRJ63AB.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-gpXy2Iyc.js} +1 -1
  148. package/dist/assets/use-confirm-dialog-Du33bHPz.js +1 -0
  149. package/dist/assets/{use-viewport-layout-P0q6Nt_N.js → use-viewport-layout-D80O1d90.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-CsLMuNFe.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 +187 -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 +188 -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 +178 -0
  198. package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +44 -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 +157 -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 +32 -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 +34 -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
@@ -65,7 +65,7 @@ describe("Sidebar", () => {
65
65
  it("keeps the settings sidebar bounded and lets the navigation scroll independently", () => {
66
66
  const { container } = render(
67
67
  <MemoryRouter initialEntries={["/model"]}>
68
- <Sidebar mode="settings" />
68
+ <Sidebar />
69
69
  </MemoryRouter>,
70
70
  );
71
71
 
@@ -90,7 +90,7 @@ describe("Sidebar", () => {
90
90
  it("keeps the original compact single-row header in settings mode", () => {
91
91
  render(
92
92
  <MemoryRouter initialEntries={["/model"]}>
93
- <Sidebar mode="settings" />
93
+ <Sidebar />
94
94
  </MemoryRouter>,
95
95
  );
96
96
 
@@ -108,7 +108,7 @@ describe("Sidebar", () => {
108
108
  it("keeps the settings navigation in the expected product order", () => {
109
109
  const { container } = render(
110
110
  <MemoryRouter initialEntries={["/model"]}>
111
- <Sidebar mode="settings" />
111
+ <Sidebar />
112
112
  </MemoryRouter>,
113
113
  );
114
114
 
@@ -140,12 +140,12 @@ describe("Sidebar", () => {
140
140
  .getAllByRole("link")
141
141
  .map((link) => link.textContent?.trim() || ""),
142
142
  ).toEqual([
143
- "Search Channels",
144
143
  "Appearance",
145
- "Security",
146
- "Routing & Runtime",
144
+ "Sign-in Management",
145
+ "Search Channels",
147
146
  "Updates",
148
147
  "Remote Access",
148
+ "Routing & Runtime",
149
149
  "Secrets",
150
150
  "MCP",
151
151
  ]);
@@ -153,12 +153,12 @@ describe("Sidebar", () => {
153
153
  "Model",
154
154
  "Providers",
155
155
  "Channels",
156
- "Search Channels",
157
156
  "Appearance",
158
- "Security",
159
- "Routing & Runtime",
157
+ "Sign-in Management",
158
+ "Search Channels",
160
159
  "Updates",
161
160
  "Remote Access",
161
+ "Routing & Runtime",
162
162
  "Secrets",
163
163
  "MCP",
164
164
  ]);
@@ -167,27 +167,39 @@ describe("Sidebar", () => {
167
167
  it("keeps the footer utilities compact without changing the top header structure", () => {
168
168
  render(
169
169
  <MemoryRouter initialEntries={["/model"]}>
170
- <Sidebar mode="settings" />
170
+ <Sidebar />
171
171
  </MemoryRouter>,
172
172
  );
173
173
 
174
174
  const accountEntry = screen.getByTestId("settings-sidebar-account-entry");
175
175
  const accountStatus = screen.getByTestId("settings-sidebar-account-status");
176
+ const footer = accountEntry.parentElement;
177
+ const navigationList = accountEntry.closest("aside")?.querySelector("nav ul");
176
178
 
177
179
  expect(accountEntry).toBeTruthy();
178
180
  expect(accountEntry.textContent).toContain("Account");
179
181
  expect(screen.getByText("user@example.com")).toBeTruthy();
182
+ expect(screen.queryByRole("combobox", { name: "Theme" })).toBeNull();
183
+ expect(screen.queryByRole("combobox", { name: "Language" })).toBeNull();
180
184
  expect(accountEntry.className).toContain("py-2");
181
185
  expect(accountEntry.className).toContain("text-muted-foreground");
182
186
  expect(accountEntry.className).toContain("hover:bg-gray-200/60");
183
- expect(accountEntry.parentElement?.className).not.toContain("border-t");
187
+ expect(navigationList?.className).toContain("space-y-0.5");
188
+ expect(footer?.className).toContain("space-y-0.5");
189
+ expect(footer?.firstElementChild?.textContent).toContain("Help Docs");
190
+ expect(footer?.lastElementChild).toBe(accountEntry);
191
+ expect(
192
+ Array.from(footer?.children ?? []).every(
193
+ (item) => !item.className.match(/(?:^|\s)mb-/),
194
+ ),
195
+ ).toBe(true);
184
196
  expect(accountStatus.className).toContain("text-[11px]");
185
197
  });
186
198
 
187
199
  it("persists the shared sidebar collapsed state through the viewport layout store", () => {
188
200
  const { container } = render(
189
201
  <MemoryRouter initialEntries={["/model"]}>
190
- <Sidebar mode="settings" />
202
+ <Sidebar />
191
203
  </MemoryRouter>,
192
204
  );
193
205
 
@@ -33,6 +33,7 @@ type SidebarItemTone = {
33
33
  icon: string;
34
34
  value: string;
35
35
  gap: string;
36
+ stack: string;
36
37
  };
37
38
 
38
39
  const SIDEBAR_ITEM_TONES: Record<SidebarItemDensity, SidebarItemTone> = {
@@ -41,12 +42,14 @@ const SIDEBAR_ITEM_TONES: Record<SidebarItemDensity, SidebarItemTone> = {
41
42
  icon: "h-[17px] w-[17px]",
42
43
  value: "text-xs",
43
44
  gap: "gap-3",
45
+ stack: "space-y-1",
44
46
  },
45
47
  compact: {
46
48
  row: "gap-2.5 px-3 py-2 text-[13px]",
47
49
  icon: "h-4 w-4",
48
50
  value: "text-[11px]",
49
51
  gap: "gap-2.5",
52
+ stack: "space-y-0.5",
50
53
  },
51
54
  };
52
55
 
@@ -54,6 +57,12 @@ function getSidebarItemTone(density: SidebarItemDensity): SidebarItemTone {
54
57
  return SIDEBAR_ITEM_TONES[density];
55
58
  }
56
59
 
60
+ export function getSidebarItemStackClass(
61
+ density: SidebarItemDensity,
62
+ ): string {
63
+ return getSidebarItemTone(density).stack;
64
+ }
65
+
57
66
  function isSidebarRouteActive(pathname: string, target: string): boolean {
58
67
  const normalizedPathname = pathname.toLowerCase();
59
68
  const normalizedTarget = target.toLowerCase();
@@ -150,7 +159,7 @@ type SidebarNavigationListProps = {
150
159
  isCollapsed: boolean;
151
160
  items: SidebarNavListItem[];
152
161
  density: SidebarItemDensity;
153
- className: string;
162
+ className?: string;
154
163
  };
155
164
 
156
165
  export function SidebarNavigationList({
@@ -160,7 +169,7 @@ export function SidebarNavigationList({
160
169
  className,
161
170
  }: SidebarNavigationListProps) {
162
171
  return (
163
- <ul className={className}>
172
+ <ul className={cn(getSidebarItemStackClass(density), className)}>
164
173
  {items.map((item) => (
165
174
  <li
166
175
  key={item.target}
@@ -1,37 +1,24 @@
1
1
  import { cn } from "@/shared/lib/utils";
2
2
  import { t } from "@/shared/lib/i18n";
3
- import { THEME_OPTIONS, type UiTheme } from "@/shared/lib/theme";
4
3
  import {
5
4
  BookOpen,
6
- Languages,
7
- Palette,
8
5
  KeyRound,
9
- Settings,
10
6
  ArrowLeft,
11
7
  PanelLeftClose,
12
8
  PanelLeftOpen,
13
9
  } from "lucide-react";
14
10
  import { NavLink } from "react-router-dom";
15
11
  import { useDocBrowser } from "@/shared/components/doc-browser";
16
- import { BrandHeader } from "@/shared/components/common/brand-header";
17
12
  import {
13
+ getSidebarItemStackClass,
18
14
  SidebarActionItem,
19
15
  SidebarNavigationList,
20
- SidebarNavLinkItem,
21
- SidebarSelectItem,
22
- type SidebarItemDensity,
23
16
  type SidebarNavListItem,
24
17
  } from "@/app/components/layout/sidebar-items";
25
- import { useTheme } from "@/app/components/theme-provider";
26
- import { SelectItem } from "@/shared/components/ui/select";
27
18
  import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
28
19
  import { useAppPresenter } from "@/app/components/app-presenter-provider";
29
20
  import { useRemoteStatus } from "@/features/remote";
30
- import {
31
- getMainSidebarNavItems,
32
- getSettingsNavSections,
33
- } from "@/app/configs/app-navigation.config";
34
- import { useLanguagePreference } from "@/features/settings";
21
+ import { getSettingsNavSections } from "@/app/configs/app-navigation.config";
35
22
  import { viewportLayoutManager } from "@/app/managers/viewport-layout.manager";
36
23
  import { useViewportLayoutStore } from "@/app/stores/viewport-layout.store";
37
24
  import {
@@ -45,44 +32,11 @@ import {
45
32
  SIDEBAR_SCROLL_EDGE_FADE_CLASS,
46
33
  } from "@/app/components/layout/sidebar-rail.styles";
47
34
 
48
- type SidebarMode = "main" | "settings";
49
-
50
- type SidebarProps = {
51
- mode: SidebarMode;
52
- };
53
-
54
35
  type SidebarNavSection = {
55
36
  label: string;
56
37
  items: SidebarNavListItem[];
57
38
  };
58
39
 
59
- type SidebarNavigationModel = {
60
- items: SidebarNavListItem[];
61
- sections?: SidebarNavSection[];
62
- density: SidebarItemDensity;
63
- };
64
-
65
- type SidebarTranslate = (key: string) => string;
66
-
67
- function resolveSidebarNavigation(
68
- isSettingsMode: boolean,
69
- translate: SidebarTranslate,
70
- ): SidebarNavigationModel {
71
- if (!isSettingsMode) {
72
- return {
73
- items: getMainSidebarNavItems(translate),
74
- density: "default",
75
- };
76
- }
77
-
78
- const sections = getSettingsNavSections(translate);
79
- return {
80
- items: sections.flatMap((section) => section.items),
81
- sections,
82
- density: "compact",
83
- };
84
- }
85
-
86
40
  function SidebarCollapseToggle({
87
41
  isCollapsed,
88
42
  onToggle,
@@ -175,72 +129,13 @@ function SettingsSidebarHeader({
175
129
  );
176
130
  }
177
131
 
178
- function MainSidebarHeader({
179
- isCollapsed,
180
- onToggle,
181
- }: {
182
- isCollapsed: boolean;
183
- onToggle: () => void;
184
- }) {
185
- return (
186
- <div
187
- className={cn(
188
- "shrink-0",
189
- isCollapsed ? "flex justify-center px-0 py-1.5" : "px-2 py-2",
190
- )}
191
- >
192
- {isCollapsed ? (
193
- <SidebarCollapseToggle isCollapsed={isCollapsed} onToggle={onToggle} />
194
- ) : (
195
- <div className="flex items-center gap-2">
196
- <BrandHeader className="flex min-w-0 flex-1 items-center gap-2.5 cursor-pointer" />
197
- <SidebarCollapseToggle
198
- isCollapsed={isCollapsed}
199
- onToggle={onToggle}
200
- />
201
- </div>
202
- )}
203
- </div>
204
- );
205
- }
206
-
207
- function SidebarHeader({
208
- isSettingsMode,
209
- isCollapsed,
210
- onToggle,
211
- }: {
212
- isSettingsMode: boolean;
213
- isCollapsed: boolean;
214
- onToggle: () => void;
215
- }) {
216
- return isSettingsMode ? (
217
- <SettingsSidebarHeader isCollapsed={isCollapsed} onToggle={onToggle} />
218
- ) : (
219
- <MainSidebarHeader isCollapsed={isCollapsed} onToggle={onToggle} />
220
- );
221
- }
222
-
223
132
  function SidebarNavigation({
224
- isSettingsMode,
225
133
  isCollapsed,
226
- items,
227
134
  sections,
228
- density,
229
135
  }: {
230
- isSettingsMode: boolean;
231
136
  isCollapsed: boolean;
232
- items: SidebarNavListItem[];
233
- sections?: SidebarNavSection[];
234
- density: SidebarItemDensity;
137
+ sections: SidebarNavSection[];
235
138
  }) {
236
- const listClassName = cn(
237
- isCollapsed
238
- ? cn(SIDEBAR_RAIL_STACK_CLASS, "pb-3")
239
- : isSettingsMode
240
- ? "space-y-0.5 pb-3"
241
- : "space-y-1 pb-4",
242
- );
243
-
244
139
  return (
245
140
  <nav
246
141
  className={cn(
@@ -249,7 +144,7 @@ function SidebarNavigation({
249
144
  SIDEBAR_SCROLL_EDGE_FADE_CLASS,
250
145
  )}
251
146
  >
252
- {sections && !isCollapsed ? (
147
+ {!isCollapsed ? (
253
148
  <div className="space-y-3 pb-3">
254
149
  {sections.map((section) => (
255
150
  <section
@@ -263,8 +158,7 @@ function SidebarNavigation({
263
158
  <SidebarNavigationList
264
159
  isCollapsed={isCollapsed}
265
160
  items={section.items}
266
- density={density}
267
- className="space-y-0.5"
161
+ density="compact"
268
162
  />
269
163
  </section>
270
164
  ))}
@@ -272,16 +166,16 @@ function SidebarNavigation({
272
166
  ) : (
273
167
  <SidebarNavigationList
274
168
  isCollapsed={isCollapsed}
275
- items={items}
276
- density={density}
277
- className={listClassName}
169
+ items={sections.flatMap((section) => section.items)}
170
+ density="compact"
171
+ className={cn(SIDEBAR_RAIL_STACK_CLASS, "pb-3")}
278
172
  />
279
173
  )}
280
174
  </nav>
281
175
  );
282
176
  }
283
177
 
284
- export function Sidebar({ mode }: SidebarProps) {
178
+ export function Sidebar() {
285
179
  const presenter = useAppPresenter();
286
180
  const docBrowser = useDocBrowser();
287
181
  const remoteStatus = useRemoteStatus();
@@ -289,30 +183,12 @@ export function Sidebar({ mode }: SidebarProps) {
289
183
  (state) => state.isSidebarCollapsed,
290
184
  );
291
185
  const toggleCollapsed = viewportLayoutManager.toggleSidebarCollapsed;
292
- const {
293
- currentLanguage,
294
- currentLanguageLabel,
295
- languageOptions,
296
- selectLanguage,
297
- } = useLanguagePreference();
298
- const { theme, setTheme } = useTheme();
299
- const isSettingsMode = mode === "settings";
300
- const currentThemeLabel = t(
301
- THEME_OPTIONS.find((option) => option.value === theme)?.labelKey ??
302
- "themeWork",
303
- );
304
186
  const accountEmail = remoteStatus.data?.account.email?.trim();
305
187
  const accountConnected = Boolean(remoteStatus.data?.account.loggedIn);
306
-
307
- const handleThemeSwitch = (nextTheme: UiTheme) => {
308
- if (theme !== nextTheme) setTheme(nextTheme);
309
- };
310
-
311
- const {
312
- items: navItems,
313
- sections: settingsNavSections,
314
- density: sidebarDensity,
315
- } = resolveSidebarNavigation(isSettingsMode, t);
188
+ const settingsNavSections = getSettingsNavSections(t);
189
+ const sidebarStackClass = isCollapsed
190
+ ? SIDEBAR_RAIL_STACK_CLASS
191
+ : getSidebarItemStackClass("compact");
316
192
 
317
193
  return (
318
194
  <aside
@@ -324,118 +200,26 @@ export function Sidebar({ mode }: SidebarProps) {
324
200
  )}
325
201
  data-sidebar-collapsed={isCollapsed ? "true" : "false"}
326
202
  >
327
- <SidebarHeader
328
- isSettingsMode={isSettingsMode}
203
+ <SettingsSidebarHeader
329
204
  isCollapsed={isCollapsed}
330
205
  onToggle={toggleCollapsed}
331
206
  />
332
207
 
333
208
  <div className="flex min-h-0 flex-1 flex-col">
334
209
  <SidebarNavigation
335
- isSettingsMode={isSettingsMode}
336
210
  isCollapsed={isCollapsed}
337
- items={navItems}
338
211
  sections={settingsNavSections}
339
- density={sidebarDensity}
340
212
  />
341
213
 
342
214
  <div
343
215
  className={cn(
344
216
  "shrink-0 bg-secondary",
345
217
  isCollapsed
346
- ? "mt-2 pt-2"
347
- : isSettingsMode
348
- ? "mt-2 pt-3"
349
- : "mt-3 pt-3",
218
+ ? "mt-2 flex flex-col items-center pt-2"
219
+ : "mt-2 pt-3",
220
+ sidebarStackClass,
350
221
  )}
351
222
  >
352
- {isSettingsMode ? (
353
- <SidebarActionItem
354
- onClick={() => presenter.accountManager.openAccountPanel()}
355
- icon={KeyRound}
356
- label={t("remoteAccountEntryManage")}
357
- density="compact"
358
- className={isCollapsed ? "mb-1" : "mb-1.5"}
359
- trailing={
360
- accountConnected
361
- ? accountEmail || t("remoteAccountEntryConnected")
362
- : t("remoteAccountEntryDisconnected")
363
- }
364
- trailingClassName="max-w-[92px] truncate text-right"
365
- testId="settings-sidebar-account-entry"
366
- trailingTestId="settings-sidebar-account-status"
367
- collapsed={isCollapsed}
368
- />
369
- ) : null}
370
- {mode === "main" && (
371
- <div
372
- className={cn(
373
- isCollapsed ? "mb-1" : "mb-2",
374
- isCollapsed ? "flex justify-center" : undefined,
375
- )}
376
- >
377
- <SidebarNavLinkItem
378
- to="/settings"
379
- label={t("settings")}
380
- icon={Settings}
381
- collapsed={isCollapsed}
382
- />
383
- </div>
384
- )}
385
- <div
386
- className={cn(
387
- isCollapsed ? "mb-1" : "mb-2",
388
- isCollapsed ? "flex justify-center" : undefined,
389
- )}
390
- >
391
- <SidebarSelectItem
392
- value={theme}
393
- onValueChange={(value) => handleThemeSwitch(value as UiTheme)}
394
- icon={Palette}
395
- label={t("theme")}
396
- valueLabel={currentThemeLabel}
397
- density={sidebarDensity}
398
- collapsed={isCollapsed}
399
- >
400
- {THEME_OPTIONS.map((option) => (
401
- <SelectItem
402
- key={option.value}
403
- value={option.value}
404
- className="text-xs"
405
- >
406
- {t(option.labelKey)}
407
- </SelectItem>
408
- ))}
409
- </SidebarSelectItem>
410
- </div>
411
- <div
412
- className={cn(
413
- isCollapsed ? "mb-1" : "mb-2",
414
- isCollapsed ? "flex justify-center" : undefined,
415
- )}
416
- >
417
- <SidebarSelectItem
418
- value={currentLanguage}
419
- onValueChange={(value) =>
420
- selectLanguage(value as typeof currentLanguage)
421
- }
422
- icon={Languages}
423
- label={t("language")}
424
- valueLabel={currentLanguageLabel}
425
- density={sidebarDensity}
426
- collapsed={isCollapsed}
427
- >
428
- {languageOptions.map((option) => (
429
- <SelectItem
430
- key={option.value}
431
- value={option.value}
432
- className="text-xs"
433
- >
434
- {option.label}
435
- </SelectItem>
436
- ))}
437
- </SidebarSelectItem>
438
- </div>
439
223
  <SidebarActionItem
440
224
  onClick={() =>
441
225
  docBrowser.open(undefined, {
@@ -445,7 +229,22 @@ export function Sidebar({ mode }: SidebarProps) {
445
229
  }
446
230
  icon={BookOpen}
447
231
  label={t("docBrowserHelp")}
448
- density={sidebarDensity}
232
+ density="compact"
233
+ collapsed={isCollapsed}
234
+ />
235
+ <SidebarActionItem
236
+ onClick={() => presenter.accountManager.openAccountPanel()}
237
+ icon={KeyRound}
238
+ label={t("remoteAccountEntryManage")}
239
+ density="compact"
240
+ trailing={
241
+ accountConnected
242
+ ? accountEmail || t("remoteAccountEntryConnected")
243
+ : t("remoteAccountEntryDisconnected")
244
+ }
245
+ trailingClassName="max-w-[92px] truncate text-right"
246
+ testId="settings-sidebar-account-entry"
247
+ trailingTestId="settings-sidebar-account-status"
449
248
  collapsed={isCollapsed}
450
249
  />
451
250
  </div>
@@ -6,7 +6,6 @@ import {
6
6
  Cpu,
7
7
  Download,
8
8
  KeyRound,
9
- Languages,
10
9
  MessageCircle,
11
10
  MessageSquare,
12
11
  Palette,
@@ -132,11 +131,6 @@ export function getSettingsNavItems(
132
131
  label: translate("channels"),
133
132
  icon: MessageSquare,
134
133
  },
135
- {
136
- target: "/search",
137
- label: translate("searchChannels"),
138
- icon: Search,
139
- },
140
134
  {
141
135
  target: "/appearance",
142
136
  label: translate("appearance"),
@@ -148,9 +142,9 @@ export function getSettingsNavItems(
148
142
  icon: Shield,
149
143
  },
150
144
  {
151
- target: "/runtime",
152
- label: translate("runtime"),
153
- icon: Cpu,
145
+ target: "/search",
146
+ label: translate("searchChannels"),
147
+ icon: Search,
154
148
  },
155
149
  {
156
150
  target: "/updates",
@@ -162,6 +156,11 @@ export function getSettingsNavItems(
162
156
  label: translate("remote"),
163
157
  icon: Wifi,
164
158
  },
159
+ {
160
+ target: "/runtime",
161
+ label: translate("runtime"),
162
+ icon: Cpu,
163
+ },
165
164
  {
166
165
  target: "/secrets",
167
166
  label: translate("secrets"),
@@ -191,25 +190,12 @@ export function getSettingsNavSections(
191
190
  ];
192
191
  }
193
192
 
194
- export function getMobileSettingsNavItems(
195
- translate: Translate,
196
- ): AppNavigationItem[] {
197
- return [
198
- {
199
- target: "/language",
200
- label: translate("language"),
201
- icon: Languages,
202
- },
203
- ...getSettingsNavItems(translate),
204
- ];
205
- }
206
-
207
193
  export function isSettingsRoute(pathname: string): boolean {
208
194
  const normalized = pathname.toLowerCase();
209
195
  if (normalized === "/settings") {
210
196
  return true;
211
197
  }
212
- return getMobileSettingsNavItems((key) => key).some((item) =>
198
+ return getSettingsNavItems((key) => key).some((item) =>
213
199
  matchesRouteTarget(normalized, item.target),
214
200
  );
215
201
  }
@@ -223,7 +209,7 @@ export function resolveMobileRouteMeta(
223
209
  backLabel: string | null;
224
210
  } {
225
211
  const normalized = pathname.toLowerCase();
226
- const settingsItems = getMobileSettingsNavItems(translate);
212
+ const settingsItems = getSettingsNavItems(translate);
227
213
 
228
214
  if (isChatSessionDetailRoute(normalized)) {
229
215
  return {
package/src/app/index.tsx CHANGED
@@ -6,7 +6,6 @@ import { Toaster } from "sonner";
6
6
  import { appQueryClient } from "@/app-query-client";
7
7
  import { AppPresenterProvider } from "@/app/components/app-presenter-provider";
8
8
  import { AppLayout } from "@/app/components/layout/app-layout";
9
- import { LanguageSettingsPage } from "@/features/settings";
10
9
  import { SettingsEntryPage } from "@/app/components/layout/settings-entry-page";
11
10
  import { LoginPage } from "@/components/auth/login-page";
12
11
  import { AccountPanel } from "@/features/account";
@@ -158,10 +157,6 @@ const protectedRouteDefinitions: ProtectedRouteDefinition[] = [
158
157
  path: "/secrets",
159
158
  element: createLazyElement(<SecretsConfigPage />),
160
159
  },
161
- {
162
- path: "/language",
163
- element: <LanguageSettingsPage />,
164
- },
165
160
  {
166
161
  path: "/settings",
167
162
  element: <SettingsEntryPage />,