@lobehub/lobehub 2.0.0-next.294 → 2.0.0-next.295

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 (170) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +0 -1
  3. package/apps/desktop/src/main/__mocks__/setup.ts +0 -1
  4. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -4
  5. package/apps/desktop/tsconfig.json +4 -10
  6. package/changelog/v1.json +9 -0
  7. package/e2e/scripts/setup.ts +45 -32
  8. package/package.json +1 -1
  9. package/packages/database/src/models/__tests__/knowledgeBase.test.ts +1 -1
  10. package/packages/database/src/repositories/knowledge/index.ts +1 -4
  11. package/packages/types/src/discover/assistants.ts +2 -2
  12. package/scripts/migrate-spa-navigation.ts +129 -0
  13. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-topics/route.ts +112 -109
  14. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-user-topics/route.ts +125 -113
  15. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-users/route.ts +74 -65
  16. package/src/app/[variants]/(auth)/auth-error/page.tsx +1 -1
  17. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
  18. package/src/app/[variants]/(auth)/next-auth/error/AuthErrorPage.tsx +1 -1
  19. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +1 -1
  20. package/src/app/[variants]/(auth)/oauth/callback/error/page.tsx +1 -1
  21. package/src/app/[variants]/(auth)/oauth/callback/success/page.tsx +1 -1
  22. package/src/app/[variants]/(auth)/oauth/consent/[uid]/page.tsx +1 -1
  23. package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
  24. package/src/app/[variants]/(auth)/reset-password/page.tsx +2 -2
  25. package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
  26. package/src/app/[variants]/(auth)/signin/useSignIn.ts +1 -1
  27. package/src/app/[variants]/(auth)/signup/[[...signup]]/BetterAuthSignUpForm.tsx +2 -2
  28. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
  29. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +1 -1
  30. package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
  31. package/src/app/[variants]/(auth)/verify-email/page.tsx +2 -2
  32. package/src/app/[variants]/(main)/_layout/index.tsx +1 -1
  33. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/CronTopicGroup.tsx +1 -1
  34. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/AddTopicButon.tsx +1 -1
  35. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
  36. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  37. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  38. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +1 -1
  39. package/src/app/[variants]/(main)/agent/features/TelemetryNotification.tsx +2 -3
  40. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Nav.tsx +9 -9
  41. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -3
  42. package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +1 -2
  43. package/src/app/[variants]/(main)/community/(detail)/features/ShareButton.tsx +2 -3
  44. package/src/app/[variants]/(main)/community/(detail)/features/Toc/Heading.tsx +2 -3
  45. package/src/app/[variants]/(main)/community/(detail)/mcp/features/Details/Versions/index.tsx +2 -2
  46. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Nav.tsx +12 -11
  47. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Parameter/ParameterItem.tsx +2 -3
  48. package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +11 -10
  49. package/src/app/[variants]/(main)/community/(detail)/provider/features/Header.tsx +10 -9
  50. package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +1 -1
  51. package/src/app/[variants]/(main)/community/(list)/assistant/features/Category/useCategory.tsx +1 -1
  52. package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +2 -3
  53. package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +1 -1
  54. package/src/app/[variants]/(main)/community/features/CreateButton/Inner.tsx +1 -1
  55. package/src/app/[variants]/(main)/community/features/CreateButton/index.tsx +1 -1
  56. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -2
  57. package/src/app/[variants]/(main)/community/features/Title.tsx +5 -5
  58. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +1 -1
  59. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  60. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  61. package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +1 -1
  62. package/src/app/[variants]/(main)/group/features/TelemetryNotification.tsx +2 -3
  63. package/src/app/[variants]/(main)/home/_layout/Body/Agent/AllAgentsDrawer/index.tsx +1 -1
  64. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +6 -11
  65. package/src/app/[variants]/(main)/image/NotSupportClient.tsx +4 -3
  66. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ImageUpload.tsx +1 -1
  67. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +1 -1
  68. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +1 -1
  69. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +1 -1
  70. package/src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx +1 -1
  71. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +1 -1
  72. package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/index.tsx +1 -1
  73. package/src/app/[variants]/(main)/settings/about/features/ItemCard.tsx +2 -3
  74. package/src/app/[variants]/(main)/settings/about/features/ItemLink.tsx +2 -3
  75. package/src/app/[variants]/(main)/settings/about/features/Version.tsx +6 -7
  76. package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +1 -1
  77. package/src/app/[variants]/(main)/settings/features/UpgradeAlert.tsx +4 -4
  78. package/src/app/[variants]/(main)/settings/provider/(list)/Footer.tsx +2 -2
  79. package/src/app/[variants]/(main)/settings/provider/detail/index.tsx +1 -1
  80. package/src/app/[variants]/(main)/settings/provider/detail/ollama/CheckError.tsx +1 -1
  81. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +12 -6
  82. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
  83. package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/ShareModal.tsx +1 -1
  84. package/src/app/[variants]/(main)/settings/stats/features/rankings/AssistantsRank.tsx +1 -1
  85. package/src/app/[variants]/(main)/settings/stats/features/rankings/TopicsRank.tsx +1 -1
  86. package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
  87. package/src/app/[variants]/(mobile)/chat/settings/features/AgentInfoDescription/index.tsx +1 -1
  88. package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +1 -1
  89. package/src/app/[variants]/(mobile)/router/index.tsx +1 -1
  90. package/src/app/[variants]/page.tsx +1 -1
  91. package/src/app/[variants]/router/index.tsx +1 -1
  92. package/src/components/404/index.tsx +4 -4
  93. package/src/components/Analytics/index.tsx +1 -1
  94. package/src/components/BrandWatermark/index.tsx +4 -4
  95. package/src/components/Branding/ProductLogo/Custom.tsx +1 -1
  96. package/src/components/Error/index.tsx +3 -4
  97. package/src/components/GoBack/index.tsx +2 -2
  98. package/src/components/LabsModal/LabCard.tsx +1 -1
  99. package/src/components/Link.tsx +25 -5
  100. package/src/components/OllamaSetupGuide/index.tsx +5 -4
  101. package/src/components/WebFavicon/index.tsx +1 -1
  102. package/src/components/client/ClientResponsiveContent/index.tsx +1 -1
  103. package/src/components/client/ClientResponsiveLayout.tsx +1 -1
  104. package/src/components/mdx/Image.tsx +1 -1
  105. package/src/components/mdx/Link.tsx +26 -9
  106. package/src/features/AlertBanner/CloudBanner.tsx +2 -3
  107. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +8 -7
  108. package/src/features/ChatInput/ActionBar/Params/Controls.tsx +1 -3
  109. package/src/features/ChatInput/ActionBar/Token/index.tsx +1 -1
  110. package/src/features/ChatInput/Mobile/index.tsx +1 -1
  111. package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +1 -1
  112. package/src/features/Conversation/Error/OllamaBizError/index.tsx +1 -1
  113. package/src/features/Conversation/Error/OllamaSetupGuide/Desktop.tsx +1 -2
  114. package/src/features/Conversation/Error/index.tsx +1 -1
  115. package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/Settings.tsx +1 -1
  116. package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +1 -1
  117. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +1 -1
  118. package/src/features/Conversation/Messages/Tool/Tool/index.tsx +1 -1
  119. package/src/features/Conversation/Messages/components/SearchGrounding.tsx +1 -1
  120. package/src/features/DataImporter/Error.tsx +3 -3
  121. package/src/features/DevPanel/CacheViewer/cacheProvider.tsx +2 -1
  122. package/src/features/DevPanel/MetadataViewer/Og.tsx +1 -1
  123. package/src/features/DevPanel/features/FloatPanel.tsx +1 -1
  124. package/src/features/DevPanel/features/Table/TooltipContent.tsx +3 -4
  125. package/src/features/DevPanel/index.tsx +1 -1
  126. package/src/features/EditorCanvas/InlineToolbar.tsx +1 -6
  127. package/src/features/FileViewer/NotSupport/index.tsx +2 -3
  128. package/src/features/Follow/index.tsx +8 -9
  129. package/src/features/LibraryModal/AddFilesToKnowledgeBase/SelectForm.tsx +2 -2
  130. package/src/features/MCP/Scores.tsx +1 -1
  131. package/src/features/MCPPluginDetail/Nav.tsx +8 -8
  132. package/src/features/MCPPluginDetail/Overview/TagList.tsx +1 -1
  133. package/src/features/MobileTabBar/index.tsx +2 -1
  134. package/src/features/OllamaSetupGuide/Desktop.tsx +1 -2
  135. package/src/features/PWAInstall/Install.tsx +1 -1
  136. package/src/features/PWAInstall/index.tsx +1 -1
  137. package/src/features/PluginStore/McpList/index.tsx +1 -1
  138. package/src/features/PluginStore/PluginList/Detail/Header.tsx +6 -6
  139. package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
  140. package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +1 -1
  141. package/src/features/ResourceManager/components/ChunkDrawer/index.tsx +1 -1
  142. package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +26 -26
  143. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +147 -149
  144. package/src/features/ResourceManager/index.tsx +1 -1
  145. package/src/features/Setting/Footer.tsx +4 -5
  146. package/src/features/User/UserPanel/PanelContent.tsx +1 -1
  147. package/src/hooks/useActiveTabKey.ts +6 -3
  148. package/src/hooks/useIsSingleMode.test.ts +10 -24
  149. package/src/hooks/useIsSingleMode.ts +4 -2
  150. package/src/hooks/useIsSubSlug.ts +2 -1
  151. package/src/hooks/useQuery.ts +5 -5
  152. package/src/layout/GlobalProvider/AppTheme.tsx +2 -2
  153. package/src/layout/GlobalProvider/StyleRegistry.tsx +1 -1
  154. package/src/layout/GlobalProvider/useUserStateRedirect.ts +13 -25
  155. package/src/libs/next/Image.tsx +13 -0
  156. package/src/libs/next/Link.tsx +13 -0
  157. package/src/libs/next/dynamic.tsx +13 -0
  158. package/src/libs/next/index.ts +22 -0
  159. package/src/libs/next/navigation.ts +22 -0
  160. package/src/libs/router/Link.tsx +30 -0
  161. package/src/libs/router/index.ts +18 -0
  162. package/src/libs/router/navigation.ts +72 -0
  163. package/src/server/modules/AgentRuntime/AgentStateManager.ts +5 -1
  164. package/src/store/chat/slices/portal/selectors.test.ts +5 -15
  165. package/src/store/page/index.ts +1 -1
  166. package/src/store/page/slices/crud/index.ts +1 -1
  167. package/src/app/[variants]/(main)/hooks/usePathname.ts +0 -10
  168. package/src/app/[variants]/(main)/hooks/useQuery.ts +0 -12
  169. package/src/app/[variants]/(main)/hooks/useRouter.ts +0 -22
  170. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +0 -11
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.295](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.294...v2.0.0-next.295)
6
+
7
+ <sup>Released on **2026-01-15**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Migrate Next.js navigation APIs to React Router for SPA.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Migrate Next.js navigation APIs to React Router for SPA, closes [#11394](https://github.com/lobehub/lobe-chat/issues/11394) ([2253d46](https://github.com/lobehub/lobe-chat/commit/2253d46))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.294](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.293...v2.0.0-next.294)
6
31
 
7
32
  <sup>Released on **2026-01-15**</sup>
@@ -2,7 +2,6 @@
2
2
  * Mock for node-mac-permissions native module
3
3
  * Used in tests since the native module only works on macOS
4
4
  */
5
-
6
5
  import { vi } from 'vitest';
7
6
 
8
7
  export const askForAccessibilityAccess = vi.fn(() => undefined);
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Vitest setup file for mocking native modules
3
3
  */
4
-
5
4
  import { vi } from 'vitest';
6
5
 
7
6
  // Mock node-mac-permissions before any imports
@@ -4,10 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
4
4
  import type { App } from '@/core/App';
5
5
  import type { IpcContext } from '@/utils/ipc';
6
6
  import { IpcHandler } from '@/utils/ipc/base';
7
- import {
8
- __resetMacPermissionsModuleCache,
9
- __setMacPermissionsModule,
10
- } from '@/utils/permissions';
7
+ import { __resetMacPermissionsModuleCache, __setMacPermissionsModule } from '@/utils/permissions';
11
8
 
12
9
  import SystemController from '../SystemCtr';
13
10
 
@@ -15,15 +15,9 @@
15
15
  "moduleResolution": "bundler",
16
16
  "resolveJsonModule": true,
17
17
  "paths": {
18
- "@/*": [
19
- "./src/main/*"
20
- ],
21
- "~common/*": [
22
- "./src/common/*"
23
- ],
24
- "*": [
25
- "./*"
26
- ]
18
+ "@/*": ["./src/main/*"],
19
+ "~common/*": ["./src/common/*"],
20
+ "*": ["./*"]
27
21
  }
28
22
  },
