@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,292 +1,30 @@
1
1
  'use client';
2
2
 
3
- import {
4
- type KlavisServerType,
5
- type LobehubSkillProviderType,
6
- getKlavisServerByServerIdentifier,
7
- getLobehubSkillProviderById,
8
- } from '@lobechat/const';
9
- import { Flexbox, Icon, Image, Modal, Tag, Text, Typography } from '@lobehub/ui';
10
- import { Button, Divider } from 'antd';
11
- import { createStaticStyles, cssVar } from 'antd-style';
12
- import { ExternalLink, Loader2, SquareArrowOutUpRight } from 'lucide-react';
13
- import { memo, useMemo } from 'react';
14
- import { useTranslation } from 'react-i18next';
3
+ import { createModal } from '@lobehub/ui';
4
+ import { t } from 'i18next';
5
+ import type { Klavis } from 'klavis';
15
6
 
16
- import { useToolStore } from '@/store/tool';
17
- import { klavisStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/selectors';
18
- import { KlavisServerStatus } from '@/store/tool/slices/klavisStore';
19
- import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types';
7
+ import { IntegrationDetailContent, type IntegrationType } from './IntegrationDetailContent';
20
8
 
21
- const styles = createStaticStyles(({ css, cssVar }) => ({
22
- authorLink: css`
23
- cursor: pointer;
9
+ export type { IntegrationType } from './IntegrationDetailContent';
24
10
 
25
- display: inline-flex;
26
- gap: 4px;
27
- align-items: center;
28
-
29
- color: ${cssVar.colorPrimary};
30
-
31
- &:hover {
32
- text-decoration: underline;
33
- }
34
- `,
35
- detailItem: css`
36
- display: flex;
37
- flex-direction: column;
38
- gap: 4px;
39
- `,
40
- detailLabel: css`
41
- font-size: 12px;
42
- color: ${cssVar.colorTextTertiary};
43
- `,
44
- header: css`
45
- display: flex;
46
- gap: 16px;
47
- align-items: center;
48
-
49
- padding: 16px;
50
- border-radius: 12px;
51
-
52
- background: ${cssVar.colorFillTertiary};
53
- `,
54
- icon: css`
55
- display: flex;
56
- flex-shrink: 0;
57
- align-items: center;
58
- justify-content: center;
59
-
60
- width: 56px;
61
- height: 56px;
62
- border-radius: 12px;
63
-
64
- background: ${cssVar.colorBgContainer};
65
- `,
66
- introduction: css`
67
- font-size: 14px;
68
- line-height: 1.8;
69
- color: ${cssVar.colorText};
70
- `,
71
- sectionTitle: css`
72
- font-size: 14px;
73
- font-weight: 600;
74
- color: ${cssVar.colorText};
75
- `,
76
- title: css`
77
- font-size: 18px;
78
- font-weight: 600;
79
- color: ${cssVar.colorText};
80
- `,
81
- toolTag: css`
82
- font-family: ${cssVar.fontFamilyCode};
83
- font-size: 12px;
84
- `,
85
- toolsContainer: css`
86
- display: flex;
87
- flex-wrap: wrap;
88
- gap: 8px;
89
- `,
90
- trustWarning: css`
91
- font-size: 12px;
92
- line-height: 1.6;
93
- color: ${cssVar.colorTextTertiary};
94
- `,
95
- }));
96
-
97
- export type IntegrationType = 'klavis' | 'lobehub';
98
-
99
- export interface IntegrationDetailModalProps {
11
+ export interface CreateIntegrationDetailModalOptions {
100
12
  identifier: string;
101
- isConnecting?: boolean;
102
- onClose: () => void;
103
- onConnect?: () => void;
104
- open: boolean;
13
+ serverName?: Klavis.McpServerName;
105
14
  type: IntegrationType;
106
15
  }
107
16
 
108
- const IntegrationDetailModal = memo<IntegrationDetailModalProps>(
109
- ({ open, onClose, type, identifier, isConnecting, onConnect }) => {
110
- const { t } = useTranslation(['plugin', 'setting']);
111
-
112
- // Get static config based on type
113
- const config = useMemo((): KlavisServerType | LobehubSkillProviderType | undefined => {
114
- if (type === 'klavis') {
115
- return getKlavisServerByServerIdentifier(identifier);
116
- }
117
- return getLobehubSkillProviderById(identifier);
118
- }, [type, identifier]);
119
-
120
- // Get dynamic state from store
121
- const klavisServers = useToolStore(klavisStoreSelectors.getServers);
122
- const lobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers);
123
-
124
- const serverState = useMemo(() => {
125
- if (type === 'klavis') {
126
- return klavisServers.find((s) => s.identifier === identifier);
127
- }
128
- return lobehubSkillServers.find((s) => s.identifier === identifier);
129
- }, [type, identifier, klavisServers, lobehubSkillServers]);
130
-
131
- const isConnected = useMemo(() => {
132
- if (!serverState) return false;
133
- if (type === 'klavis') {
134
- return serverState.status === KlavisServerStatus.CONNECTED;
135
- }
136
- return serverState.status === LobehubSkillStatus.CONNECTED;
137
- }, [type, serverState]);
138
-
139
- const tools = useMemo(() => {
140
- return serverState?.tools?.map((tool) => tool.name) || [];
141
- }, [serverState]);
142
-
143
- if (!config) return null;
144
-
145
- const { author, authorUrl, description, icon, introduction, label } = config;
146
-
147
- // Get identifier for i18n keys
148
- const i18nIdentifier =
149
- type === 'klavis'
150
- ? (config as KlavisServerType).identifier
151
- : (config as LobehubSkillProviderType).id;
152
- const i18nPrefix = type === 'klavis' ? 'tools.klavis.servers' : 'tools.lobehubSkill.providers';
153
-
154
- const localizedDescription = t(`${i18nPrefix}.${i18nIdentifier}.description`, {
155
- defaultValue: description,
156
- ns: 'setting',
157
- });
158
- const localizedIntroduction = t(`${i18nPrefix}.${i18nIdentifier}.introduction`, {
159
- defaultValue: introduction,
160
- ns: 'setting',
161
- });
162
-
163
- const renderIcon = () => {
164
- if (typeof icon === 'string') {
165
- return <Image alt={label} height={36} src={icon} width={36} />;
166
- }
167
- return <Icon fill={cssVar.colorText} icon={icon} size={36} />;
168
- };
169
-
170
- const handleAuthorClick = () => {
171
- if (authorUrl) {
172
- window.open(authorUrl, '_blank', 'noopener,noreferrer');
173
- }
174
- };
175
-
176
- const renderConnectButton = () => {
177
- if (isConnected) return null;
178
- if (!onConnect) return null;
179
-
180
- if (isConnecting) {
181
- return (
182
- <Button disabled icon={<Icon icon={Loader2} spin />} type="default">
183
- {t('tools.klavis.connect', { defaultValue: 'Connect', ns: 'setting' })}
184
- </Button>
185
- );
186
- }
187
-
188
- return (
189
- <Button icon={<Icon icon={SquareArrowOutUpRight} />} onClick={onConnect} type="primary">
190
- {t('tools.klavis.connect', { defaultValue: 'Connect', ns: 'setting' })}
191
- </Button>
192
- );
193
- };
194
-
195
- return (
196
- <Modal
197
- destroyOnHidden
198
- footer={null}
199
- onCancel={onClose}
200
- open={open}
201
- title={t('dev.title.skillDetails')}
202
- width={800}
203
- >
204
- <Flexbox gap={20}>
205
- {/* Header */}
206
- <Flexbox
207
- align="center"
208
- className={styles.header}
209
- horizontal
210
- justify="space-between"
211
- style={{ flexWrap: 'nowrap' }}
212
- >
213
- <Flexbox align="center" gap={16} horizontal>
214
- <div className={styles.icon}>{renderIcon()}</div>
215
- <Flexbox gap={4}>
216
- <span className={styles.title}>{label}</span>
217
- <Text style={{ fontSize: 14 }} type="secondary">
218
- {localizedDescription}
219
- </Text>
220
- </Flexbox>
221
- </Flexbox>
222
- {renderConnectButton()}
223
- </Flexbox>
224
-
225
- {/* Introduction */}
226
- <Typography className={styles.introduction}>{localizedIntroduction}</Typography>
227
-
228
- {/* Developed by */}
229
- <Flexbox gap={8}>
230
- <Flexbox align="center" gap={4} horizontal>
231
- <span className={styles.sectionTitle}>{t('integrationDetail.developedBy')}</span>
232
- <span
233
- className={styles.authorLink}
234
- onClick={handleAuthorClick}
235
- style={{ cursor: authorUrl ? 'pointer' : 'default' }}
236
- >
237
- {author}
238
- {authorUrl && <Icon icon={ExternalLink} size={12} />}
239
- </span>
240
- </Flexbox>
241
- <Text className={styles.trustWarning} type="secondary">
242
- {t('integrationDetail.trustWarning')}
243
- </Text>
244
- </Flexbox>
245
-
246
- {/* Tools */}
247
- {tools.length > 0 && (
248
- <>
249
- <Divider style={{ margin: 0 }} />
250
- <Flexbox gap={12}>
251
- <Flexbox align="center" gap={8} horizontal>
252
- <span className={styles.sectionTitle}>{t('integrationDetail.tools')}</span>
253
- <Tag>{tools.length}</Tag>
254
- </Flexbox>
255
- <div className={styles.toolsContainer}>
256
- {tools.map((tool) => (
257
- <Tag className={styles.toolTag} key={tool}>
258
- {tool}
259
- </Tag>
260
- ))}
261
- </div>
262
- </Flexbox>
263
- </>
264
- )}
265
-
266
- {/* Details */}
267
- <Divider style={{ margin: 0 }} />
268
- <Flexbox gap={12}>
269
- <span className={styles.sectionTitle}>{t('integrationDetail.details')}</span>
270
- <Flexbox gap={16} horizontal>
271
- <div className={styles.detailItem}>
272
- <span className={styles.detailLabel}>{t('integrationDetail.author')}</span>
273
- <span
274
- className={styles.authorLink}
275
- onClick={handleAuthorClick}
276
- style={{ cursor: authorUrl ? 'pointer' : 'default' }}
277
- >
278
- {author}
279
- {authorUrl && <Icon icon={ExternalLink} size={12} />}
280
- </span>
281
- </div>
282
- </Flexbox>
283
- </Flexbox>
284
- </Flexbox>
285
- </Modal>
286
- );
287
- },
288
- );
289
-
290
- IntegrationDetailModal.displayName = 'IntegrationDetailModal';
291
-
292
- export default IntegrationDetailModal;
17
+ export const createIntegrationDetailModal = ({
18
+ identifier,
19
+ serverName,
20
+ type,
21
+ }: CreateIntegrationDetailModalOptions) =>
22
+ createModal({
23
+ children: (
24
+ <IntegrationDetailContent identifier={identifier} serverName={serverName} type={type} />
25
+ ),
26
+ destroyOnHidden: true,
27
+ footer: null,
28
+ title: t('dev.title.skillDetails', { ns: 'plugin' }),
29
+ width: 800,
30
+ });
@@ -23,12 +23,12 @@ import {
23
23
  Package,
24
24
  TerminalIcon,
25
25
  } from 'lucide-react';
26
- import { markdownToTxt } from 'markdown-to-txt';
27
26
  import { memo, useState } from 'react';
28
27
  import { useTranslation } from 'react-i18next';
29
28
 
30
29
  import Descriptions from '@/components/Descriptions';
31
30
  import InlineTable from '@/components/InlineTable';
31
+ import { markdownToTxt } from '@/utils/markdownToTxt';
32
32
 
33
33
  import Title from '../../../app/[variants]/(main)/community/features/Title';
34
34
  import InstallationIcon from '../../../components/MCPDepsIcon';
@@ -1,11 +1,11 @@
1
1
  import { Block, Collapse, Empty, Highlighter, Icon, Markdown } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { CheckIcon, MessageSquare, MinusIcon } from 'lucide-react';
4
- import { markdownToTxt } from 'markdown-to-txt';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  import InlineTable from '@/components/InlineTable';
8
+ import { markdownToTxt } from '@/utils/markdownToTxt';
9
9
 
10
10
  import Title from '../../../app/[variants]/(main)/community/features/Title';
11
11
  import CollapseDesc from '../CollapseDesc';
@@ -1,11 +1,11 @@
1
1
  import { Block, Collapse, Empty, Highlighter, Icon, Markdown, Tag } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { CheckIcon, MinusIcon, Wrench } from 'lucide-react';
4
- import { markdownToTxt } from 'markdown-to-txt';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  import InlineTable from '@/components/InlineTable';
8
+ import { markdownToTxt } from '@/utils/markdownToTxt';
9
9
 
10
10
  import Title from '../../../app/[variants]/(main)/community/features/Title';
11
11
  import CollapseDesc from '../CollapseDesc';
@@ -18,7 +18,7 @@ import KlavisServerItem from '@/features/ChatInput/ActionBar/Tools/KlavisServerI
18
18
  import LobehubSkillServerItem from '@/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem';
19
19
  import ToolItem from '@/features/ChatInput/ActionBar/Tools/ToolItem';
20
20
  import ActionDropdown from '@/features/ChatInput/ActionBar/components/ActionDropdown';
21
- import SkillStore from '@/features/SkillStore';
21
+ import { createSkillStoreModal } from '@/features/SkillStore';
22
22
  import { useCheckPluginsIsInstalled } from '@/hooks/useCheckPluginsIsInstalled';
23
23
  import { useFetchInstalledPlugins } from '@/hooks/useFetchInstalledPlugins';
24
24
  import { useAgentStore } from '@/store/agent';
@@ -157,8 +157,6 @@ const AgentTool = memo<AgentToolProps>(
157
157
  const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual);
158
158
  const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
159
159
 
160
- // Plugin store modal state
161
- const [modalOpen, setModalOpen] = useState(false);
162
160
  const [updating, setUpdating] = useState(false);
163
161
 
164
162
  // Tab state for dual-column layout
@@ -423,7 +421,7 @@ const AgentTool = memo<AgentToolProps>(
423
421
  key: 'plugin-store',
424
422
  label: t('tools.plugins.store'),
425
423
  onClick: () => {
426
- setModalOpen(true);
424
+ createSkillStoreModal();
427
425
  },
428
426
  },
429
427
  ],
