From bd9b4231329dcb31709c5b4a66343cce43cd2c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 15 Sep 2026 17:26:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E5=B7=B2=E5=90=AF=E7=94=A8Skill=E5=80=99=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从扩展索引读取启用状态并合并内置 Skill 清单 输入提示只展示可用 Skill 并保持取消安全 --- .../ResourceReferenceInput.tsx | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx index 9fbe5a52c..4ba64bd61 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx @@ -491,6 +491,7 @@ function ResourceReferenceEditor({ const skipInitialDraftChangeRef = useRef(false); const [query, setQuery] = useState(null); const [skillQuery, setSkillQuery] = useState(null); + const [clientSkills, setClientSkills] = useState([]); const [pickerOpen, setPickerOpen] = useState(false); // Enter 提交要避开候选浮层。用 ref 让命令处理器读到最新状态,不必因为 // query / pickerOpen 变化反复重注册 HIGH 优先级命令。 @@ -512,6 +513,39 @@ function ResourceReferenceEditor({ bottom: number; width: number; } | null>(null); + useEffect(() => { + const invoke = resolveTauriInvoke(); + if (!invoke) return; + let cancelled = false; + void invoke< + Array<{ + name: string; + extensionType: string; + enabled: boolean; + status: string; + }> + >('list_client_extensions') + .then((items) => { + if (cancelled) return; + setClientSkills( + items + .filter( + (item) => + item.extensionType === 'skill' && + item.enabled && + item.status === 'enabled', + ) + .map((item) => ({ type: 'skill' as const, name: item.name })), + ); + }) + .catch(() => { + if (!cancelled) setClientSkills([]); + }); + return () => { + cancelled = true; + }; + }, []); + const assetsContentSignature = assetsSignature(assets); const versionsContentSignature = iterationsSignature(versions); const assetReferences = useMemo( @@ -573,7 +607,7 @@ function ResourceReferenceEditor({ const skillOptions = useMemo(() => { if (skillQuery === null) return []; const normalized = skillQuery.trim().toLowerCase(); - const allSkills = [...BUILTIN_SKILL_REFERENCES, ...skills]; + const allSkills = [...BUILTIN_SKILL_REFERENCES, ...clientSkills, ...skills]; const seen = new Set(); return allSkills .filter((skill) => { @@ -587,7 +621,7 @@ function ResourceReferenceEditor({ }) .slice(0, 8) .map((skill) => new SkillMentionOption(skill)); - }, [skillQuery, skills]); + }, [clientSkills, skillQuery, skills]); const triggerFn = useBasicTypeaheadTriggerMatch('@', { minLength: 0,