Claude Code 学习站
Mingyu's Library

学习站 / 系统课程 / D14

D14 · Plugins 打包分发

把前面学的 Skills、Hooks、MCP、Subagents 装进一个可安装、可版本化的 plugin,通过 marketplace 分发给团队和社区——本课是 14 天课程的收官。

前 13 课教你给自己的 Claude Code 加能力;这一课教你把这些能力打包成 plugin,让换一台机器、换一个项目、换一个同事都不用重抄配置。学完你就有了从「自己会用」到「整个团队都用上」的完整闭环。

为什么这天学这个

回顾课表:D7 学了 SkillsD8 学了 HooksD9 学了 MCPD10 学了 Subagents。这四种能力有个共同点:它们的配置都散落在你本机的 .claude/ 目录或 settings.json 里。想分享给同事,只能靠手工复制文件——没有版本、没有更新机制、没有安装命令。

官方Plugin 正是官方给出的打包答案:一个自包含目录(self-contained directory),把 skills、agents、hooks、MCP servers、LSP servers 等组件装在一起,配上 manifest 就能通过 marketplace 安装、更新、分发。本站观点把它放在最后一课,是因为 plugin 本身不引入新能力——它是前面所有能力的「集装箱」;先懂内容物,再学打包,顺序才对。D13 的 CI 场景也在这里收口:官方提供了 seed 目录机制,让容器镜像在构建期预装好 plugin。

概念讲清楚

一个盒子,装下前面学的所有能力

官方plugin 的物理形态就是一个目录:元数据放在 .claude-plugin/plugin.json(manifest),其余组件各按默认位置放在插件根目录下。官方文档特别警告:.claude-plugin/ 里只放 plugin.json,把 skills/agents/hooks/ 等目录塞进去是最常见的结构错误。

