ZCode 的”插件生态”是三层结构:官方市场(Builtin + CDN 分片)、Personal Source(用户自加)、以及不入市场的系统内置(node-repl-host、bundled-skills)。三者可卸载性、可见性、分发方式完全不同。领域词汇的唯一裁决来源是根目录 CONTEXT.md。
领域词汇(CONTEXT.md)
| 概念 | 定义 |
|---|---|
| Official Marketplace | 官方唯一分发渠道,id = zcode-plugins-official,内容 = Builtin + CDN;是”分发渠道”而非”作者归属” |
| Builtin Plugin | 随应用包分发、启动时 seed 进官方市场的插件(官方插件子集) |
| CDN Plugin | 官方市场中经官方 CDN、以 sha256 校验 zip 分发、按需下载的插件 |
| Personal Source | 用户自行添加的一切来源:claude-plugins-official、git/GitHub/URL/本地目录市场、inline 插件 |
| Store Listing vs Plugin Manifest | Listing 是展示元数据(目录条目);Manifest 是包内 plugin.json 的功能定义 |
| Restorable Builtin | 被卸载并入持久化抑制态的内置插件,重启不自动 reseed,可从 Public Segment 恢复 |
| Orphaned Installed Plugin | Personal Source 被删但安装目录/数据保留的插件,仍可用但不能更新 |
常量在 packages/shared/src/plugin-marketplaces.ts:ZCODE_OFFICIAL_PLUGIN_MARKETPLACE_ID、CLAUDE_OFFICIAL_PLUGIN_MARKETPLACE_ID、DEFAULT_ENABLED_OFFICIAL_PLUGIN_IDS(须与 bootstrap 定义机械对齐)、DEFAULT_PLUGIN_MARKETPLACES(官方 CDN source)。
插件来源(loader 候选)
apps/zcode-cli/packages/adapters/src/plugins/index.ts 的 resolveCandidates()(:238-277)按序收集:
config.dirs→source:"inline",默认启用(本地/导入插件)request.officialPluginRoots→source:"official"(本次 seed/兜底的 Builtin 根)scanOfficialCache()→ 官方 cache 目录(优先读 bundled 分片指向的cachePath)listInstalledPluginRecords()→ 已安装记录(source:"cache")
- 权威 id:
id = ${manifest.name}@${candidate.marketplace}。 - 内置插件被卸载时只在 user config 写
suppressedBuiltins标记,发现层据 id 过滤。 - Manifest 查找顺序:
.zcode-plugin/plugin.json→.claude-plugin/plugin.json→.codex-plugin/plugin.json(兼容 Claude Code / Codex;README 只写了前两者,代码实际还兼容 Codex)。
Plugin Manifest(plugin.json)
规范见 apps/zcode-cli/packages/plugin-creator-plugin/skills/plugin-creator/references/plugin-json-spec.md。最小形态:
{
"name": "my-plugin",
"version": "0.1.0",
"description": "The implemented workflow",
"author": { "name": "Your team" },
"skills": "./skills"
}组件字段:skills / commands(目录路径)、hooks、mcpServers、agents、userConfig。变量:${CLAUDE_PLUGIN_ROOT} / ${ZCODE_PLUGIN_ROOT}、${ZCODE_PROJECT_DIR}、${ZCODE_PLUGIN_DATA}、${user_config.<key>}。
Loader 校验:
name匹配/^[a-z0-9][a-z0-9._-]{0,127}$/,版本缺失兜底0.0.0。- 组件路径必须
resolveInside(pluginRoot),越界报plugin_component_path_invalid。 - 仅诊断字段:
UNSUPPORTED_COMPONENT_KEYS = [channels, lspServers, outputStyles, settings]。 - 插件 skill 根 scope:官方 →
system,其余 →user,source:"plugin"。
官方市场 = 两个分片合并
apps/zcode-cli/packages/adapters/src/plugins/official-marketplace.ts:
- 三文件:
bundled-marketplace.json、cdn-marketplace.json、合并产物marketplace.json,位于<storageRoot>/marketplaces/zcode-plugins-official/。 rebuildOfficialMarketplaceSync():合并两分片,同名时以可刷新的 CDN 条目为准,但不清除内置 cache。loadBundledOfficialPluginRootsSync():从 bundled 分片读cachePath,仅接受位于官方 cache 根下的严格后代路径(信任边界)。
内置插件 seed 机制
apps/zcode-cli/packages/bootstrap/src/app/bundled-plugins.ts:
seedBundledOfficialPlugins():从 filesystem 或 SEA 内嵌资源解析 seed 源,写入官方 cache 原子目录<storageRoot>/cache/zcode-plugins-official/<name>/<version>/。- 原子替换:写唯一临时目录 →
rename→ 旧 target 移 backup;用.zcode-plugin-seed.jsonmarker 记录内容 hash 与版本;并发多进程用 seed lock + 15s 总预算。 - 文件白名单
includedTopLevelPaths:.zcode-plugin、agents、commands、dist、docs、hooks、output-styles、package.json、scripts、skills、templates(runtimeTopLevelPaths可增加如node_modules)。 - 失败降级:单插件缺
requiredSeedPaths只降级该插件,回退可用旧 cache。 - 官方定义清单
official-plugin-definitions.ts的OFFICIAL_PLUGIN_DEFINITIONS,含name/version/rootCandidates/requiredSeedPaths/listing/defaultEnabled/hostMcpServerNames。
插件生命周期
权威用例目录:docs/plugin-management-lifecycle-case-catalog.md(PLM-LC-001…020)与 docs/plugins/workspace-level-plugin-architecture.md。完整路径:
发现 → 查看详情 → 安装 → 配置 → 启停 → 使用 → 检查更新 → 升级
→ 持久化恢复 → 卸载 / 恢复内置- 添加市场
addMarketplace():支持url|github|git|npm|file|directory|hostPattern|pathPattern|settings;先解析 manifest 不落盘 → 官方 id 守卫 → 原子目录激活 → 写known_marketplaces.json。 - 安装
installMarketplacePlugin():解析依赖闭包(禁跨市场依赖除非allowCrossMarketplaceDependenciesOn,检测环),逐个复制/解压到cache/{marketplace}/{plugin}/{version}/,原子提交,写installed_plugins.json。 - 启停/scope:
resolveEnabled()=enabledPlugins[id] ?? defaultEnabled;Workspace/User 优先级workspace ?? user ?? manifest default。 - 更新
updateMarketplace():刷新目录并持久化lastRefreshFailure。 - 卸载 / 恢复内置
uninstallMarketplacePlugin():--keep-data保留 data 目录;内置插件转suppressedBuiltins。 - 来源删除:只删市场记录,已安装插件转 Orphaned(ADR
0003)。
UI Plugin 与 MCP Apps
主文档 UI_PLUGIN.md(中文 48KB)/ UI_PLUGIN.en.md(英文 461 行)。
能力矩阵:交互式 tool results、会话侧面板、页面调 plugin server、与主会话协作、App 内模型调用、页面工具注册、页面状态与资源更新。当前仅本地桌面 workspace 支持;Web/移动/远端只保留普通 MCP tool records。
Manifest ui.surfaces:
{
"mcpServers": { "app": { "type": "stdio", "command": "node",
"args": ["${ZCODE_PLUGIN_ROOT}/dist/server.mjs"], "cwd": "${ZCODE_PROJECT_DIR}" } },
"ui": { "surfaces": [ { "id": "editor", "title": {"en":"Editor","zh-CN":"编辑器"},
"server": "app", "resourceUri": "ui://my-panel/editor.html", "availability": "session" } ] }
}- server 须注册
ui://...资源并返回text/html;profile=mcp-app;tool 用_meta.ui.resourceUri+_meta.ui.surface关联。 - 官方 SDK 版本 pin:page SDK
2.0.0、MCP server SDK1.29.0。 - 数据/能力边界:HTML 资源 16 MiB,资源读取 8 MiB;初始 tool result
structuredContent64 KiB、page metadata 16 KiB、content32 KiB;localStorage/IndexedDB 按 plugin/workspace/account 隔离。 - 判定规则:提供
ui.surfaces面板或 tool_meta.ui.resourceUri页面的才是 UI Plugin;“仅 MCP tools”或”生成 Gen UI 的 skill”都不是。
MCP Apps 沙箱(Electron Main):分区 persist:plugin-sandbox-v2-<hash(appIdentity)>,guest 固定 contextIsolation/sandbox/webSecurity,CSP default-src none,最多 64 实例。详见 desktop。
两类插件的区分
| 类别 | 标志 | 例子 |
|---|---|---|
| UI Plugin | 有 MCP server + HTML page + ui.surfaces | visualize-plugin |
| 内置能力插件 | 仅 Skill/Command/Agent/Hook/MCP 组合,无交互页 | browser-use-plugin、documents/pdf/presentations/spreadsheets、android/ios-simulator、image-search |
| 创建器/指南 | 提供元能力 | plugin-creator、skill-creator、zcode-guide |
MCP servers(插件侧)
adapters/src/plugins/mcp.ts:
- 来源合并:
.mcp.json(插件根)+ manifestmcpServers,后者覆盖前者。 - 支持
stdio/http/sse。 - server 名命名空间
plugin:<pluginName>:<serverName>。 - 官方鉴权
auth: {type:"zcode_official", provider:"jwt_token"}(仅 http/stdio,sse禁用;与 oauth 不能共存)。 - 环境模板:
CLAUDE_PROJECT_DIR/ZCODE_PROJECT_DIR、ZCODE_PLUGIN_DATA、ZCODE_PLUGIN_ROOT;sensitiveuser_config 只允许展开到敏感 sink(env/header/clientSecret),不得进入 command/args/URL。 - 身份注入:
ZCODE_PLUGIN_ID_ENV_KEY由 resolver 权威覆盖,防第三方伪造 official CUA 身份。
详见 mcp-integration。
已知偏差(本 wiki 分析)
上游
plugin-compat.md说第三方 hook”只诊断、不注入运行时”,但当前canRunPluginHooks()无条件返回true,所有插件来源的hooks/hooks.json/ manifest hooks 都会被解析并装入PluginLoadOutcome.hooks(adapters/src/plugins/index.ts:371)。写 hook 信任边界时需明确这是当前实现风险或近期行为变化。NOTICE.md也指出”插件 Hook 与工作区 Hook 使用不同准入路径”。
相关页面
- skills-system — 插件贡献的 Skills、bundled-skills
- mcp-integration — MCP 配置、传输、OAuth
- desktop — 插件沙箱与 UI Plugin 宿主
- monorepo — 各
*-plugin包清单