From ae9af725b27fa75363c3025b68d4030ecc548dc3 Mon Sep 17 00:00:00 2001 From: Felix <24791380+vcfgv@users.noreply.github.com> Date: Fri, 24 Apr 2026 10:26:33 +0800 Subject: [PATCH] optimize: skills page structure (#905) --- src/extensions/registry.ts | 6 ++++++ src/extensions/types.ts | 11 +++++++++++ src/pages/Skills/index.tsx | 7 ++++++- vite.config.ts | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/extensions/registry.ts b/src/extensions/registry.ts index 03f11bb..b53f6d4 100644 --- a/src/extensions/registry.ts +++ b/src/extensions/registry.ts @@ -4,7 +4,9 @@ import type { NavItemDef, RouteDef, SettingsSectionDef, + SkillDetailMetaProps, } from './types'; +import type { ComponentType } from 'react'; class RendererExtensionRegistry { private extensions: RendererExtension[] = []; @@ -56,6 +58,10 @@ class RendererExtensionRegistry { .sort((a, b) => (a.order ?? 100) - (b.order ?? 100)); } + getSkillDetailMetaComponents(): ComponentType[] { + return this.extensions.flatMap((ext) => ext.skills?.detailMetaComponents ?? []); + } + async initializeAll(): Promise { for (const ext of this.extensions) { try { diff --git a/src/extensions/types.ts b/src/extensions/types.ts index b8f6550..a5d5ac4 100644 --- a/src/extensions/types.ts +++ b/src/extensions/types.ts @@ -1,4 +1,5 @@ import type { ComponentType } from 'react'; +import type { Skill } from '../types/skill'; export interface NavItemDef { to: string; @@ -37,11 +38,21 @@ export interface SettingsSectionExtension { sections: SettingsSectionDef[]; } +export interface SkillDetailMetaProps { + skill: Skill; +} + +export interface SkillsExtension { + id: string; + detailMetaComponents?: ComponentType[]; +} + export interface RendererExtension { id: string; sidebar?: SidebarExtension; routes?: RouteExtension; settings?: SettingsSectionExtension; + skills?: SkillsExtension; i18nResources?: I18nResources; setup?(): void | Promise; teardown?(): void; diff --git a/src/pages/Skills/index.tsx b/src/pages/Skills/index.tsx index 5c14dbe..dfe13b6 100644 --- a/src/pages/Skills/index.tsx +++ b/src/pages/Skills/index.tsx @@ -33,6 +33,7 @@ import { hostApiFetch } from '@/lib/host-api'; import { trackUiEvent } from '@/lib/telemetry'; import { toast } from 'sonner'; import type { Skill } from '@/types/skill'; +import { rendererExtensionRegistry } from '@/extensions/registry'; import { useTranslation } from 'react-i18next'; import type { TFunction } from 'i18next'; @@ -73,6 +74,7 @@ function SkillDetailDialog({ skill, isOpen, onClose, onToggle, onUninstall, onOp const [envVars, setEnvVars] = useState>([]); const [apiKey, setApiKey] = useState(''); const [isSaving, setIsSaving] = useState(false); + const detailMetaComponents = rendererExtensionRegistry.getSkillDetailMetaComponents(); // Initialize config from skill useEffect(() => { @@ -206,13 +208,16 @@ function SkillDetailDialog({ skill, isOpen, onClose, onToggle, onUninstall, onOp

{skill.name}

-
+
v{skill.version} {skill.isCore ? t('detail.coreSystem') : skill.isBundled ? t('detail.bundled') : t('detail.userInstalled')} + {detailMetaComponents.map((DetailMetaComponent, index) => ( + + ))}
{skill.description && ( diff --git a/vite.config.ts b/vite.config.ts index b652863..be276ef 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -86,6 +86,7 @@ export default defineConfig({ '@': resolve(__dirname, 'src'), '@electron': resolve(__dirname, 'electron'), }, + dedupe: ['react', 'react-dom', 'react-i18next', 'zustand', 'sonner', 'lucide-react'], }, server: { port: 5173,