my-plugin/ —— 插件根目录 .claude-plugin/plugin.json manifest:name / version / description 这个子目录里只放 manifest; 下面的组件全部放在插件根目录 skills/<name>/SKILL.md Skills · 对应 D7 hooks/hooks.json 事件钩子 · 对应 D8 .mcp.json MCP servers · 对应 D9 agents/*.md Subagents · 对应 D10 .lsp.json · bin/ LSP 代码智能 · 加入 PATH 的可执行文件 settings.json · monitors/ 等 默认设置、后台监视、themes、workflows
plugin 内容物一览:manifest 独居 .claude-plugin/,组件都在根目录。前四个组件正是 D7–D10 学过的能力。

官方manifest 本身是可选的:没有它时 Claude Code 按默认位置自动发现组件,插件名取目录名;写了 manifest 则只有 name 是必填字段。plugin 里的 skill 会带命名空间前缀,如插件 my-plugin 里的 hello 变成 /my-plugin:hello,避免多个插件重名冲突。

独立配置还是 plugin?

官方文档给出了明确的选型标准:

方式Skill 名字适合场景
独立配置(.claude/ 目录)/hello个人工作流、单项目定制、快速实验
Plugin(自包含目录 + manifest)/my-plugin:hello分享给团队/社区、跨项目复用、版本化发布、走 marketplace 分发

官方推荐的路径是:先在 .claude/ 里快速迭代,成熟后再转成 plugin 分享。迁移基本就是把 .claude/skills/agents/ 拷进插件根目录,settings 里的 hooks 挪到 hooks/hooks.json(格式相同)。本站观点注意迁移后要删掉 .claude/ 里的原件:同名 agent 会被项目级定义覆盖,plugin 版本反而不生效。五种扩展机制怎么选,可参考 Tip Skill / Hook / MCP / Subagent / Plugin 怎么选

类比:marketplace 是应用商店,plugin 是应用

官方文档自己用了这个类比:添加 marketplace 就像添加一个应用商店——只是注册了目录,可以浏览,还没装任何东西;之后再从中挑选安装单个 plugin。所以分发永远是两步:/plugin marketplace add 注册目录,/plugin install 插件名@市场名 安装。

marketplace 的实体是仓库根下的 .claude-plugin/marketplace.json,必填 nameownerplugins 三个字段;plugins 数组里每个条目至少要有 namesourcesource 支持五种:仓库内相对路径(./plugins/xx)、github(owner/repo)、url(任意 git 地址)、git-subdir(monorepo 子目录,稀疏克隆)、npm(npm 包)。官方要分清两层:marketplace source 是「目录清单本身放在哪」,plugin source 是「清单里每个插件从哪取」,两者可以指向不同仓库、独立锁定版本。

开发目录 --plugin-dir 测试 marketplace marketplace.json 用户注册市场 marketplace add 安装到缓存 复制进版本化缓存 列入清单并 push 分享 owner/repo /plugin install 发新版:bump version(或不设 version 时推新 commit)→ 用户 /plugin update 拉取
从开发到用户机器的分发链路。安装不是原地引用,而是复制进 ~/.claude/plugins/cache

版本与缓存:两个最容易踩的坑

误区一:「push 了新 commit,用户就能更新」。官方版本按这个顺序解析:① plugin.jsonversion → ② marketplace 条目的 version → ③ 插件源的 git commit SHA。一旦你写了 "version": "1.0.0",不 bump 这个字段,再多 commit 用户跑 /plugin update 也只会得到「已是最新版本」——版本字符串就是缓存键。官方建议:快速迭代的内部插件干脆不设 version,让每个 commit 都算新版本;稳定发布的公开插件才用显式语义化版本。也不要在 plugin.json 和 marketplace 条目里同时设:前者会静默胜出,过期的 manifest 版本会盖住你在清单里改的号。

误区二:「插件可以引用仓库里其他目录的文件」。官方从 marketplace 安装时,插件目录被复制进本地缓存 ~/.claude/plugins/cache,不是原地使用。../shared-utils 这类越界路径指向的文件不会被复制,装完必然失效。引用插件自带文件要用 ${CLAUDE_PLUGIN_ROOT} 变量(它指向安装目录,且每次更新都会变);要存跨版本、跨更新持久化的数据(如 node_modules、缓存),用 ${CLAUDE_PLUGIN_DATA}。同一 marketplace 内确需共享文件,官方给的出路是符号链接。

团队分发的三条路

本站观点按受众从小到大,分发方式可以这样排:

  1. 项目仓库自带(团队标配)。官方在项目的 .claude/settings.json 里写 extraKnownMarketplaces(声明市场)加 enabledPlugins(声明默认启用哪些插件),组员信任该目录后会被提示安装。安装 scope 也印证了这套设计:user(个人全项目)、project(写进 .claude/settings.json 随仓库共享)、local(个人本项目)、managed(管理员管控,只读)。
  2. 私有 marketplace 仓库(公司内部)。官方支持从私有 git 仓库安装,git 权限就是访问控制;GitHub、GitLab、自建 git 服务都行。CI/容器场景用 CLAUDE_CODE_PLUGIN_SEED_DIR 在镜像构建期预置市场与插件缓存,运行时零克隆启动——正是 D13 无头模式的配套。
  3. 公开发布(社区)。官方维护两个公共市场:claude-plugins-official 由 Anthropic 策展、首次交互启动时自动注册、无申请通道;claude-community 接受第三方提交,经自动校验与安全筛查后收录,用户手动 /plugin marketplace add anthropics/claude-plugins-community 添加。提交入口是 claude.ai 或 Console 的表单,提交前先本地跑 claude plugin validate ./your-plugin
安全提醒官方plugin 和 marketplace 是高信任组件,能以你的用户权限执行任意代码;只从可信来源安装。装前可用 claude plugin details 插件名 查看它的组件清单和预估 token 开销,组织可用 strictKnownMarketplaces 管控允许添加哪些市场。

当天能做完的实操

照官方 quickstart 走一遍「建插件 → 本地测试 → 建市场 → 安装」,约 30 分钟。

  1. 建插件目录和 manifest。预期得到 my-first-plugin/.claude-plugin/plugin.json:
    mkdir -p my-first-plugin/.claude-plugin
    cat > my-first-plugin/.claude-plugin/plugin.json <<'EOF'
    {
      "name": "my-first-plugin",
      "description": "A greeting plugin to learn the basics",
      "version": "1.0.0"
    }
    EOF
  2. 加一个 skill。创建 my-first-plugin/skills/hello/SKILL.md:
    ---
    description: Greet the user with a friendly message
    disable-model-invocation: true
    ---
    
    Greet the user warmly and ask how you can help them today.
  3. 本地加载测试:claude --plugin-dir ./my-first-plugin 启动后输入 /my-first-plugin:hello。预期 Claude 回一句问候;/help 的 Custom commands 标签里能看到带命名空间的这个 skill。改动后跑 /reload-plugins 即可热加载,不用重启。
  4. 校验结构:claude plugin validate ./my-first-plugin。预期打印带对勾的 Validation passed;加 --strict 可把警告也当错误,适合放进 CI。
  5. 建一个本地 marketplace 并安装。先建目录清单:
    mkdir -p my-marketplace/.claude-plugin
    mv my-first-plugin my-marketplace/plugins/
    cat > my-marketplace/.claude-plugin/marketplace.json <<'EOF'
    {
      "name": "my-plugins",
      "owner": { "name": "Your Name" },
      "plugins": [
        {
          "name": "my-first-plugin",
          "source": "./plugins/my-first-plugin",
          "description": "A greeting plugin to learn the basics"
        }
      ]
    }
    EOF
    然后在 Claude Code 里执行 /plugin marketplace add ./my-marketplace,再 /plugin install my-first-plugin@my-plugins,在弹出的详情页选一个 scope。预期安装摘要显示插件已激活,或提示 Run /reload-plugins to activate.——照做即可。想公开分发,把 my-marketplace push 到 GitHub,别人用 /plugin marketplace add owner/repo 就能添加。
  6. 把你自己的存量配置打包。用下面的 prompt 让 Claude Code 代劳:
把我这个项目 .claude/ 目录下的 skills、agents 和 settings 里的 hooks 迁移成一个名为 team-toolkit 的 Claude Code plugin:
1. 建 team-toolkit/.claude-plugin/plugin.json,先不要写 version 字段(用 commit SHA 当版本,方便迭代);
2. 把 .claude/skills/ 和 .claude/agents/ 拷到插件根目录,hooks 配置挪到 hooks/hooks.json,脚本路径改用 ${CLAUDE_PLUGIN_ROOT};
3. 跑 claude plugin validate ./team-toolkit 确认通过,把警告也修掉;
4. 列出迁移后我应该从 .claude/ 删除哪些原件以避免同名覆盖,先别直接删。

验收标准

  • 能说清独立配置(.claude/)与 plugin 的区别和取舍:命名空间(/hello vs /plugin:hello)、可分发性、版本化。
  • 能画出 plugin 目录结构,并指出「组件目录放进 .claude-plugin/」这个最常见错误。
  • --plugin-dir 跑通了自己的第一个 plugin,claude plugin validate 通过,并从本地 marketplace 完成了一次安装。
  • 能解释 /plugin marketplace add/plugin install 两步各做了什么,以及 marketplace source 和 plugin source 的区别。
  • 自测题:你在 plugin.json 里写了 "version": "1.0.0" 发布后,又 push 了三个修 bug 的 commit,用户跑 /plugin update 会看到什么?怎么修?(答:看到「已是最新版本」,因为版本字符串是缓存键、没变就不更新;要么每次发布 bump version,要么删掉该字段让 commit SHA 充当版本。)

到这里 14 天课程完结。回看整条线:D1–D6 打底(循环、上下文、权限、记忆、计划、会话),D7–D10 四种扩展能力,D11–D13 并行与自动化,D14 打包分发。从「会用」到「用好」再到「让团队都用上」,闭环完成。