@lobehub/lobehub 2.0.0-next.72 → 2.0.0-next.74

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 (358) hide show
  1. package/.github/workflows/desktop-pr-build.yml +7 -3
  2. package/CHANGELOG.md +50 -0
  3. package/apps/desktop/package.json +1 -0
  4. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +55 -11
  5. package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +153 -0
  6. package/changelog/v1.json +18 -0
  7. package/locales/en-US/tool.json +12 -1
  8. package/locales/zh-CN/tool.json +12 -1
  9. package/next.config.ts +5 -5
  10. package/package.json +2 -1
  11. package/packages/electron-client-ipc/src/types/localSystem.ts +4 -0
  12. package/scripts/prebuild.mts +16 -6
  13. package/src/app/(backend)/trpc/desktop/[trpc]/route.ts +6 -6
  14. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +7 -4
  15. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +4 -4
  16. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +5 -6
  17. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/useCategory.tsx +5 -8
  18. package/src/app/[variants]/(main)/(mobile)/me/(home)/index.tsx +25 -0
  19. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +13 -16
  20. package/src/app/[variants]/(main)/(mobile)/me/profile/features/Category.tsx +6 -6
  21. package/src/app/[variants]/(main)/(mobile)/me/profile/features/Header.tsx +3 -3
  22. package/src/app/[variants]/(main)/(mobile)/me/profile/index.tsx +16 -0
  23. package/src/app/[variants]/(main)/(mobile)/me/profile/layout.tsx +9 -11
  24. package/src/app/[variants]/(main)/(mobile)/me/settings/features/Header.tsx +3 -3
  25. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +3 -4
  26. package/src/app/[variants]/(main)/(mobile)/me/settings/index.tsx +16 -0
  27. package/src/app/[variants]/(main)/(mobile)/me/settings/layout.tsx +15 -13
  28. package/src/app/[variants]/(main)/changelog/_layout/Desktop/index.tsx +6 -5
  29. package/src/app/[variants]/(main)/changelog/_layout/Mobile/Header.tsx +3 -3
  30. package/src/app/[variants]/(main)/changelog/_layout/Mobile/index.tsx +5 -5
  31. package/src/app/[variants]/(main)/changelog/features/Post.tsx +7 -4
  32. package/src/app/[variants]/(main)/changelog/index.tsx +55 -0
  33. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +6 -7
  34. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +3 -3
  35. package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +1 -14
  36. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatHydration/index.tsx +2 -2
  37. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/Desktop/MessageFromUrl.tsx +11 -13
  38. package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/Desktop/index.tsx +0 -1
  39. package/src/app/[variants]/(main)/chat/components/conversation/features/ThreadHydration.tsx +2 -2
  40. package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +20 -11
  41. package/src/app/[variants]/(main)/chat/features/PageTitle/index.tsx +1 -2
  42. package/src/app/[variants]/(main)/chat/index.tsx +29 -0
  43. package/src/app/[variants]/(main)/chat/session/features/SessionHydration.tsx +8 -6
  44. package/src/app/[variants]/(main)/chat/session/features/SessionListContent/Inbox/index.tsx +2 -4
  45. package/src/app/[variants]/(main)/chat/session/features/SessionListContent/List/index.tsx +1 -1
  46. package/src/app/[variants]/(main)/chat/session/layout/Mobile/SessionHeader.tsx +3 -3
  47. package/src/app/[variants]/(main)/chat/settings/_layout/Desktop/Header.tsx +3 -3
  48. package/src/app/[variants]/(main)/chat/settings/_layout/Mobile/Header.tsx +3 -3
  49. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +3 -3
  50. package/src/app/[variants]/(main)/chat/{components/SettingsPage.tsx → settings/index.tsx} +6 -35
  51. package/src/app/[variants]/(main)/components/Link.tsx +21 -0
  52. package/src/app/[variants]/(main)/discover/(detail)/_layout/{Desktop.tsx → Desktop/index.tsx} +15 -7
  53. package/src/app/[variants]/(main)/discover/(detail)/_layout/Mobile/index.tsx +3 -3
  54. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Block.tsx +1 -1
  55. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Overview/index.tsx +1 -1
  56. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  57. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/SystemRole/index.tsx +3 -3
  58. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Versions/index.tsx +4 -4
  59. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/index.tsx +1 -1
  60. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Header.tsx +2 -2
  61. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/ActionButton/AddAgent.tsx +3 -3
  62. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  63. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Related/index.tsx +1 -1
  64. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/TocList/index.tsx +2 -2
  65. package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/StatusPage/index.tsx +3 -3
  66. package/src/app/[variants]/(main)/discover/(detail)/assistant/{AssistantDetailPage.tsx → index.tsx} +18 -11
  67. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +1 -1
  68. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/Related/index.tsx +2 -2
  69. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/Versions/index.tsx +5 -5
  70. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Details/index.tsx +1 -1
  71. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/Related/index.tsx +2 -2
  72. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ServerConfig.tsx +4 -4
  73. package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/TocList/index.tsx +2 -2
  74. package/src/app/[variants]/(main)/discover/(detail)/mcp/{McpDetailPage.tsx → index.tsx} +15 -7
  75. package/src/app/[variants]/(main)/discover/(detail)/mcp/loading.tsx +1 -0
  76. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Overview/index.tsx +1 -1
  77. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Parameter/ParameterItem.tsx +1 -1
  78. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  79. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/index.tsx +1 -1
  80. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Header.tsx +1 -1
  81. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/ActionButton/ChatWithModel.tsx +3 -3
  82. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  83. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/Related/index.tsx +2 -2
  84. package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/RelatedProviders/index.tsx +1 -1
  85. package/src/app/[variants]/(main)/discover/(detail)/model/{ModelDetailPage.tsx → index.tsx} +17 -10
  86. package/src/app/[variants]/(main)/discover/(detail)/model/loading.tsx +1 -0
  87. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Related/index.tsx +2 -2
  88. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/index.tsx +1 -1
  89. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/ActionButton/ProviderConfig.tsx +5 -4
  90. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/ActionButton/index.tsx +1 -1
  91. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/Related/index.tsx +2 -2
  92. package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/RelatedModels/index.tsx +1 -1
  93. package/src/app/[variants]/(main)/discover/(detail)/provider/{ProviderDetailPage.tsx → index.tsx} +17 -10
  94. package/src/app/[variants]/(main)/discover/(detail)/provider/loading.tsx +1 -0
  95. package/src/app/[variants]/(main)/discover/(list)/(home)/{HomePage.tsx → index.tsx} +14 -0
  96. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +2 -3
  97. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/index.tsx +4 -3
  98. package/src/app/[variants]/(main)/discover/(list)/_layout/Mobile/Nav.tsx +3 -4
  99. package/src/app/[variants]/(main)/discover/(list)/_layout/Mobile/index.tsx +4 -3
  100. package/src/app/[variants]/(main)/discover/(list)/assistant/_layout/Desktop.tsx +3 -4
  101. package/src/app/[variants]/(main)/discover/(list)/assistant/_layout/Mobile.tsx +3 -3
  102. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +2 -2
  103. package/src/app/[variants]/(main)/discover/(list)/assistant/{AssistantPage.tsx → index.tsx} +18 -4
  104. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +2 -2
  105. package/src/app/[variants]/(main)/discover/(list)/mcp/_layout/Desktop.tsx +3 -3
  106. package/src/app/[variants]/(main)/discover/(list)/mcp/_layout/Mobile.tsx +3 -3
  107. package/src/app/[variants]/(main)/discover/(list)/mcp/features/List/Item.tsx +1 -1
  108. package/src/app/[variants]/(main)/discover/(list)/mcp/{McpPage.tsx → index.tsx} +9 -2
  109. package/src/app/[variants]/(main)/discover/(list)/model/_layout/Desktop.tsx +3 -3
  110. package/src/app/[variants]/(main)/discover/(list)/model/_layout/Mobile.tsx +3 -3
  111. package/src/app/[variants]/(main)/discover/(list)/model/features/List/Item.tsx +1 -1
  112. package/src/app/[variants]/(main)/discover/(list)/model/{ModelPage.tsx → index.tsx} +9 -2
  113. package/src/app/[variants]/(main)/discover/(list)/provider/features/List/Item.tsx +1 -1
  114. package/src/app/[variants]/(main)/discover/(list)/provider/{Client.tsx → index.tsx} +9 -2
  115. package/src/app/[variants]/(main)/discover/_layout/Desktop/index.tsx +4 -4
  116. package/src/app/[variants]/(main)/discover/_layout/Mobile/index.tsx +3 -3
  117. package/src/app/[variants]/(main)/discover/components/Title.tsx +1 -1
  118. package/src/app/[variants]/(main)/discover/features/Search.tsx +2 -2
  119. package/src/app/[variants]/(main)/discover/features/useNav.tsx +11 -12
  120. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +40 -0
  121. package/src/app/[variants]/(main)/hooks/usePathname.ts +10 -0
  122. package/src/app/[variants]/(main)/hooks/useQuery.ts +12 -0
  123. package/src/app/[variants]/(main)/hooks/useRouter.ts +22 -0
  124. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +11 -0
  125. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/index.tsx +5 -5
  126. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicUrlSync.tsx +1 -1
  127. package/src/app/[variants]/(main)/image/ComingSoon.tsx +15 -0
  128. package/src/app/[variants]/(main)/image/_layout/Desktop/index.tsx +5 -2
  129. package/src/app/[variants]/(main)/image/_layout/DesktopWrapper.tsx +15 -0
  130. package/src/app/[variants]/(main)/image/_layout/Mobile/index.tsx +3 -1
  131. package/src/app/[variants]/(main)/image/features/ImageWorkspace/index.tsx +1 -2
  132. package/src/app/[variants]/(main)/image/index.tsx +18 -0
  133. package/src/app/[variants]/(main)/knowledge/_layout/Desktop.tsx +17 -0
  134. package/src/app/[variants]/(main)/knowledge/_layout/Mobile.tsx +17 -0
  135. package/src/app/[variants]/(main)/knowledge/components/KnowledgeBaseItem/index.tsx +1 -1
  136. package/src/app/[variants]/(main)/knowledge/components/modal/ModalPageClient.tsx +4 -4
  137. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeBaseDetail/index.tsx +5 -8
  138. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeBaseDetail/menu/Head.tsx +1 -1
  139. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeHome/menu/CategoryMenu.tsx +2 -2
  140. package/src/app/[variants]/(main)/knowledge/routes/KnowledgeHome/menu/KnowledgeBase.tsx +1 -1
  141. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/DesktopLayoutContainer.tsx +3 -2
  142. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/BottomActions.tsx +4 -4
  143. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/TopActions.test.tsx +9 -9
  144. package/src/app/[variants]/(main)/layouts/desktop/SideBar/TopActions.tsx +117 -0
  145. package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/index.tsx +9 -4
  146. package/src/app/[variants]/(main)/layouts/index.tsx +11 -0
  147. package/src/app/[variants]/(main)/{_layout/Mobile → layouts/mobile}/NavBar.tsx +5 -5
  148. package/src/app/[variants]/(main)/{_layout/Mobile → layouts/mobile}/index.tsx +10 -7
  149. package/src/app/[variants]/(main)/profile/(home)/desktop.tsx +26 -0
  150. package/src/app/[variants]/(main)/profile/(home)/index.tsx +26 -0
  151. package/src/app/[variants]/(main)/profile/@category/features/CategoryContent.tsx +5 -7
  152. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +3 -2
  153. package/src/app/[variants]/(main)/profile/_layout/DesktopWrapper.tsx +14 -0
  154. package/src/app/[variants]/(main)/profile/_layout/Mobile/Header.tsx +3 -3
  155. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +4 -3
  156. package/src/app/[variants]/(main)/profile/apikey/index.tsx +18 -0
  157. package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +6 -6
  158. package/src/app/[variants]/(main)/profile/security/index.tsx +29 -0
  159. package/src/app/[variants]/(main)/profile/stats/features/AssistantsRank.tsx +4 -4
  160. package/src/app/[variants]/(main)/profile/stats/features/TopicsRank.tsx +4 -4
  161. package/src/app/[variants]/(main)/profile/stats/index.tsx +20 -0
  162. package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +7 -9
  163. package/src/app/[variants]/(main)/profile/usage/index.tsx +13 -0
  164. package/src/app/[variants]/(main)/settings/_layout/Desktop/Header.tsx +2 -2
  165. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +2 -2
  166. package/src/app/[variants]/(main)/settings/_layout/DesktopWrapper.tsx +23 -0
  167. package/src/app/[variants]/(main)/settings/_layout/Mobile/Header.tsx +8 -7
  168. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +2 -5
  169. package/src/app/[variants]/(main)/settings/_layout/MobileWrapper.tsx +23 -0
  170. package/src/app/[variants]/(main)/settings/agent/AgentMenu/Menu.tsx +2 -4
  171. package/src/app/[variants]/(main)/settings/agent/index.tsx +2 -4
  172. package/src/app/[variants]/(main)/settings/provider/(list)/index.tsx +2 -3
  173. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/All.tsx +2 -2
  174. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +38 -37
  175. package/src/app/[variants]/(main)/settings/provider/_layout/Mobile.tsx +2 -2
  176. package/src/app/[variants]/(main)/settings/provider/features/CreateNewProvider/index.tsx +3 -3
  177. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +3 -3
  178. package/src/app/[variants]/DesktopRouter.tsx +40 -0
  179. package/src/app/[variants]/MobileRouter.tsx +41 -0
  180. package/src/app/[variants]/desktopRouter.config.tsx +364 -0
  181. package/src/app/[variants]/layout.tsx +1 -3
  182. package/src/app/[variants]/loaders/routeParams.ts +45 -0
  183. package/src/app/[variants]/loading/Server/Redirect.tsx +1 -1
  184. package/src/app/[variants]/mobileRouter.config.tsx +396 -0
  185. package/src/app/[variants]/page.tsx +17 -6
  186. package/src/app/desktop/devtools/page.tsx +1 -1
  187. package/src/app/desktop/layout.tsx +1 -1
  188. package/src/components/BootErrorBoundary/index.tsx +129 -0
  189. package/src/components/mdx/constants.ts +1 -0
  190. package/src/features/ChangelogModal/index.tsx +3 -3
  191. package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +23 -4
  192. package/src/features/KnowledgeManager/FileExplorer/index.tsx +4 -4
  193. package/src/features/KnowledgeManager/Header/FilesSearchBar.tsx +1 -1
  194. package/src/features/User/UserPanel/PanelContent.tsx +4 -3
  195. package/src/features/User/UserPanel/useMenu.tsx +20 -14
  196. package/src/features/User/__tests__/PanelContent.test.tsx +13 -7
  197. package/src/hooks/useDiscoverTab.ts +2 -2
  198. package/src/hooks/useInterceptingRoutes.test.ts +23 -26
  199. package/src/hooks/useInterceptingRoutes.ts +5 -4
  200. package/src/hooks/usePinnedAgentState.ts +6 -6
  201. package/src/hooks/useQuery.ts +5 -0
  202. package/src/hooks/useQueryParam.ts +322 -0
  203. package/src/hooks/useQueryRoute.test.ts +2 -12
  204. package/src/hooks/useQueryRoute.ts +5 -5
  205. package/src/hooks/useShowMobileWorkspace.ts +1 -1
  206. package/src/hooks/useSwitchSession.ts +4 -3
  207. package/src/layout/GlobalProvider/ImportSettings.tsx +22 -9
  208. package/src/layout/GlobalProvider/StoreInitialization.tsx +9 -1
  209. package/src/locales/default/tool.ts +11 -0
  210. package/src/proxy.ts +13 -1
  211. package/src/services/message/index.ts +11 -2
  212. package/src/store/chat/agents/createAgentExecutors.ts +31 -16
  213. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +218 -0
  214. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +4 -0
  215. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +9 -3
  216. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +142 -61
  217. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +5 -6
  218. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +204 -10
  219. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +45 -182
  220. package/src/store/chat/slices/builtinTool/actions/search.ts +51 -26
  221. package/src/store/chat/slices/message/action.test.ts +182 -33
  222. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +79 -36
  223. package/src/store/chat/slices/message/actions/query.ts +7 -5
  224. package/src/store/chat/slices/message/selectors/dbMessage.ts +11 -4
  225. package/src/store/chat/slices/plugin/action.test.ts +257 -54
  226. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +63 -26
  227. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +52 -19
  228. package/src/store/chat/slices/plugin/actions/publicApi.ts +6 -1
  229. package/src/store/chat/slices/plugin/actions/workflow.ts +17 -6
  230. package/src/store/chat/slices/thread/action.ts +2 -0
  231. package/src/store/global/action.test.ts +3 -3
  232. package/src/store/global/actions/workspacePane.ts +2 -1
  233. package/src/store/global/initialState.ts +10 -2
  234. package/src/store/user/slices/common/action.ts +4 -0
  235. package/src/tools/executionRuntimes.ts +3 -0
  236. package/src/tools/local-system/ExecutionRuntime/index.ts +407 -0
  237. package/src/tools/local-system/Intervention/EditLocalFile/index.tsx +89 -0
  238. package/src/tools/local-system/Intervention/WriteFile/index.tsx +72 -0
  239. package/src/tools/local-system/Intervention/index.ts +4 -0
  240. package/src/tools/local-system/Render/EditLocalFile/index.tsx +67 -0
  241. package/src/tools/local-system/Render/ReadLocalFile/ReadFileView.tsx +53 -78
  242. package/src/tools/local-system/Render/index.ts +2 -0
  243. package/src/tools/local-system/index.ts +1 -0
  244. package/src/tools/local-system/type.ts +4 -3
  245. package/src/app/[variants]/(main)/(mobile)/me/(home)/loading.tsx +0 -38
  246. package/src/app/[variants]/(main)/(mobile)/me/(home)/page.tsx +0 -40
  247. package/src/app/[variants]/(main)/(mobile)/me/profile/loading.tsx +0 -5
  248. package/src/app/[variants]/(main)/(mobile)/me/profile/page.tsx +0 -30
  249. package/src/app/[variants]/(main)/(mobile)/me/settings/loading.tsx +0 -5
  250. package/src/app/[variants]/(main)/(mobile)/me/settings/page.tsx +0 -30
  251. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +0 -106
  252. package/src/app/[variants]/(main)/changelog/layout.tsx +0 -10
  253. package/src/app/[variants]/(main)/changelog/modal/page.tsx +0 -23
  254. package/src/app/[variants]/(main)/changelog/page.tsx +0 -78
  255. package/src/app/[variants]/(main)/chat/ChatRouter.tsx +0 -83
  256. package/src/app/[variants]/(main)/chat/_layout/ChatLayout.tsx +0 -22
  257. package/src/app/[variants]/(main)/chat/components/MainChatPage.tsx +0 -25
  258. package/src/app/[variants]/(main)/chat/error.tsx +0 -3
  259. package/src/app/[variants]/(main)/chat/layout.tsx +0 -10
  260. package/src/app/[variants]/(main)/chat/loading.tsx +0 -3
  261. package/src/app/[variants]/(main)/chat/not-found.tsx +0 -1
  262. package/src/app/[variants]/(main)/chat/page.tsx +0 -12
  263. package/src/app/[variants]/(main)/chat/settings/error.tsx +0 -3
  264. package/src/app/[variants]/(main)/chat/settings/loading.tsx +0 -3
  265. package/src/app/[variants]/(main)/chat/settings/not-found.tsx +0 -1
  266. package/src/app/[variants]/(main)/discover/(detail)/_layout/DetailLayout.tsx +0 -22
  267. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +0 -51
  268. package/src/app/[variants]/(main)/discover/(detail)/mcp/[slug]/Client.tsx +0 -43
  269. package/src/app/[variants]/(main)/discover/(detail)/mcp/[slug]/loading.tsx +0 -1
  270. package/src/app/[variants]/(main)/discover/(detail)/model/[...slugs]/Client.tsx +0 -40
  271. package/src/app/[variants]/(main)/discover/(detail)/model/[...slugs]/loading.tsx +0 -1
  272. package/src/app/[variants]/(main)/discover/(detail)/provider/[...slugs]/Client.tsx +0 -40
  273. package/src/app/[variants]/(main)/discover/(detail)/provider/[...slugs]/loading.tsx +0 -1
  274. package/src/app/[variants]/(main)/discover/(list)/_layout/ListLayout.tsx +0 -22
  275. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantLayout.tsx +0 -21
  276. package/src/app/[variants]/(main)/discover/(list)/mcp/Client.tsx +0 -44
  277. package/src/app/[variants]/(main)/discover/(list)/mcp/McpLayout.tsx +0 -21
  278. package/src/app/[variants]/(main)/discover/(list)/model/Client.tsx +0 -44
  279. package/src/app/[variants]/(main)/discover/(list)/model/ModelLayout.tsx +0 -21
  280. package/src/app/[variants]/(main)/discover/(list)/provider/ProviderPage.tsx +0 -43
  281. package/src/app/[variants]/(main)/discover/DiscoverRouter.tsx +0 -170
  282. package/src/app/[variants]/(main)/discover/[[...path]]/page.tsx +0 -12
  283. package/src/app/[variants]/(main)/discover/_layout/DiscoverLayout.tsx +0 -22
  284. package/src/app/[variants]/(main)/discover/error.tsx +0 -3
  285. package/src/app/[variants]/(main)/discover/not-found.tsx +0 -1
  286. package/src/app/[variants]/(main)/error.tsx +0 -3
  287. package/src/app/[variants]/(main)/image/layout.tsx +0 -15
  288. package/src/app/[variants]/(main)/image/page.tsx +0 -45
  289. package/src/app/[variants]/(main)/knowledge/KnowledgeRouter.tsx +0 -74
  290. package/src/app/[variants]/(main)/knowledge/[[...path]]/page.tsx +0 -12
  291. package/src/app/[variants]/(main)/knowledge/components/modal/page.tsx +0 -13
  292. package/src/app/[variants]/(main)/knowledge/layout.tsx +0 -12
  293. package/src/app/[variants]/(main)/layout.tsx +0 -10
  294. package/src/app/[variants]/(main)/not-found.tsx +0 -1
  295. package/src/app/[variants]/(main)/profile/apikey/page.tsx +0 -32
  296. package/src/app/[variants]/(main)/profile/error.tsx +0 -3
  297. package/src/app/[variants]/(main)/profile/layout.tsx +0 -11
  298. package/src/app/[variants]/(main)/profile/loading.tsx +0 -3
  299. package/src/app/[variants]/(main)/profile/not-found.tsx +0 -1
  300. package/src/app/[variants]/(main)/profile/security/page.tsx +0 -28
  301. package/src/app/[variants]/(main)/profile/stats/page.tsx +0 -23
  302. package/src/app/[variants]/(main)/profile/usage/page.tsx +0 -23
  303. package/src/app/[variants]/@modal/(.)changelog/modal/features/Cover.tsx +0 -48
  304. package/src/app/[variants]/@modal/(.)changelog/modal/features/Hero.tsx +0 -29
  305. package/src/app/[variants]/@modal/(.)changelog/modal/features/Post.tsx +0 -57
  306. package/src/app/[variants]/@modal/(.)changelog/modal/features/PublishedTime.tsx +0 -50
  307. package/src/app/[variants]/@modal/(.)changelog/modal/features/ReadDetail.tsx +0 -72
  308. package/src/app/[variants]/@modal/(.)changelog/modal/features/VersionTag.tsx +0 -26
  309. package/src/app/[variants]/@modal/(.)changelog/modal/layout.tsx +0 -41
  310. package/src/app/[variants]/@modal/(.)changelog/modal/loading.tsx +0 -10
  311. package/src/app/[variants]/@modal/(.)changelog/modal/page.tsx +0 -38
  312. package/src/app/[variants]/@modal/_layout/ModalLayout.tsx +0 -63
  313. package/src/app/[variants]/@modal/_layout/SettingModalLayout.tsx +0 -71
  314. package/src/app/[variants]/@modal/default.tsx +0 -3
  315. package/src/app/[variants]/@modal/error.tsx +0 -3
  316. package/src/app/[variants]/@modal/layout.tsx +0 -7
  317. package/src/app/[variants]/@modal/loading.tsx +0 -5
  318. /package/src/app/[variants]/{@modal/(.)changelog/modal → (main)/changelog}/features/Pagination.tsx +0 -0
  319. /package/src/app/[variants]/{@modal/(.)changelog/modal → (main)/changelog}/features/UpdateChangelogStatus.tsx +0 -0
  320. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  321. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Knowledge.tsx +0 -0
  322. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/KnowledgeItem.tsx +0 -0
  323. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/PluginItem.tsx +0 -0
  324. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/Plugins.tsx +0 -0
  325. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Capabilities/index.tsx +0 -0
  326. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  327. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/Overview/TagList.tsx +0 -0
  328. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Details/SystemRole/TagList.tsx +0 -0
  329. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  330. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/Summary/index.tsx +0 -0
  331. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  332. /package/src/app/[variants]/(main)/discover/(detail)/assistant/{[...slugs]/loading.tsx → loading.tsx} +0 -0
  333. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ActionButton/index.tsx +0 -0
  334. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/ConnectionTypeAlert.tsx +0 -0
  335. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/Related/Item.tsx +0 -0
  336. /package/src/app/[variants]/(main)/discover/(detail)/mcp/{[slug]/features → features}/Sidebar/index.tsx +0 -0
  337. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  338. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  339. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Overview/ProviderList/index.tsx +0 -0
  340. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Details/Parameter/index.tsx +0 -0
  341. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  342. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/RelatedProviders/Item.tsx +0 -0
  343. /package/src/app/[variants]/(main)/discover/(detail)/model/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  344. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/DetailProvider.tsx +0 -0
  345. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Guide/index.tsx +0 -0
  346. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Nav.tsx +0 -0
  347. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Overview/ModelList/index.tsx +0 -0
  348. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Details/Overview/index.tsx +0 -0
  349. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Header.tsx +0 -0
  350. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/Related/Item.tsx +0 -0
  351. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/RelatedModels/Item.tsx +0 -0
  352. /package/src/app/[variants]/(main)/discover/(detail)/provider/{[...slugs]/features → features}/Sidebar/index.tsx +0 -0
  353. /package/src/app/[variants]/(main)/labs/{page.tsx → index.tsx} +0 -0
  354. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/RegisterHotkeys.tsx +0 -0
  355. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/Avatar.test.tsx +0 -0
  356. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/Avatar.tsx +0 -0
  357. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/PinList/index.tsx +0 -0
  358. /package/src/app/[variants]/(main)/{_layout/Desktop → layouts/desktop}/SideBar/index.tsx +0 -0
