plugin-structure:把 Claude Code 插件目录写死的那份官方规范

你在项目里攒了一堆 slash command、几个好用的 subagent、一套 PreToolUse 校验脚本,想打包发给同事。仓库建好了,文件丢进去,然后卡住:plugin.json 放哪层?commands/ 和 skills/ 是不是一回事?脚本里写死绝对路径,别人机器上的落点跟你一样吗?

anthropics/plugin-structure 回答的就是这类问题。它是 Anthropic 官方 plugin-dev 工具包里的 7 个 skill 之一,Smithery 上归类 Coding,安装量 5.6K(第三方目录站 2026 年 8 月同步数据),源码落在 anthropics/claude-code 仓库的 plugins/plugin-dev/skills/plugin-structure/。顺带说一句,你给的链接末尾那段 command-name 是文档里的示例占位符,真实 slug 是 plugin-structure

plugin-structure:把 Claude Code 插件目录写死的那份官方规范

它不是命令行工具,也不装任何依赖。整个产物是一个 SKILL.md,内容只有三块:目录约定、manifest 规范、路径规则。触发方式也很直白,用户嘴里冒出下面这类词,Claude Code 就把它读进上下文:

  • “create a plugin”
  • “scaffold a plugin”
  • “set up plugin.json”
  • “use ${CLAUDE_PLUGIN_ROOT}”

装它本身没有门槛,一条命令进当前项目:

npx -y skills add anthropics/claude-code --skill plugin-structure

我一开始以为这只是份目录说明,没什么可拆的。把它的内容和当前官方 Create plugins 文档逐条对了一遍,发现事情有点意思:这份规范里相当一部分条目,已经和线上文档对不上了。它更像一个时间切片,不是活的真相源。

架构解析

它定下的骨架长这样。只有 .claude-plugin/plugin.json 是必须的,其余组件目录一律平铺在插件根,任何一层放错地方,自动发现就静默失效,连报错都不会给你。

plugin-name/
├── .claude-plugin/
│   └── plugin.json          # Required
├── commands/                 # 斜杠命令(.md)
├── agents/                   # 子代理定义(.md)
├── skills/<name>/SKILL.md    # 技能(目录 + SKILL.md)
├── hooks/hooks.json          # 事件处理器
├── .mcp.json                 # MCP server 定义
└── scripts/                  # 辅助脚本

最容易踩的坑,官方在文档里专门挂了 Warning。下面这四个目录都不能塞进 .claude-plugin/,那个目录只放 plugin.json

  • commands/
  • agents/
  • skills/
  • hooks/

违反的后果不是报错,是静默失效。组件放错层,自动发现扫不到,你只会看到命令凭空消失却查不到任何日志,这个失败方式相当阴险。

五类组件的职责分工很清楚,混用会直接导致行为跑偏,因为它们的触发方根本不是同一类东西:

组件 触发方 位置
skills 模型自主判断 skills/<name>/SKILL.md
commands 用户敲 /name commands/<name>.md
agents 模型或用户 @ 提及 agents/<name>.md
hooks 生命周期事件 hooks/hooks.json
MCP 插件启用即启动 根目录 .mcp.json

plugin-structure:把 Claude Code 插件目录写死的那份官方规范

命名约定贯穿始终,所有目录和文件一律 kebab-case。skills 用“目录加 SKILL.md”而不是扁平文件,这不是形式主义,skills/api-testing/ 的目录名直接决定了调用名,改名等于改 API。连带一个反常识的细节:只发一个 skill 的插件可以把 SKILL.md 直接放插件根,省掉 skills/ 这一层。

manifest 这一层,规范只强制一个 name 字段,要求 kebab-case 且全局唯一。剩下这一堆全是推荐项,功能各不相同:

  • version:语义化版本,只有 bump 了用户才会收到更新
  • description:装在插件管理器里显示的那句话
  • author / homepage / repository / license:归属与出处
  • keywords:marketplace 检索归类用

它同时还允许在 manifest 里重定义组件路径,规则是“补充”不是“替换”:

{
  "name": "plugin-name",
  "commands": "./custom-commands",
  "agents": ["./agents", "./specialized-agents"],
  "hooks": "./config/hooks.json",
  "mcpServers": "./.mcp.json"
}

