01-插件架构与组件约定
插件架构与组件约定
学习目标
本章深入 Claude Code 的插件文件系统,掌握:
- 标准插件目录结构的每个组件和文件
- plugin.json 清单文件的字段定义和验证规则
- 组件自动发现的具体规则(哪些文件被发现,哪些被忽略)
${CLAUDE_PLUGIN_ROOT}环境变量在不同组件中的可用范围
前置知识
项目实践
标准目录结构
Claude Code 插件遵循统一的目录约定:
plugin-name/├── .claude-plugin/│ └── plugin.json # 必需:插件元数据├── commands/ # 可选:斜杠命令定义│ └── command-name.md├── agents/ # 可选:Agent 定义│ └── agent-name.md├── skills/ # 可选:Skill 定义│ └── skill-name/│ ├── SKILL.md│ ├── references/│ └── examples/├── hooks/ # 可选:Hook 事件注册│ ├── hooks.json│ └── hook-script.py├── .mcp.json # 可选:MCP 服务器配置└── README.md # 推荐:人类可读文档plugin.json 清单
清单文件只声明元数据,不声明组件列表:
必需字段:
name:插件唯一标识符(kebab-case)version:语义化版本号
可选字段:
description:一句话描述author:作者信息(name+email)
不声明的内容:
commands、agents、skills、hooks列表 → 从目录自动发现
自动发现规则
| 目录 | 发现规则 |
|---|---|
commands/*.md | 每个 .md 文件 = 一个斜杠命令,文件名(不含扩展名)= 命令名 |
agents/*.md | 每个 .md 文件 = 一个 Agent,frontmatter name = Agent 标识符 |
skills/*/SKILL.md | 每个包含 SKILL.md 的子目录 = 一个 Skill,目录名 = Skill 名 |
hooks/hooks.json | 唯一注册文件,声明事件类型和执行脚本的映射 |
.mcp.json | 自动加载,声明 MCP 服务器连接配置 |
不被发现的内容:
commands/下的非.md文件agents/下缺少 frontmatter 的.md文件skills/下不包含SKILL.md的子目录hooks/下不在hooks.json中注册的脚本
${CLAUDE_PLUGIN_ROOT} 环境变量
在所有组件中可用,解析为插件的绝对路径:
| 组件 | 使用方式 |
|---|---|
| Command | 在 allowed-tools 中引用脚本路径 |
| Hook | 在 hooks.json 的 command 字段中引用脚本 |
| Skill | 在 SKILL.md 中引用示例文件 |
注意事项:
- 该变量在 Shell 命令和 JSON 配置中均可被 Claude Code 正确解析
- 不应硬编码插件的绝对路径
陷阱与对策
| 陷阱 | 表现 | 对策 |
|---|---|---|
目录名与 plugin.json name 不一致 | 插件可能被重复计数 | 保持一致 |
commands/ 下放了 .txt 等非 .md 文件 | 文件被忽略,静默失败 | 只放 .md 文件 |
agents/ 的 .md 缺少 YAML frontmatter | Agent 无法被发现 | 每个 Agent .md 必须以 --- frontmatter 开头 |
hooks/hooks.json 格式错误 | Hook 不生效 | 使用 JSON 验证器检查 |
设计取舍
为什么以文件系统为 Single Source of Truth?
避免清单文件与实际文件不同步是软件工程中的经典问题。通过目录自动发现,新增组件只需添加文件,删除组件只需删除文件,清单永远与实际状态一致。
代价:无法通过查看清单文件快速了解插件包含哪些组件。需要通过 claude plugin details <name> 命令或阅读 README.md 获取。
参考来源
- Claude Code Plugin Development 文档
- 源码:
plugins/*/目录下所有插件的实际结构