diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/README.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/README.md new file mode 100644 index 000000000..421ae802e --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/README.md @@ -0,0 +1,26 @@ +# DirectProject 扩展导入阶段 0 样例 + +本目录只保存导入分类和命名契约使用的最小样例,不作为运行时扩展安装目录。阶段 0 不启动其中的 MCP,也不执行 Skill 中的脚本。 + +## 样例与预期 + +| 样例 | 预期拆分 | 备注 | +| --- | --- | --- | +| `single-skill/` | 1 个 Skill:`single-skill` | 根目录 `SKILL.md` | +| `multi-skill/` | 2 个 Skill:`art-skill`、`code-skill` | 一个 Skill root,分别导入 | +| `mcp-config/` | 2 个 MCP:`search`、`filesystem` | 原生 `config.toml` | +| `mcp-json/` | 2 个 MCP:`search`、`filesystem` | 兼容 `.mcp.json` | +| `plugin/` | 1 个 Skill:`plugin-skill` | Plugin 只作为导入来源 | +| `mixed-source/` | 1 个 Skill:`mixed-skill`、2 个 MCP:`search`、`filesystem` | 一个来源拆成多个独立项 | +| `unknown/` | 1 个未知项:`unknown.bin` | 不执行、不作为 MCP 入口 | + +`mixed-source/` 表示目录或 zip 解压后的标准内容。实际 zip 测试可以在测试运行时将该目录压缩为临时归档,不把生成的二进制 zip 提交到仓库。 + +## 阶段 0 固定规则 + +- 一个来源里的每个 Skill 和每个 MCP Server 都是独立扩展项。 +- 导入后已识别项默认启用;未知项保留但不可启动。 +- 同名或重复内容再次导入时保留新项,名称使用原生标识追加 `-2`、`-3`。 +- 前端列表名称和 Codex 运行时名称相同,不维护两套名称。 +- 单个可执行文件或脚本不提供手动指定为 MCP 入口的功能。 +- Plugin 只提取支持的 Skill/MCP,不开启 hooks、apps 或完整 Plugin Runtime。 diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/expected-imports.json b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/expected-imports.json new file mode 100644 index 000000000..01952fb67 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/expected-imports.json @@ -0,0 +1,67 @@ +{ + "schemaVersion": "direct-project-extension-fixture.v1", + "cases": [ + { + "id": "single-skill", + "source": "single-skill", + "items": [ + { "type": "skill", "name": "single-skill" } + ] + }, + { + "id": "multi-skill", + "source": "multi-skill", + "items": [ + { "type": "skill", "name": "art-skill" }, + { "type": "skill", "name": "code-skill" } + ] + }, + { + "id": "mcp-config", + "source": "mcp-config/config.toml", + "items": [ + { "type": "mcp", "name": "search" }, + { "type": "mcp", "name": "filesystem" } + ] + }, + { + "id": "mcp-json", + "source": "mcp-json/.mcp.json", + "items": [ + { "type": "mcp", "name": "search" }, + { "type": "mcp", "name": "filesystem" } + ] + }, + { + "id": "plugin", + "source": "plugin", + "items": [ + { "type": "skill", "name": "plugin-skill" } + ], + "ignoredCapabilities": ["hooks", "apps", "remote_plugin"] + }, + { + "id": "mixed-source", + "source": "mixed-source", + "items": [ + { "type": "skill", "name": "mixed-skill" }, + { "type": "mcp", "name": "search" }, + { "type": "mcp", "name": "filesystem" } + ] + }, + { + "id": "unknown", + "source": "unknown/unknown.bin", + "items": [ + { "type": "unknown", "name": "unknown.bin", "launchable": false } + ] + } + ], + "duplicateImport": { + "source": "single-skill", + "items": [ + { "type": "skill", "name": "single-skill-2" } + ], + "preserveOriginal": true + } +} diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-config/config.toml b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-config/config.toml new file mode 100644 index 000000000..3ab5542bf --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-config/config.toml @@ -0,0 +1,5 @@ +[mcp_servers.search] +command = "fixture-search" + +[mcp_servers.filesystem] +command = "fixture-filesystem" diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-json/.mcp.json b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-json/.mcp.json new file mode 100644 index 000000000..1b638569c --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mcp-json/.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "search": { + "command": "fixture-search" + }, + "filesystem": { + "command": "fixture-filesystem" + } + } +} diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/mcp/config.toml b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/mcp/config.toml new file mode 100644 index 000000000..3ab5542bf --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/mcp/config.toml @@ -0,0 +1,5 @@ +[mcp_servers.search] +command = "fixture-search" + +[mcp_servers.filesystem] +command = "fixture-filesystem" diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/skills/mixed-skill/SKILL.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/skills/mixed-skill/SKILL.md new file mode 100644 index 000000000..6ade141c3 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/mixed-source/skills/mixed-skill/SKILL.md @@ -0,0 +1,8 @@ +--- +name: mixed-skill +description: Stage 0 fixture for a source containing independent Skill and MCP entries. +--- + +# Mixed Source Skill Fixture + +This fixture is used only to verify independent import items. diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/art-skill/SKILL.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/art-skill/SKILL.md new file mode 100644 index 000000000..9bf137047 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/art-skill/SKILL.md @@ -0,0 +1,8 @@ +--- +name: art-skill +description: Stage 0 fixture for an imported art Skill. +--- + +# Art Skill Fixture + +This fixture is used only to verify that one Skill root becomes independent items. diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/code-skill/SKILL.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/code-skill/SKILL.md new file mode 100644 index 000000000..76ac45358 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/multi-skill/skills/code-skill/SKILL.md @@ -0,0 +1,8 @@ +--- +name: code-skill +description: Stage 0 fixture for an imported code Skill. +--- + +# Code Skill Fixture + +This fixture is used only to verify that one Skill root becomes independent items. diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/.codex-plugin/plugin.json b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/.codex-plugin/plugin.json new file mode 100644 index 000000000..cddf17197 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/.codex-plugin/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "stage-0-fixture-plugin", + "version": "0.1.0", + "description": "Fixture for extracting standard Skill content from a Plugin source.", + "skills": "./skills/" +} diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/skills/plugin-skill/SKILL.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/skills/plugin-skill/SKILL.md new file mode 100644 index 000000000..50c6d19bd --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/plugin/skills/plugin-skill/SKILL.md @@ -0,0 +1,8 @@ +--- +name: plugin-skill +description: Stage 0 fixture for a Skill contained in a Plugin. +--- + +# Plugin Skill Fixture + +This fixture is used only to verify Plugin source extraction. diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/single-skill/SKILL.md b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/single-skill/SKILL.md new file mode 100644 index 000000000..6b4b717e2 --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/single-skill/SKILL.md @@ -0,0 +1,8 @@ +--- +name: single-skill +description: Stage 0 fixture for a single imported Skill. +--- + +# Single Skill Fixture + +This fixture is used only to verify discovery and naming. diff --git a/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/unknown/unknown.bin b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/unknown/unknown.bin new file mode 100644 index 000000000..c922f5e9c --- /dev/null +++ b/apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/unknown/unknown.bin @@ -0,0 +1 @@ +This is an inert unknown-file fixture. It must never be executed as an MCP server. diff --git a/docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md b/docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md index 440f8cb0f..1bbdba7b5 100644 --- a/docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md +++ b/docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md @@ -384,6 +384,8 @@ remove_client_extension(id) 准备最小样例并确认每个样例的预期拆分结果。 +阶段 0 样例位于 `apps/ai-game-creator-shell/src-tauri/tests/fixtures/direct_extensions/`,其 `README.md` 和 `expected-imports.json` 是本阶段输入分类、拆分和命名预期的机器可读/人工可读基线。zip 场景使用 `mixed-source/` 在测试运行时生成临时归档,不提交生成的二进制 zip。 + ### 阶段 1:客户端导入和列表 完成: