跳转至

v0.3.0 迁移指南:Plugin install / enable 分离

状态:0.3.0-dev(开发中,未发布)。本指南随 0.3.0 定稿;两站 latest 仍为 0.2.3。

一句话

v0.2.x 是「装即活跃」:install 一个 plugin,其 SKILLs 立即进入投影。v0.3.0 把 install(安装) 与 enable(启用) 分离为两个可分别停留的状态——install 只安装、不激活,enable 才激活。这是一次破坏性行为变更。

为什么改

产品侧(Marketplace UI)期望 install / enable / disable / uninstall 各对应一个明确状态,且「安装完再决定是否启用」符合应用市场的通用心智;同时 v0.2.x 存在「skill 装完即可见、bundled MCP server 却要等 enable 才挂」的半态 bug(rust-sdk#102)。分离后:install 什么都不点亮,enable 把 skills 与 server 原子一并点亮。

关联:a2c-smcp-protocol#11、python-sdk#120、rust-sdk#102。

状态模型(权威)

两个正交、独立生命周期的维度:

  • 是否安装——全局一次,承载于 installedPlugins(已安装 <plugin>@<marketplace> 集合)。
  • 本 scope 是否启用——per-scope,承载于 enabledPlugins(<plugin>@<marketplace> → bool)。

组合出三态:

状态 installedPlugins enabledPlugins(合并后) 投影
available 不含 —— 无
installed_disabled 含 absent 或 false 无(惰性)
installed_enabled 含 true skills + bundled server 一并

enabledPlugins[id] 三态(scope 合并 user < project < local):absent = 无意见、继承上层(无任何 scope 置 true 即不激活);true = 启用;false = 显式禁用(覆盖上层 true)。

完整规范见 runtime-contract §2.4。

行为对照

动作 v0.2.x(装即活跃) v0.3.0(分离)
install 写账本 + skills 立即 active(server 需 hooks 才挂) 写 installedPlugins + 物化;不激活、不写 enabledPlugins → installed_disabled
enable 补挂 bundled server 写 enabledPlugins=true + 原子投影 skills 与 server;失败回滚 installed_disabled
disable 反激活 写 enabledPlugins=false + 移除投影;保留 installation
uninstall 删账本 + teardown 删 installedPlugins + 清 enabledPlugins 条目 + teardown
boot 账本存在即恢复 active 活跃集 = 已安装 ∧ 本 scope 启用;installed_disabled 恢复为惰性
账本删除 可能丢安装集 无损:从 installedPlugins 重物化

SDK 迁移清单

  1. install:改为写 installedPlugins(config-first),物化 + 校验 manifest + MCP 依赖预检(按 bundle_id 比对运行期权威配置集,依赖已满足 → 提示不拒绝,见 runtime-contract §2.5);移除 install 阶段对 SKILL/MCP 的激活;不写 enabledPlugins。
  2. enable:写 enabledPlugins[scope]=true,把 skills 与 bundled server 原子并入投影;挂载失败回滚 installed_disabled。
  3. enabledPlugins 缺省翻转:plugin_enabled 判定从「absent/true 视为启用、仅 false 跳过」改为「仅 true 激活,absent/false 均不激活」。
  4. boot / reconcile:安装集取自 installedPlugins;活跃集 = 已安装 ∧ 启用;installed_disabled 恢复为惰性、不投影。
  5. 账本:降级为可从 installedPlugins 重建的纯派生缓存,MUST NOT 手编、MUST NOT 作为权威。

一次性状态迁移(保住既有用户现状)

v0.2.x 用户的既有安装:账本有记录、enabledPlugins 无条目——在 v0.2.x 下是 active,在 v0.3.0 下(absent = 未启用)会熄灯。SDK 升级 MUST 提供一次性迁移:把每个「账本已安装」的 plugin 写入 installedPlugins,并在记录该安装的 scope(通常即承载该 home / 账本的 scope,缺省 user scope)写 enabledPlugins=true(迁为 installed_enabled)。scope 要点:enabledPlugins 是 per-scope,且 project / local 的 false 会覆盖 user 的 true——迁移 MUST 写在能确保合并后为 true 的 scope,否则「保住升级前活跃态」不确定。此迁移只跑一次。

验收(对应 conformance-tests §5)

  • install-only ⇒ 在已安装列表、get_skills() 不含其 skills、活跃 MCP 不含其 bundled server;
  • installed_disabled 重启 ⇒ 仍惰性、不被激活;
  • enable ⇒ skills 与 server 一并出现;enable 挂载失败 ⇒ 回滚 installed_disabled;
  • installed_enabled 重启 ⇒ 能力与归属重现;disable/uninstall 重启 ⇒ 不恢复;
  • 账本删除 ⇒ 从 installedPlugins 重建,恢复不受影响。