连载

阶段小结|Plugin:把你打磨好的 Claude Code 配置打包分享

AI Coding 系列第 07 篇 · 第一阶段终点站


前言:学了一圈,怎么让这些东西长腿跑起来

前面 01 到 05 篇,我们从 Prompt 的基本写法,一路走到了 CLI 命令、CLAUDE.md 规则、Skill 模板、Hooks 自动化。每一篇解决一个独立问题,但横向看,它们其实在回答同一个问题:"怎么让 Claude Code 越来越像你的搭档?"

篇目 解决的场景 承载形式
01 开篇 建立全局认知:Claude Code 是什么、能做什么 ---
02 Prompt 单次对话的质量控制 一条 prompt
03 Commands 把重复操作固化为 /命令 commands/*.md
04 CLAUDE.md 持久的行为规则,跨会话生效 CLAUDE.md 文件
05 Skill 复杂任务的 SOP 模板 skills/*.md
06 Hooks 确定性自动化(写文件后跑 lint、切换分支前提示) hooks/hooks.json

现在你手里攒了一堆好用的东西------一个精心维护的 CLAUDE.md、几套验证过的 Skill、一组靠谱的 Hooks。但这些东西困在了你的机器里。团队里另一个同事问你:你的 Claude Code 怎么比我的好用那么多?

你发给他几个文件,他一个个手动复制,发现有的路径不对,有的配置缺了依赖,折腾了半小时还没跑起来。

Plugin 解决的就是这个问题:把你打磨好的整套配置打包成一个可安装的单元,一条命令即可在任何机器上复现你的 Claude Code 环境。

回顾:前五篇的产物,天然就是 Plugin 的零件

Plugin 不是什么新奇东西。把前面几篇文章产出的文件放进同一个目录,你就已经拥有了一个 Plugin 的雏形------以社区最成熟的 Superpowers 插件为例,它的完整结构:

bash 复制代码
superpowers/                            # Git 仓库根目录 = Plugin 根目录
├── .claude-plugin/                     # ★ Claude Code 插件定义
│   ├── plugin.json                     #    插件清单(必须)
│   └── marketplace.json               #    市场定义(给安装者发现用)
├── .codex-plugin/                      #    同时支持 Codex CLI
│   └── plugin.json
├── .cursor-plugin/                     #    同时支持 Cursor
│   └── plugin.json
├── skills/                             # ← 第05篇:14 个 Skill(每个一个子目录)
│   ├── brainstorming/
│   │   ├── SKILL.md                    #    核心 Skill 定义(frontmatter + 执行步骤)
│   │   ├── visual-companion.md         #    辅助文档
│   │   └── scripts/                    #    Skill 自带的脚本资源
│   ├── test-driven-development/
│   │   └── SKILL.md
│   ├── dispatching-parallel-agents/
│   │   └── SKILL.md
│   └── ...  (共 14 个)
├── hooks/                              # ← 第06篇:自动化钩子
│   ├── hooks.json                      #    SessionStart 钩子配置
│   ├── run-hook.cmd                    #    跨平台启动脚本
│   └── session-start/                  #    会话启动时注入上下文
├── CLAUDE.md                           #    本项目的 contributor 指南(给维护者看)
├── AGENTS.md                           #    → 指向 CLAUDE.md
├── README.md                           #    项目说明 + 安装指南
├── docs/                               #    设计文档、计划
├── tests/                              #    测试套件(7 个)
├── assets/                             #    图标、SVG
├── .github/                            #    Issue/PR 模板
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── ISSUE_TEMPLATE/
├── package.json
└── LICENSE

对比一下各篇的产物是怎么装进 Plugin 的:

前文产物 在 Plugin 中的位置
04 CLAUDE.md 规则 重构成 Skill:行为规则写在 SKILL.md 正文中,触发条件和权限声明在 frontmatter
03 Commands 可放在 commands/ 目录,或在 plugin.jsoncommands 字段声明
05 Skill 模板 skills/<name>/SKILL.md,每个 Skill 一个子目录
06 Hooks 配置 hooks/hooks.json,使用 ${CLAUDE_PLUGIN_ROOT} 引用插件内路径

Plugin 不创造新能力,它是一种分发机制------把你的 Skills、Hooks、Commands 打包进一个 Git 仓库,通过 marketplace 让团队一键安装。安装后,这些内容按层级合并到用户的配置中,不会覆盖用户自己的设置。

明白了这一点,下面逐个看 Plugin 的每一个组成部分。


一、Plugin 的组成:plugin.json + marketplace.json

Claude Code 的 Plugin 系统由两层组成:

第一层:plugin.json(插件清单) ------定义插件本身提供什么。每个 Plugin 必须有一个 plugin.json,放在 .claude-plugin/ 目录下:

json 复制代码
{
  "name": "team-review-plugin",
  "description": "团队代码 Review 标准化配置",
  "version": "1.0.0",
  "author": {
    "name": "Your Team"
  },
  "homepage": "https://github.com/your-team/claude-plugins",
  "repository": "https://github.com/your-team/claude-plugins",
  "license": "MIT",
  "keywords": ["code-review", "team-standards"]
}

第二层:marketplace.json(市场定义)------告诉 Claude Code 去哪里找这个插件,以及有哪些版本可用:

json 复制代码
{
  "name": "my-team",
  "owner": { "name": "Your Team" },
  "plugins": [
    {
      "name": "team-review-plugin",
      "description": "团队代码 Review 标准化配置",
      "version": "1.0.0",
      "source": "./"
    }
  ]
}

source: "./" 表示插件目录就是仓库根目录。两个 JSON 文件 + 你的 skills/ 和 hooks/ 目录 → 一个完整的 Plugin。

安装后,Plugin 的 Skills、Hooks、Commands 按层级合并到用户配置里,不会互相覆盖。冲突时用户优先级更高(详见第五章)。


二、什么时候需要打一个 Plugin

判断标准很简单:这套配置是否有人会重复安装?

个人使用,不需要 Plugin。 你自己电脑上的 CLAUDE.md 和 Skills,直接放在对应目录就行,没有分发需求。

以下场景值得打成 Plugin:

团队新人入职,需要快速获得和老员工一致的 Claude Code 环境。与其发一份"配置说明文档"让人手动操作,不如给一个 Plugin,让新人 /plugin install onboarding-plugin@team-marketplace 一行搞定。

你做了一套针对某类项目的完整配置(比如专门为 React + TypeScript 项目优化的 Skills 和 Hooks),想开源出去给社区用。

公司有统一的安全合规要求,需要确保所有工程师的 Claude Code 都安装了同一套红线规则,不依赖个人自觉。


三、从零打一个 Plugin

以"团队代码 Review 标准化"为例,走一遍完整流程。

第一步:创建仓库结构

bash 复制代码
mkdir team-review-plugin
cd team-review-plugin
mkdir -p .claude-plugin skills/code-review hooks
git init

第二步:写 plugin.json(插件清单)

这是 Plugin 的唯一身份文件 ------告诉 Claude Code 这个插件叫什么、谁做的、版本是多少。注意:是 plugin.json,不是 SKILL.mdSKILL.md 是单个 Skill 的入口,Plugin 可以有多个 Skill。

json 复制代码
// .claude-plugin/plugin.json
{
  "name": "team-review-plugin",
  "description": "帮助团队成员用一致的标准做代码 Review",
  "version": "1.0.0",
  "author": { "name": "Your Team" },
  "homepage": "https://github.com/your-team/team-review-plugin",
  "repository": "https://github.com/your-team/team-review-plugin",
  "license": "MIT",
  "keywords": ["code-review", "team-standards"]
}

plugin.json 的关键字段:

字段 必须 说明
name 唯一标识,kebab-case,不能有空格。安装后完整 ID 为 name@marketplace
description 简介,给用户看的
version semver(如 1.0.0
author { name, email, url }
dependencies 依赖的其他 Plugin,格式 dep-name@marketplace

第三步:放入 Skills

每个 Skill 是一个子目录 ,里面放一个 SKILL.md,用 YAML frontmatter 声明触发条件和权限(第 05 篇讲过):

markdown 复制代码
# skills/code-review/SKILL.md
---
name: code-review
description: 按团队标准执行代码审查
when_to_use: 需要 Review 代码时
allowed-tools:
  - Bash(git diff *)
  - Read
---

## 执行步骤
1. 用 `git diff` 获取当前变更
2. 按三个维度逐一检查:
   - 安全性:注入漏洞、越权访问、敏感数据泄露
   - 性能:不必要的循环、N+1 查询、内存泄漏风险
   - 可读性:命名清晰度、函数长度、注释必要性
3. 每个问题标注严重级别(high / medium / low)
4. 给出修改建议,不直接改代码

你的 CLAUDE.md 里的行为规则,重构成 Skill:规则正文放在 SKILL.md 的 Markdown 部分,触发条件(when_to_use)和权限限制(allowed-tools)声明在 frontmatter。Plugin 系统没有单独的"CLAUDE.md 注入"机制------行为规则以 Skill 为载体进入 Claude 的上下文。

第四步:放入 Hooks 配置

json 复制代码
// hooks/hooks.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix ${CLAUDE_PLUGIN_ROOT}/../.. 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

注意:Hook 里可以用 ${CLAUDE_PLUGIN_ROOT} 引用插件根目录,避免硬编码路径。模板变量语法在不同版本的 Claude Code 间可能有差异,建议对着你当前版本验证。

第五步:写 marketplace.json

这是"分发层"的配置------Claude Code 通过 marketplace 发现和安装插件。一个 marketplace 可以包含多个插件。

json 复制代码
// .claude-plugin/marketplace.json
{
  "name": "my-team",
  "owner": { "name": "Your Team" },
  "plugins": [
    {
      "name": "team-review-plugin",
      "description": "团队代码 Review 标准化配置",
      "version": "1.0.0",
      "source": "./"
    }
  ]
}

source: "./" 表示插件就在仓库根目录。如果 monorepo 里有多个插件,可以用 source: "./plugins/code-review" 指向子目录。

第六步:推送到 Git(真正的"打包")

Plugin 不打包成 zip。直接 push 到 Git 仓库即可:

bash 复制代码
git add -A
git commit -m "init: team-review-plugin v1.0.0"
git remote add origin https://github.com/your-team/team-review-plugin.git
git push -u origin main

完成------你的 Plugin 已经在 GitHub 上了,可以分发了。


四、安装和使用 Plugin

方式一:添加你的 marketplace 后安装(推荐)

团队成员只需要两步:

bash 复制代码
# 1. 注册你的 marketplace(只需做一次)
claude plugin marketplace add your-team/team-review-plugin

# 或通过 slash command
/plugin marketplace add your-team/team-review-plugin
bash 复制代码
# 2. 安装插件
claude plugin install team-review-plugin@my-team

# 或
/plugin install team-review-plugin@my-team

marketplace 系统会自动从 Git 仓库拉取 marketplace.json,定位插件并安装。

方式二:本地目录测试(开发阶段)

在推送到 Git 之前,可以用本地目录验证:

bash 复制代码
# 直接指向插件目录
claude --plugin-dir ./team-review-plugin

查看已安装的 Plugin:

bash 复制代码
claude plugin list
# 或
/plugin list

启用 / 禁用:

bash 复制代码
claude plugin enable team-review-plugin@my-team
claude plugin disable team-review-plugin@my-team

卸载:

bash 复制代码
claude plugin uninstall team-review-plugin@my-team

安装后,Plugin 里的 Skills、Hooks 立即生效,不需要重启。


源码视角:Claude Code 是怎么挂载 Plugin 的

理解了"怎么做一个 Plugin",再往下一层看 Claude Code 内部是怎么加载它的。整个流程从三个来源汇集:

三路汇入:marketplace + session + builtin

scss 复制代码
assemblePluginLoadResult()                        // pluginLoader.ts:3155
  ├── loadPluginsFromMarketplaces()               // 从 settings.json 里注册的 marketplace 拉取
  ├── loadSessionOnlyPlugins()                    // 从 --plugin-dir 传入的本地目录加载
  └── getBuiltinPlugins()                         // CLI 内置的可开关 Plugin(name@builtin)
         ↓
  mergePluginSources()                            // 三路合并,session 覆盖 marketplace
         ↓
  PluginLoadResult { enabled[], disabled[], errors[] }

合并优先级:session(--plugin-dir)> marketplace(已安装)> builtin。但企业的 managed settings 可以锁死某些 Plugin 不被 session 覆盖。

单个 Plugin 的加载:从 plugin.json 到 LoadedPlugin

typescript 复制代码
// pluginLoader.ts:1348 --- createPluginFromPath()
export async function createPluginFromPath(pluginPath, source, enabled, fallbackName) {
  // Step 1: 读 .claude-plugin/plugin.json,用 Zod schema 校验
  const manifest = await loadPluginManifest(manifestPath, fallbackName, source)

  // Step 2: 并行探测 4 个可选目录是否存在
  const [commandsDirExists, agentsDirExists, skillsDirExists, outputStylesDirExists] =
    await Promise.all([
      pathExists(join(pluginPath, 'commands')),
      pathExists(join(pluginPath, 'agents')),
      pathExists(join(pluginPath, 'skills')),
      pathExists(join(pluginPath, 'output-styles')),
    ])

  // Step 3: 组装 LoadedPlugin 对象
  const plugin: LoadedPlugin = {
    name: manifest.name,
    manifest,
    path: pluginPath,      // 插件根目录的绝对路径
    source,                // 来源标识(如 "github:repo")
    enabled,
    commandsPath,          // 探测到的 commands/ 目录路径
    skillsPaths,           // 探测到的 skills/ 目录路径
    hooksConfig,           // hooks/hooks.json 解析后的配置
    mcpServers,            // MCP 服务器配置
    lspServers,            // LSP 服务器配置
  }
}

关键点:Plugin 不要求所有目录都存在 ------createPluginFromPath() 只挂载实际存在的目录。你的 Plugin 可以只有 skills/,没有 commands/hooks/,它照常工作。

manifest 校验:JSON → Zod Schema

typescript 复制代码
// pluginLoader.ts:1147 --- loadPluginManifest()
export async function loadPluginManifest(manifestPath, pluginName, source) {
  if (!(await pathExists(manifestPath))) {
    // plugin.json 缺失时,用最小兜底 manifest
    return { name: pluginName, description: `Plugin from ${source}` }
  }

  const content = await readFile(manifestPath, 'utf-8')
  const parsedJson = jsonParse(content)

  // Zod 校验 --- 不通过直接抛异常
  const result = PluginManifestSchema().safeParse(parsedJson)
  if (result.success) {
    // 注意:Zod 默认 strip 未知字段,所以 plugin.json 里多写字段不会报错
    return result.data
  }
  // 校验失败:name 带空格、非法字段类型等 → 阻止加载
  throw new Error(`Plugin ${pluginName} has an invalid manifest file`)
}

PluginManifestSchema (schemas.ts:884) 定义了 plugin.json 的完整 Zod schema,核心约束:

  • name 不能为空、不能包含空格、必须 kebab-case
  • version 可选,semver
  • dependencies 数组,格式 dep-name@marketplace
  • commands / agents / skills / hooks / mcpServers / lspServers / outputStyles / userConfig / settings 等可选扩展字段

Command 提取:扫描 commands/ 和 skills/

typescript 复制代码
// loadPluginCommands.ts --- 核心逻辑
// 1. walkPluginMarkdown() 遍历 commands/ + commandsPaths,收集所有 .md 文件
// 2. 对每个 .md 文件:
//    - 解析 YAML frontmatter(parseFrontmatter)
//    - skills/ 目录下的 SKILL.md 用父目录名作为 skill 名
//    - 提取 name, description, allowedTools, whenToUse, model, hooks 等字段
//    - 替换变量(${CLAUDE_SKILL_DIR}, ${CLAUDE_SESSION_ID}, 用户参数)
// 3. 返回 Command[] 数组,注入到 Claude 的可用工具列表中

Skill 的命名规则(loadPluginCommands.ts:60):

ini 复制代码
skills/brainstorming/SKILL.md  →  Command.name = "brainstorming"
skills/tdd/SKILL.md            →  Command.name = "tdd"
commands/review.md             →  Command.name = "review"(文件名去 .md)

Hook 挂载:注册 + 热更新

typescript 复制代码
// loadPluginHooks.ts:28 --- convertPluginHooksToMatchers()
// 读取 plugin.hooksConfig(来自 hooks/hooks.json 或 manifest.hooks 内联)
// 遍历 25 种 Hook 事件(SessionStart / PostToolUse / PreToolUse / ...)
// 为每个 matcher 注入 Plugin 上下文:

pluginMatchers[hookEvent].push({
  matcher: matcher.matcher,      // "startup" / "Write" / "*"
  hooks: matcher.hooks,           // 实际要执行的命令
  pluginRoot: plugin.path,        // → ${CLAUDE_PLUGIN_ROOT} 的值
  pluginName: plugin.name,
  pluginId: plugin.source,
})

Hook 还支持热更新:当 enabledPlugins 在 settings.json 中变化时,自动注销旧 Hook、注册新 Hook,不需要重启。

一句话总结

Claude Code 的 Plugin 挂载本质上是一个 三路 merge + 目录探测 + frontmatter 解析 的流程。没有魔法------plugin.json 是 Zod 校验的 JSON,Skills 是带 frontmatter 的 Markdown,Hooks 是 JSON 配置。理解这三样,你就完全理解了 Plugin 系统的内核。


五、Plugin 的优先级和冲突处理

Plugin 的配置和你自己的配置共存时,有明确的优先级:

markdown 复制代码
用户配置(个人 CLAUDE.md + Skills)
    ↓ 优先级更高
Plugin 配置(Plugin 的 Skills + Hooks)
    ↓
默认配置

用户自己的规则始终优先于 Plugin 的规则,所以安装一个 Plugin 不会覆盖掉你的个人设置。如果你的规则和 Plugin 规则有冲突,以你的为准。

这个设计的好处:团队统一安装公司 Plugin,个人仍然可以有自己的偏好配置,两者互不干扰。


六、从"用别人的 Plugin"到"做自己的 Plugin"

大多数人的路径应该是这样的:

第一阶段:用社区现成的 Plugin。 Anthropic 官方和社区有一些公开的 Plugin,覆盖常见语言和框架。先安装来用,观察它做了什么、效果怎样。

第二阶段:基于现有 Plugin 修改。 克隆别人的 Plugin 仓库(就是 Git 仓库),看看 .claude-plugin/plugin.jsonskills/hooks/ 的结构,提取对你有用的部分,删掉不适合你项目的,改好 plugin.json 后推到你自己的仓库。

第三阶段:从零沉淀自己的 Plugin。 等你积累了足够多的 Skills 和 Hooks,发现某些组合在你们团队反复使用,这时候打成 Plugin 才有意义------不是为了打包而打包,是因为真的有分发需求。


本篇实践任务

任务一(了解结构): 克隆 Superpowers 仓库,查看 .claude-plugin/plugin.jsonmarketplace.jsonskills/hooks/ 的完整结构,对照本篇理解每个文件的作用。

任务二(从头做一个): 把你在第 05 篇提炼的 Skill 和第 06 篇配好的 Hooks 组合成一个 Plugin。建仓库 → 写 plugin.json + marketplace.json → 放 Skills 和 Hooks → 推送到 Git → 用 --plugin-dir 本地测试验证。

任务三(团队推广预演): 让同事用 claude plugin marketplace add 添加你的仓库,然后 claude plugin install 安装。观察他能否在 5 分钟内跑起来,记录遇到的问题,改进文档。


总结

这篇文章是第一阶段(01 ~ 07)的收尾。

回头看一下我们走过的路:

markdown 复制代码
02 Prompt          → 怎么和 Claude 说话
03 Commands        → 怎么把常用操作固化为 /命令
04 CLAUDE.md       → 怎么给 Claude 持久的规则和记忆
05 Skill           → 怎么把复杂任务封装成可复用的 SOP
06 Hooks           → 怎么让 Claude 在关键节点自动做检查
                                                        ↓
07 Plugin          → 怎么把上面这些打包,一键分发

Plugin 是配置旅程的最后一步:你把好用的东西固化下来,让别人不需要重走你走过的路。

单独用 Claude Code 时,Plugin 不是必须的。但一旦涉及团队协作------统一标准、快速 onboarding、分发最佳实践------Plugin 是目前最干净的解法。

打包的时机不要太早。先用 CLAUDE.md、Skills 和 Hooks 把效果验证清楚,真正到了"这套东西值得让五个人以上用"的时候,再花时间打包成 Plugin,回报才值得。


展望:下一阶段,从"配置"到"编排"

前面 01 ~ 07 篇,我们把 Claude Code 单会话的体验打磨到了极致。但从第 08 篇开始,问题变了:

  • 单个 Claude 完成不了的任务怎么办?→ Sub-agents(第 09 篇)
  • 多个 Agent 怎么分工合作?→ Multi-agent 与 Agent Teams(第 10 篇)
  • 怎么把外部工具接进来?→ MCP 与工具系统(第 11 篇)
  • 怎么设计可持续的日常 AI Coding 工作流?→ 工作流设计(第 12 篇)

如果你已经把自己的配置打成了 Plugin,恭喜------你已经有了一个标准化的"Agent 起点"。 接下来要做的是让这个 Agent 能调动更多 Agent,去完成一个人做不完的任务。


AI Coding 系列持续更新。如果你做了有意思的 Plugin,欢迎开源出来。

相关推荐
Honmaple1 小时前
FFF:面向人类与 AI 代理的极速文件搜索工具包
后端
求学中--1 小时前
DeepSeek V4 API实战:从零搭建AI编程助手全流程
人工智能·ai编程
dinl_vin1 小时前
LangChain 系列·(九):Agent——让 AI 自己做决策
前端·人工智能·langchain
孟祥_成都1 小时前
前端唯一的护城河?结合 AI 将字节组件库 Headless 化后的感想~
前端·人工智能·react.js
Java面试题总结1 小时前
spring重点详解
java·后端·spring
尽欢i1 小时前
前端大坑!文件切片上传后端总报错找不到文件名?
前端·javascript
Sylvia33.1 小时前
世界杯数据链路解析:从球场传感器到终端推送的毫秒级架构
java·前端·python·架构
镜宇秋霖丶2 小时前
2026.5.10@霖宇博客制作中遇见的问题
前端·vue.js·elementui
ai超级个体2 小时前
前端唯一的护城河?结合 AI 将字节组件库 Headless 化后的感想~
前端·react·ai编程·ant design·组件库·vibe coding