Claude Code 生态与安全
Claude Code 生态与安全
插件依赖版本管理
2 分钟阅读
约束插件依赖版本
为插件依赖声明版本约束,避免上游插件发布破坏性更改后导致你的插件停止工作。
插件可以在 plugin.json 或其插件市场条目中列出其他插件作为依赖。默认情况下,依赖会跟踪最新的可用版本,因此,上游发布新版本时可能会在没有任何提醒的情况下改变你的插件所用依赖。版本约束可以把依赖限制在经过测试的版本范围内,直到你决定升级。
安装声明了依赖的插件时,Claude Code 会自动解析并安装这些依赖,并在安装输出末尾列出新增的依赖。如果之后缺少某项依赖,只要它所属的插件市场已在配置的插件市场中,/reload-plugins 和后台插件自动更新都会重新安装它。对依赖方插件再次运行 claude plugin install,或使用 claude plugin marketplace add 添加插件市场,也会解析尚未安装的缺失依赖。对于来自尚未添加的插件市场的依赖,则会保持未解析状态。
本指南面向在 plugin.json 中声明依赖的插件作者,以及为发布版本添加 tag 的插件市场维护者。要安装带有依赖的插件,请参阅发现并安装插件。完整的 manifest schema 请参阅插件参考。
插件依赖版本约束需要 Claude Code v2.1.110 或更高版本。
为什么要约束依赖版本
假设一个内部插件市场中有两个团队发布插件。平台团队维护 secrets-vault,这是一个对密钥后端进行封装的 MCP 服务器。部署团队维护 deploy-kit,它在部署期间调用 secrets-vault 获取凭证。
deploy-kit 已针对 secrets-vault v2.1.0 完成测试。如果不设置版本约束,平台团队下一次为某个重命名了 MCP 工具的版本添加 tag 后,自动更新会把每位工程师的 secrets-vault 升级到新版本,导致 deploy-kit 无法工作。
设置版本约束后,deploy-kit 可以声明它需要 ~2.1.0 范围内的 secrets-vault。安装了 deploy-kit 的工程师会继续使用满足条件的最高 2.1.x 补丁版本。部署团队可以按照自己的计划,通过发布一个放宽约束的新 deploy-kit 版本来完成升级。
声明带有版本约束的依赖
在插件的 .claude-plugin/plugin.json 中,将依赖列入 dependencies 数组。每个条目可以是插件名称,也可以是带有版本约束的对象。
以下 manifest 声明了一个无版本约束的依赖和一个受约束的依赖:
条目可以是只包含插件名称的字符串,例如上例中的 "audit-logger";这表示依赖该插件所属插件市场提供的任意版本。如需更精细地控制,请使用包含以下字段的对象:
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | 插件名称。在声明依赖的插件所属插件市场中解析。必填。 |
version | string | semver 范围,例如 ~2.1.0、^2.0、>=1.4 或 =2.1.0。依赖会获取满足此范围的最高 tag 版本。 |
marketplace | string | 解析 name 时使用的另一个插件市场。除非目标插件市场已列入根插件市场 marketplace.json 的 allowCrossMarketplaceDependenciesOn,否则跨插件市场依赖会被阻止。 |
version 字段接受 Node semver 包支持的所有表达式,包括插入符号、波浪号、连字符和比较符范围。除非范围使用 ^2.0.0-0 这样的预发布后缀明确选择加入,否则 2.0.0-beta.1 等预发布版本会被排除。
依赖另一个插件市场中的插件
默认情况下,如果依赖与声明它的插件不在同一个插件市场,Claude Code 会拒绝自动安装。这可以防止某个插件市场在用户不知情的情况下,从未经审查的来源引入插件。
要允许跨插件市场依赖,根插件市场的维护者需要在 marketplace.json 的 allowCrossMarketplaceDependenciesOn 中添加目标插件市场名称。根插件市场指托管用户正在安装的插件的插件市场;系统只检查它的允许列表,因此,信任关系不会通过中间插件市场形成传递链。
以下 marketplace.json 允许 deploy-kit 依赖来自 acme-shared 的插件:
如果该字段缺失或未包含目标插件市场,安装会失败,并返回一个 cross-marketplace 错误,指出需要设置的字段。用户仍可先手动安装依赖;这样无需修改允许列表也能满足约束。
为插件发布版本添加 tag
版本约束根据插件市场仓库中的 git tag 进行解析。为了让 Claude Code 找到依赖的可用版本,上游插件的发布版本必须按特定命名约定添加 tag。
请将每个发布版本的 tag 设为 {plugin-name}--v{version},其中 {version} 与相应 commit 中 plugin.json 的 version 字段一致。在插件目录中运行:
claude plugin tag 命令会根据插件的 manifest 及其所在的插件市场条目生成 tag 名称。创建 tag 前,它会验证插件内容,检查 plugin.json 与插件市场条目中的版本是否一致,要求插件目录下的工作树保持干净,并在 tag 已存在时拒绝继续。添加 --dry-run 可以查看将要添加的 tag,而不实际创建。如果你能自行保持 plugin.json 与插件市场条目同步,直接运行 git tag secrets-vault--v2.1.0 也具有同等效果。
插件名称前缀使一个插件市场仓库可以托管多款插件,并各自维护独立的版本线。解析 --v 分隔符时,会按完整插件名称进行前缀匹配,因此,插件名称本身包含连字符也能得到正确处理。
当你安装声明了 { "name": "secrets-vault", "version": "~2.1.0" } 的插件时,Claude Code 会列出插件市场的 tag,筛选出以 secrets-vault--v 开头的 tag,再获取满足 ~2.1.0 的最高版本。如果没有匹配的 tag,依赖方插件会被禁用,错误信息中会列出可用版本。
如果以本地文件夹路径添加的插件市场本身是 git 仓库,也会以相同方式解析 tag。此功能需要 Claude Code v2.1.196 或更高版本。在以下两种情况下,Claude Code 会改为从文件夹的当前内容安装依赖:
- 较早版本不会读取本地文件夹插件市场中的 tag,因此,受约束依赖只有在该本地副本满足版本范围时才能加载。
- 不属于 git 仓库的本地文件夹没有任何 tag,无论其中声明了什么版本。
系统会把已解析 tag 的 semver 与 plugin.json 的 version 分开记录,因此,即使该 commit 中 plugin.json 的值已经过时,约束检查仍会使用实际获取的 tag。按 tag 解析的安装,其缓存目录名称会带有 12 个字符的 commit-SHA 后缀;因此,如果维护者强制把 tag 移到另一个 commit,下次安装会获得全新的缓存目录,而不会复用过时内容。
对于 npm 插件市场来源,版本约束不会控制获取哪个版本,因为基于 tag 的解析仅适用于 git 支持的来源。系统仍会在加载时检查约束;如果已安装版本不满足要求,依赖方插件会被禁用,并显示 dependency-version-unsatisfied。
多项约束如何交互
如果多个已安装插件约束同一个依赖,Claude Code 会对这些范围取交集,并将依赖解析为满足所有范围的最高版本。下表展示常见组合的解析结果。
| 插件 A 要求 | 插件 B 要求 | 结果 |
|---|---|---|
^2.0 | >=2.1 | 安装一个不低于 2.1.0 的最高 2.x tag。两个插件都会加载。 |
~2.1 | ~3.0 | 插件 B 安装失败并显示 range-conflict。插件 A 和依赖保持原状。 |
=2.1.0 | 无 | 依赖保持在 2.1.0。只要插件 A 仍处于安装状态,自动更新就会跳过较新版本。 |
自动更新会在满足所有已安装插件版本范围的 git tag 中,选择最高版本来获取受约束依赖,而不是使用插件市场中的最新版本;这样,依赖仍能在允许范围内继续获得更新。如果没有任何 tag 同时满足所有范围,自动更新会跳过该依赖,并在 /plugin 的 Errors 标签页中列出这次跳过,同时指出施加约束的插件。
卸载最后一个约束某项依赖的插件后,该依赖将不再受到限制,并会在下次更新时恢复跟踪其插件市场条目。
启用或禁用带有依赖的插件
启用插件时,也会启用它所依赖的插件;如果另一个已启用插件仍需要某个插件,则无法禁用该插件。这两项行为都需要 Claude Code v2.1.143 或更高版本。较早版本只会启用或禁用指定插件,并在下次加载时显示 dependency-unsatisfied 错误。
启用插件时,Claude Code 还会在同一作用域启用其依赖。如果依赖本身还有依赖,Claude Code 也会一并启用。成功消息会列出除指定插件外还启用了哪些内容。如果某个依赖无法启用,命令会拒绝继续,并说明阻碍原因和修复方法:
| 情况 | 结果 |
|---|---|
| 依赖尚未安装 | 启用失败,并为每项缺失依赖输出对应的 claude plugin install 命令。 |
| 依赖被组织的插件策略阻止 | 启用失败,并指出被阻止的依赖。 |
在优先级高于目标作用域的作用域中,依赖被设为 false | 启用失败。请在该作用域启用依赖,或传入 --scope 将配置写入该作用域。 |
| 所有依赖均已安装并获准使用 | 启用成功,并为目标作用域中尚未启用的插件及每项依赖写入 true。 |
即使依赖在 manifest 中设置了 defaultEnabled: false,上述行为仍然成立,因为 Claude Code 会为其显式写入 true。安装时也是如此:为了满足活跃插件的要求而引入的依赖,无论自身默认设置如何,安装时都会设为 true。
禁用插件时,如果另一个已启用插件仍依赖它,Claude Code 会拒绝操作。错误信息会列出依赖它的插件,并提供一条按正确顺序禁用这些插件的链式命令,最后禁用你最初指定的插件。
例如,如果 deploy-kit 依赖 secrets-vault,单独禁用 secrets-vault 会失败,并显示类似以下内容:
复制错误信息中的链式命令,即可一步禁用整组插件。
移除自动安装后成为孤立项的依赖
卸载引入依赖的插件后,自动安装的依赖仍会保留在磁盘上,以便你重新安装依赖方插件,或继续直接使用该依赖。要清理这些依赖,请运行 claude plugin prune,列出不再被任何已安装插件需要的自动安装依赖,并在你确认后将其移除。此功能需要 Claude Code v2.1.121 或更高版本。
默认情况下,prune 在用户作用域运行。使用 --scope project 或 --scope local 可以指定其他作用域。传入 --dry-run 可列出将要移除的内容而不作更改,传入 -y 可跳过确认 Prompt。如果 stdin 或 stdout 不是终端,prune 会列出孤立项后退出,不会将其移除,除非传入 -y。
要在卸载过程中执行清理,请向 claude plugin uninstall 传入 --prune。移除指定插件后,Claude Code 会扫描并移除刚刚成为孤立项的所有自动安装依赖。系统绝不会清理你自行安装的插件,只会清理由其他插件的 dependencies 数组自动安装的插件。
例如,要卸载 deploy-kit 并清理它留下的依赖:
解决依赖错误
依赖问题会显示在 claude plugin list 和 /plugin 界面中。Claude Code 会禁用受影响的插件,直到你解决错误。下表列出最常见的错误及其解决方法。
| 错误 | 含义 | 解决方法 |
|---|---|---|
dependency-unsatisfied | 声明的依赖尚未安装,或已经安装但处于禁用状态。 | 运行错误信息中显示的 claude plugin install 命令。如果尚未配置该依赖所属的插件市场,请使用 claude plugin marketplace add 添加;Claude Code 随后会自动解析依赖。如果依赖已禁用,请将其启用。 |
range-conflict | 某项依赖的版本要求无法合并。错误信息会指出原因:没有版本能同时满足所有范围;范围不是有效的 semver 语法;或组合后的范围过于复杂,无法计算交集。 | 卸载或更新一个发生冲突的插件,修正无效的 version 字符串,简化过长的 || 链,或请上游作者放宽约束。 |
dependency-version-unsatisfied | 已安装依赖的版本不在此插件声明的范围内。 | 运行 claude plugin install <dependency>@<marketplace>,根据当前所有约束重新解析依赖。 |
no-matching-tag | 依赖仓库中不存在满足范围的 {name}--v* tag。 | 检查上游是否按照上述约定为发布版本添加了 tag,或放宽版本范围。 |
要以编程方式检查这些错误,请运行 claude plugin list --json,并读取每个插件的 errors 字段。
桂公网安备45010502001169号