From 8349db9947907a0afd8931e2bb9a8cfe90a9c504 Mon Sep 17 00:00:00 2001 From: Rick Ye Date: Fri, 11 Sep 2026 01:18:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=A0=B8=E5=BF=83=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E4=B8=8E=E6=8F=92=E4=BB=B6=E9=A1=B5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E2=80=94=E2=80=94=E6=8F=92=E4=BB=B6=E9=A1=B5=E6=8C=89=20?= =?UTF-8?q?=E5=86=85=E7=BD=AE/=E5=85=A8=E5=B1=80/=E9=A1=B9=E7=9B=AE=20?= =?UTF-8?q?=E4=B8=89=E4=BD=9C=E7=94=A8=E5=9F=9F=E7=BB=9F=E4=B8=80=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../renderer/src/components/SettingsModal.tsx | 104 +++++------------- 1 file changed, 28 insertions(+), 76 deletions(-) diff --git a/apps/desktop/src/renderer/src/components/SettingsModal.tsx b/apps/desktop/src/renderer/src/components/SettingsModal.tsx index e227087..8301882 100644 --- a/apps/desktop/src/renderer/src/components/SettingsModal.tsx +++ b/apps/desktop/src/renderer/src/components/SettingsModal.tsx @@ -30,7 +30,7 @@ import type { import { THEME_MODES, THEME_PRESETS, applyThemeColor } from '../lib/theme' import { usePluginList } from '../plugins/store' -type Tab = 'general' | 'corePlugins' | 'model' | 'prompt' | 'plugins' | 'skills' | 'commands' +type Tab = 'general' | 'model' | 'prompt' | 'plugins' | 'skills' | 'commands' /** 左侧分组导航(参考 ZCode 设置页:基础设置 / Agent 能力) */ const NAV: Array<{ group: string; items: Array<{ id: Tab; label: string; icon: IconType }> }> = [ @@ -39,8 +39,7 @@ const NAV: Array<{ group: string; items: Array<{ id: Tab; label: string; icon: I items: [ { id: 'general', label: '常规', icon: LuSettings2 }, { id: 'model', label: '模型设置', icon: LuCpu }, - { id: 'prompt', label: '系统提示词', icon: LuTextQuote }, - { id: 'corePlugins', label: '核心插件', icon: LuPuzzle } + { id: 'prompt', label: '系统提示词', icon: LuTextQuote } ] }, { @@ -55,10 +54,9 @@ const NAV: Array<{ group: string; items: Array<{ id: Tab; label: string; icon: I const TAB_META: Record = { general: { title: '常规', desc: '主题色等外观偏好。' }, - corePlugins: { title: '核心插件', desc: '内置的第一方功能插件,官方维护' }, model: { title: '模型设置', desc: '' }, prompt: { title: '系统提示词', desc: '' }, - plugins: { title: '插件', desc: '第三方扩展插件(全局 / 项目目录),按需启停。' }, + plugins: { title: '插件', desc: '扩展插件(内置 / 全局 / 项目),按需启停。' }, skills: { title: '技能', desc: 'SKILL.md 技能包,Agent 自动按需加载。' }, commands: { title: '命令', desc: '聊天中 / 触发的自定义命令模板。' } } @@ -628,74 +626,22 @@ function ModelSettings({ ) } -/** 核心插件页:内置插件列表 + 启停开关(单一事实源在主进程,listChanged 事件驱动刷新) */ -function CorePluginPanel({ - togglingId, - onToggle -}: { - /** 正在切换中的插件 id(切换期间全部开关禁用,避免并发重建运行时) */ - togglingId: string | null - onToggle: (plugin: PluginInfo, next: boolean) => void -}): ReactNode { - // 本页只管核心(内置)插件;外置插件留给「Agent 能力 → 插件」 - const core = usePluginList().filter((p) => p.source === 'builtin') - if (core.length === 0) { - return ( -
-
暂无核心插件
-
- ) - } - return ( -
- {core - .slice() - .sort((a, b) => (a.manifest.order ?? 100) - (b.manifest.order ?? 100) || a.manifest.id.localeCompare(b.manifest.id)) - .map((p) => ( -
-
- {p.manifest.name} - 内置 v{p.manifest.version} - {p.enabled ? '已启用' : '已停用'} - -
- {p.manifest.description &&
{p.manifest.description}
} - {p.error &&
装载失败:{p.error}
} -
- ))} -
- ) -} - -/** 第三方插件页:全局/项目两个作用域(交互对齐技能页),行内启停开关与核心插件相同 */ -function ExternalPluginPanel({ +/** 插件页:内置 / 全局 / 项目三个作用域统一管理(交互对齐技能页),行内启停开关;单一事实源在主进程,listChanged 驱动刷新 */ +function PluginsPanel({ togglingId, onToggle, devBuild, onOpenDir }: { + /** 正在切换中的插件 id(切换期间全部开关禁用,避免并发重建运行时) */ togglingId: string | null onToggle: (plugin: PluginInfo, next: boolean) => void /** 开发版构建(第三方装载开关开启);用户版展示关闭提示 */ devBuild: boolean onOpenDir: (path: string) => void }): ReactNode { - const external = usePluginList().filter((p) => p.source === 'external') - const [scope, setScope] = useState<'user' | 'project'>('user') + const plugins = usePluginList() + const [scope, setScope] = useState<'user' | 'project' | 'builtin'>('user') const [dirs, setDirs] = useState<{ user: string[]; project: string[]; global: string[] }>({ user: [], project: [], @@ -713,16 +659,19 @@ function ExternalPluginPanel({ alive = false } }, []) - // 全局作用域 = 全局扩展目录(含应用外置目录,统一按全局展示);项目作用域 = 当前工作区 .pi/extensions - const scoped = external.filter((p) => (scope === 'project' ? p.origin === 'project' : p.origin !== 'project')) - const scopedDirs = (scope === 'user' ? dirs.global : dirs.project).filter(Boolean) + + const scoped = + scope === 'builtin' + ? plugins.filter((p) => p.source === 'builtin') + : plugins.filter((p) => p.source === 'external' && (scope === 'project' ? p.origin === 'project' : p.origin !== 'project')) + const scopedDirs = scope === 'user' ? dirs.global : scope === 'project' ? dirs.project : [] const scopedHints = scope === 'user' ? ['全局'] : ['项目'] return (
- {(['user', 'project'] as const).map((s) => ( + {(['user', 'project', 'builtin'] as const).map((s) => ( ))}
@@ -753,11 +702,12 @@ function ExternalPluginPanel({ {scoped.length === 0 ? (
- {devBuild ? '暂无第三方插件' : '第三方插件装载已关闭(用户版构建)'} + {scope === 'builtin' ? '暂无内置插件' : devBuild ? '暂无第三方插件' : '第三方插件装载已关闭(用户版构建)'}
- {devBuild && ( + {scope !== 'builtin' && devBuild && (
- 把含 manifest.json 的插件目录放入全局(~/.pi/agent/extensions)即可自动识别 + 把含 manifest.json 的插件目录放入 + {scope === 'user' ? '全局(~/.pi/agent/extensions)' : '项目 .pi/extensions/'}即可自动识别
)}
@@ -765,13 +715,16 @@ function ExternalPluginPanel({
{scoped .slice() - .sort((a, b) => a.manifest.id.localeCompare(b.manifest.id)) + .sort( + (a, b) => + (a.manifest.order ?? 100) - (b.manifest.order ?? 100) || a.manifest.id.localeCompare(b.manifest.id) + ) .map((p) => (
{p.manifest.name} - {scope === 'user' ? '全局' : '项目'} v{p.manifest.version} + {scope === 'builtin' ? '内置' : scope === 'user' ? '全局' : '项目'} v{p.manifest.version} {p.enabled ? '已启用' : '已停用'}
)} - {tab === 'corePlugins' && } - {tab === 'plugins' && ( - )} - {tab !== 'general' && tab !== 'corePlugins' && tab !== 'plugins' && tab !== 'model' && tab !== 'prompt' && tab !== 'skills' && tab !== 'commands' && ( + {tab !== 'general' && tab !== 'plugins' && tab !== 'model' && tab !== 'prompt' && tab !== 'skills' && tab !== 'commands' && ( i.id === tab)?.icon ?? LuPuzzle} label={meta.title} /> )}