29
23
  "include": [
@@ -33,4 +27,4 @@
33
27
  "electron-builder.js",
34
28
  "native-deps.config.js"
35
29
  ]
36
- }
30
+ }
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Migrate Next.js navigation APIs to React Router for SPA."
6
+ ]
7
+ },
8
+ "date": "2026-01-15",
9
+ "version": "2.0.0-next.295"
10
+ },
2
11
  {
3
12
  "children": {},
4
13
  "date": "2026-01-15",
@@ -16,9 +16,7 @@
16
16
  * --port <port> Server port (default: 3006)
17
17
  * --help Show help message
18
18
  */
19
-
20
- import { type ChildProcess, spawn, spawnSync } from 'node:child_process';
21
- import { existsSync, unlinkSync, writeFileSync } from 'node:fs';
19
+ import { spawn, spawnSync } from 'node:child_process';
22
20
  import { resolve } from 'node:path';
23
21
 
24
22
  // ============================================================================
@@ -33,21 +31,27 @@ const CONFIG = {
33
31
  defaultPort: 3006,
34
32
  dockerImage: 'paradedb/paradedb:latest',
35
33
  projectRoot: resolve(__dirname, '../..'),
36
- serverTimeout: 120_000, // 2 minutes
37
-
38
- // Secrets (for e2e testing only)
39
- secrets: {
40
- betterAuthSecret: 'e2e-test-secret-key-for-better-auth-32chars!',
41
- keyVaultsSecret: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
42
- },
34
+
43
35
 
44
- // S3 Mock (required even if not testing file uploads)
45
- s3Mock: {
36
+ // S3 Mock (required even if not testing file uploads)
37
+ s3Mock: {
46
38
  accessKeyId: 'e2e-mock-access-key',
47
39
  bucket: 'e2e-mock-bucket',
48
40
  endpoint: 'https://e2e-mock-s3.localhost',
49
41
  secretAccessKey: 'e2e-mock-secret-key',
42
+ },
43
+
44
+
45
+
46
+ // 2 minutes
47
+ // Secrets (for e2e testing only)
48
+ secrets: {
49
+ betterAuthSecret: 'e2e-test-secret-key-for-better-auth-32chars!',
50
+ keyVaultsSecret: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
50
51
  },
52
+
53
+
54
+ serverTimeout: 120_000,
51
55
  };
52
56
 
53
57
  // ============================================================================
@@ -55,11 +59,11 @@ const CONFIG = {
55
59
  // ============================================================================
56
60
 
57
61
  const colors = {
58
- cyan: (s: string) => `\x1b[36m${s}\x1b[0m`,
59
- dim: (s: string) => `\x1b[2m${s}\x1b[0m`,
60
- green: (s: string) => `\x1b[32m${s}\x1b[0m`,
61
- red: (s: string) => `\x1b[31m${s}\x1b[0m`,
62
- yellow: (s: string) => `\x1b[33m${s}\x1b[0m`,
62
+ cyan: (s: string) => `\u001B[36m${s}\u001B[0m`,
63
+ dim: (s: string) => `\u001B[2m${s}\u001B[0m`,
64
+ green: (s: string) => `\u001B[32m${s}\u001B[0m`,
65
+ red: (s: string) => `\u001B[31m${s}\u001B[0m`,
66
+ yellow: (s: string) => `\u001B[33m${s}\u001B[0m`,
63
67
  };
64
68
 
65
69
  function log(emoji: string, message: string) {
@@ -73,12 +77,12 @@ function logStep(step: number, total: number, message: string) {
73
77
  function exec(
74
78
  command: string,
75
79
  args: string[] = [],
76
- options: { cwd?: string; silent?: boolean } = {}
80
+ options: { cwd?: string; silent?: boolean } = {},
77
81
  ) {
78
82
  const { cwd = CONFIG.projectRoot, silent = false } = options;
79
83
  const result = spawnSync(command, args, {
80
84
  cwd,
81
- encoding: 'utf-8',
85
+ encoding: 'utf8',
82
86
  shell: true,
83
87
  stdio: silent ? 'pipe' : 'inherit',
84
88
  });
@@ -88,7 +92,7 @@ function exec(
88
92
  function execAsync(
89
93
  command: string,
90
94
  args: string[] = [],
91
- env: Record<string, string> = {}
95
+ env: Record<string, string> = {},
92
96
  ): Promise<void> {
93
97
  return new Promise((resolve, reject) => {
94
98
  const child = spawn(command, args, {
@@ -111,14 +115,16 @@ function execAsync(
111
115
  }
112
116
 
113
117
  async function sleep(ms: number): Promise<void> {
114
- return new Promise((resolve) => setTimeout(resolve, ms));
118
+ return new Promise((resolve) => {
119
+ setTimeout(resolve, ms);
120
+ });
115
121
  }
116
122
 
117
123
  async function waitForCondition(
118
124
  check: () => Promise<boolean>,
119
125
  timeout: number,
120
126
  interval: number = 1000,
121
- onWait?: () => void
127
+ onWait?: () => void,
122
128
  ): Promise<boolean> {
123
129
  const startTime = Date.now();
124
130
  while (Date.now() - startTime < timeout) {
@@ -204,7 +210,7 @@ async function startPostgres(): Promise<void> {
204
210
  },
205
211
  30_000,
206
212
  2000,
207
- () => process.stdout.write('.')
213
+ () => process.stdout.write('.'),
208
214
  );
209
215
 
210
216
  console.log();
@@ -327,7 +333,7 @@ async function startServer(port: number): Promise<void> {
327
333
  () => isServerRunning(port),
328
334
  CONFIG.serverTimeout,
329
335
  2000,
330
- () => process.stdout.write('.')
336
+ () => process.stdout.write('.'),
331
337
  );
332
338
 
333
339
  console.log();
@@ -412,27 +418,34 @@ function parseArgs(): Options {
412
418
  for (let i = 0; i < args.length; i++) {
413
419
  switch (args[i]) {
414
420
  case '--help':
415
- case '-h':
421
+ case '-h': {
416
422
  options.help = true;
417
423
  break;
418
- case '--clean':
424
+ }
425
+ case '--clean': {
419
426
  options.clean = true;
420
427
  break;
421
- case '--skip-db':
428
+ }
429
+ case '--skip-db': {
422
430
  options.skipDb = true;
423
431
  break;
424
- case '--skip-migrate':
432
+ }
433
+ case '--skip-migrate': {
425
434
  options.skipMigrate = true;
426
435
  break;
427
- case '--build':
436
+ }
437
+ case '--build': {
428
438
  options.build = true;
429
439
  break;
430
- case '--start':
440
+ }
441
+ case '--start': {
431
442
  options.start = true;
432
443
  break;
433
- case '--port':
444
+ }
445
+ case '--port': {
434
446
  options.port = parseInt(args[++i], 10) || CONFIG.defaultPort;
435
447
  break;
448
+ }
436
449
  }
437
450
  }
438
451
 
@@ -526,4 +539,4 @@ ${colors.green('✅ E2E environment setup completed!')}
526
539
  }
527
540
  }
528
541
 
529
- main();
542
+ await main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.294",
3
+ "version": "2.0.0-next.295",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
4
4
 
5
5
  import { sleep } from '@/utils/sleep';
6
6
 
7
+ import { getTestDB } from '../../core/getTestDB';
7
8
  import {
8
9
  NewKnowledgeBase,
9
10
  documents,
@@ -15,7 +16,6 @@ import {
15
16
  } from '../../schemas';
16
17
  import { LobeChatDatabase } from '../../type';
17
18
  import { KnowledgeBaseModel } from '../knowledgeBase';
18
- import { getTestDB } from '../../core/getTestDB';
19
19
 
20
20
  const serverDB: LobeChatDatabase = await getTestDB();
21
21
 
@@ -556,10 +556,7 @@ export class KnowledgeRepo {
556
556
  // When in a knowledge base, return standalone documents (folders and notes without fileId)
557
557
  // that have the knowledgeBaseId column set. Documents with fileId are already
558
558
  // returned by the file query via their linked file records.
559
- kbWhereConditions.push(
560
- sql`d.file_id IS NULL`,
561
- sql`d.knowledge_base_id = ${knowledgeBaseId}`,
562
- );
559
+ kbWhereConditions.push(sql`d.file_id IS NULL`, sql`d.knowledge_base_id = ${knowledgeBaseId}`);
563
560
 
564
561
  return sql`
565
562
  SELECT
@@ -18,7 +18,7 @@ export enum AssistantCategory {
18
18
  Marketing = 'marketing',
19
19
  Office = 'office',
20
20
  Programming = 'programming',
21
- Translation = 'translation'
21
+ Translation = 'translation',
22
22
  }
23
23
 
24
24
  export enum AssistantSorts {
@@ -29,7 +29,7 @@ export enum AssistantSorts {
29
29
  PluginCount = 'pluginCount',
30
30
  Recommended = 'recommended',
31
31
  Title = 'title',
32
- TokenUsage = 'tokenUsage'
32
+ TokenUsage = 'tokenUsage',
33
33
  }
34
34
 
35
35
  export enum AssistantNavKey {
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Script to migrate SPA internal components from @/libs/next/navigation
4
+ * to React Router version hooks.
5
+ *
6
+ * For files in (main) directory:
7
+ * - usePathname -> @/app/[variants]/(main)/hooks/usePathname
8
+ * - useSearchParams -> @/app/[variants]/(main)/hooks/useSearchParams
9
+ * - useRouter -> @/app/[variants]/(main)/hooks/useRouter
10
+ *
11
+ * @see RFC 147: LOBE-2850 - Phase 3
12
+ */
13
+
14
+ import { readFile, writeFile } from 'node:fs/promises';
15
+ import { dirname, join, relative } from 'node:path';
16
+ import { fileURLToPath } from 'node:url';
17
+
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+
20
+ // Files that should be migrated to React Router version
21
+ const SPA_FILES = [
22
+ // (main) directory files using @/libs/next/navigation
23
+ 'src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx',
24
+ 'src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx',
25
+ 'src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts',
26
+ 'src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts',
27
+ 'src/app/[variants]/(main)/chat/_layout/Sidebar/Header/AddTopicButon.tsx',
28
+ 'src/app/[variants]/(main)/chat/_layout/Sidebar/Header/Nav.tsx',
29
+ 'src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts',
30
+ 'src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts',
31
+ 'src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx',
32
+ ];
33
+
34
+ interface MigrationResult {
35
+ changes: string[];
36
+ filePath: string;
37
+ }
38
+
39
+ async function migrateFile(relativePath: string): Promise<MigrationResult | null> {
40
+ const fullPath = join(__dirname, '..', relativePath);
41
+ const content = await readFile(fullPath, 'utf8');
42
+ let newContent = content;
43
+ const changes: string[] = [];
44
+
45
+ // Check what hooks are being imported from @/libs/next/navigation
46
+ const importMatch = content.match(
47
+ /import\s*\{([^}]+)\}\s*from\s*['"]@\/libs\/next\/navigation['"]/
48
+ );
49
+
50
+ if (!importMatch) {
51
+ console.log(`⏭️ ${relativePath} - No @/libs/next/navigation import found`);
52
+ return null;
53
+ }
54
+
55
+ const importedHooks = importMatch[1]
56
+ .split(',')
57
+ .map((s) => s.trim())
58
+ .filter(Boolean);
59
+
60
+ console.log(`📝 ${relativePath}`);
61
+ console.log(` Imported hooks: ${importedHooks.join(', ')}`);
62
+
63
+ // Build new imports
64
+ const newImports: string[] = [];
65
+
66
+ for (const hook of importedHooks) {
67
+ if (hook === 'usePathname') {
68
+ newImports.push(`import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';`);
69
+ changes.push('usePathname -> React Router version');
70
+ } else if (hook === 'useSearchParams') {
71
+ newImports.push(
72
+ `import { useSearchParams } from '@/app/[variants]/(main)/hooks/useSearchParams';`
73
+ );
74
+ changes.push('useSearchParams -> React Router version');
75
+ } else if (hook === 'useRouter') {
76
+ newImports.push(`import { useRouter } from '@/app/[variants]/(main)/hooks/useRouter';`);
77
+ changes.push('useRouter -> React Router version');
78
+ } else {
79
+ // Keep other imports (like notFound, redirect) from next/navigation
80
+ console.log(` ⚠️ Unknown hook "${hook}" - keeping original import`);
81
+ }
82
+ }
83
+
84
+ if (newImports.length === 0) {
85
+ console.log(` ⏭️ No hooks to migrate`);
86
+ return null;
87
+ }
88
+
89
+ // Replace the old import with new imports
90
+ newContent = newContent.replace(
91
+ /import\s*\{[^}]+\}\s*from\s*['"]@\/libs\/next\/navigation['"];?\n?/,
92
+ newImports.join('\n') + '\n'
93
+ );
94
+
95
+ if (newContent !== content) {
96
+ await writeFile(fullPath, newContent, 'utf8');
97
+ for (const change of changes) {
98
+ console.log(` ✅ ${change}`);
99
+ }
100
+ return { changes, filePath: relativePath };
101
+ }
102
+
103
+ return null;
104
+ }
105
+
106
+ async function main() {
107
+ console.log('🚀 Starting SPA navigation migration...\n');
108
+
109
+ const results: MigrationResult[] = [];
110
+
111
+ for (const file of SPA_FILES) {
112
+ try {
113
+ const result = await migrateFile(file);
114
+ if (result) {
115
+ results.push(result);
116
+ }
117
+ } catch (error) {
118
+ console.error(`❌ Error processing ${file}:`, error);
119
+ }
120
+ }
121
+
122
+ console.log('\n' + '='.repeat(60));
123
+ console.log(`📊 Migration Summary:`);
124
+ console.log(` - Files processed: ${SPA_FILES.length}`);
125
+ console.log(` - Files modified: ${results.length}`);
126
+ console.log('\n✨ SPA navigation migration complete!');
127
+ }
128
+
129
+ await main();