@lobehub/lobehub 2.0.0-next.344 → 2.0.0-next.346

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 (185) hide show
  1. package/.cursor/rules/i18n.mdc +1 -1
  2. package/.cursor/rules/modal-imperative.mdc +162 -0
  3. package/.cursor/rules/rules-index.mdc +1 -0
  4. package/.env.example +0 -14
  5. package/.eslintrc.js +8 -1
  6. package/CHANGELOG.md +66 -0
  7. package/CLAUDE.md +4 -2
  8. package/Dockerfile +3 -13
  9. package/README.md +3 -5
  10. package/README.zh-CN.md +3 -5
  11. package/changelog/v1.json +20 -0
  12. package/docs/self-hosting/advanced/auth/clerk-to-betterauth.mdx +11 -42
  13. package/docs/self-hosting/advanced/auth/clerk-to-betterauth.zh-CN.mdx +10 -41
  14. package/e2e/src/support/webServer.ts +2 -0
  15. package/locales/ar/error.json +0 -4
  16. package/locales/bg-BG/error.json +0 -4
  17. package/locales/de-DE/error.json +0 -4
  18. package/locales/en-US/error.json +0 -4
  19. package/locales/es-ES/error.json +0 -4
  20. package/locales/fa-IR/error.json +0 -4
  21. package/locales/fr-FR/error.json +0 -4
  22. package/locales/it-IT/error.json +0 -4
  23. package/locales/ja-JP/error.json +0 -4
  24. package/locales/ko-KR/error.json +0 -4
  25. package/locales/nl-NL/error.json +0 -4
  26. package/locales/pl-PL/error.json +0 -4
  27. package/locales/pt-BR/error.json +0 -4
  28. package/locales/ru-RU/error.json +0 -4
  29. package/locales/tr-TR/error.json +0 -4
  30. package/locales/vi-VN/error.json +0 -4
  31. package/locales/zh-CN/error.json +0 -4
  32. package/locales/zh-TW/error.json +0 -4
  33. package/package.json +12 -12
  34. package/packages/builtin-agents/package.json +2 -0
  35. package/packages/builtin-agents/src/agents/agent-builder/index.ts +4 -2
  36. package/packages/builtin-agents/src/agents/group-agent-builder/index.ts +4 -2
  37. package/packages/builtin-agents/src/agents/page-agent/index.ts +5 -2
  38. package/packages/context-engine/src/engine/messages/MessagesEngine.ts +9 -9
  39. package/packages/context-engine/src/providers/GroupContextInjector.ts +19 -33
  40. package/packages/context-engine/src/providers/__tests__/GroupContextInjector.test.ts +79 -43
  41. package/packages/context-engine/src/providers/__tests__/__snapshots__/GroupContextInjector.test.ts.snap +5 -15
  42. package/packages/database/src/repositories/userMemory/__tests__/UserMemoryTopicRepository.test.ts +24 -3
  43. package/packages/file-loaders/package.json +1 -1
  44. package/packages/file-loaders/src/loadFile.ts +10 -15
  45. package/packages/file-loaders/src/loaders/index.ts +68 -19
  46. package/packages/file-loaders/src/loaders/pdf/__snapshots__/index.test.ts.snap +1 -1
  47. package/packages/file-loaders/test/__snapshots__/loaders.test.ts.snap +1 -1
  48. package/packages/model-bank/src/modelProviders/comfyui.ts +0 -1
  49. package/packages/model-bank/src/modelProviders/fal.ts +0 -1
  50. package/packages/types/src/fetch.ts +1 -2
  51. package/packages/utils/src/server/__tests__/auth.test.ts +0 -47
  52. package/packages/utils/src/server/auth.ts +1 -9
  53. package/pnpm-workspace.yaml +1 -0
  54. package/scripts/_shared/checkDeprecatedClerkEnv.js +42 -0
  55. package/scripts/changelogWorkflow/buildStaticChangelog.ts +2 -1
  56. package/scripts/clerk-to-betterauth/_internal/types.ts +53 -20
  57. package/scripts/clerk-to-betterauth/export-clerk-users-with-api.ts +43 -36
  58. package/scripts/countEnWord.ts +1 -1
  59. package/scripts/electronWorkflow/modifiers/appCode.mts +2 -131
  60. package/scripts/i18nWorkflow/protectedPatterns.ts +1 -2
  61. package/scripts/prebuild.mts +10 -8
  62. package/scripts/serverLauncher/startServer.js +23 -5
  63. package/src/app/(backend)/middleware/auth/index.test.ts +8 -4
  64. package/src/app/(backend)/middleware/auth/index.ts +0 -15
  65. package/src/app/(backend)/middleware/auth/utils.test.ts +0 -28
  66. package/src/app/(backend)/middleware/auth/utils.ts +2 -17
  67. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +3 -51
  68. package/src/app/(backend)/webapi/models/[provider]/route.test.ts +8 -4
  69. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +7 -6
  70. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -16
  71. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/index.tsx +1 -1
  72. package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +13 -13
  73. package/src/app/[variants]/(main)/home/features/RecentPage/Item.tsx +2 -2
  74. package/src/app/[variants]/(main)/resource/features/store/action.ts +2 -2
  75. package/src/app/[variants]/(main)/resource/features/store/initialState.ts +2 -2
  76. package/src/app/[variants]/(main)/resource/store/action.ts +2 -2
  77. package/src/app/[variants]/(main)/resource/store/initialState.ts +2 -2
  78. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +3 -21
  79. package/src/app/[variants]/(main)/settings/profile/features/AvatarRow.tsx +1 -2
  80. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -22
  81. package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +12 -14
  82. package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +8 -14
  83. package/src/app/[variants]/(main)/settings/skill/index.tsx +7 -5
  84. package/src/app/[variants]/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +2 -35
  85. package/src/app/[variants]/(mobile)/me/(home)/__tests__/useCategory.test.tsx +0 -20
  86. package/src/app/[variants]/(mobile)/me/(home)/features/UserBanner.tsx +1 -2
  87. package/src/app/[variants]/(mobile)/me/profile/features/Category.tsx +3 -13
  88. package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +2 -3
  89. package/src/app/[variants]/share/t/[id]/_layout/index.tsx +1 -1
  90. package/src/app/[variants]/share/t/[id]/index.tsx +1 -1
  91. package/src/app/robots.tsx +1 -1
  92. package/src/envs/auth.ts +2 -27
  93. package/src/envs/llm.ts +2 -2
  94. package/src/features/AgentSetting/AgentPlugin/index.tsx +9 -12
  95. package/src/features/ChatInput/ActionBar/Tools/index.tsx +7 -5
  96. package/src/features/ChatMiniMap/utils.ts +1 -1
  97. package/src/features/CommandMenu/SearchResults.tsx +1 -1
  98. package/src/features/Conversation/ChatList/components/AutoScroll/DebugInspector.tsx +166 -0
  99. package/src/features/Conversation/ChatList/components/AutoScroll/index.tsx +86 -0
  100. package/src/features/Conversation/ChatList/components/VirtualizedList.tsx +11 -17
  101. package/src/features/Conversation/Messages/AgentCouncil/components/AutoScrollShadow.tsx +25 -14
  102. package/src/features/Conversation/Messages/AgentCouncil/components/CouncilMember.tsx +1 -1
  103. package/src/features/FileViewer/Renderer/PDF/index.tsx +5 -8
  104. package/src/features/IntegrationDetailModal/IntegrationDetailContent.tsx +305 -0
  105. package/src/features/IntegrationDetailModal/index.tsx +21 -283
  106. package/src/features/MCPPluginDetail/Deployment/index.tsx +1 -1
  107. package/src/features/MCPPluginDetail/Schema/Prompts.tsx +1 -1
  108. package/src/features/MCPPluginDetail/Schema/Tools.tsx +1 -1
  109. package/src/features/ProfileEditor/AgentTool.tsx +14 -20
  110. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +0 -8
  111. package/src/features/ResourceManager/components/Explorer/MasonryView/MasonryFileItem/NoteFileItem.tsx +1 -1
  112. package/src/features/ResourceManager/index.tsx +1 -1
  113. package/src/features/ShareModal/SharePdf/PdfPreview.tsx +4 -4
  114. package/src/features/SkillStore/LobeHubList/index.tsx +50 -87
  115. package/src/features/SkillStore/Search/index.tsx +1 -1
  116. package/src/features/SkillStore/{Content.tsx → SkillStoreContent.tsx} +3 -8
  117. package/src/features/SkillStore/index.tsx +15 -33
  118. package/src/features/User/UserPanel/PanelContent.tsx +0 -8
  119. package/src/features/User/__tests__/PanelContent.test.tsx +1 -35
  120. package/src/features/User/__tests__/UserAvatar.test.tsx +30 -57
  121. package/src/features/User/__tests__/useMenu.test.tsx +2 -43
  122. package/src/layout/AuthProvider/index.tsx +0 -5
  123. package/src/libs/next/config/define-config.ts +20 -15
  124. package/src/libs/next/proxy/createRouteMatcher.test.ts +121 -0
  125. package/src/libs/next/proxy/createRouteMatcher.ts +18 -0
  126. package/src/libs/next/proxy/define-config.ts +4 -53
  127. package/src/libs/next-auth/adapter/index.ts +1 -2
  128. package/src/libs/oidc-provider/provider.test.ts +5 -316
  129. package/src/libs/pdfjs/pdf.worker.ts +1 -0
  130. package/src/libs/pdfjs/worker.ts +12 -0
  131. package/src/libs/trpc/lambda/context.test.ts +0 -13
  132. package/src/libs/trpc/lambda/context.ts +3 -22
  133. package/src/libs/trpc/middleware/userAuth.ts +2 -4
  134. package/src/libs/trusted-client/getSessionUser.ts +2 -17
  135. package/src/locales/default/error.ts +0 -6
  136. package/src/locales/default/index.ts +0 -2
  137. package/src/proxy.ts +0 -1
  138. package/src/server/routers/lambda/__tests__/user.test.ts +0 -71
  139. package/src/server/routers/lambda/user.ts +6 -63
  140. package/src/server/services/changelog/index.test.ts +3 -2
  141. package/src/server/services/changelog/index.ts +1 -1
  142. package/src/server/services/user/index.ts +0 -83
  143. package/src/services/chat/index.ts +1 -2
  144. package/src/services/chat/mecha/agentConfigResolver.test.ts +43 -0
  145. package/src/services/chat/mecha/agentConfigResolver.ts +3 -1
  146. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +58 -14
  147. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +10 -2
  148. package/src/store/user/slices/auth/action.test.ts +1 -81
  149. package/src/store/user/slices/auth/action.ts +3 -28
  150. package/src/store/user/slices/auth/initialState.ts +1 -18
  151. package/src/store/user/slices/auth/selectors.test.ts +2 -127
  152. package/src/store/user/slices/auth/selectors.ts +1 -21
  153. package/src/utils/errorResponse.ts +1 -4
  154. package/src/utils/markdownToTxt.ts +20 -0
  155. package/locales/ar/clerk.json +0 -545
  156. package/locales/bg-BG/clerk.json +0 -545
  157. package/locales/de-DE/clerk.json +0 -545
  158. package/locales/en-US/clerk.json +0 -545
  159. package/locales/es-ES/clerk.json +0 -545
  160. package/locales/fa-IR/clerk.json +0 -545
  161. package/locales/fr-FR/clerk.json +0 -545
  162. package/locales/it-IT/clerk.json +0 -545
  163. package/locales/ja-JP/clerk.json +0 -545
  164. package/locales/ko-KR/clerk.json +0 -545
  165. package/locales/nl-NL/clerk.json +0 -545
  166. package/locales/pl-PL/clerk.json +0 -545
  167. package/locales/pt-BR/clerk.json +0 -545
  168. package/locales/ru-RU/clerk.json +0 -545
  169. package/locales/tr-TR/clerk.json +0 -545
  170. package/locales/vi-VN/clerk.json +0 -545
  171. package/locales/zh-CN/clerk.json +0 -545
  172. package/locales/zh-TW/clerk.json +0 -545
  173. package/src/app/(backend)/api/webhooks/clerk/__tests__/fixtures/createUser.json +0 -73
  174. package/src/app/(backend)/api/webhooks/clerk/route.ts +0 -95
  175. package/src/app/(backend)/api/webhooks/clerk/validateRequest.ts +0 -22
  176. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +0 -27
  177. package/src/app/[variants]/(main)/settings/security/features/ClerkProfile.tsx +0 -67
  178. package/src/features/Conversation/ChatList/components/AutoScroll.tsx +0 -25
  179. package/src/layout/AuthProvider/Clerk/UserUpdater.tsx +0 -40
  180. package/src/layout/AuthProvider/Clerk/index.tsx +0 -54
  181. package/src/layout/AuthProvider/Clerk/useAppearance.ts +0 -133
  182. package/src/libs/clerk-auth/index.test.ts +0 -216
  183. package/src/libs/clerk-auth/index.ts +0 -80
  184. package/src/locales/default/clerk.ts +0 -677
  185. package/src/server/services/user/index.test.ts +0 -220