@@ -556,20 +554,7 @@ const AgentTool = memo<AgentToolProps>(
556
554
  <>
557
555
  {/* Plugin Selector and Tags */}
558
556
  <Flexbox align="center" gap={8} horizontal wrap={'wrap'}>
559
- {/* Second Row: Selected Plugins as Tags */}
560
- {allEnabledTools.map((pluginId) => {
561
- return (
562
- <PluginTag
563
- key={pluginId}
564
- onRemove={handleRemovePlugin(pluginId)}
565
- pluginId={pluginId}
566
- showDesktopOnlyLabel={filterAvailableInWeb}
567
- useAllMetaList={useAllMetaList}
568
- />
569
- );
570
- })}
571
557
  {/* Plugin Selector Dropdown - Using Action component pattern */}
572
-
573
558
  <Suspense fallback={button}>
574
559
  <ActionDropdown
575
560
  maxHeight={500}
@@ -622,10 +607,19 @@ const AgentTool = memo<AgentToolProps>(
622
607
  {button}
623
608
  </ActionDropdown>
624
609
  </Suspense>
610
+ {/* Selected Plugins as Tags */}
611
+ {allEnabledTools.map((pluginId) => {
612
+ return (
613
+ <PluginTag
614
+ key={pluginId}
615
+ onRemove={handleRemovePlugin(pluginId)}
616
+ pluginId={pluginId}
617
+ showDesktopOnlyLabel={filterAvailableInWeb}
618
+ useAllMetaList={useAllMetaList}
619
+ />
620
+ );
621
+ })}
625
622
  </Flexbox>
626
-
627
- {/* PluginStore Modal - rendered outside Flexbox to avoid event interference */}
628
- {modalOpen && <SkillStore open={modalOpen} setOpen={setModalOpen} />}
629
623
  </>
630
624
  );
631
625
  },