默认目录和自定义路径会同时生效,两边都有的组件全都会被加载。这个行为符合直觉,但真踩上去会让人排查半天,尤其当你以为自定义路径会覆盖默认值的时候。

工作流分析

组件是怎么被找到的?规范给了一条六步链路,全部在插件启用时跑完,改完之后跑 /reload-plugins 就能生效,不用重启会话:

  1. 读 .claude-plugin/plugin.json
  2. 扫 commands/ 下的 .md 文件
  3. 扫 agents/ 下的 .md 文件
  4. 扫 skills/ 下含 SKILL.md 的子目录
  5. 加载 hooks/hooks.json
  6. 加载根目录 .mcp.json

真正让这套东西可移植的是 ${CLAUDE_PLUGIN_ROOT}。同一个插件,装在不同人机器上落点完全不同,因为路径取决于安装方式、操作系统、个人偏好这一堆变量。marketplace 装是一种路径,本地目录装又是另一种,npm 分发的还会再变一次。所以规范要求把插件内部路径统统抽象成这个环境变量,作者必须放弃对安装位置的知情权。

# hook 脚本里这样引用
bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh

# 这三样全部禁止
bash /Users/name/plugins/my-plugin/hooks/scripts/validate.sh
bash ./hooks/scripts/validate.sh
bash ~/plugins/my-plugin/hooks/scripts/validate.sh

hooks 是这个体系里最能玩出花的部分,一共支持 9 种事件,按时机可以分成四组:

  • PreToolUse / PostToolUse:工具调用前后
  • SessionStart / SessionEnd:会话起止
  • UserPromptSubmit / PreCompact:提示词提交与上下文压缩
  • Stop / SubagentStop / Notification:结束与通知

配置里的 matcher 用正则匹配工具名,命中才执行:

{
  "PreToolUse": [{
    "matcher": "Write|Edit",
    "hooks": [{
      "type": "command",
      "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh",
      "timeout": 30
    }]
  }]
}

一次文件写入的完整链路里,hook 的介入时机长下面这样。中间那一步脚本执行是分水岭,退出码决定了这次调用是放行还是被拦下来,整套拦截机制的代价就压在这个数字上:

plugin-structure:把 Claude Code 插件目录写死的那份官方规范

skills 的加载逻辑和 hooks 完全相反。它不在启动时把正文全量读进上下文,而是走渐进披露:启动时只读每个 SKILL.md 的 description,命中了才把正文拉进来。这也是为什么 description 的写法比正文更致命,写砸了等于这个 skill 从不存在。

使用场景

适不适合用它,判断标准很朴素:你要不要把这套配置交给别人。从零搭一个插件时,目录怎么分层、manifest 写哪些字段,它能一次性给全,省掉翻文档的时间,也省掉踩完坑才发现约定早写在那里的懊恼。

把现有 .claude/ 配置迁成可分发的插件,官方给的迁移路径直白到有点粗暴,cp -r .claude/commands my-plugin/ 一行就完事,hooks 从 settings.json 里原样拷出来即可。团队里要分发、要版本化,那更是插件的主场,marketplace 就是为这件事建的。

不适合的场景同样清楚。如果你只是自己用两三个 skill,standalone 的 .claude/skills/ 更快,不用管 manifest,不用管命名空间,改完文件实时生效。Anthropic 的态度也很明确:先在项目里快速迭代,等要分享了再转成插件,别一上来就上工程化。

它最大的局限在定位本身,这是份规范快照,不是活文档。SKILL.md 结尾写着“详见 references/ 和 examples/ 目录”,但那些配套文件不在 skills.sh 的抓取范围内,你装完 skill 手里只有一份主文档,示例和参考资料得自己去仓库翻。

从工具包内部的热度分布也能看出点东西。plugin-dev 的 7 个 skill 安装量咬得很紧,最高的 agent-development 和最低的 plugin-structure 之间差不到 8%,说明开发者要的从来不是其中一个,是整包:

plugin-structure:把 Claude Code 插件目录写死的那份官方规范

所以真正划算的用法是直接装 plugin-dev 插件,跑 /plugin-dev:create-plugin 走那套 8 阶段引导流程,把 12 个示例和 6 个校验脚本一起拿到手,而不是单独拎出 plugin-structure 来读。claude.com 上给整个工具包标了 6.7 万次安装,比任何单个 skill 高出一个数量级,这个对比本身就把话说完了。