@@ -1,9 +1,7 @@
1
- import { type AuthObject } from '@clerk/backend';
2
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
3
2
 
4
3
  import { checkAuthMethod } from './utils';
5
4
 
6
- let enableClerkMock = false;
7
5
  let enableNextAuthMock = false;
8
6
  let enableBetterAuthMock = false;
9
7
 
@@ -12,9 +10,6 @@ vi.mock('@/envs/auth', async (importOriginal) => {
12
10
 
13
11
  return {
14
12
  ...(data as any),
15
- get enableClerk() {
16
- return enableClerkMock;
17
- },
18
13
  get enableBetterAuth() {
19
14
  return enableBetterAuthMock;
20
15
  },
@@ -29,29 +24,6 @@ describe('checkAuthMethod', () => {
29
24
  vi.clearAllMocks();
30
25
  });
31
26
 
32
- it('should pass with valid Clerk auth', () => {
33
- enableClerkMock = true;
34
- expect(() =>
35
- checkAuthMethod({
36
- clerkAuth: { userId: 'someUserId' } as AuthObject,
37
- }),
38
- ).not.toThrow();
39
-
40
- enableClerkMock = false;
41
- });
42
-
43
- it('should throw error with invalid Clerk auth', () => {
44
- enableClerkMock = true;
45
- try {
46
- checkAuthMethod({
47
- clerkAuth: {} as any,
48
- });
49
- } catch (e) {
50
- expect(e).toEqual({ errorType: 'InvalidClerkUser' });
51
- }
52
- enableClerkMock = false;
53
- });
54
-
55
27
  it('should pass with valid Next auth', () => {
56
28
  enableNextAuthMock = true;
57
29
  expect(() =>
@@ -1,13 +1,8 @@
1
- import { type AuthObject } from '@clerk/backend';
2
- import { AgentRuntimeError } from '@lobechat/model-runtime';
3
- import { ChatErrorType } from '@lobechat/types';
4
-
5
- import { enableBetterAuth, enableClerk, enableNextAuth } from '@/envs/auth';
1
+ import { enableBetterAuth, enableNextAuth } from '@/envs/auth';
6
2
 
7
3
  interface CheckAuthParams {
8
4
  apiKey?: string;
9
5
  betterAuthAuthorized?: boolean;
10
- clerkAuth?: AuthObject;
11
6
  nextAuthAuthorized?: boolean;
12
7
  }
13
8
  /**
@@ -16,20 +11,10 @@ interface CheckAuthParams {
16
11
  * @param {CheckAuthParams} params - Authentication parameters extracted from headers.
17
12
  * @param {string} [params.apiKey] - The user API key.
18
13
  * @param {boolean} [params.betterAuthAuthorized] - Whether the Better Auth session exists.
19
- * @param {AuthObject} [params.clerkAuth] - Clerk authentication payload from middleware.
20
14
  * @param {boolean} [params.nextAuthAuthorized] - Whether the OAuth 2 header is provided.
21
- * @throws {AgentRuntimeError} If authentication fails.
22
15
  */
23
16
  export const checkAuthMethod = (params: CheckAuthParams) => {
24
- const { apiKey, betterAuthAuthorized, nextAuthAuthorized, clerkAuth } = params;
25
- // clerk auth handler
26
- if (enableClerk) {
27
- // if there is no userId, means the use is not login, just throw error
28
- if (!(clerkAuth as any)?.userId)
29
- throw AgentRuntimeError.createError(ChatErrorType.InvalidClerkUser);
30
- // if the user is login, just return
31
- else return;
32
- }
17
+ const { apiKey, betterAuthAuthorized, nextAuthAuthorized } = params;
33
18
 
34
19
  // if better auth session exists
35
20
  if (enableBetterAuth && betterAuthAuthorized) return;
@@ -1,5 +1,4 @@
1
1
  // @vitest-environment node
2
- import { getAuth } from '@clerk/nextjs/server';
3
2
  import { LobeRuntimeAI, ModelRuntime } from '@lobechat/model-runtime';
4
3
  import { ChatErrorType } from '@lobechat/types';
5
4
  import { getXorPayload } from '@lobechat/utils/server';
@@ -11,10 +10,6 @@ import { initModelRuntimeFromDB } from '@/server/modules/ModelRuntime';
11
10
 
12
11
  import { POST } from './route';
13
12
 
14
- vi.mock('@clerk/nextjs/server', () => ({
15
- getAuth: vi.fn(),
16
- }));
17
-
18
13
  vi.mock('@/app/(backend)/middleware/auth/utils', () => ({
19
14
  checkAuthMethod: vi.fn(),
20
15
  }));
@@ -28,17 +23,11 @@ vi.mock('@/server/modules/ModelRuntime', () => ({
28
23
  createTraceOptions: vi.fn().mockReturnValue({}),
29
24
  }));
30
25
 
31
- // Use vi.hoisted to ensure mockState is initialized before mocks are set up
32
- const mockState = vi.hoisted(() => ({ enableClerk: false }));
33
-
34
- // 模拟 @/const/auth 模块
35
26
  vi.mock('@/envs/auth', async (importOriginal) => {
36
- const modules = await importOriginal();
27
+ const actual = await importOriginal<typeof import('@/envs/auth')>();
37
28
  return {
38
- ...(modules as any),
39
- get enableClerk() {
40
- return mockState.enableClerk;
41
- },
29
+ ...actual,
30
+ enableBetterAuth: false,
42
31
  };
43
32
  });
44
33
 
@@ -58,7 +47,6 @@ beforeEach(() => {
58
47
  afterEach(() => {
59
48
  // 清除模拟调用历史
60
49
  vi.clearAllMocks();
61
- mockState.enableClerk = false;
62
50
  });
63
51
 
64
52
  describe('POST handler', () => {
@@ -108,42 +96,6 @@ describe('POST handler', () => {
108
96
  });
109
97
  });
110
98
 
111
- it('should have pass clerk Auth when enable clerk', async () => {
112
- mockState.enableClerk = true;
113
-
114
- vi.mocked(getXorPayload).mockReturnValueOnce({
115
- apiKey: 'test-api-key',
116
- azureApiVersion: 'v1',
117
- });
118
-
119
- const mockParams = Promise.resolve({ provider: 'test-provider' });
120
- vi.mocked(getAuth).mockReturnValue({} as any);
121
- vi.mocked(checkAuthMethod).mockReset();
122
-
123
- const mockRuntime: LobeRuntimeAI = { baseURL: 'abc', chat: vi.fn() };
124
-
125
- // Mock initModelRuntimeFromDB
126
- vi.mocked(initModelRuntimeFromDB).mockResolvedValue(new ModelRuntime(mockRuntime));
127
-
128
- const request = new Request(new URL('https://test.com'), {
129
- method: 'POST',
130
- body: JSON.stringify({ model: 'test-model' }),
131
- headers: {
132
- [LOBE_CHAT_AUTH_HEADER]: 'some-valid-token',
133
- [OAUTH_AUTHORIZED]: '1',
134
- },
135
- });
136
-
137
- await POST(request, { params: mockParams });
138
-
139
- expect(checkAuthMethod).toBeCalledWith({
140
- apiKey: 'test-api-key',
141
- betterAuthAuthorized: false,
142
- clerkAuth: {},
143
- nextAuthAuthorized: true,
144
- });
145
- });
146
-
147
99
  it('should return InternalServerError error when throw a unknown error', async () => {
148
100
  const mockParams = Promise.resolve({ provider: 'test-provider' });
149
101
  vi.mocked(getXorPayload).mockImplementationOnce(() => {
@@ -9,10 +9,6 @@ import { initModelRuntimeFromDB } from '@/server/modules/ModelRuntime';
9
9
 
10
10
  import { GET } from './route';
11
11
 
12
- vi.mock('@clerk/nextjs/server', () => ({
13
- getAuth: vi.fn(),
14
- }));
15
-
16
12
  vi.mock('@/app/(backend)/middleware/auth/utils', () => ({
17
13
  checkAuthMethod: vi.fn(),
18
14
  }));
@@ -21,6 +17,14 @@ vi.mock('@lobechat/utils/server', () => ({
21
17
  getXorPayload: vi.fn(),
22
18
  }));
23
19
 
20
+ vi.mock('@/envs/auth', async (importOriginal) => {
21
+ const actual = await importOriginal<typeof import('@/envs/auth')>();
22
+ return {
23
+ ...actual,
24
+ enableBetterAuth: false,
25
+ };
26
+ });
27
+
24
28
  vi.mock('@/server/modules/ModelRuntime', () => ({
25
29
  initModelRuntimeFromDB: vi.fn(),
26
30
  }));
@@ -68,7 +68,8 @@ const BtnListLoading = memo(() => {
68
68
  * ref: https://authjs.dev/guides/pages/signin
69
69
  */
70
70
  export default memo(() => {
71
- const { t } = useTranslation('clerk');
71
+ const { t } = useTranslation('auth');
72
+ const { t: tCommon } = useTranslation('common');
72
73
  const router = useRouter();
73
74
  const [loadingProvider, setLoadingProvider] = useState<string | null>(null);
74
75
 
@@ -100,9 +101,9 @@ export default memo(() => {
100
101
  };
101
102
 
102
103
  const footerBtns = [
103
- { href: DOCUMENTS_REFER_URL, id: 0, label: t('footerPageLink__help') },
104
- { href: PRIVACY_URL, id: 1, label: t('footerPageLink__privacy') },
105
- { href: TERMS_URL, id: 2, label: t('footerPageLink__terms') },
104
+ { href: DOCUMENTS_REFER_URL, id: 0, label: tCommon('document') },
105
+ { href: PRIVACY_URL, id: 1, label: t('footer.privacy') },
106
+ { href: TERMS_URL, id: 2, label: t('footer.terms') },
106
107
  ];
107
108
 
108
109
  return (
@@ -116,10 +117,10 @@ export default memo(() => {
116
117
  <div>
117
118
  <LobeHub size={48} />
118
119
  </div>
119
- {t('signIn.start.title', { applicationName: BRANDING_NAME })}
120
+ {t('signin.title')}
120
121
  </Text>
121
122
  <Text as={'p'} className={styles.description}>
122
- {t('signIn.start.subtitle')}
123
+ {t('signin.subtitle', { appName: BRANDING_NAME })}
123
124
  </Text>
124
125
  </div>
125
126
  {/* Content */}
@@ -1,6 +1,4 @@
1
- import { SignUp } from '@clerk/nextjs';
2
-
3
- import { enableBetterAuth, enableClerk } from '@/envs/auth';
1
+ import { enableBetterAuth } from '@/envs/auth';
4
2
  import { notFound } from '@/libs/next/navigation';
5
3
  import { metadataModule } from '@/server/metadata';
6
4
  import { translation } from '@/server/translation';
@@ -12,15 +10,6 @@ import BetterAuthSignUpForm from './BetterAuthSignUpForm';
12
10
  export const generateMetadata = async (props: DynamicLayoutProps) => {
13
11
  const locale = await RouteVariants.getLocale(props);
14
12
 
15
- if (enableClerk) {
16
- const { t } = await translation('clerk', locale);
17
- return metadataModule.generate({
18
- description: t('signUp.start.subtitle'),
19
- title: t('signUp.start.title'),
20
- url: '/signup',
21
- });
22
- }
23
-
24
13
  if (enableBetterAuth) {
25
14
  const { t } = await translation('auth', locale);
26
15
  return metadataModule.generate({
@@ -37,10 +26,6 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
37
26
  };
38
27
 
39
28
  const Page = () => {
40
- if (enableClerk) {
41
- return <SignUp path="/signup" />;
42
- }
43
-
44
29
  if (enableBetterAuth) {
45
30
  return <BetterAuthSignUpForm />;
46
31
  }
@@ -42,7 +42,7 @@ const AgentList = memo<{ onMoreClick?: () => void }>(({ onMoreClick }) => {
42
42
 
43
43
  return (
44
44
  <>
45
- <InboxItem />
45
+ <InboxItem style={{ minHeight: 36 }} />
46
46
  {showPinned && <SessionList dataSource={pinnedList!} />}
47
47
  {showCustom && <Group dataSource={customList!} />}
48
48
  {showDefault && (
@@ -4,10 +4,10 @@ import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '
4
4
  import { Avatar, Flexbox, Icon } from '@lobehub/ui';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { Blocks } from 'lucide-react';
7
- import { type ReactNode, createElement, memo, useMemo, useState } from 'react';
7
+ import { type ReactNode, createElement, memo, useCallback, useMemo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
10
- import SkillStore from '@/features/SkillStore';
10
+ import { createSkillStoreModal } from '@/features/SkillStore';
11
11
  import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
12
12
  import { useToolStore } from '@/store/tool';
13
13
 
@@ -61,7 +61,6 @@ const BANNER_SKILL_IDS = [
61
61
 
62
62
  const SkillInstallBanner = memo(() => {
63
63
  const { t } = useTranslation('plugin');
64
- const [open, setOpen] = useState(false);
65
64
 
66
65
  const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
67
66
  const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis);
@@ -108,20 +107,21 @@ const SkillInstallBanner = memo(() => {
108
107
  return items;
109
108
  }, []);
110
109
 
110
+ const handleOpenStore = useCallback(() => {
111
+ createSkillStoreModal();
112
+ }, []);
113
+
111
114
  // Don't show banner if no skills are enabled
112
115
  if (!isLobehubSkillEnabled && !isKlavisEnabled) return null;
113
116
 
114
117
  return (
115
- <>
116
- <div className={styles.banner} onClick={() => setOpen(true)}>
117
- <Flexbox align="center" gap={8} horizontal>
118
- <Icon className={styles.icon} icon={Blocks} size={18} />
119
- <span className={styles.text}>{t('skillInstallBanner.title')}</span>
120
- </Flexbox>
121
- {avatarItems.length > 0 && <Avatar.Group items={avatarItems} shape="circle" size={24} />}
122
- </div>
123
- <SkillStore open={open} setOpen={setOpen} />
124
- </>
118
+ <div className={styles.banner} onClick={handleOpenStore}>
119
+ <Flexbox align="center" gap={8} horizontal>
120
+ <Icon className={styles.icon} icon={Blocks} size={18} />
121
+ <span className={styles.text}>{t('skillInstallBanner.title')}</span>
122
+ </Flexbox>
123
+ {avatarItems.length > 0 && <Avatar.Group items={avatarItems} shape="circle" size={24} />}
124
+ </div>
125
125
  );
126
126
  });
127
127
 
@@ -3,12 +3,12 @@
3
3
  import { Avatar, Block, Center, Flexbox, Icon, Text } from '@lobehub/ui';
4
4
  import { cssVar } from 'antd-style';
5
5
  import { FileTextIcon } from 'lucide-react';
6
- import markdownToTxt from 'markdown-to-txt';
7
6
  import { memo } from 'react';
8
7
 
9
8
  import Time from '@/app/[variants]/(main)/home/features/components/Time';
10
9
  import { RECENT_BLOCK_SIZE } from '@/app/[variants]/(main)/home/features/const';
11
10
  import { type FileListItem } from '@/types/files';
11
+ import markdownToTxt from '@/utils/markdownToTxt';
12
12
 
13
13
  // Helper to extract title from markdown content
14
14
  const extractTitle = (content: string): string | null => {
@@ -24,7 +24,7 @@ const getPreviewText = (item: FileListItem): string => {
24
24
  if (!item.content) return '';
25
25
 
26
26
  // Convert markdown to plain text
27
- let plainText = markdownToTxt(item.content);
27
+ let plainText = markdownToTxt(item.content.slice(0, 120));
28
28
 
29
29
  // Remove the title line if it exists
30
30
  const title = extractTitle(item.content);
@@ -1,6 +1,6 @@
1
1
  import { type StateCreator } from 'zustand/vanilla';
2
2
 
3
- import { type ResouceManagerMode } from '@/features/ResourceManager';
3
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
4
4
  import { type FilesTabs, SortType } from '@/types/files';
5
5
 
6
6
  import { type State, type ViewMode, initialState } from './initialState';
@@ -67,7 +67,7 @@ export interface Action {
67
67
  /**
68
68
  * Set the view mode
69
69
  */
70
- setMode: (mode: ResouceManagerMode) => void;
70
+ setMode: (mode: ResourceManagerMode) => void;
71
71
  /**
72
72
  * Set the pending rename item ID
73
73
  */
@@ -1,4 +1,4 @@
1
- import { type ResouceManagerMode } from '@/features/ResourceManager';
1
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
2
2
  import { FilesTabs, SortType } from '@/types/files';
3
3
 
4
4
  export type ViewMode = 'list' | 'masonry';
@@ -39,7 +39,7 @@ export interface State {
39
39
  /**
40
40
  * View mode for displaying resources
41
41
  */
42
- mode: ResouceManagerMode;
42
+ mode: ResourceManagerMode;
43
43
  /**
44
44
  * ID of item currently being renamed (for inline editing)
45
45
  */
@@ -1,6 +1,6 @@
1
1
  import { type StateCreator } from 'zustand/vanilla';
2
2
 
3
- import { type ResouceManagerMode } from '@/features/ResourceManager';
3
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
4
4
 
5
5
  import { type State, initialState } from './initialState';
6
6
 
@@ -12,7 +12,7 @@ export interface Action {
12
12
  /**
13
13
  * Set the view mode
14
14
  */
15
- setMode: (mode: ResouceManagerMode) => void;
15
+ setMode: (mode: ResourceManagerMode) => void;
16
16
  /**
17
17
  * Set selected file IDs
18
18
  */
@@ -1,8 +1,8 @@
1
- import { type ResouceManagerMode } from '@/features/ResourceManager';
1
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
2
2
 
3
3
  export interface State {
4
4
  currentViewItemId?: string;
5
- mode: ResouceManagerMode;
5
+ mode: ResourceManagerMode;
6
6
  selectedFileIds: string[];
7
7
  }
8
8
 
@@ -20,7 +20,6 @@ import {
20
20
  Mic2,
21
21
  PaletteIcon,
22
22
  PieChart,
23
- ShieldCheck,
24
23
  Sparkles,
25
24
  UserCircle,
26
25
  } from 'lucide-react';
@@ -32,7 +31,7 @@ import { electronSyncSelectors } from '@/store/electron/selectors';
32
31
  import { SettingsTabs } from '@/store/global/initialState';
33
32
  import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
34
33
  import { useUserStore } from '@/store/user';
35
- import { authSelectors, userProfileSelectors } from '@/store/user/slices/auth/selectors';
34
+ import { userProfileSelectors } from '@/store/user/slices/auth/selectors';
36
35
 
37
36
  export enum SettingsGroupKey {
38
37
  AIConfig = 'ai-config',
@@ -61,8 +60,7 @@ export const useCategory = () => {
61
60
  const mobile = useServerConfigStore((s) => s.isMobile);
62
61
  const { enableSTT, hideDocs, showAiImage, showApiKeyManage } =
63
62
  useServerConfigStore(featureFlagsSelectors);
64
- const [isLoginWithClerk, avatar, username] = useUserStore((s) => [
65
- authSelectors.isLoginWithClerk(s),
63
+ const [avatar, username] = useUserStore((s) => [
66
64
  userProfileSelectors.userAvatar(s),
67
65
  userProfileSelectors.nickName(s),
68
66
  ]);
@@ -87,11 +85,6 @@ export const useCategory = () => {
87
85
  key: SettingsTabs.Profile,
88
86
  label: username ? username : tAuth('tab.profile'),
89
87
  },
90
- isLoginWithClerk && {
91
- icon: ShieldCheck,
92
- key: SettingsTabs.Security,
93
- label: tAuth('tab.security'),
94
- },
95
88
  {
96
89
  icon: ChartColumnBigIcon,
97
90
  key: SettingsTabs.Stats,
@@ -237,18 +230,7 @@ export const useCategory = () => {
237
230
  });
238
231
 
239
232
  return groups;
240
- }, [
241
- t,
242
- tAuth,
243
- enableSTT,
244
- hideDocs,
245
- mobile,
246
- showAiImage,
247
- showApiKeyManage,
248
- isLoginWithClerk,
249
- avatarUrl,
250
- username,
251
- ]);
233
+ }, [t, tAuth, enableSTT, hideDocs, mobile, showAiImage, showApiKeyManage, avatarUrl, username]);
252
234
 
253
235
  return categoryGroups;
254
236
  };
@@ -7,7 +7,6 @@ import { useCallback, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
 
9
9
  import { fetchErrorNotification } from '@/components/Error/fetchErrorNotification';
10
- import { enableAuth } from '@/envs/auth';
11
10
  import UserAvatar from '@/features/User/UserAvatar';
12
11
  import { useUserStore } from '@/store/user';
13
12
  import { authSelectors } from '@/store/user/selectors';
@@ -54,7 +53,7 @@ const AvatarRow = ({ mobile }: AvatarRowProps) => {
54
53
  [updateAvatar],
55
54
  );
56
55
 
57
- const canUpload = !enableAuth || isLogin;
56
+ const canUpload = isLogin;
58
57
 
59
58
  const avatarContent = canUpload ? (
60
59
  <Spin indicator={<LoadingOutlined spin />} spinning={uploading}>
@@ -1,30 +1,9 @@
1
1
  'use client';
2
2
 
3
- import { Skeleton } from '@lobehub/ui';
4
- import { useTranslation } from 'react-i18next';
5
3
  import { Navigate } from 'react-router-dom';
6
4
 
7
- import SettingHeader from '@/app/[variants]/(main)/settings/features/SettingHeader';
8
- import { enableClerk } from '@/envs/auth';
9
- import dynamic from '@/libs/next/dynamic';
10
-
11
- const ClerkProfile = dynamic(() => import('./features/ClerkProfile'), {
12
- loading: () => (
13
- <div style={{ flex: 1 }}>
14
- <Skeleton paragraph={{ rows: 8 }} title={false} />
15
- </div>
16
- ),
17
- });
18
-
19
5
  const Page = () => {
20
- const { t } = useTranslation('setting');
21
- if (!enableClerk) return <Navigate replace to="/settings" />;
22
- return (
23
- <>
24
- <SettingHeader title={t('tab.security')} />
25
- <ClerkProfile />
26
- </>
27
- );
6
+ return <Navigate replace to="/settings" />;
28
7
  };
29
8
 
30
9
  export default Page;
@@ -8,7 +8,7 @@ import { Loader2, MoreVerticalIcon, SquareArrowOutUpRight, Unplug } from 'lucide
8
8
  import { memo, useCallback, useEffect, useRef, useState } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
11
- import IntegrationDetailModal from '@/features/IntegrationDetailModal';
11
+ import { createIntegrationDetailModal } from '@/features/IntegrationDetailModal';
12
12
  import { useToolStore } from '@/store/tool';
13
13
  import { type KlavisServer, KlavisServerStatus } from '@/store/tool/slices/klavisStore';
14
14
  import { useUserStore } from '@/store/user';
@@ -72,7 +72,6 @@ const KlavisSkillItem = memo<KlavisSkillItemProps>(({ serverType, server }) => {
72
72
  const { modal } = App.useApp();
73
73
  const [isConnecting, setIsConnecting] = useState(false);
74
74
  const [isWaitingAuth, setIsWaitingAuth] = useState(false);
75
- const [detailOpen, setDetailOpen] = useState(false);
76
75
 
77
76
  const oauthWindowRef = useRef<Window | null>(null);
78
77
  const windowCheckIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
@@ -313,8 +312,7 @@ const KlavisSkillItem = memo<KlavisSkillItemProps>(({ serverType, server }) => {
313
312
  const isConnected = server?.status === KlavisServerStatus.CONNECTED;
314
313
 
315
314
  return (
316
- <>
317
- <Flexbox
315
+ <Flexbox
318
316
  align="center"
319
317
  className={styles.container}
320
318
  gap={16}
@@ -324,7 +322,16 @@ const KlavisSkillItem = memo<KlavisSkillItemProps>(({ serverType, server }) => {
324
322
  <Flexbox align="center" gap={16} horizontal style={{ flex: 1, overflow: 'hidden' }}>
325
323
  <div className={styles.icon}>{renderIcon()}</div>
326
324
  <Flexbox gap={4} style={{ overflow: 'hidden' }}>
327
- <span className={styles.title} onClick={() => setDetailOpen(true)}>
325
+ <span
326
+ className={styles.title}
327
+ onClick={() =>
328
+ createIntegrationDetailModal({
329
+ identifier: serverType.identifier,
330
+ serverName: serverType.serverName,
331
+ type: 'klavis',
332
+ })
333
+ }
334
+ >
328
335
  {serverType.label}
329
336
  </span>
330
337
  {!isConnected && renderStatus()}
@@ -335,15 +342,6 @@ const KlavisSkillItem = memo<KlavisSkillItemProps>(({ serverType, server }) => {
335
342
  {renderAction()}
336
343
  </Flexbox>
337
344
  </Flexbox>
338
- <IntegrationDetailModal
339
- identifier={serverType.identifier}
340
- isConnecting={isConnecting || isWaitingAuth}
341
- onClose={() => setDetailOpen(false)}
342
- onConnect={handleConnect}
343
- open={detailOpen}
344
- type="klavis"
345
- />
346
- </>
347
345
  );
348
346
  });
349
347
 
@@ -8,7 +8,7 @@ import { Loader2, MoreVerticalIcon, SquareArrowOutUpRight, Unplug } from 'lucide
8
8
  import { memo, useCallback, useEffect, useRef, useState } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
11
- import IntegrationDetailModal from '@/features/IntegrationDetailModal';
11
+ import { createIntegrationDetailModal } from '@/features/IntegrationDetailModal';
12
12
  import { useToolStore } from '@/store/tool';
13
13
  import {
14
14
  type LobehubSkillServer,
@@ -75,7 +75,6 @@ const LobehubSkillItem = memo<LobehubSkillItemProps>(({ provider, server }) => {
75
75
  const { modal } = App.useApp();
76
76
  const [isConnecting, setIsConnecting] = useState(false);
77
77
  const [isWaitingAuth, setIsWaitingAuth] = useState(false);
78
- const [detailOpen, setDetailOpen] = useState(false);
79
78
 
80
79
  const oauthWindowRef = useRef<Window | null>(null);
81
80
  const windowCheckIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
@@ -299,8 +298,7 @@ const LobehubSkillItem = memo<LobehubSkillItemProps>(({ provider, server }) => {
299
298
  const isConnected = server?.status === LobehubSkillStatus.CONNECTED;
300
299
 
301
300
  return (
302
- <>
303
- <Flexbox
301
+ <Flexbox
304
302
  align="center"
305
303
  className={styles.container}
306
304
  gap={16}
@@ -314,7 +312,12 @@ const LobehubSkillItem = memo<LobehubSkillItemProps>(({ provider, server }) => {
314
312
  <Flexbox gap={4} style={{ overflow: 'hidden' }}>
315
313
  <span
316
314
  className={`${styles.title} ${!isConnected ? styles.disconnectedTitle : ''}`}
317
- onClick={() => setDetailOpen(true)}
315
+ onClick={() =>
316
+ createIntegrationDetailModal({
317
+ identifier: provider.id,
318
+ type: 'lobehub',
319
+ })
320
+ }
318
321
  >
319
322
  {provider.label}
320
323
  </span>
@@ -326,15 +329,6 @@ const LobehubSkillItem = memo<LobehubSkillItemProps>(({ provider, server }) => {
326
329
  {renderAction()}
327
330
  </Flexbox>
328
331
  </Flexbox>
329
- <IntegrationDetailModal
330
- identifier={provider.id}
331
- isConnecting={isConnecting || isWaitingAuth}
332
- onClose={() => setDetailOpen(false)}
333
- onConnect={handleConnect}
334
- open={detailOpen}
335
- type="lobehub"
336
- />
337
- </>
338
332
  );
339
333
  });
340
334