@@ -41,7 +41,6 @@ const styles = createStaticStyles(({ css }) => {
41
41
  cursor: pointer;
42
42
  min-width: 800px;
43
43
 
44
- /* Hover effect for individual rows */
45
44
  &:hover {
46
45
  background: ${cssVar.colorFillTertiary};
47
46
  }
@@ -194,7 +193,6 @@ const FileListItem = memo<FileListItemProps>(
194
193
  const [isDragging, setIsDragging] = useState(false);
195
194
  const [isOver, setIsOver] = useState(false);
196
195
 
197
- // Memoize computed values that don't change
198
196
  const computedValues = useMemo(() => {
199
197
  const isPDF = fileType?.toLowerCase() === 'pdf' || name?.toLowerCase().endsWith('.pdf');
200
198
  return {
@@ -208,7 +206,6 @@ const FileListItem = memo<FileListItemProps>(
208
206
 
209
207
  const { isSupportedForChunking, isPage, isFolder, emoji } = computedValues;
210
208
 
211
- // Memoize drag data to prevent recreation
212
209
  const dragData = useMemo(
213
210
  () => ({
214
211
  fileType,
@@ -219,7 +216,6 @@ const FileListItem = memo<FileListItemProps>(
219
216
  [fileType, isFolder, name, sourceType],
220
217
  );
221
218
 
222
- // Native HTML5 drag event handlers
223
219
  const handleDragStart = useCallback(
224
220
  (e: DragEvent) => {
225
221
  if (!resourceManagerState.libraryId) {
@@ -264,7 +260,6 @@ const FileListItem = memo<FileListItemProps>(
264
260
  }, []);
265
261
 
266
262
  const handleDrop = useCallback(() => {
267
- // Clear the highlight after drop
268
263
  setIsOver(false);
269
264
  }, []);
270
265
 
@@ -359,7 +354,6 @@ const FileListItem = memo<FileListItemProps>(
359
354
  { replace: true },
360
355
  );
361
356
  } else {
362
- // Set mode to file and store the file ID
363
357
  resourceManagerState.setCurrentViewItemId(id);
364
358
  resourceManagerState.setMode('editor');
365
359
  // Also update URL query parameter for shareable links
@@ -378,7 +372,6 @@ const FileListItem = memo<FileListItemProps>(
378
372
  useEffect(() => {
379
373
  if (pendingRenameItemId === id && isFolder && !isRenaming) {
380
374
  handleRenameStart();
381
- // Clear the pending rename item after triggering
382
375
  resourceManagerState.setPendingRenameItemId(null);
383
376
  }
384
377
  }, [pendingRenameItemId, id, isFolder, resourceManagerState]);
@@ -575,7 +568,6 @@ const FileListItem = memo<FileListItemProps>(
575
568
  },
576
569
  // Custom comparison function to prevent unnecessary re-renders
577
570
  (prevProps, nextProps) => {
578
- // Only re-render if these critical props change
579
571
  return (
580
572
  prevProps.id === nextProps.id &&
581
573
  prevProps.name === nextProps.name &&
@@ -2,7 +2,6 @@ import { Button, Tooltip } from '@lobehub/ui';
2
2
  import { createStaticStyles, cx } from 'antd-style';
3
3
  import { isNull } from 'es-toolkit/compat';
4
4
  import { FileBoxIcon } from 'lucide-react';
5
- import markdownToTxt from 'markdown-to-txt';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
 
@@ -10,6 +9,7 @@ import FileIcon from '@/components/FileIcon';
10
9
  import { fileManagerSelectors, useFileStore } from '@/store/file';
11
10
  import { type AsyncTaskStatus, type IAsyncTaskError } from '@/types/asyncTask';
12
11
  import { isChunkingUnsupported } from '@/utils/isChunkingUnsupported';
12
+ import markdownToTxt from '@/utils/markdownToTxt';
13
13
 
14
14
  import ChunksBadge from '../../ListView/ListItem/ChunkTag';
15
15
 
@@ -48,7 +48,7 @@ const styles = createStaticStyles(({ css, cssVar }) => {
48
48
  };
49
49
  });
50
50
 
51
- export type ResouceManagerMode = 'editor' | 'explorer' | 'page';
51
+ export type ResourceManagerMode = 'editor' | 'explorer' | 'page';
52
52
 
53
53
  /**
54
54
  * Manage resources. Can be from a certian library.
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { LoadingOutlined } from '@ant-design/icons';
2
4
  import { Button, Flexbox } from '@lobehub/ui';
3
5
  import { Input, Modal, Spin } from 'antd';
@@ -5,15 +7,13 @@ import { createStaticStyles, cx } from 'antd-style';
5
7
  import { ChevronLeft, ChevronRight, Expand, FileText } from 'lucide-react';
6
8
  import { memo, useState } from 'react';
7
9
  import { useTranslation } from 'react-i18next';
8
- import { Document, Page, pdfjs } from 'react-pdf';
10
+ import { Document, Page } from 'react-pdf';
9
11
 
10
12
  import { useIsMobile } from '@/hooks/useIsMobile';
13
+ import '@/libs/pdfjs/worker';
11
14
 
12
15
  import { containerStyles } from '../style';
13
16
 
14
- // Set PDF.js worker
15
- pdfjs.GlobalWorkerOptions.workerSrc = `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/build/pdf.worker.min.mjs`;
16
-
17
17
  const styles = createStaticStyles(({ css }) => ({
18
18
  containerWrapper: css`
19
19
  position: relative;