Claude Code 插件与 Hook 开发完整教程
<p>Claude Code 提供了强大的插件系统,允许你通过自定义命令、代理、Hook、Skills 和 MCP 服务器来扩展功能。本文将完整介绍如何从零开始开发 Claude Code 插件和 Hook,包括创建插件、配置 Hook、发布到 Marketplace 等全流程。</p>
<!--more-->
<h2 id="为什么需要插件系统">为什么需要插件系统</h2>
<p>Claude Code 的插件系统提供了多种扩展方式:</p>
<ul>
<li><strong>Commands(命令)</strong>:创建自定义斜杠命令,快速执行常用操作</li>
<li><strong>Agents(代理)</strong>:定义专门的子代理来处理特定任务</li>
<li><strong>Skills(技能)</strong>:扩展 Claude 的能力,让模型自主调用</li>
<li><strong>Hooks(钩子)</strong>:在特定事件发生时自动执行脚本</li>
<li><strong>MCP Servers</strong>:集成外部工具和服务</li>
</ul>
<p>通过插件系统,你可以:</p>
<ul>
<li><strong>自动化工作流</strong>:在文件写入后自动格式化、运行测试</li>
<li><strong>增强安全性</strong>:拦截危险操作、验证命令</li>
<li><strong>集成工具</strong>:连接数据库、API、通知系统等</li>
<li><strong>团队协作</strong>:在项目级别配置插件,确保团队使用一致的工具</li>
</ul>
<hr />
<h2 id="快速开始创建第一个插件">快速开始:创建第一个插件</h2>
<p>让我们通过创建一个简单的问候插件来熟悉插件系统。</p>
<h3 id="前置要求">前置要求</h3>
<ul>
<li>已安装 Claude Code(可通过 <code class="language-plaintext highlighter-rouge">claude -v</code> 验证)</li>
<li>基本的命令行操作知识</li>
</ul>
<h3 id="步骤-1创建-marketplace-结构">步骤 1:创建 Marketplace 结构</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>test-marketplace
<span class="nb">cd </span>test-marketplace
</code></pre></div></div>
<h3 id="步骤-2创建插件目录">步骤 2:创建插件目录</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>my-first-plugin
<span class="nb">cd </span>my-first-plugin
</code></pre></div></div>
<h3 id="步骤-3创建插件清单文件">步骤 3:创建插件清单文件</h3>
<p>插件清单文件 <code class="language-plaintext highlighter-rouge">.claude-plugin/plugin.json</code> 描述了插件的基本信息:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> .claude-plugin
<span class="nb">cat</span> <span class="o">></span> .claude-plugin/plugin.json <span class="o"><<</span> <span class="sh">'</span><span class="no">EOF</span><span class="sh">'
{
"name": "my-first-plugin",
"description": "一个简单的问候插件,用于学习基础知识",
"version": "1.0.0",
"author": {
"name": "Your Name"
}
}
</span><span class="no">EOF
</span></code></pre></div></div>
<h3 id="步骤-4添加自定义命令">步骤 4:添加自定义命令</h3>
<p>在 <code class="language-plaintext highlighter-rouge">commands/</code> 目录下创建命令文件:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>commands
<span class="nb">cat</span> <span class="o">></span> commands/hello.md <span class="o"><<</span> <span class="sh">'</span><span class="no">EOF</span><span class="sh">'
---
description: 用个性化的消息问候用户
---
# Hello Command
热情地问候用户,并询问今天能如何帮助他们。让问候更加个性化和鼓励性。
</span><span class="no">EOF
</span></code></pre></div></div>
<h3 id="步骤-5创建-marketplace-清单">步骤 5:创建 Marketplace 清单</h3>
<p>返回上级目录,创建 Marketplace 配置文件:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ..
<span class="nb">mkdir</span> .claude-plugin
<span class="nb">cat</span> <span class="o">></span> .claude-plugin/marketplace.json <span class="o"><<</span> <span class="sh">'</span><span class="no">EOF</span><span class="sh">'
{
"name": "test-marketplace",
"owner": {
"name": "Test User"
},
"plugins": [
{
"name": "my-first-plugin",
"source": "./my-first-plugin",
"description": "我的第一个测试插件"
}
]
}
</span><span class="no">EOF
</span></code></pre></div></div>
<h3 id="步骤-6安装和测试">步骤 6:安装和测试</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 从父目录启动 Claude Code</span>
<span class="nb">cd</span> ..
claude
<span class="c"># 在 Claude Code 中添加测试 Marketplace</span>
/plugin marketplace add ./test-marketplace
<span class="c"># 安装你的插件</span>
/plugin <span class="nb">install </span>my-first-plugin@test-marketplace
</code></pre></div></div>
<p>选择 “Install now”,然后需要重启 Claude Code 才能使用新插件。</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 尝试你的新命令</span>
/hello
</code></pre></div></div>
<p>你会看到 Claude 使用你的问候命令!运行 <code class="language-plaintext highlighter-rouge">/help</code> 可以查看新命令是否已列出。</p>
<hr />
<h2 id="插件结构详解">插件结构详解</h2>
<p>一个完整的插件可以包含以下组件:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my-plugin/
├── .claude-plugin/
│ └── plugin.json # 插件元数据(必需)
├── commands/ # 自定义斜杠命令(可选)
│ └── hello.md
├── agents/ # 自定义代理(可选)
│ └── helper.md
├── skills/ # Agent Skills(可选)
│ └── my-skill/
│ └── SKILL.md
├── hooks/ # 事件处理器(可选)
│ └── hooks.json
└── .mcp.json # MCP 服务器配置(可选)
</code></pre></div></div>
<h3 id="插件清单pluginjson">插件清单(plugin.json)</h3>
<p>这是插件的核心配置文件,必须包含:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plugin-name"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"插件描述"</span><span class="p">,</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"作者名称"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="commands命令">Commands(命令)</h3>
<p>Commands 是自定义的斜杠命令,通过 Markdown 文件定义。文件内容会被发送给 Claude 作为指令。</p>
<p><strong>示例:代码格式化命令</strong></p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">自动格式化当前项目的代码</span>
<span class="nn">---</span>
<span class="gh"># Format Command</span>
格式化当前项目中的所有代码文件。使用项目配置的格式化工具(如 Prettier、Black 等)。
确保遵循项目的代码风格指南。
</code></pre></div></div>
<h3 id="agents代理">Agents(代理)</h3>
<p>Agents 是专门的子代理,用于处理特定类型的任务。</p>
<p><strong>示例:代码审查代理</strong></p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">description</span><span class="pi">:</span> <span class="s">专业的代码审查助手</span>
<span class="nn">---</span>
<span class="gh"># Code Review Agent</span>
你是一个专业的代码审查助手。你的任务是:
<span class="p">1.</span> 仔细审查代码的质量、可读性和最佳实践
<span class="p">2.</span> 识别潜在的安全漏洞和性能问题
<span class="p">3.</span> 提供建设性的反馈和改进建议
<span class="p">4.</span> 确保代码符合项目的编码标准
</code></pre></div></div>
<h3 id="skills技能">Skills(技能)</h3>
<p>Skills 是模型可以自主调用的能力扩展。创建 <code class="language-plaintext highlighter-rouge">skills/</code> 目录,每个技能是一个包含 <code class="language-plaintext highlighter-rouge">SKILL.md</code> 的子目录。</p>
<p><strong>示例:Git 操作技能</strong></p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># Git Operations Skill</span>
这个技能允许 Claude 执行常见的 Git 操作,如提交、推送、创建分支等。
Claude 可以在需要版本控制操作时自动使用此技能。
</code></pre></div></div>
<hr />
<h2 id="hook-开发详解">Hook 开发详解</h2>
<p>Hook 是插件系统中最强大的功能之一,允许你在特定事件发生时自动执行脚本。</p>
<h3 id="hook-配置位置">Hook 配置位置</h3>
<p>Hook 可以在以下位置配置:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">~/.claude/settings.json</code> - 用户级设置</li>
<li><code class="language-plaintext highlighter-rouge">.claude/settings.json</code> - 项目级设置</li>
<li><code class="language-plaintext highlighter-rouge">.claude/settings.local.json</code> - 本地项目设置(不提交)</li>
<li>插件中的 <code class="language-plaintext highlighter-rouge">hooks/hooks.json</code> - 插件提供的 Hook</li>
</ul>
<h3 id="hook-事件类型">Hook 事件类型</h3>
<h4 id="pretooluse">PreToolUse</h4>
<p>在工具调用之前执行,可以拦截、修改或自动批准操作。</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"PreToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write|Edit"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$CLAUDE_PROJECT_DIR/.claude/hooks/validate-write.sh"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h4 id="posttooluse">PostToolUse</h4>
<p>在工具成功执行后立即运行,常用于自动格式化、运行测试等。</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"PostToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write|Edit"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$CLAUDE_PROJECT_DIR/.claude/hooks/format-code.sh"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h4 id="notification">Notification</h4>
<p>当 Claude Code 发送通知时触发,可以用于桌面通知、日志记录等。</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"Notification"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"permission_prompt"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/notification.sh"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h4 id="userpromptsubmit">UserPromptSubmit</h4>
<p>在用户提交提示之前执行,可以添加上下文、验证提示等。</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"UserPromptSubmit"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$CLAUDE_PROJECT_DIR/.claude/hooks/add-context.sh"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h4 id="sessionstart--sessionend">SessionStart / SessionEnd</h4>
<p>在会话开始或结束时执行,用于环境设置、清理任务等。</p>
<h3 id="hook-输入和输出">Hook 输入和输出</h3>
<p>Hook 通过 stdin 接收 JSON 数据,包含会话信息和事件特定数据:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"abc123"</span><span class="p">,</span><span class="w">
</span><span class="nl">"transcript_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/transcript.jsonl"</span><span class="p">,</span><span class="w">
</span><span class="nl">"cwd"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/current/working/directory"</span><span class="p">,</span><span class="w">
</span><span class="nl">"permission_mode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"default"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hook_event_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PostToolUse"</span><span class="p">,</span><span class="w">
</span><span class="nl">"tool_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write"</span><span class="p">,</span><span class="w">
</span><span class="nl">"tool_input"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"file_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/file.txt"</span><span class="p">,</span><span class="w">
</span><span class="nl">"content"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file content"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"tool_response"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"filePath"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/path/to/file.txt"</span><span class="p">,</span><span class="w">
</span><span class="nl">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="hook-输出控制">Hook 输出控制</h3>
<p>Hook 可以通过退出码和 JSON 输出来控制行为:</p>
<p><strong>简单方式:退出码</strong></p>
<ul>
<li><code class="language-plaintext highlighter-rouge">0</code>:成功,stdout 在详细模式下显示</li>
<li><code class="language-plaintext highlighter-rouge">2</code>:阻止操作,stderr 作为错误消息返回给 Claude</li>
<li>其他:非阻塞错误,stderr 在详细模式下显示</li>
</ul>
<p><strong>高级方式:JSON 输出</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"decision"</span><span class="p">:</span><span class="w"> </span><span class="s2">"block"</span><span class="p">,</span><span class="w">
</span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="s2">"解释为什么阻止操作"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hookSpecificOutput"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"hookEventName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"PreToolUse"</span><span class="p">,</span><span class="w">
</span><span class="nl">"permissionDecision"</span><span class="p">:</span><span class="w"> </span><span class="s2">"deny"</span><span class="p">,</span><span class="w">
</span><span class="nl">"permissionDecisionReason"</span><span class="p">:</span><span class="w"> </span><span class="s2">"此操作被安全策略阻止"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<hr />
<h2 id="实战案例通知插件开发">实战案例:通知插件开发</h2>
<p>让我们参考 <a href="https://github.com/discountry/ritmex-marketplace">ritmex-marketplace</a> 来创建一个完整的通知插件。</p>
<h3 id="项目结构">项目结构</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ritmex-marketplace/
├── .claude-plugin/
│ └── marketplace.json # Marketplace 配置
├── claude-code-notification/ # 通知插件
│ ├── .claude-plugin/
│ │ └── plugin.json # 插件清单
│ ├── hooks/
│ │ └── hooks.json # Hook 配置
│ └── scripts/
│ └── notification.sh # 通知脚本
└── README.md
</code></pre></div></div>
<h3 id="marketplace-配置">Marketplace 配置</h3>
<p><code class="language-plaintext highlighter-rouge">.claude-plugin/marketplace.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ritmex-marketplace"</span><span class="p">,</span><span class="w">
</span><span class="nl">"owner"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"discountry"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"plugins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"claude-code-notification"</span><span class="p">,</span><span class="w">
</span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./claude-code-notification"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"在 macOS 上显示 Claude Code 通知"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="插件清单">插件清单</h3>
<p><code class="language-plaintext highlighter-rouge">claude-code-notification/.claude-plugin/plugin.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"claude-code-notification"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"当 Claude Code 触发 Notification hook 时显示 macOS 通知"</span><span class="p">,</span><span class="w">
</span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1.0.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"discountry"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="hook-配置">Hook 配置</h3>
<p><code class="language-plaintext highlighter-rouge">claude-code-notification/hooks/hooks.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"自动显示 macOS 通知"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"Notification"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"*"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"${CLAUDE_PLUGIN_ROOT}/scripts/notification.sh"</span><span class="p">,</span><span class="w">
</span><span class="nl">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="通知脚本">通知脚本</h3>
<p><code class="language-plaintext highlighter-rouge">claude-code-notification/scripts/notification.sh</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="c"># 读取 JSON 输入</span>
<span class="nv">INPUT</span><span class="o">=</span><span class="si">$(</span><span class="nb">cat</span><span class="si">)</span>
<span class="nv">MESSAGE</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$INPUT</span><span class="s2">"</span> | jq <span class="nt">-r</span> <span class="s1">'.message // "Claude Code Notification"'</span><span class="si">)</span>
<span class="nv">NOTIFICATION_TYPE</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$INPUT</span><span class="s2">"</span> | jq <span class="nt">-r</span> <span class="s1">'.notification_type // ""'</span><span class="si">)</span>
<span class="nv">TRANSCRIPT_PATH</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$INPUT</span><span class="s2">"</span> | jq <span class="nt">-r</span> <span class="s1">'.transcript_path // ""'</span><span class="si">)</span>
<span class="c"># 设置通知标题</span>
<span class="nv">TITLE</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">CLAUDE_NOTIFY_TITLE</span><span class="k">:-</span><span class="nv">Claude</span><span class="p"> Code</span><span class="k">}</span><span class="s2">"</span>
<span class="c"># 根据通知类型设置点击行为</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$NOTIFICATION_TYPE</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"permission_prompt"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
<span class="c"># 权限提示:点击时聚焦到终端</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> terminal-notifier &> /dev/null<span class="p">;</span> <span class="k">then
</span>terminal-notifier <span class="se">\</span>
<span class="nt">-title</span> <span class="s2">"</span><span class="nv">$TITLE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-message</span> <span class="s2">"</span><span class="nv">$MESSAGE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-activate</span> <span class="s2">"com.warp.Warp"</span> <span class="se">\</span>
<span class="nt">-sender</span> <span class="s2">"com.warp.Warp"</span> 2>/dev/null <span class="o">||</span> <span class="se">\</span>
terminal-notifier <span class="se">\</span>
<span class="nt">-title</span> <span class="s2">"</span><span class="nv">$TITLE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-message</span> <span class="s2">"</span><span class="nv">$MESSAGE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-activate</span> <span class="s2">"com.apple.Terminal"</span> <span class="se">\</span>
<span class="nt">-sender</span> <span class="s2">"com.apple.Terminal"</span>
<span class="k">else</span>
<span class="c"># 使用 osascript 作为后备</span>
osascript <span class="nt">-e</span> <span class="s2">"display notification </span><span class="se">\"</span><span class="nv">$MESSAGE</span><span class="se">\"</span><span class="s2"> with title </span><span class="se">\"</span><span class="nv">$TITLE</span><span class="se">\"</span><span class="s2">"</span>
<span class="k">fi
elif</span> <span class="o">[</span> <span class="nt">-n</span> <span class="s2">"</span><span class="nv">$TRANSCRIPT_PATH</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
<span class="c"># 有 transcript 路径:点击时打开文件</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> terminal-notifier &> /dev/null<span class="p">;</span> <span class="k">then
</span>terminal-notifier <span class="se">\</span>
<span class="nt">-title</span> <span class="s2">"</span><span class="nv">$TITLE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-message</span> <span class="s2">"</span><span class="nv">$MESSAGE</span><span class="s2">"</span> <span class="se">\</span>
<span class="nt">-open</span> <span class="s2">"</span><span class="nv">$TRANSCRIPT_PATH</span><span class="s2">"</span>
<span class="k">else
</span>osascript <span class="nt">-e</span> <span class="s2">"display notification </span><span class="se">\"</span><span class="nv">$MESSAGE</span><span class="se">\"</span><span class="s2"> with title </span><span class="se">\"</span><span class="nv">$TITLE</span><span class="se">\"</span><span class="s2">"</span>
<span class="k">fi
else</span>
<span class="c"># 普通通知</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> terminal-notifier &> /dev/null<span class="p">;</span> <span class="k">then
</span>terminal-notifier <span class="nt">-title</span> <span class="s2">"</span><span class="nv">$TITLE</span><span class="s2">"</span> <span class="nt">-message</span> <span class="s2">"</span><span class="nv">$MESSAGE</span><span class="s2">"</span>
<span class="k">else
</span>osascript <span class="nt">-e</span> <span class="s2">"display notification </span><span class="se">\"</span><span class="nv">$MESSAGE</span><span class="se">\"</span><span class="s2"> with title </span><span class="se">\"</span><span class="nv">$TITLE</span><span class="se">\"</span><span class="s2">"</span>
<span class="k">fi
fi
</span><span class="nb">exit </span>0
</code></pre></div></div>
<h3 id="安装和使用">安装和使用</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 添加 Marketplace</span>
/plugin marketplace add discountry/ritmex-marketplace
<span class="c"># 安装插件</span>
/plugin <span class="nb">install </span>claude-code-notification@ritmex-marketplace
<span class="c"># 验证安装</span>
/plugin
</code></pre></div></div>
<hr />
<h2 id="高级-hook-示例">高级 Hook 示例</h2>
<h3 id="示例-1自动代码格式化">示例 1:自动代码格式化</h3>
<p>在文件写入后自动运行格式化工具:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"PostToolUse"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"matcher"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write|Edit"</span><span class="p">,</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command"</span><span class="p">,</span><span class="w">
</span><span class="nl">"command"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$CLAUDE_PROJECT_DIR/.claude/hooks/format.sh"</span><span class="p">,</span><span class="w">
</span><span class="nl">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">format.sh</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nv">INPUT</span><span class="o">=</span><span class="si">$(</span><span class="nb">cat</span><span class="si">)</span>
<span class="nv">FILE_PATH</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$INPUT</span><span class="s2">"</span> | jq <span class="nt">-r</span> <span class="s1">'.tool_response.filePath // .tool_input.file_path // ""'</span><span class="si">)</span>
<span class="k">if</span> <span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$FILE_PATH</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span><span class="nb">exit </span>0
<span class="k">fi</span>
<span class="c"># 根据文件类型选择格式化工具</span>
<span class="k">case</span> <span class="s2">"</span><span class="nv">$FILE_PATH</span><span class="s2">"</span> <span class="k">in</span>
<span class="k">*</span>.js|<span class="k">*</span>.jsx|<span class="k">*</span>.ts|<span class="k">*</span>.tsx|<span class="k">*</span>.json<span class="p">)</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> prettier &> /dev/null<span class="p">;</span> <span class="k">then
</span>prettier <span class="nt">--write</span> <span class="s2">"</span><span class="nv">$FILE_PATH</span><span class="s2">"</span> 2>/dev/null
<span class="k">fi</span>
<span class="p">;;</span>
<span class="k">*</span>.py<span class="p">)</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> black &> /dev/null<span class="p">;</span> <span class="k">then
</span>black <span class="s2">"</span><span class="nv">$FILE_PATH</span><span class="s2">"</span> 2>/dev/null
<span class="k">fi</span>
<span class="p">;;</span>
<span class="k">*</span>.go<span class="p">)</span>
<span class="k">if </span><span class="nb">command</span> <span class="nt">-v</span> gofmt &> /dev/null<span class="p">;</span> <span class="k">then
</span>gofmt <span class="nt">-w</span> <span class="s2">"</span><span class="nv">$FILE_PATH</span><span class="s2">"</span> 2>/dev/null
<span class="k">fi</span>
<span class="p">;;</span>
<span class="k">esac</span>
<span class="nb">exit </span>0
</code></pre></div></div>
<h3 id="示例-2命令验证">示例 2:命令验证</h3>
<p>拦截危险命令并建议更安全的替代方案:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">VALIDATION_RULES</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span>
<span class="sa">r</span><span class="s">"\bgrep\b(?!.*\|)"</span><span class="p">,</span>
<span class="s">"建议使用 'rg' (ripgrep) 替代 'grep',性能更好且功能更强大"</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">(</span>
<span class="sa">r</span><span class="s">"\bfind\s+\S+\s+-name\b"</span><span class="p">,</span>
<span class="s">"建议使用 'rg --files | rg pattern' 替代 'find -name',性能更好"</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">(</span>
<span class="sa">r</span><span class="s">"rm\s+-rf\s+/"</span><span class="p">,</span>
<span class="s">"危险操作:删除根目录!请确认这是你想要的。"</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">input_data</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">stdin</span><span class="p">)</span>
<span class="k">except</span> <span class="n">json</span><span class="p">.</span><span class="n">JSONDecodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"错误: 无效的 JSON 输入: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">sys</span><span class="p">.</span><span class="n">stderr</span><span class="p">)</span>
<span class="n">sys</span><span class="p">.</span><span class="nb">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">tool_name</span> <span class="o">=</span> <span class="n">input_data</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"tool_name"</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span>
<span class="n">tool_input</span> <span class="o">=</span> <span class="n">input_data</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"tool_input"</span><span class="p">,</span> <span class="p">{})</span>
<span class="n">command</span> <span class="o">=</span> <span class="n">tool_input</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"command"</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span>
<span class="k">if</span> <span class="n">tool_name</span> <span class="o">!=</span> <span class="s">"Bash"</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">command</span><span class="p">:</span>
<span class="n">sys</span><span class="p">.</span><span class="nb">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">issues</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">VALIDATION_RULES</span><span class="p">:</span>
<span class="k">if</span> <span class="n">re</span><span class="p">.</span><span class="n">search</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">command</span><span class="p">):</span>
<span class="n">issues</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">if</span> <span class="n">issues</span><span class="p">:</span>
<span class="k">for</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">issues</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"• </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">sys</span><span class="p">.</span><span class="n">stderr</span><span class="p">)</span>
<span class="n">sys</span><span class="p">.</span><span class="nb">exit</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># 阻止命令执行
</span>
<span class="n">sys</span><span class="p">.</span><span class="nb">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
</code></pre></div></div>
<h3 id="示例-3智能停止判断">示例 3:智能停止判断</h3>
<p>使用 LLM 判断 Claude 是否应该继续工作:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"Stop"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"hooks"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"prompt"</span><span class="p">,</span><span class="w">
</span><span class="nl">"prompt"</span><span class="p">:</span><span class="w"> </span><span class="s2">"评估 Claude 是否应该停止工作。上下文: $ARGUMENTS</span><span class="se">\n\n</span><span class="s2">分析对话并判断:</span><span class="se">\n</span><span class="s2">1. 用户请求的所有任务是否已完成</span><span class="se">\n</span><span class="s2">2. 是否有需要解决的错误</span><span class="se">\n</span><span class="s2">3. 是否需要后续工作</span><span class="se">\n\n</span><span class="s2">返回 JSON: {</span><span class="se">\"</span><span class="s2">decision</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">approve</span><span class="se">\"</span><span class="s2"> 或 </span><span class="se">\"</span><span class="s2">block</span><span class="se">\"</span><span class="s2">, </span><span class="se">\"</span><span class="s2">reason</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">你的解释</span><span class="se">\"</span><span class="s2">}"</span><span class="p">,</span><span class="w">
</span><span class="nl">"timeout"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<hr />
<h2 id="发布和分发插件">发布和分发插件</h2>
<h3 id="创建-github-marketplace">创建 GitHub Marketplace</h3>
<ol>
<li><strong>创建仓库结构</strong>:</li>
</ol>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir </span>my-marketplace
<span class="nb">cd </span>my-marketplace
<span class="nb">mkdir</span> .claude-plugin
<span class="c"># 创建 marketplace.json</span>
<span class="c"># 添加插件目录</span>
</code></pre></div></div>
<ol>
<li><strong>推送到 GitHub</strong>:</li>
</ol>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git init
git add <span class="nb">.</span>
git commit <span class="nt">-m</span> <span class="s2">"Initial marketplace"</span>
git remote add origin https://github.com/your-org/my-marketplace.git
git push <span class="nt">-u</span> origin main
</code></pre></div></div>
<ol>
<li><strong>用户安装</strong>:</li>
</ol>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin marketplace add your-org/my-marketplace
/plugin <span class="nb">install </span>plugin-name@my-marketplace
</code></pre></div></div>
<h3 id="团队配置">团队配置</h3>
<p>在项目的 <code class="language-plaintext highlighter-rouge">.claude/settings.json</code> 中配置自动安装:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"extraKnownMarketplaces"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"my-marketplace"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"github"</span><span class="p">,</span><span class="w">
</span><span class="nl">"repo"</span><span class="p">:</span><span class="w"> </span><span class="s2">"your-org/my-marketplace"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"enabledPlugins"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"plugin-name@my-marketplace"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>团队成员信任仓库文件夹后,插件会自动安装。</p>
<hr />
<h2 id="最佳实践">最佳实践</h2>
<h3 id="安全性">安全性</h3>
<ol>
<li><strong>验证输入</strong>:永远不要盲目信任输入数据</li>
<li><strong>引用变量</strong>:使用 <code class="language-plaintext highlighter-rouge">"$VAR"</code> 而不是 <code class="language-plaintext highlighter-rouge">$VAR</code></li>
<li><strong>阻止路径遍历</strong>:检查文件路径中的 <code class="language-plaintext highlighter-rouge">..</code></li>
<li><strong>使用绝对路径</strong>:为脚本指定完整路径</li>
<li><strong>跳过敏感文件</strong>:避免处理 <code class="language-plaintext highlighter-rouge">.env</code>、<code class="language-plaintext highlighter-rouge">.git/</code>、密钥等</li>
</ol>
<h3 id="性能">性能</h3>
<ol>
<li><strong>设置超时</strong>:为长时间运行的脚本设置合理的超时</li>
<li><strong>并行执行</strong>:多个匹配的 Hook 会并行运行</li>
<li><strong>去重</strong>:相同的 Hook 命令会自动去重</li>
</ol>
<h3 id="调试">调试</h3>
<ol>
<li><strong>使用调试模式</strong>:<code class="language-plaintext highlighter-rouge">claude --debug</code> 查看详细执行信息</li>
<li><strong>测试命令</strong>:先手动运行 Hook 命令确保正常工作</li>
<li><strong>检查配置</strong>:使用 <code class="language-plaintext highlighter-rouge">/hooks</code> 查看已注册的 Hook</li>
</ol>
<hr />
<h2 id="总结">总结</h2>
<p>Claude Code 的插件系统提供了强大的扩展能力:</p>
<ul>
<li><strong>Commands</strong>:快速创建自定义命令</li>
<li><strong>Agents</strong>:定义专门的子代理</li>
<li><strong>Skills</strong>:扩展模型能力</li>
<li><strong>Hooks</strong>:自动化工作流和增强安全性</li>
<li><strong>MCP Servers</strong>:集成外部工具</li>
</ul>
<p>通过插件系统,你可以:</p>
<ul>
<li>自动化重复任务</li>
<li>增强开发安全性</li>
<li>集成团队工具</li>
<li>提升开发效率</li>
</ul>
<p>参考资源:</p>
<ul>
<li><a href="https://code.claude.com/docs">Claude Code 官方文档</a></li>
<li><a href="https://github.com/discountry/ritmex-marketplace">ritmex-marketplace 示例</a></li>
<li><a href="https://code.claude.com/docs/plugins-reference">Plugin 参考文档</a></li>
<li><a href="https://code.claude.com/docs/hooks-reference">Hook 参考文档</a></li>
</ul>
<p>开始创建你的第一个插件,让 Claude Code 更加强大!</p>