@lobehub/lobehub 2.0.0-next.337 → 2.0.0-next.339

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 (270) hide show
  1. package/.gitattributes +35 -0
  2. package/CHANGELOG.md +69 -0
  3. package/changelog/v1.json +24 -0
  4. package/locales/ar/plugin.json +12 -2
  5. package/locales/ar/providers.json +1 -0
  6. package/locales/ar/setting.json +77 -1
  7. package/locales/bg-BG/models.json +5 -10
  8. package/locales/bg-BG/plugin.json +12 -2
  9. package/locales/bg-BG/providers.json +1 -0
  10. package/locales/bg-BG/setting.json +78 -2
  11. package/locales/de-DE/models.json +51 -9
  12. package/locales/de-DE/plugin.json +12 -2
  13. package/locales/de-DE/providers.json +1 -0
  14. package/locales/de-DE/setting.json +78 -2
  15. package/locales/en-US/models.json +11 -10
  16. package/locales/en-US/plugin.json +14 -4
  17. package/locales/en-US/providers.json +1 -0
  18. package/locales/en-US/setting.json +97 -2
  19. package/locales/es-ES/plugin.json +12 -2
  20. package/locales/es-ES/providers.json +1 -0
  21. package/locales/es-ES/setting.json +78 -2
  22. package/locales/fa-IR/plugin.json +12 -2
  23. package/locales/fa-IR/providers.json +1 -0
  24. package/locales/fa-IR/setting.json +78 -2
  25. package/locales/fr-FR/plugin.json +12 -2
  26. package/locales/fr-FR/providers.json +1 -0
  27. package/locales/fr-FR/setting.json +78 -2
  28. package/locales/it-IT/plugin.json +12 -2
  29. package/locales/it-IT/providers.json +1 -0
  30. package/locales/it-IT/setting.json +78 -2
  31. package/locales/ja-JP/plugin.json +12 -2
  32. package/locales/ja-JP/providers.json +1 -0
  33. package/locales/ja-JP/setting.json +78 -2
  34. package/locales/ko-KR/plugin.json +12 -2
  35. package/locales/ko-KR/providers.json +1 -0
  36. package/locales/ko-KR/setting.json +78 -2
  37. package/locales/nl-NL/models.json +4 -9
  38. package/locales/nl-NL/plugin.json +12 -2
  39. package/locales/nl-NL/providers.json +1 -0
  40. package/locales/nl-NL/setting.json +78 -2
  41. package/locales/pl-PL/plugin.json +12 -2
  42. package/locales/pl-PL/providers.json +1 -0
  43. package/locales/pl-PL/setting.json +78 -2
  44. package/locales/pt-BR/plugin.json +12 -2
  45. package/locales/pt-BR/providers.json +1 -0
  46. package/locales/pt-BR/setting.json +78 -2
  47. package/locales/ru-RU/plugin.json +12 -2
  48. package/locales/ru-RU/providers.json +1 -0
  49. package/locales/ru-RU/setting.json +78 -2
  50. package/locales/tr-TR/plugin.json +12 -2
  51. package/locales/tr-TR/providers.json +1 -0
  52. package/locales/tr-TR/setting.json +78 -2
  53. package/locales/vi-VN/plugin.json +12 -2
  54. package/locales/vi-VN/providers.json +1 -0
  55. package/locales/vi-VN/setting.json +77 -1
  56. package/locales/zh-CN/auth.json +1 -0
  57. package/locales/zh-CN/plugin.json +12 -2
  58. package/locales/zh-CN/providers.json +1 -0
  59. package/locales/zh-CN/setting.json +97 -2
  60. package/locales/zh-TW/plugin.json +12 -2
  61. package/locales/zh-TW/providers.json +1 -0
  62. package/locales/zh-TW/setting.json +78 -2
  63. package/package.json +1 -1
  64. package/packages/agent-runtime/src/groupOrchestration/GroupOrchestrationSupervisor.ts +2 -0
  65. package/packages/agent-runtime/src/groupOrchestration/__tests__/GroupOrchestrationSupervisor.test.ts +3 -1
  66. package/packages/agent-runtime/src/groupOrchestration/types.ts +5 -0
  67. package/packages/const/src/index.ts +1 -0
  68. package/packages/const/src/klavis.ts +144 -0
  69. package/packages/const/src/lobehubSkill.ts +34 -0
  70. package/packages/const/src/recommendedSkill.ts +17 -0
  71. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +38 -0
  72. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +20 -1
  73. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +42 -0
  74. package/packages/model-runtime/src/core/contextBuilders/google.ts +17 -0
  75. package/packages/model-runtime/src/providers/google/index.ts +14 -14
  76. package/packages/model-runtime/src/providers/moonshot/index.ts +1 -1
  77. package/packages/model-runtime/src/providers/openai/index.ts +3 -3
  78. package/packages/types/src/discover/index.ts +1 -1
  79. package/scripts/electronWorkflow/modifiers/dynamicToStatic.mts +273 -0
  80. package/scripts/electronWorkflow/modifiers/index.mts +10 -0
  81. package/scripts/electronWorkflow/modifiers/nextConfig.mts +1 -0
  82. package/scripts/electronWorkflow/modifiers/nextDynamicToStatic.mts +233 -0
  83. package/scripts/electronWorkflow/modifiers/removeSuspense.mts +124 -0
  84. package/scripts/electronWorkflow/modifiers/routes.mts +14 -2
  85. package/scripts/electronWorkflow/modifiers/settingsContentToStatic.mts +148 -0
  86. package/scripts/electronWorkflow/modifiers/wrapChildrenWithClientOnly.mts +73 -0
  87. package/src/app/[variants]/(main)/agent/cron/[cronId]/CronConfig.ts +16 -16
  88. package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobSaveButton.tsx +1 -1
  89. package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobScheduleConfig.tsx +5 -2
  90. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -1
  91. package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +131 -0
  92. package/src/app/[variants]/(main)/home/features/InputArea/index.tsx +34 -27
  93. package/src/app/[variants]/(main)/settings/features/SettingHeader.tsx +8 -4
  94. package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +3 -0
  95. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +6 -0
  96. package/src/{features/PluginStore/InstalledList/List/Item/Action.tsx → app/[variants]/(main)/settings/skill/features/Actions.tsx} +45 -40
  97. package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +353 -0
  98. package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +344 -0
  99. package/src/app/[variants]/(main)/settings/skill/features/McpSkillItem.tsx +116 -0
  100. package/src/app/[variants]/(main)/settings/skill/features/SkillList.tsx +244 -0
  101. package/src/app/[variants]/(main)/settings/skill/index.tsx +35 -0
  102. package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +27 -0
  103. package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +8 -17
  104. package/src/app/[variants]/(mobile)/settings/_layout/index.tsx +6 -1
  105. package/src/app/[variants]/(mobile)/settings/provider/_layout/index.tsx +22 -0
  106. package/src/components/Plugins/PluginTag.tsx +23 -35
  107. package/src/components/client/ClientOnly.tsx +6 -2
  108. package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
  109. package/src/features/ChatInput/ActionBar/Tools/KlavisServerItem.tsx +8 -32
  110. package/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx +8 -30
  111. package/src/features/ChatInput/ActionBar/Tools/PopoverContent.tsx +48 -59
  112. package/src/features/ChatInput/ActionBar/Tools/index.tsx +5 -23
  113. package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +158 -56
  114. package/src/features/IntegrationDetailModal/index.tsx +293 -0
  115. package/src/features/{PluginStore/McpList/Detail → MCP/MCPDetail}/index.tsx +15 -6
  116. package/src/features/MCP/MCPSettings/McpSettingsModal.tsx +58 -0
  117. package/src/features/{PluginStore/McpList/Detail/Settings → MCP/MCPSettings}/index.tsx +39 -27
  118. package/src/features/PluginDetailModal/index.tsx +2 -2
  119. package/src/features/PluginDevModal/index.tsx +16 -40
  120. package/src/features/ProfileEditor/AgentTool.tsx +2 -2
  121. package/src/features/ProtocolUrlHandler/InstallPlugin/OfficialPluginInstallModal/index.tsx +1 -1
  122. package/src/features/{PluginStore/AddPluginButton.tsx → SkillStore/AddSkillButton.tsx} +3 -3
  123. package/src/features/SkillStore/CommunityList/Item.tsx +158 -0
  124. package/src/features/SkillStore/CommunityList/index.tsx +101 -0
  125. package/src/features/SkillStore/Content.tsx +59 -0
  126. package/src/features/{PluginStore/PluginEmpty.tsx → SkillStore/Empty.tsx} +8 -8
  127. package/src/features/SkillStore/LobeHubList/Item.tsx +118 -0
  128. package/src/features/SkillStore/LobeHubList/index.tsx +187 -0
  129. package/src/features/SkillStore/LobeHubList/useSkillConnect.ts +239 -0
  130. package/src/features/SkillStore/Search/index.tsx +43 -0
  131. package/src/features/{PluginStore → SkillStore}/index.tsx +14 -10
  132. package/src/features/SkillStore/style.ts +27 -0
  133. package/src/locales/default/plugin.ts +15 -4
  134. package/src/locales/default/setting.ts +204 -2
  135. package/src/services/chat/mecha/agentConfigResolver.test.ts +197 -0
  136. package/src/services/chat/mecha/agentConfigResolver.ts +44 -17
  137. package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +40 -37
  138. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +78 -0
  139. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +50 -16
  140. package/src/store/global/initialState.ts +1 -0
  141. package/src/store/tool/slices/lobehubSkillStore/action.test.ts +914 -0
  142. package/src/store/tool/slices/lobehubSkillStore/selectors.test.ts +548 -0
  143. package/.cursor/skills/vercel-react-best-practices/AGENTS.md +0 -2410
  144. package/.cursor/skills/vercel-react-best-practices/SKILL.md +0 -125
  145. package/.cursor/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  146. package/.cursor/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -49
  147. package/.cursor/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  148. package/.cursor/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  149. package/.cursor/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -36
  150. package/.cursor/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  151. package/.cursor/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  152. package/.cursor/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  153. package/.cursor/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  154. package/.cursor/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  155. package/.cursor/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  156. package/.cursor/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  157. package/.cursor/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  158. package/.cursor/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  159. package/.cursor/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  160. package/.cursor/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  161. package/.cursor/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -57
  162. package/.cursor/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  163. package/.cursor/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  164. package/.cursor/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  165. package/.cursor/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  166. package/.cursor/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  167. package/.cursor/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  168. package/.cursor/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  169. package/.cursor/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  170. package/.cursor/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  171. package/.cursor/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  172. package/.cursor/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  173. package/.cursor/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  174. package/.cursor/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  175. package/.cursor/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  176. package/.cursor/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  177. package/.cursor/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  178. package/.cursor/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  179. package/.cursor/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  180. package/.cursor/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  181. package/.cursor/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  182. package/.cursor/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  183. package/.cursor/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  184. package/.cursor/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  185. package/.cursor/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  186. package/.cursor/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  187. package/.cursor/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  188. package/.cursor/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  189. package/.cursor/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  190. package/.cursor/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  191. package/.cursor/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  192. package/src/features/PluginStore/Content.tsx +0 -54
  193. package/src/features/PluginStore/InstalledList/Detail/CustomPluginEmptyState.tsx +0 -79
  194. package/src/features/PluginStore/InstalledList/Detail/index.tsx +0 -21
  195. package/src/features/PluginStore/InstalledList/List/Item/index.tsx +0 -61
  196. package/src/features/PluginStore/InstalledList/List/index.tsx +0 -72
  197. package/src/features/PluginStore/InstalledList/index.tsx +0 -90
  198. package/src/features/PluginStore/McpList/List/Action.tsx +0 -119
  199. package/src/features/PluginStore/McpList/List/Item.tsx +0 -83
  200. package/src/features/PluginStore/McpList/List/index.tsx +0 -93
  201. package/src/features/PluginStore/McpList/index.tsx +0 -58
  202. package/src/features/PluginStore/PluginList/Detail/DetailProvider.tsx +0 -19
  203. package/src/features/PluginStore/PluginList/Detail/EmptyState.tsx +0 -56
  204. package/src/features/PluginStore/PluginList/Detail/Header.tsx +0 -130
  205. package/src/features/PluginStore/PluginList/Detail/InstallDetail/Nav.tsx +0 -73
  206. package/src/features/PluginStore/PluginList/Detail/InstallDetail/Settings.tsx +0 -19
  207. package/src/features/PluginStore/PluginList/Detail/InstallDetail/Tools.tsx +0 -111
  208. package/src/features/PluginStore/PluginList/Detail/InstallDetail/index.tsx +0 -24
  209. package/src/features/PluginStore/PluginList/Detail/Loading.tsx +0 -42
  210. package/src/features/PluginStore/PluginList/Detail/TagList.tsx +0 -35
  211. package/src/features/PluginStore/PluginList/Detail/index.tsx +0 -39
  212. package/src/features/PluginStore/PluginList/Detail/useCategory.tsx +0 -76
  213. package/src/features/PluginStore/PluginList/List/Action.tsx +0 -78
  214. package/src/features/PluginStore/PluginList/List/Item.tsx +0 -92
  215. package/src/features/PluginStore/PluginList/List/index.tsx +0 -94
  216. package/src/features/PluginStore/PluginList/index.tsx +0 -46
  217. package/src/features/PluginStore/Search/index.tsx +0 -40
  218. /package/{.codex/skills → .agents}/vercel-react-best-practices/AGENTS.md +0 -0
  219. /package/{.codex/skills → .agents}/vercel-react-best-practices/SKILL.md +0 -0
  220. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -0
  221. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/advanced-use-latest.md +0 -0
  222. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-api-routes.md +0 -0
  223. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-defer-await.md +0 -0
  224. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-dependencies.md +0 -0
  225. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-parallel.md +0 -0
  226. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -0
  227. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -0
  228. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-conditional.md +0 -0
  229. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -0
  230. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -0
  231. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-preload.md +0 -0
  232. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-event-listeners.md +0 -0
  233. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -0
  234. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -0
  235. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-swr-dedup.md +0 -0
  236. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -0
  237. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-function-results.md +0 -0
  238. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-property-access.md +0 -0
  239. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-storage.md +0 -0
  240. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-combine-iterations.md +0 -0
  241. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-early-exit.md +0 -0
  242. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -0
  243. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-index-maps.md +0 -0
  244. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-length-check-first.md +0 -0
  245. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-min-max-loop.md +0 -0
  246. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -0
  247. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -0
  248. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-activity.md +0 -0
  249. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -0
  250. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -0
  251. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -0
  252. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -0
  253. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -0
  254. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -0
  255. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -0
  256. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-dependencies.md +0 -0
  257. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-derived-state.md +0 -0
  258. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -0
  259. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -0
  260. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-memo.md +0 -0
  261. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-transitions.md +0 -0
  262. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -0
  263. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-cache-lru.md +0 -0
  264. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-cache-react.md +0 -0
  265. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -0
  266. /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-serialization.md +0 -0
  267. /package/src/{features/PluginStore/InstalledList → app/[variants]/(main)/settings/skill/features}/EditCustomPlugin.tsx +0 -0
  268. /package/src/features/{PluginStore/McpList/Detail → MCP/MCPDetail}/Loading.tsx +0 -0
  269. /package/src/features/{PluginStore → SkillStore}/Loading.tsx +0 -0
  270. /package/src/features/{PluginStore → SkillStore}/VirtuosoLoading.tsx +0 -0