@@ -23,7 +23,7 @@ const Redirect = memo<RedirectProps>(({ setLoadingStage }) => {
23
23
 
24
24
  const navToChat = () => {
25
25
  setLoadingStage(AppLoadingStage.GoToChat);
26
- router.replace('/chat');
26
+ // router.replace('/chat');
27
27
  };
28
28
 
29
29
  useEffect(() => {
@@ -0,0 +1,396 @@
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import { type LoaderFunction, createBrowserRouter, redirect, useNavigate } from 'react-router-dom';
5
+
6
+ import Loading from '@/components/Loading/BrandTextLoading';
7
+ import { useGlobalStore } from '@/store/global';
8
+ import type { Locales } from '@/types/locale';
9
+
10
+ import { MobileMainLayout } from './(main)/layouts/mobile';
11
+ import { idLoader, slugLoader } from './loaders/routeParams';
12
+
13
+ // Component to register navigate function in global store
14
+ const NavigatorRegistrar = () => {
15
+ const navigate = useNavigate();
16
+
17
+ useEffect(() => {
18
+ useGlobalStore.setState({ navigate });
19
+
20
+ return () => {
21
+ useGlobalStore.setState({ navigate: undefined });
22
+ };
23
+ }, [navigate]);
24
+
25
+ return null;
26
+ };
27
+
28
+ // Root layout wrapper component - just registers navigator and renders outlet
29
+ // Note: Mobile layout is provided by individual route components
30
+ const RootLayout = (props: { locale: Locales }) => (
31
+ <>
32
+ <NavigatorRegistrar />
33
+ <MobileMainLayout locale={props.locale} />
34
+ </>
35
+ );
36
+
37
+ // Hydration gate loader - waits for client state to be ready before rendering
38
+ const hydrationGateLoader: LoaderFunction = () => {
39
+ const { isAppHydrated } = useGlobalStore.getState();
40
+
41
+ // 如果状态已经就绪,直接放行
42
+ if (isAppHydrated) {
43
+ return null;
44
+ }
45
+
46
+ // 否则,返回一个 Promise,"暂停" 渲染
47
+ return new Promise((resolve) => {
48
+ console.log('[HydrationGate] Waiting for client state...');
49
+ // 订阅 useGlobalStore 的变化
50
+ const unsubscribe = useGlobalStore.subscribe((state) => {
51
+ if (state.isAppHydrated) {
52
+ console.log('[HydrationGate] Client state ready. Gate opened!');
53
+ unsubscribe(); // 清理订阅
54
+ resolve(null); // Promise 完成,门卫放行
55
+ }
56
+ });
57
+ });
58
+ };
59
+
60
+ // Create mobile router configuration
61
+ export const createMobileRouter = (locale: Locales) =>
62
+ createBrowserRouter([
63
+ {
64
+ HydrateFallback: () => <Loading />,
65
+ children: [
66
+ // Chat routes
67
+ {
68
+ children: [
69
+ {
70
+ index: true,
71
+ lazy: () =>
72
+ import('./(main)/chat/index').then((m) => ({
73
+ Component: m.MobileChatPage,
74
+ })),
75
+ },
76
+ {
77
+ lazy: () =>
78
+ import('./(main)/chat/settings').then((m) => ({
79
+ Component: m.default,
80
+ })),
81
+ path: 'settings',
82
+ },
83
+ ],
84
+ lazy: () =>
85
+ import('./(main)/chat/_layout/Mobile').then((m) => ({
86
+ Component: m.default,
87
+ })),
88
+ path: 'chat',
89
+ },
90
+
91
+ // Discover routes with nested structure
92
+ {
93
+ children: [
94
+ // List routes (with ListLayout)
95
+ {
96
+ children: [
97
+ {
98
+ index: true,
99
+ lazy: () =>
100
+ import('./(main)/discover/(list)/(home)/index').then((m) => ({
101
+ Component: m.MobileHomePage,
102
+ })),
103
+ },
104
+ {
105
+ children: [
106
+ {
107
+ lazy: () =>
108
+ import('./(main)/discover/(list)/assistant/index').then((m) => ({
109
+ Component: m.MobileAssistantPage,
110
+ })),
111
+ path: 'assistant',
112
+ },
113
+ ],
114
+ lazy: () =>
115
+ import('./(main)/discover/(list)/assistant/_layout/Mobile').then((m) => ({
116
+ Component: m.default,
117
+ })),
118
+ },
119
+ {
120
+ children: [
121
+ {
122
+ lazy: () =>
123
+ import('./(main)/discover/(list)/model/index').then((m) => ({
124
+ Component: m.MobileModelPage,
125
+ })),
126
+ path: 'model',
127
+ },
128
+ ],
129
+ lazy: () =>
130
+ import('./(main)/discover/(list)/model/_layout/Mobile').then((m) => ({
131
+ Component: m.default,
132
+ })),
133
+ },
134
+ {
135
+ lazy: () =>
136
+ import('./(main)/discover/(list)/provider/index').then((m) => ({
137
+ Component: m.MobileProviderPage,
138
+ })),
139
+ path: 'provider',
140
+ },
141
+ {
142
+ children: [
143
+ {
144
+ lazy: () =>
145
+ import('./(main)/discover/(list)/mcp/index').then((m) => ({
146
+ Component: m.MobileMcpPage,
147
+ })),
148
+ path: 'mcp',
149
+ },
150
+ ],
151
+ lazy: () =>
152
+ import('./(main)/discover/(list)/mcp/_layout/Mobile').then((m) => ({
153
+ Component: m.default,
154
+ })),
155
+ },
156
+ ],
157
+ lazy: () =>
158
+ import('./(main)/discover/(list)/_layout/Mobile/index').then((m) => ({
159
+ Component: m.default,
160
+ })),
161
+ },
162
+ // Detail routes (with DetailLayout)
163
+ {
164
+ children: [
165
+ {
166
+ lazy: () =>
167
+ import('./(main)/discover/(detail)/assistant/index').then((m) => ({
168
+ Component: m.MobileDiscoverAssistantDetailPage,
169
+ })),
170
+ loader: slugLoader,
171
+ path: 'assistant/:slug',
172
+ },
173
+ {
174
+ lazy: () =>
175
+ import('./(main)/discover/(detail)/model/index').then((m) => ({
176
+ Component: m.MobileModelPage,
177
+ })),
178
+ loader: slugLoader,
179
+ path: 'model/:slug',
180
+ },
181
+ {
182
+ lazy: () =>
183
+ import('./(main)/discover/(detail)/provider/index').then((m) => ({
184
+ Component: m.MobileProviderPage,
185
+ })),
186
+ loader: slugLoader,
187
+ path: 'provider/:slug',
188
+ },
189
+ {
190
+ lazy: () =>
191
+ import('./(main)/discover/(detail)/mcp/index').then((m) => ({
192
+ Component: m.MobileMcpPage,
193
+ })),
194
+ loader: slugLoader,
195
+ path: 'mcp/:slug',
196
+ },
197
+ ],
198
+ lazy: () =>
199
+ import('./(main)/discover/(detail)/_layout/Mobile/index').then((m) => ({
200
+ Component: m.default,
201
+ })),
202
+ },
203
+ ],
204
+ lazy: () =>
205
+ import('./(main)/discover/_layout/Mobile/index').then((m) => ({
206
+ Component: m.default,
207
+ })),
208
+ path: 'discover',
209
+ },
210
+
211
+ // Knowledge routes
212
+ {
213
+ children: [
214
+ {
215
+ index: true,
216
+ lazy: () =>
217
+ import('./(main)/knowledge/routes/KnowledgeHome').then((m) => ({
218
+ Component: m.default,
219
+ })),
220
+ },
221
+ {
222
+ lazy: () =>
223
+ import('./(main)/knowledge/routes/KnowledgeBasesList').then((m) => ({
224
+ Component: m.default,
225
+ })),
226
+ path: 'bases',
227
+ },
228
+ {
229
+ lazy: () =>
230
+ import('./(main)/knowledge/routes/KnowledgeBaseDetail').then((m) => ({
231
+ Component: m.default,
232
+ })),
233
+ loader: idLoader,
234
+ path: 'bases/:id',
235
+ },
236
+ ],
237
+ lazy: () =>
238
+ import('./(main)/knowledge/_layout/Mobile').then((m) => ({
239
+ Component: m.default,
240
+ })),
241
+ path: 'knowledge',
242
+ },
243
+
244
+ // Settings routes
245
+ {
246
+ children: [
247
+ {
248
+ index: true,
249
+ lazy: () =>
250
+ import('./(main)/settings/_layout/Mobile').then((m) => ({
251
+ Component: m.default,
252
+ })),
253
+ },
254
+ ],
255
+ lazy: () =>
256
+ import('./(main)/settings/_layout/MobileWrapper').then((m) => ({
257
+ Component: m.default,
258
+ })),
259
+ path: 'settings',
260
+ },
261
+
262
+ // Image routes
263
+ {
264
+ children: [
265
+ {
266
+ index: true,
267
+ lazy: () =>
268
+ import('./(main)/image/ComingSoon').then((m) => ({
269
+ Component: m.default,
270
+ })),
271
+ },
272
+ ],
273
+ lazy: () =>
274
+ import('./(main)/image/_layout/Mobile').then((m) => ({
275
+ Component: m.default,
276
+ })),
277
+ path: 'image',
278
+ },
279
+
280
+ // Labs routes
281
+ {
282
+ lazy: () =>
283
+ import('./(main)/labs').then((m) => ({
284
+ Component: m.default,
285
+ })),
286
+ path: 'labs',
287
+ },
288
+
289
+ // Profile routes
290
+ {
291
+ children: [
292
+ {
293
+ index: true,
294
+ lazy: () =>
295
+ import('./(main)/profile/(home)').then((m) => ({
296
+ Component: m.default,
297
+ })),
298
+ },
299
+ {
300
+ lazy: () =>
301
+ import('./(main)/profile/apikey/index').then((m) => ({
302
+ Component: m.default,
303
+ })),
304
+ path: 'apikey',
305
+ },
306
+ {
307
+ lazy: () =>
308
+ import('./(main)/profile/security').then((m) => ({
309
+ Component: m.MobileProfileSecurityPage,
310
+ })),
311
+ path: 'security',
312
+ },
313
+ {
314
+ lazy: () =>
315
+ import('./(main)/profile/stats').then((m) => ({
316
+ Component: m.MobileProfileStatsPage,
317
+ })),
318
+ path: 'stats',
319
+ },
320
+ ],
321
+ lazy: () =>
322
+ import('./(main)/profile/_layout/Mobile').then((m) => ({
323
+ Component: m.default,
324
+ })),
325
+ path: 'profile',
326
+ },
327
+
328
+ // Me routes (mobile personal center)
329
+ {
330
+ children: [
331
+ {
332
+ children: [
333
+ {
334
+ index: true,
335
+ lazy: () =>
336
+ import('./(main)/(mobile)/me/(home)').then((m) => ({
337
+ Component: m.default,
338
+ })),
339
+ },
340
+ ],
341
+ lazy: () =>
342
+ import('./(main)/(mobile)/me/(home)/layout').then((m) => ({
343
+ Component: m.default,
344
+ })),
345
+ },
346
+ {
347
+ children: [
348
+ {
349
+ lazy: () =>
350
+ import('./(main)/(mobile)/me/profile').then((m) => ({
351
+ Component: m.default,
352
+ })),
353
+ path: 'profile',
354
+ },
355
+ ],
356
+ lazy: () =>
357
+ import('./(main)/(mobile)/me/profile/layout').then((m) => ({
358
+ Component: m.default,
359
+ })),
360
+ },
361
+ {
362
+ children: [
363
+ {
364
+ lazy: () =>
365
+ import('./(main)/(mobile)/me/settings').then((m) => ({
366
+ Component: m.default,
367
+ })),
368
+ path: 'settings',
369
+ },
370
+ ],
371
+ lazy: () =>
372
+ import('./(main)/(mobile)/me/settings/layout').then((m) => ({
373
+ Component: m.default,
374
+ })),
375
+ },
376
+ ],
377
+ path: 'me',
378
+ },
379
+
380
+ // Default route - redirect to chat
381
+ {
382
+ index: true,
383
+ loader: () => redirect('/chat', { status: 302 }),
384
+ },
385
+
386
+ // Catch-all route
387
+ {
388
+ loader: () => redirect('/chat', { status: 302 }),
389
+ path: '*',
390
+ },
391
+ ],
392
+ element: <RootLayout locale={locale} />,
393
+ loader: hydrationGateLoader,
394
+ path: '/',
395
+ },
396
+ ]);
@@ -1,9 +1,20 @@
1
- import { Metadata } from 'next';
1
+ import { DynamicLayoutProps } from '@/types/next';
2
+ import { RouteVariants } from '@/utils/server/routeVariants';
2
3
 
3
- import { getCanonicalUrl } from '@/server/utils/url';
4
+ import DesktopRouter from './DesktopRouter';
5
+ import MobileRouter from './MobileRouter';
4
6
 
5
- export const metadata: Metadata = {
6
- alternates: { canonical: getCanonicalUrl('/') },
7
- };
7
+ export default async (props: DynamicLayoutProps) => {
8
+ // Get isMobile from variants parameter on server side
9
+ const isMobile = await RouteVariants.getIsMobile(props);
10
+ const { locale } = await RouteVariants.getVariantsFromProps(props);
11
+
12
+ // Conditionally load and render based on device type
13
+ // Using native dynamic import ensures complete code splitting
14
+ // Mobile and Desktop bundles will be completely separate
15
+ if (isMobile) {
16
+ return <MobileRouter locale={locale} />;
17
+ }
8
18
 
9
- export { default } from './loading';
19
+ return <DesktopRouter locale={locale} />;
20
+ };
@@ -86,4 +86,4 @@ const DevTools = memo(() => {
86
86
  );
87
87
  });
88
88
 
89
- export default DevTools;
89
+ export default DevTools;
@@ -28,4 +28,4 @@ const RootLayout = async ({ children }: RootLayoutProps) => {
28
28
  );
29
29
  };
30
30
 
31
- export default RootLayout;
31
+ export default RootLayout;
@@ -0,0 +1,129 @@
1
+ 'use client';
2
+
3
+ import { Component, ErrorInfo, ReactNode } from 'react';
4
+
5
+ interface BootErrorBoundaryProps {
6
+ children: ReactNode;
7
+ fallback?: ReactNode;
8
+ /**
9
+ * Number of hard reload attempts we should try before giving up.
10
+ * Defaults to 1 to avoid reload loops.
11
+ */
12
+ maxBootReloads?: number;
13
+ }
14
+
15
+ interface BootErrorBoundaryState {
16
+ hasError: boolean;
17
+ }
18
+
19
+ const DEFAULT_MAX_RELOADS = 1;
20
+ const RELOAD_SESSION_KEY = 'lobe:boot:hard-reload-attempts';
21
+ const FORCE_RELOAD_QUERY_KEY = '__lobe_force_reload';
22
+
23
+ /**
24
+ * BootErrorBoundary guards the SPA bootstrap process. If we hit an error before
25
+ * the first successful render, we force a one-time hard refresh to pull the
26
+ * latest assets (similar to Cmd+Shift+R) to recover from cache mismatches.
27
+ */
28
+ class BootErrorBoundary extends Component<BootErrorBoundaryProps, BootErrorBoundaryState> {
29
+ public state: BootErrorBoundaryState = { hasError: false };
30
+
31
+ private hasBooted = false;
32
+
33
+ public componentDidMount() {
34
+ this.hasBooted = true;
35
+ this.resetReloadAttempts();
36
+ this.cleanForceReloadMarker();
37
+ }
38
+
39
+ public static getDerivedStateFromError(): BootErrorBoundaryState {
40
+ return { hasError: true };
41
+ }
42
+
43
+ public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
44
+ // eslint-disable-next-line no-console
45
+ console.error('Unexpected boot error captured by BootErrorBoundary', error, errorInfo);
46
+
47
+ if (!this.hasBooted && this.tryHardReload()) {
48
+ return;
49
+ }
50
+ }
51
+
52
+ public render() {
53
+ if (this.state.hasError) {
54
+ return this.props.fallback ?? null;
55
+ }
56
+
57
+ return this.props.children;
58
+ }
59
+
60
+ private resetReloadAttempts() {
61
+ if (typeof window === 'undefined') return;
62
+ try {
63
+ window.sessionStorage.removeItem(RELOAD_SESSION_KEY);
64
+ } catch (error) {
65
+ // Access to sessionStorage can fail in restricted environments; ignore.
66
+ if (process.env.NODE_ENV === 'development') {
67
+ // eslint-disable-next-line no-console
68
+ console.warn('BootErrorBoundary failed to reset reload attempts', error);
69
+ }
70
+ }
71
+ }
72
+
73
+ private tryHardReload() {
74
+ if (typeof window === 'undefined') return false;
75
+
76
+ try {
77
+ const maxReloads = this.props.maxBootReloads ?? DEFAULT_MAX_RELOADS;
78
+ const attempts = Number(window.sessionStorage.getItem(RELOAD_SESSION_KEY) ?? '0');
79
+ const href = window.location.href;
80
+
81
+ if (attempts >= maxReloads) {
82
+ // eslint-disable-next-line no-console
83
+ console.warn('BootErrorBoundary reached max reload attempts', {
84
+ attempts,
85
+ href,
86
+ maxReloads,
87
+ });
88
+ return false;
89
+ }
90
+
91
+ // eslint-disable-next-line no-console
92
+ console.info('BootErrorBoundary forcing hard reload', { attempts, href, maxReloads });
93
+ window.sessionStorage.setItem(RELOAD_SESSION_KEY, String(attempts + 1));
94
+ } catch (error) {
95
+ // If sessionStorage is unavailable, we still attempt a reload once.
96
+ if (process.env.NODE_ENV === 'development') {
97
+ // eslint-disable-next-line no-console
98
+ console.warn('BootErrorBoundary failed to persist reload attempts', error);
99
+ }
100
+ }
101
+
102
+ this.forceHardReload();
103
+ return true;
104
+ }
105
+
106
+ private forceHardReload() {
107
+ const { location } = window;
108
+
109
+ // Append a cache-busting query parameter so the browser bypasses cached assets.
110
+ const url = new URL(location.href);
111
+ url.searchParams.set(FORCE_RELOAD_QUERY_KEY, Date.now().toString());
112
+
113
+ location.replace(url.toString());
114
+ }
115
+
116
+ private cleanForceReloadMarker() {
117
+ if (typeof window === 'undefined') return;
118
+ const { history, location } = window;
119
+
120
+ const url = new URL(location.href);
121
+
122
+ if (!url.searchParams.has(FORCE_RELOAD_QUERY_KEY)) return;
123
+
124
+ url.searchParams.delete(FORCE_RELOAD_QUERY_KEY);
125
+ history.replaceState(history.state, '', url.toString());
126
+ }
127
+ }
128
+
129
+ export default BootErrorBoundary;
@@ -0,0 +1 @@
1
+ export const DEFAULT_IMAGE_WIDTH = 800;
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
 
3
3
  import { useTimeout } from 'ahooks';
4
- import { useRouter } from 'next/navigation';
5
4
  import { memo } from 'react';
5
+ import { useNavigate } from 'react-router-dom';
6
6
 
7
7
  import { useGlobalStore } from '@/store/global';
8
8
 
@@ -11,14 +11,14 @@ const ChangelogModal = memo<{ currentId?: string }>(({ currentId }) => {
11
11
  s.status.latestChangelogId,
12
12
  s.updateSystemStatus,
13
13
  ]);
14
- const router = useRouter();
14
+ const navigate = useNavigate();
15
15
 
16
16
  useTimeout(() => {
17
17
  if (!currentId) return;
18
18
  if (!latestChangelogId) {
19
19
  updateSystemStatus({ latestChangelogId: currentId });
20
20
  } else if (latestChangelogId !== currentId) {
21
- router.push('/changelog/modal');
21
+ navigate('/changelog/modal');
22
22
  }
23
23
  }, 1000);
24
24
 
@@ -11,7 +11,7 @@ import {
11
11
  Trash2,
12
12
  X,
13
13
  } from 'lucide-react';
14
- import { CSSProperties, memo, useState } from 'react';
14
+ import { CSSProperties, memo, useEffect, useState } from 'react';
15
15
  import { useTranslation } from 'react-i18next';
16
16
  import { Flexbox } from 'react-layout-kit';
17
17
 
@@ -97,7 +97,6 @@ const Inspectors = memo<InspectorProps>(
97
97
  apiName,
98
98
  id,
99
99
  arguments: requestArgs,
100
- showRender,
101
100
  result,
102
101
  setShowRender,
103
102
  showPluginRender,
@@ -109,6 +108,8 @@ const Inspectors = memo<InspectorProps>(
109
108
  const { styles, theme } = useStyles();
110
109
 
111
110
  const [showDebug, setShowDebug] = useState(false);
111
+ const [isPinned, setIsPinned] = useState(false);
112
+ const [isHovered, setIsHovered] = useState(false);
112
113
 
113
114
  const [deleteAssistantMessage] = useChatStore((s) => [s.deleteAssistantMessage]);
114
115
 
@@ -121,7 +122,15 @@ const Inspectors = memo<InspectorProps>(
121
122
  const isReject = intervention?.status === 'rejected';
122
123
  const isTitleLoading = !hasResult && !isPending;
123
124
 
124
- const showCustomPluginRender = showRender && !isPending && !isReject;
125
+ // Compute actual render state based on pinned or hovered
126
+ const shouldShowRender = isPinned || isHovered;
127
+
128
+ // Sync with parent state
129
+ useEffect(() => {
130
+ setShowRender(shouldShowRender);
131
+ }, [shouldShowRender, setShowRender]);
132
+
133
+ const showCustomPluginRender = shouldShowRender && !isPending && !isReject;
125
134
  return (
126
135
  <Flexbox className={styles.container} gap={4}>
127
136
  <Flexbox align={'center'} distribution={'space-between'} gap={8} horizontal>
@@ -131,7 +140,17 @@ const Inspectors = memo<InspectorProps>(
131
140
  gap={8}
132
141
  horizontal
133
142
  onClick={() => {
134
- setShowRender(!showRender);
143
+ setIsPinned(!isPinned);
144
+ }}
145
+ onMouseEnter={() => {
146
+ if (!isPinned) {
147
+ setIsHovered(true);
148
+ }
149
+ }}
150
+ onMouseLeave={() => {
151
+ if (!isPinned) {
152
+ setIsHovered(false);
153
+ }
135
154
  }}
136
155
  paddingInline={4}
137
156
  >
@@ -3,13 +3,13 @@
3
3
  import { Text } from '@lobehub/ui';
4
4
  import { VirtuosoMasonry } from '@virtuoso.dev/masonry';
5
5
  import { createStyles } from 'antd-style';
6
- import { useQueryState } from 'nuqs';
7
6
  import { rgba } from 'polished';
8
7
  import React, { memo, useMemo, useState } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import { Center, Flexbox } from 'react-layout-kit';
11
10
  import { Virtuoso } from 'react-virtuoso';
12
11
 
12
+ import { useQueryState } from '@/hooks/useQueryParam';
13
13
  import { useFileStore } from '@/store/file';
14
14
  import { useGlobalStore } from '@/store/global';
15
15
  import { FilesTabs, SortType } from '@/types/files';
@@ -113,9 +113,9 @@ const FileExplorer = memo<FileExplorerProps>(({ knowledgeBaseId, category, onOpe
113
113
  const { data, isLoading } = useFetchKnowledgeItems({
114
114
  category,
115
115
  knowledgeBaseId,
116
- q: query,
117
- sortType,
118
- sorter,
116
+ q: query ?? undefined,
117
+ sortType: sortType ?? undefined,
118
+ sorter: sorter ?? undefined,
119
119
  ...viewConfig,
120
120
  });
121
121