阶段小结|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.json 的 commands 字段声明 |
| 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.md。SKILL.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-caseversion可选,semverdependencies数组,格式dep-name@marketplacecommands/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.json、skills/、hooks/ 的结构,提取对你有用的部分,删掉不适合你项目的,改好 plugin.json 后推到你自己的仓库。
第三阶段:从零沉淀自己的 Plugin。 等你积累了足够多的 Skills 和 Hooks,发现某些组合在你们团队反复使用,这时候打成 Plugin 才有意义------不是为了打包而打包,是因为真的有分发需求。
本篇实践任务
任务一(了解结构): 克隆 Superpowers 仓库,查看 .claude-plugin/plugin.json、marketplace.json、skills/、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,欢迎开源出来。