洞察与反思

把 SKILL.md 和当前官方 Create plugins 文档逐条比对,能抓到三处实打实的漂移。每一处都不是措辞差异,是足以让你写出过时配置的那种,而且是照着做才发现不对的那种。

条目 plugin-structure SKILL.md 当前官方文档
commands/ 一等组件,与 skills 并列 标注“Use skills/ for new plugins”
plugin.json Required: Plugin manifest optional if components use default locations
目录清单 7 项 11 项,新增 .lsp.jsonmonitors/bin/settings.json

最要命的在 commands/。SKILL.md 把它当成和 skills/ 平级的推荐做法,当前文档却已把它归为遗留格式,明确要求新插件用 skills/。背后的原因也不复杂:两者在 Claude Code 里早就合并了,skills/<name>/SKILL.md 同样能生成 /name,还额外支持模型自动触发,commands 只是扁平文件的旧形态。

manifest 的必填性也变了。当前文档的原话是“optional if components use default locations”,只要组件全在默认目录,连 plugin.json 都可以省。这一刀把插件的入门门槛又砍低了一档,很符合 Anthropic 一贯的收敛方向,从 skill 到插件一直在做减法。

目录清单还膨胀了一圈,多出来的这四样在 SKILL.md 里一个字都没提:

  • .lsp.json:接语言服务器,给 Claude 实时代码智能
  • monitors/monitors.json:挂后台日志监听,有事件主动通知
  • bin/:塞进 Bash 工具的 PATH,随插件启用生效
  • settings.json:下发默认配置

它们不是边角料。尤其是 settings.json 里的 agent 字段,能直接把插件的某个 subagent 设成主线程,等于让插件接管 Claude Code 的默认行为。

工具包里真正值钱的其实另有其物,是那 6 个生产级校验脚本。validate-hook-schema.sh 这类东西能在你提交之前就把 hooks 配置的语法错误挑出来,比人眼可靠。再配上 /plugin-dev:create-plugin 那条从 discovery 一路走到 documentation 的 8 阶段引导,整条链路比照着规范手搓目录稳当得多。

不过公平地说,这份规范最精彩的部分和这些漂移无关,是 ${CLAUDE_PLUGIN_ROOT} 这个设计。它解决的不是“路径写起来方便”,而是“插件作者必须放弃对安装位置的知情权”。正是这个放弃,换来了整个生态的可分发性,插件体系能立住靠的就是这一条。

所以结论就一句:把它当心智模型读,把 plugins-reference 当真相源查。前者帮你建立目录直觉,后者保证你不写出过时的配置。真要动手,直接上 claude plugin validate ./your-plugin,官方提交 marketplace 前跑的就是这条命令,过不了它连提交入口都进不去。

资源地址

资源 链接
Smithery 技能页 https://smithery.ai/skills/anthropics/plugin-structure
官方插件页 https://claude.com/plugins/plugin-dev
源码仓库 https://github.com/anthropics/claude-code
插件创建文档 https://code.claude.com/docs/en/plugins
插件规范参考 https://code.claude.com/docs/en/plugins-reference

总结

plugin-structure 讲的东西不复杂,但它把“插件该长什么样”从口口相传变成了可执行的约定。目录分层、组件平铺、路径环境变量化,这三条撑起了整个 Claude Code 插件生态的可组合性,也让别人写的插件你一眼就能看懂结构。

它不适合当实时参考。三处版本漂移说明文档维护存在滞后,你要真照着 SKILL.md 搭新插件,会在 commands 和 manifest 上做出过时选择。把它当入门心智模型,配合官方 plugins-reference 一起用,才是性价比最高的姿势。

最后留个判断:当插件数量继续涨,靠目录约定做自动发现还够不够?Anthropic 已经在往 marketplace、依赖管理、命名空间这些方向加东西,插件体系正在从“文件夹约定”长成一套真正的包管理系统,这个演化过程比这份静态规范值得盯得多。

skills资源

hook-development:给 Claude Code 装上九个拦截点

2026-8-29 11:46:26

行业动态

做MCP的基础设施,种子轮就拿3500万美金,让AI Agent像管理容器一样简单

2025-10-4 15:36:14

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