@@ -1,8 +1,8 @@
1
1
  import { Button, Flexbox, Icon, Input, Text } from '@lobehub/ui';
2
- import { Form as AForm, App, Space } from 'antd';
2
+ import { Form as AForm, App } from 'antd';
3
3
  import { createStaticStyles } from 'antd-style';
4
- import { EditIcon, LinkIcon, SaveIcon, Settings2Icon, TerminalIcon } from 'lucide-react';
5
- import { memo, useState } from 'react';
4
+ import { EditIcon, LinkIcon, Settings2Icon, TerminalIcon } from 'lucide-react';
5
+ import { forwardRef, useImperativeHandle, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
8
  import KeyValueEditor from '@/components/KeyValueEditor';
@@ -148,7 +148,17 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
148
148
  `,
149
149
  }));
150
150
 
151
- const Settings = memo<{ identifier: string }>(({ identifier }) => {
151
+ export interface SettingsRef {
152
+ reset: () => void;
153
+ save: () => Promise<void>;
154
+ }
155
+
156
+ interface SettingsProps {
157
+ hideFooter?: boolean;
158
+ identifier: string;
159
+ }
160
+
161
+ const Settings = forwardRef<SettingsRef, SettingsProps>(({ identifier, hideFooter }, ref) => {
152
162
  const { t } = useTranslation(['plugin', 'common']);
153
163
  const [connectionForm] = AForm.useForm();
154
164
  const [envForm] = AForm.useForm();
@@ -162,6 +172,20 @@ const Settings = memo<{ identifier: string }>(({ identifier }) => {
162
172
  ]);
163
173
  const { message } = App.useApp();
164
174
 
175
+ useImperativeHandle(ref, () => ({
176
+ reset: () => {
177
+ connectionForm.resetFields();
178
+ envForm.resetFields();
179
+ setIsEditingConnection(false);
180
+ },
181
+ save: async () => {
182
+ if (isEditingConnection) {
183
+ await connectionForm.submit();
184
+ }
185
+ await envForm.submit();
186
+ },
187
+ }));
188
+
165
189
  // 获取已安装插件信息
166
190
  const installedPlugin = useToolStore(pluginSelectors.getInstalledPluginById(identifier));
167
191
  const pluginSettings = useToolStore(pluginSelectors.getPluginSettingsById(identifier));
@@ -305,19 +329,12 @@ const Settings = memo<{ identifier: string }>(({ identifier }) => {
305
329
  </AForm.Item>
306
330
  </>
307
331
  )}
308
- <div className={styles.footer}>
309
- <Space>
310
- <Button
311
- htmlType="submit"
312
- icon={<SaveIcon size={12} />}
313
- loading={connectionLoading}
314
- type="primary"
315
- >
316
- {t('common:save')}
317
- </Button>
318
- <Button onClick={handleCancelEdit}>{t('common:cancel')}</Button>
319
- </Space>
320
- </div>
332
+ <Flexbox className={styles.footer} gap={8} horizontal>
333
+ <Button htmlType="submit" loading={connectionLoading} type="primary">
334
+ {t('common:save')}
335
+ </Button>
336
+ <Button onClick={handleCancelEdit}>{t('common:cancel')}</Button>
337
+ </Flexbox>
321
338
  </AForm>
322
339
  </div>
323
340
  )}
@@ -345,19 +362,14 @@ const Settings = memo<{ identifier: string }>(({ identifier }) => {
345
362
  keyPlaceholder="VARIABLE_NAME"
346
363
  />
347
364
  </AForm.Item>
348
- <div className={styles.footer}>
349
- <Space>
350
- <Button
351
- htmlType="submit"
352
- icon={<SaveIcon size={14} />}
353
- loading={loading}
354
- type="primary"
355
- >
365
+ {!hideFooter && (
366
+ <Flexbox className={styles.footer} gap={8} horizontal>
367
+ <Button htmlType="submit" loading={loading} type="primary">
356
368
  {t('common:save')}
357
369
  </Button>
358
370
  <Button onClick={() => envForm.resetFields()}>{t('common:reset')}</Button>
359
- </Space>
360
- </div>
371
+ </Flexbox>
372
+ )}
361
373
  </AForm>
362
374
  </Flexbox>
363
375
  )}
@@ -42,8 +42,8 @@ const PluginDetailModal = memo<PluginDetailModalProps>(
42
42
  onClose();
43
43
  }}
44
44
  open={open}
45
- title={t('detailModal.title')}
46
- width={650}
45
+ title={t('dev.title.skillDetails')}
46
+ width={800}
47
47
  >
48
48
  <Meta id={id} />
49
49
  <Segmented
@@ -1,18 +1,15 @@
1
1
  import { TITLE_BAR_HEIGHT } from '@lobechat/desktop-bridge';
2
- import { Alert, Button, Drawer, Flexbox, Icon, Segmented, Tag } from '@lobehub/ui';
2
+ import { Button, Drawer, Flexbox, Segmented, Tag } from '@lobehub/ui';
3
3
  import { App, Form, Popconfirm } from 'antd';
4
4
  import { useResponsive } from 'antd-style';
5
- import { MoveUpRight } from 'lucide-react';
6
5
  import { memo, useEffect, useState } from 'react';
7
- import { Trans, useTranslation } from 'react-i18next';
6
+ import { useTranslation } from 'react-i18next';
8
7
 
9
- import { WIKI_PLUGIN_GUIDE } from '@/const/url';
10
8
  import { isDesktop } from '@/const/version';
11
9
  import { type LobeToolCustomPlugin } from '@/types/tool/plugin';
12
10
 
13
11
  import MCPManifestForm from './MCPManifestForm';
14
12
  import PluginPreview from './PluginPreview';
15
- import UrlManifestForm from './UrlManifestForm';
16
13
 
17
14
  interface DevModalProps {
18
15
  mode?: 'edit' | 'create';
@@ -27,7 +24,7 @@ interface DevModalProps {
27
24
  const DevModal = memo<DevModalProps>(
28
25
  ({ open, mode = 'create', value, onValueChange, onSave, onOpenChange, onDelete }) => {
29
26
  const isEditMode = mode === 'edit';
30
- const [configMode, setConfigMode] = useState<'url' | 'mcp'>('mcp');
27
+ const [configMode, setConfigMode] = useState<'mcp' | 'claude'>('mcp');
31
28
  const { t } = useTranslation('plugin');
32
29
  const { message } = App.useApp();
33
30
 
@@ -129,7 +126,7 @@ const DevModal = memo<DevModalProps>(
129
126
  height: '100%',
130
127
  },
131
128
  }}
132
- title={t(isEditMode ? 'dev.title.edit' : 'dev.title.create')}
129
+ title={t(isEditMode ? 'dev.title.skillSettings' : 'dev.title.create')}
133
130
  width={mobile ? '100%' : 800}
134
131
  >
135
132
  <Flexbox
@@ -144,55 +141,34 @@ const DevModal = memo<DevModalProps>(
144
141
  <Segmented
145
142
  block
146
143
  onChange={(e) => {
147
- setConfigMode(e as 'url' | 'mcp');
144
+ if (e === 'claude') return; // Claude Skill is disabled
145
+ setConfigMode(e as 'mcp' | 'claude');
148
146
  }}
149
147
  options={[
150
148
  {
149
+ label: t('dev.manifest.mode.mcp'),
150
+ value: 'mcp',
151
+ },
152
+ {
153
+ disabled: true,
151
154
  label: (
152
155
  <Flexbox align={'center'} gap={4} horizontal justify={'center'}>
153
- {t('dev.manifest.mode.mcp')}
156
+ {t('dev.manifest.mode.claude')}
154
157
  <div>
155
- <Tag color={'warning'} variant={'filled'}>
156
- {t('dev.manifest.mode.mcpExp')}
158
+ <Tag variant={'filled'}>
159
+ {t('dev.manifest.mode.claudeWip')}
157
160
  </Tag>
158
161
  </div>
159
162
  </Flexbox>
160
163
  ),
161
- value: 'mcp',
162
- },
163
- {
164
- label: t('dev.manifest.mode.url'),
165
- value: 'url',
164
+ value: 'claude',
166
165
  },
167
166
  ]}
168
167
  value={configMode}
169
168
  variant={'filled'}
170
169
  />
171
170
 
172
- {configMode === 'url' && (
173
- <>
174
- <Alert
175
- showIcon
176
- title={
177
- <Trans i18nKey={'dev.modalDesc'} ns={'plugin'}>
178
- 添加自定义插件后,可用于插件开发验证,也可直接在会话中使用。插件开发文档请参考:
179
- <a
180
- href={WIKI_PLUGIN_GUIDE}
181
- rel="noreferrer"
182
- style={{ paddingInline: 8 }}
183
- target={'_blank'}
184
- >
185
- 文档
186
- </a>
187
- <Icon icon={MoveUpRight} />
188
- </Trans>
189
- }
190
- type={'info'}
191
- />
192
- <UrlManifestForm form={form} isEditMode={isEditMode} />
193
- </>
194
- )}
195
- {configMode === 'mcp' && <MCPManifestForm form={form} isEditMode={isEditMode} />}
171
+ <MCPManifestForm form={form} isEditMode={isEditMode} />
196
172
  </Flexbox>
197
173
  <PluginPreview form={form} />
198
174
  </Flexbox>
@@ -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 PluginStore from '@/features/PluginStore';
21
+ import SkillStore from '@/features/SkillStore';
22
22
  import { useCheckPluginsIsInstalled } from '@/hooks/useCheckPluginsIsInstalled';
23
23
  import { useFetchInstalledPlugins } from '@/hooks/useFetchInstalledPlugins';
24
24
  import { useAgentStore } from '@/store/agent';
@@ -625,7 +625,7 @@ const AgentTool = memo<AgentToolProps>(
625
625
  </Flexbox>
626
626
 
627
627
  {/* PluginStore Modal - rendered outside Flexbox to avoid event interference */}
628
- {modalOpen && <PluginStore open={modalOpen} setOpen={setModalOpen} />}
628
+ {modalOpen && <SkillStore open={modalOpen} setOpen={setModalOpen} />}
629
629
  </>
630
630
  );
631
631
  },
@@ -5,7 +5,7 @@ import { App } from 'antd';
5
5
  import { memo, useCallback, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import DetailLoading from '@/features/PluginStore/McpList/Detail/Loading';
8
+ import DetailLoading from '@/features/MCP/MCPDetail/Loading';
9
9
  import { useAgentStore } from '@/store/agent';
10
10
  import { useDiscoverStore } from '@/store/discover';
11
11
  import { useToolStore } from '@/store/tool';
@@ -7,7 +7,7 @@ import DevModal from '@/features/PluginDevModal';
7
7
  import { useAgentStore } from '@/store/agent';
8
8
  import { useToolStore } from '@/store/tool';
9
9
 
10
- const AddPluginButton = forwardRef<HTMLButtonElement>((props, ref) => {
10
+ const AddSkillButton = forwardRef<HTMLButtonElement>((props, ref) => {
11
11
  const { t } = useTranslation('setting');
12
12
  const [showModal, setModal] = useState(false);
13
13
 
@@ -39,10 +39,10 @@ const AddPluginButton = forwardRef<HTMLButtonElement>((props, ref) => {
39
39
  }}
40
40
  ref={ref}
41
41
  >
42
- {t('plugin.addMCPPlugin')}
42
+ {t('tab.addCustomSkill')}
43
43
  </Button>
44
44
  </div>
45
45
  );
46
46
  });
47
47
 
48
- export default AddPluginButton;
48
+ export default AddSkillButton;
@@ -0,0 +1,158 @@
1
+ 'use client';
2
+
3
+ import { ActionIcon, Block, DropdownMenu, Flexbox, Icon, Modal } from '@lobehub/ui';
4
+ import { App, Button } from 'antd';
5
+ import isEqual from 'fast-deep-equal';
6
+ import { MoreVerticalIcon, Plus, Trash2 } from 'lucide-react';
7
+ import React, { memo, useState } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ import PluginAvatar from '@/components/Plugins/PluginAvatar';
11
+ import MCPInstallProgress from '@/features/MCP/MCPInstallProgress';
12
+ import McpDetail from '@/features/MCP/MCPDetail';
13
+ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
14
+ import { useAgentStore } from '@/store/agent';
15
+ import { agentSelectors } from '@/store/agent/selectors';
16
+ import { useToolStore } from '@/store/tool';
17
+ import { mcpStoreSelectors, pluginSelectors } from '@/store/tool/selectors';
18
+ import { type DiscoverMcpItem } from '@/types/discover';
19
+
20
+ import { useItemStyles } from '../style';
21
+
22
+ const Item = memo<DiscoverMcpItem>(({ name, description, icon, identifier }) => {
23
+ const { styles } = useItemStyles();
24
+ const { t } = useTranslation('plugin');
25
+ const { modal } = App.useApp();
26
+ const [detailOpen, setDetailOpen] = useState(false);
27
+
28
+ const [installed, installing, installMCPPlugin, cancelInstallMCPPlugin, unInstallPlugin, plugin] =
29
+ useToolStore((s) => [
30
+ pluginSelectors.isPluginInstalled(identifier)(s),
31
+ mcpStoreSelectors.isMCPInstalling(identifier)(s),
32
+ s.installMCPPlugin,
33
+ s.cancelInstallMCPPlugin,
34
+ s.uninstallPlugin,
35
+ mcpStoreSelectors.getPluginById(identifier)(s),
36
+ ]);
37
+
38
+ const installProgress = useToolStore(
39
+ mcpStoreSelectors.getMCPInstallProgress(identifier),
40
+ isEqual,
41
+ );
42
+
43
+ const [togglePlugin, isPluginEnabledInAgent] = useAgentStore((s) => [
44
+ s.togglePlugin,
45
+ agentSelectors.currentAgentPlugins(s).includes(identifier),
46
+ ]);
47
+ const { isAuthenticated, signIn } = useMarketAuth();
48
+
49
+ const isCloudMcp = !!((plugin as any)?.cloudEndPoint || (plugin as any)?.haveCloudEndpoint);
50
+
51
+ const handleInstall = async () => {
52
+ if (isCloudMcp && !isAuthenticated) {
53
+ try {
54
+ await signIn();
55
+ } catch {
56
+ return;
57
+ }
58
+ }
59
+
60
+ const isSuccess = await installMCPPlugin(identifier);
61
+
62
+ if (isSuccess) {
63
+ await togglePlugin(identifier);
64
+ }
65
+ };
66
+
67
+ const handleCancel = async () => {
68
+ await cancelInstallMCPPlugin(identifier);
69
+ };
70
+
71
+ const renderAction = () => {
72
+ if (installed) {
73
+ return (
74
+ <DropdownMenu
75
+ items={[
76
+ {
77
+ danger: true,
78
+ icon: <Icon icon={Trash2} />,
79
+ key: 'uninstall',
80
+ label: t('store.actions.uninstall'),
81
+ onClick: () => {
82
+ modal.confirm({
83
+ centered: true,
84
+ okButtonProps: { danger: true },
85
+ onOk: async () => {
86
+ if (isPluginEnabledInAgent) {
87
+ await togglePlugin(identifier, false);
88
+ }
89
+ await unInstallPlugin(identifier);
90
+ },
91
+ title: t('store.actions.confirmUninstall'),
92
+ type: 'error',
93
+ });
94
+ },
95
+ },
96
+ ]}
97
+ placement="bottomRight"
98
+ >
99
+ <ActionIcon icon={MoreVerticalIcon} />
100
+ </DropdownMenu>
101
+ );
102
+ }
103
+
104
+ if (installing) {
105
+ return (
106
+ <Button onClick={handleCancel} size="small" variant={'filled'}>
107
+ {t('store.actions.cancel')}
108
+ </Button>
109
+ );
110
+ }
111
+
112
+ return <ActionIcon icon={Plus} onClick={handleInstall} title={t('store.actions.install')} />;
113
+ };
114
+
115
+ return (
116
+ <>
117
+ <Flexbox className={styles.container} gap={0}>
118
+ <Block
119
+ align={'center'}
120
+ gap={12}
121
+ horizontal
122
+ onClick={() => setDetailOpen(true)}
123
+ paddingBlock={12}
124
+ paddingInline={12}
125
+ style={{ cursor: 'pointer' }}
126
+ variant={'filled'}
127
+ >
128
+ <PluginAvatar avatar={icon} size={40} />
129
+ <Flexbox flex={1} gap={4} style={{ minWidth: 0, overflow: 'hidden' }}>
130
+ <span className={styles.title}>{name}</span>
131
+ {description && <span className={styles.description}>{description}</span>}
132
+ </Flexbox>
133
+ <div onClick={(e) => e.stopPropagation()}>{renderAction()}</div>
134
+ </Block>
135
+
136
+ {!!installProgress && (
137
+ <Flexbox paddingInline={12}>
138
+ <MCPInstallProgress identifier={identifier} />
139
+ </Flexbox>
140
+ )}
141
+ </Flexbox>
142
+ <Modal
143
+ destroyOnHidden
144
+ footer={null}
145
+ onCancel={() => setDetailOpen(false)}
146
+ open={detailOpen}
147
+ title={t('dev.title.skillDetails')}
148
+ width={800}
149
+ >
150
+ <McpDetail identifier={identifier} noSettings />
151
+ </Modal>
152
+ </>
153
+ );
154
+ });
155
+
156
+ Item.displayName = 'CommunityListItem';
157
+
158
+ export default Item;
@@ -0,0 +1,101 @@
1
+ 'use client';
2
+
3
+ import { Center, Flexbox, Icon, Text } from '@lobehub/ui';
4
+ import { ServerCrash } from 'lucide-react';
5
+ import { memo, useEffect } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { Virtuoso } from 'react-virtuoso';
8
+
9
+ import { useToolStore } from '@/store/tool';
10
+
11
+ import Empty from '../Empty';
12
+ import Loading from '../Loading';
13
+ import VirtuosoLoading from '../VirtuosoLoading';
14
+ import Item from './Item';
15
+
16
+ export const CommunityList = memo(() => {
17
+ const { t } = useTranslation('setting');
18
+
19
+ const [
20
+ keywords,
21
+ isMcpListInit,
22
+ allItems,
23
+ totalCount,
24
+ currentPage,
25
+ searchLoading,
26
+ useFetchMCPPluginList,
27
+ loadMoreMCPPlugins,
28
+ resetMCPPluginList,
29
+ ] = useToolStore((s) => [
30
+ s.mcpSearchKeywords,
31
+ s.isMcpListInit,
32
+ s.mcpPluginItems,
33
+ s.totalCount,
34
+ s.currentPage,
35
+ s.searchLoading,
36
+ s.useFetchMCPPluginList,
37
+ s.loadMoreMCPPlugins,
38
+ s.resetMCPPluginList,
39
+ ]);
40
+
41
+ useEffect(() => {
42
+ resetMCPPluginList(keywords);
43
+ }, [keywords, resetMCPPluginList]);
44
+
45
+ const { isLoading, error } = useFetchMCPPluginList({
46
+ page: currentPage,
47
+ pageSize: 20,
48
+ q: keywords,
49
+ });
50
+
51
+ const hasSearchKeywords = Boolean(keywords && keywords.trim());
52
+
53
+ const renderContent = () => {
54
+ // Show loading when searching, not initialized, or first page is loading with no items
55
+ if (searchLoading || !isMcpListInit || (isLoading && allItems.length === 0)) return <Loading />;
56
+
57
+ if (error) {
58
+ return (
59
+ <Center gap={12} padding={40}>
60
+ <Icon icon={ServerCrash} size={80} />
61
+ <Text type={'secondary'}>{t('skillStore.networkError')}</Text>
62
+ </Center>
63
+ );
64
+ }
65
+
66
+ if (allItems.length === 0) return <Empty search={hasSearchKeywords} />;
67
+
68
+ return (
69
+ <Virtuoso
70
+ components={{
71
+ Footer: isLoading ? VirtuosoLoading : undefined,
72
+ }}
73
+ data={allItems}
74
+ endReached={loadMoreMCPPlugins}
75
+ increaseViewportBy={typeof window !== 'undefined' ? window.innerHeight : 0}
76
+ itemContent={(index) => {
77
+ const item = allItems[index];
78
+ // Render two items per row
79
+ if (index % 2 !== 0) return null;
80
+
81
+ const nextItem = allItems[index + 1];
82
+ return (
83
+ <Flexbox gap={12} horizontal paddingInline={16} style={{ paddingBottom: 12 }}>
84
+ <Item {...item} />
85
+ {nextItem && <Item {...nextItem} />}
86
+ </Flexbox>
87
+ );
88
+ }}
89
+ overscan={24}
90
+ style={{ height: '60vh', width: '100%' }}
91
+ totalCount={Math.ceil((totalCount || 0) / 2)}
92
+ />
93
+ );
94
+ };
95
+
96
+ return renderContent();
97
+ });
98
+
99
+ CommunityList.displayName = 'CommunityList';
100
+
101
+ export default CommunityList;
@@ -0,0 +1,59 @@
1
+ 'use client';
2
+
3
+ import { Flexbox, Segmented } from '@lobehub/ui';
4
+ import { type SegmentedOptions } from 'antd/es/segmented';
5
+ import { memo, useState } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+
8
+ import AddSkillButton from './AddSkillButton';
9
+
10
+ import CommunityList from './CommunityList';
11
+ import LobeHubList from './LobeHubList';
12
+ import Search from './Search';
13
+
14
+ export enum SkillStoreTab {
15
+ Community = 'community',
16
+ LobeHub = 'lobehub',
17
+ }
18
+
19
+ export const Content = memo(() => {
20
+ const { t } = useTranslation('setting');
21
+ const [activeTab, setActiveTab] = useState<SkillStoreTab>(SkillStoreTab.LobeHub);
22
+ const [lobehubKeywords, setLobehubKeywords] = useState('');
23
+
24
+ const options: SegmentedOptions = [
25
+ { label: t('skillStore.tabs.lobehub'), value: SkillStoreTab.LobeHub },
26
+ { label: t('skillStore.tabs.community'), value: SkillStoreTab.Community },
27
+ ];
28
+
29
+ const isLobeHub = activeTab === SkillStoreTab.LobeHub;
30
+
31
+ return (
32
+ <Flexbox gap={8} style={{ maxHeight: '75vh' }} width={'100%'}>
33
+ <Flexbox gap={8} paddingInline={16}>
34
+ <Flexbox align="center" gap={8} horizontal>
35
+ <Segmented
36
+ block
37
+ onChange={(v) => setActiveTab(v as SkillStoreTab)}
38
+ options={options}
39
+ style={{ flex: 1 }}
40
+ value={activeTab}
41
+ variant={'filled'}
42
+ />
43
+ <AddSkillButton />
44
+ </Flexbox>
45
+ <Search activeTab={activeTab} onLobeHubSearch={setLobehubKeywords} />
46
+ </Flexbox>
47
+ <Flexbox flex={1} style={{ display: isLobeHub ? 'flex' : 'none', overflow: 'auto' }}>
48
+ <LobeHubList keywords={lobehubKeywords} />
49
+ </Flexbox>
50
+ <Flexbox flex={1} style={{ display: !isLobeHub ? 'flex' : 'none', overflow: 'auto' }}>
51
+ <CommunityList />
52
+ </Flexbox>
53
+ </Flexbox>
54
+ );
55
+ });
56
+
57
+ Content.displayName = 'SkillStoreContent';
58
+
59
+ export default Content;
@@ -1,19 +1,19 @@
1
- import { Center, Empty, type EmptyProps } from '@lobehub/ui';
1
+ import { Center, Empty as EmptyComponent, type EmptyProps } from '@lobehub/ui';
2
2
  import { Plug2 } from 'lucide-react';
3
3
  import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- interface PluginEmptyProps extends Omit<EmptyProps, 'icon'> {
6
+ interface SkillEmptyProps extends Omit<EmptyProps, 'icon'> {
7
7
  search?: boolean;
8
8
  }
9
9
 
10
- const PluginEmpty = memo<PluginEmptyProps>(({ search, ...rest }) => {
11
- const { t } = useTranslation('plugin');
10
+ const Empty = memo<SkillEmptyProps>(({ search, ...rest }) => {
11
+ const { t } = useTranslation('setting');
12
12
 
13
13
  return (
14
14
  <Center height="100%" style={{ minHeight: '50vh' }} width="100%">
15
- <Empty
16
- description={search ? t('empty.search') : t('empty.description')}
15
+ <EmptyComponent
16
+ description={search ? t('skillStore.emptySearch') : t('skillStore.empty')}
17
17
  descriptionProps={{
18
18
  fontSize: 14,
19
19
  }}
@@ -27,6 +27,6 @@ const PluginEmpty = memo<PluginEmptyProps>(({ search, ...rest }) => {
27
27
  );
28
28
  });
29
29
 
30
- PluginEmpty.displayName = 'PluginEmpty';
30
+ Empty.displayName = 'SkillEmpty';
31
31
 
32
- export default PluginEmpty;
32
+ export default Empty;