mod 参考
Claude Code mod 的完整参考:hook 模块布局、事件、mods API 方法、渲染位置、按使用入口划分的元素、限制和设置。
查阅 mod 可以处理的任何事件、可以调用的任何 mods API 方法,或可以在其中绘制的任何渲染位置,适用于 v2.1.287 起的 Claude Code CLI 和 Desktop 应用。每个条目给出名称和一行描述,如有相应的指南章节,还会链接到该章节。
完整的参考是 Claude Code 的 mod TypeScript 声明,其中描述了每个事件、方法和元素,并附有示例。GitHub 上的副本可能比您安装的 Claude Code 版本更旧。两者不一致时,请以 Claude Code 为您的版本写入的副本为准。
文件
mod 是一个包含以下文件的插件目录:
| 文件 | 必需 | 内容 |
|---|---|---|
.claude-plugin/plugin.json |
是 | 插件清单。mod 不会添加任何必需字段。 |
hooks/hooks.json |
是 | modules:一个数组,包含一个指向 hook 模块的路径(相对于此文件),如 "modules": ["./register.js"]。也可以在 hooks 下包含设置 hook。 |
hook 模块,例如 hooks/register.js |
是 | mod 的入口点。导出 register(on, options)。文件名以 .js、.mjs、.cjs、.jsx、.ts、.mts、.cts 或 .tsx 结尾。是一个 ES 模块。 |
types/index.d.ts,由清单中的 types 指定 |
当 mod 使用 $.state 或向 mods API 添加命名空间时 |
声明 PluginState 值以及 mod 添加的任何命名空间 |
名称以 .test.ts 或 .test.tsx 结尾的文件 |
否 | claude plugin test 运行的测试 |
register 接收 on 和 options。options 包含清单所声明的 userConfig 字段的值,并已填入默认值。
hook 函数
mod 通过在 register 内调用 on 来注册它的每个 hook(即事件处理程序)。on 接受事件名称、一个可选的匹配器(即对事件字段的过滤条件)以及 hook,如 on('tool.call', { tool: 'Bash' }, async ($, e, next) => next(e))。on 返回一个注册对象,它只有一个方法 .catch(handler),用于设置该 hook 的错误处理程序。
| 参数 | 说明 |
|---|---|
$ |
mods API:mods API 方法中的所有方法。每次调用都要完整写出,先写命名空间再写方法,如 $.fs.read('notes.md')。 |
e |
事件的输入,为深度冻结的纯数据。要更改它,请将副本传给 next。 |
next(e) |
下一个处理程序,类似中间件。先运行此 hook 之后的 hook,再运行 Claude Code 的行为。解析为事件的结果。 |
next.signal |
一个 AbortSignal,在事件被放弃时中止 |
next.origin |
触发该事件者的 { plugin, tier }。Claude Code 自身为 { plugin: 'engine', tier: 'core' }。mod 的 tier 是它在 mod 运行顺序中的优先级组:prepend、user、append 或 builtin。 |
next.budget |
hook 的时间限制(以毫秒为单位):next.budget.ms 是总限制,next.budget.remainingMs 是当前剩余时间 |
next.to(e, tier) |
跳到后面的层级,即 append、builtin 或 core。next.to(e, 'append') 会跳过用户安装的 mod。只有 prependPlugins 或 appendPlugins 中的 mod 才能调用它。 |
next.error, next.called |
仅在 .catch 处理程序中可用。next.error.kind 为 throw 或 timeout,next.error.message 是错误文本;当失败的 hook 已调用 next 时,next.called 为 true。 |
事件
事件按其涉及的内容分组,每个事件都列出了触发时机以及其上的 hook 可以返回的内容。turn.step 和 process.spawn 上的 hook 是异步生成器,其他 hook 是异步函数。
每个表格的最后一列使用简写。next(e) 原样传递事件。next({ ...e, text }) 传递一个更改了指定字段的副本,如 next({ ...e, text: e.text.trim() })。对象表示不调用 next 而直接应答该事件,而 reason 之类的词代表您编写的字符串,如 { deny: 'Use the file tools.' }。
工具
工具事件围绕 Claude 发出的每个工具调用触发,涵盖从 Claude 读取的描述到是否运行该调用的决定:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
tool.call |
工具即将运行 | next(e)、{ deny: reason } 或 { result } |
tool.check |
Claude Code 在 tool.call 和 PreToolUse hook 之后决定是否允许运行某个工具调用。next(e) 解析为规则、权限模式和这些 hook 得出的决定。 |
{ decision },其值为 allow、ask 或 deny |
tool.describe |
每个工具一次,在其描述首次发送给 Claude 时 | { description } |
提示词以及 Claude 读取的内容
提示词事件涵盖用户输入的文本,以及 Claude Code 自行发送给 Claude 的文本,例如系统提示词和提醒:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
prompt.submit |
提交提示词时 | next({ ...e, text })、next({ ...e, context }) 或 { drop: reason } |
prompt.fill, prompt.suggest |
文本即将作为草稿或暗色建议进入输入框 | 更改了文本的 next(e) |
prompt.edit |
用户编辑输入框 | next(e) |
prompt.compose |
Claude Code 渲染系统提示词 | { sections },一个按发送顺序排列的 { id, text, scope } 列表 |
prompt.section |
系统提示词的每个命名部分一次。e.name 是该部分在 prompt.compose 中的 id。 |
{ text },或 { text: null } 以省略该部分 |
prompt.context |
每个对话一次,用于随第一条消息发送的上下文 | { blocks } |
prompt.attachment |
Claude Code 为 Claude 添加一条它自己的消息,例如提醒。e.type 指明消息类型;对于类型声明中已声明的类型,e.detail 包含编写该文本所依据的事实。 |
{ text },或 { text: null } 以省略它 |
skill.prompt |
skill 的文本为 Claude 展开时 | { text } |
attribution.text |
Claude Code 撰写提交或 Pull Request 的署名文本时 | { text } |
命令和配置
命令和配置事件在命令运行或被列出时,以及 /config 行显示或更改时触发:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
command.run |
命令即将运行 | { text }、{} 或 next(e) |
command.describe |
每个命令一次,用于命令列表 | { description, argumentHint, isHidden } |
config.set |
/config 行即将更改 |
next({ ...e, value }) 或 { deny: reason } |
config.describe |
每个 /config 行一次 |
{ label, description, isHidden } |
轮次
轮次事件从头到尾跟踪一次回答,包括其中每个发往模型的请求:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
turn.start |
轮次开始 | next(e) |
turn.step |
一个请求即将发往模型 | yield* next(e),或 next({ ...e, model })、next({ ...e, effort }) |
turn.complete |
轮次结束 | next(e),或 { text } 以在回答下方显示一行 |
会话
会话事件标记会话的开始、结束、压缩,以及与其他会话交换消息:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
session.start |
每个已加载的 mod 一次,在第一个提示词之前触发,并在该 mod 重新加载后再次触发。/clear、/resume 或 /branch 之后不会触发。 |
next(e) |
session.end |
会话结束,或运行 /clear、/resume 或 /branch 时。e.reason 为 clear、resume、logout、prompt_input_exit 或 other。/branch 报告为 resume。 |
next(e) |
session.compact |
对话即将被压缩 | { skip: reason } |
session.receive, session.send |
一条消息从另一个 Agent 或会话到达,或即将发往另一个 Agent 或会话。请参阅在会话之间发送和接收消息。 | receive 返回 { consumed: reason },send 返回 { isDelivered: false, reason } |
session.append |
对话保留的每一行一次,例如提示词、响应块、工具结果或通知,在存储之前触发 | next({ ...e, message }) 以重写该行的 content |
session.attach, session.detach |
另一个应用连接到会话或从会话断开 | next(e) |
session.measure |
每个轮次之后,以及套餐限制的已用百分比发生变化时 | next(e) |
子代理
子代理事件在向 Claude 提供某个子代理类型时,以及子代理即将启动时触发:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
agent.offer |
向 Claude 提供某个子代理类型 | { isOffered: false } 以不提供它 |
agent.spawn |
子代理即将启动 | { model } 或 { deny: reason } |
界面
界面事件在 Claude Code 绘制渲染位置时,以及用户使用 mod 绘制的控件时触发。在界面中绘制展示了 ui.render hook 返回的内容:
| 事件 | 触发时机 |
|---|---|
ui.render |
某个渲染位置即将被绘制 |
ui.resolve |
mod 加载时,每个应用、渲染位置和 mod 各一次。其结果是 $.ui.resolve(e) 读取的元素表。 |
ui.press, ui.input, ui.select |
mod 绘制的 Button、Input 或 Select 被使用 |
ui.focus, ui.scroll |
获得焦点的控件,或窗格或横栏的滚动位置即将更改 |
ui.close |
窗格即将关闭。e.id 是该窗格,e.origin.kind 为 plugin、person 或 unload。 |
ui.message |
Client 元素向其 mod 发送数据 |
其他 mod
这些事件让 mod 在其他 mod 加载时对其进行操作,以拒绝某个 mod 或更改它收到的 mods API:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
plugin.register |
hook 模块即将加载。e.uses 列出它的事件、mods API 调用、环境变量和状态,与 claude plugin validate 打印的内容一致。每个调用都不带 $. 前缀,如 fs.read。 |
{ refuse: reason } |
engine.create |
正在为此 mod 构建 mods API | 更改后的 mods API,用于添加或隐藏某个命名空间 |
遥测
遥测事件针对 Claude Code 记录的使用情况记录触发:
| 事件 | 触发时机 | hook 可以返回 |
|---|---|---|
telemetry.log, telemetry.mark |
一条遥测记录即将被记录,或标记某项功能的一次使用。在您安装的 mod 中,请为遥测 hook 设置过滤条件 { to: 'collector' },如 on('telemetry.log', { to: 'collector' }, hook)。如果没有该过滤条件,mod 将无法通过 claude plugin validate。* 不匹配这些事件。 |
next(e) 或 { deny: reason } |
设置 hook 事件
每个设置 hook 事件都是一个名为 classic.<Event> 的事件,如 classic.Stop 或 classic.PostToolUse。e 是该 hook 的 stdin JSON。
mods API 调用
每个 mods API 方法也是一个事件,以其命名空间和方法命名,如 fs.read、model.complete 或 ui.open。其上的 hook 会拦截在它之后运行的 mod 发出的调用,并可以返回 next(e)、{ deny: reason } 或 { value }。
mods API 方法
mods API 是每个 hook 接收的 $ 参数。它的方法按命名空间分组,例如 $.ui。此表按名称列出每个命名空间的方法,因此 $.ui 行中的 open 就是调用 $.ui.open(...)。指南展示了常用方法的用法,而您的构建版本的类型记录了每个方法并附有示例。
| 命名空间 | 方法 |
|---|---|
$.plugin |
name、root:此插件的名称和目录 |
$.ui |
resolve、invalidate、open、close、panes、focus、scroll、toast、status、log、notice、ask、copy、blit |
$.command |
register、run、list |
$.tool |
register、call、check、list |
$.agent |
register、spawn、list |
$.model |
complete、fork、classify |
$.prompt |
submit、read、fill、suggest、compose。Claude 读取来自 submit({ text }) 的文本时,前面会有一句指明您的 mod 为发送者的话。submit({ text, asUser: true }) 将文本作为用户自己的话发送,不带那句话。 |
$.turn |
abort |
$.session |
messages、cwd、root、model、turns、id、repo、surfaces、usage、version、compact、send、append、authorize。usage() 返回 { startedAt, context, rateLimits, cost }:context 包含 tokens、window 和 percent,rateLimits 是由 { kind, percentUsed, resetsAt } 组成的列表。 |
$.config |
list、set |
$.settings |
read |
$.env |
get、set |
$.fs |
read、write、list、exists、stat、ancestors。write 不是原子操作:它会原地替换文件内容,因此另一个进程可能读到只写了一部分的文件。请将多个会话都会更改的数据保存在 $.store 中。 |
$.store |
get、set、delete、keys。一个由本机所有会话共享的键值存储。请参阅从多个会话保存。 |
$.state |
响应式状态:get、set,以及从 claude-code 导入的辅助函数 atom、read、update、derive 和 memberOf |
$.clock |
now、sleep、after、every |
$.http |
fetch |
$.process |
run、spawn |
$.mcp |
call、connect。connect(server) 连接您自己的插件清单中列出的 MCP 服务器。 |
$.audio |
play、speak |
$.telemetry |
log、mark。仅当由 Claude Code 或内置 mod 发出调用时,才会发送记录。 |
渲染位置
渲染位置是 Claude Code 界面中的扩展点。每一行是 ui.render hook 中 e.component 的一个值,并列出了 e.props 的字段以及渲染它的应用。e.surface 为 terminal 或 desktop。更改 Claude Code 已绘制的内容展示了 hook 在某个位置可以做什么,并为每种选择提供了示例。
| 位置 | e.props |
e.requestId |
渲染于 |
|---|---|---|---|
Pane |
title、isFocused、bodyColumns、placement、scroll、view |
窗格的 id |
终端、Desktop |
AbovePrompt |
hasSurvey、isWorking、maxRows、bodyColumns、scroll、view |
单一实例 | 终端、Desktop |
UserMessage |
text、origin、isExpanded,以及视来源而定的 task 或 from |
消息 id | 终端、Desktop |
AssistantMessage |
回复的文本 | 消息 id | 终端、Desktop |
ToolUse, ToolResult, ToolGroup |
工具的名称、输入和结果 | 工具调用 id | 终端、Desktop |
CommandOutput |
command、text |
消息 id | 终端、Desktop |
AskUserQuestion |
问题和选项 | 工具调用 id | 终端、Desktop |
ToolProgress |
kind |
工具调用 id | 终端 |
Spinner |
word、message、suffix、mode |
Agent id | 终端、Desktop |
TurnDuration |
word、durationMs |
消息 id | 终端 |
InfoNotice |
text、command |
消息 id | 终端 |
SessionMode |
modes |
单一实例 | 终端、Desktop |
PromptHint |
isDraft、isWorking、hint |
单一实例 | 终端、Desktop |
e.viewport 包含 columns、rows 和 isFullscreen。在应用测量其窗口之前,它不存在。它的 rows 是整个窗口的高度,而不是您的窗格的高度。
要使树适配其所在位置,请在 hook 中读取以下 prop:
Pane或横栏的宽度:按e.props.bodyColumns绘制- 会话记录旁的
Pane的高度:当e.props.placement为'dock'时,e.props.scroll.bodyRows是该窗格拥有的行数 - 输入框上方的
Pane的高度:当e.props.placement为'inline'时,窗格会随您的树增高,直到达到上限,且bodyRows只计算当前显示的行。$.ui.open的rows字段可请求不同的上限。
比窗格更高的树会整体滚动。
元素
元素是 ui.render hook 所返回的树的构建块,您可以从 $.ui.resolve(e) 获取它们。用元素构建树展示了常用元素以及终端如何绘制它们,界面图库提供了大多数元素的截图。对勾表示该应用可以绘制该元素。
| 元素 | 主要 prop | 终端 | Desktop |
|---|---|---|---|
Box |
key、flex 布局、gap、padding、margin、width、height、borderStyle、backgroundColor、position、hover |
✓ | ✓ |
Text |
color、backgroundColor、bold、italic、underline、dimColor、inverse、wrap |
✓ | ✓ |
Button |
key、label、onPress、hotkey、plain、dimColor、autoFocus、action |
✓ | ✓ |
Link |
href、label |
✓ | ✓ |
Code |
代码,最多 10,000 个字符 | ✓ | ✓ |
Markdown |
text(最多 10,000 个字符)、key、dimColor、onLinkPress、pressableLinks |
✓ | ✓ |
Input |
key、label、placeholder、value、submitLabel、onSubmit、onInput、autoFocus |
✓ | ✓ |
Select |
key、label、options、value、onSelect、autoFocus |
✓ | ✓ |
Svg |
一个 SVG 文档,最多 131,072 个字符 | ✓ | |
Client |
module、key |
✓ | ✓ |
Raster |
key、columns(最多 512)、rows(最多 256)、cells。请参阅绘制彩色单元格网格。 |
✓ | |
Image |
最多 2 MiB 的 PNG 或 RGBA 字节,或文件路径 | ✓ |
更多 Button 规则:action 指定 Claude Code 自身的某个快捷键操作,当用户为该操作设置的绑定是组合键或带修饰键的按键时,该绑定会按下此按钮。当用户在空的输入框中只输入某个数字并停顿时,横栏中设置了该数字 hotkey 的按钮也会触发。当同一次绘制中的两个按钮指定相同的 hotkey 时,由后一个按钮获得它。autoFocus 在任何控件上都只接受 true,因此要关闭它,请省略该 prop。
限制
hook 和 mods API 调用受时间和大小限制。Claude Code 会跳过超出时间限制的 hook,并拒绝超出大小限制的调用。
| 限制 | 值 |
|---|---|
单个事件中 hook 自身的执行时间,不计入在 next 内或在除 $.clock.sleep 之外的 mods API 调用中花费的时间 |
10 秒 |
.catch 处理程序的执行时间 |
1 秒 |
所有 session.end hook 合计 |
1.5 秒 |
$.process.run 超时时间 |
默认 30 秒,最长 10 分钟 |
$.model.complete maxTokens |
默认 1024,最多 64,000 或模型的输出上限 |
$.fs.read 和 $.fs.write |
单个文件 4 MiB |
Text 的单个字符串子元素 |
10,000 个字符 |
$.store |
JSON 总计 4 MiB |
$.session.messages() |
最新的 4,096 个条目 |
$.ui.invalidate('ui.render') 重绘 |
限制为每秒 10 次;在终端中,对于可见窗格、展开区域以及输入框下方的提示行,限制为每秒 30 次。更早到达的调用会被合并。 |
$.ui.toast |
显示 4 秒,除非您传入 { timeoutMs } |
| 非用户主动打开的窗格 | 从终端第 144 列起放置;用户打开过一次后,从第 110 列起放置 |
| 命令、工具、子代理类型和窗格名称 | 字母、数字、_ 和 -,最多 64 个字符 |
单个 claude plugin test 测试 |
5 秒,除非该测试设置了 timeoutMs |
设置和环境变量
以下是影响 mod 的设置和环境变量。“位置”列说明每一项从哪个设置文件或环境中读取:
| 名称 | 位置 | 作用 |
|---|---|---|
CLAUDE_CODE_PLUGIN_DIRS |
环境变量,或 ~/.claude/settings.json 中的 env |
要像 --plugin-dir 那样加载的插件目录,用于无法传递标志的应用。以 : 分隔的绝对路径,在 Windows 上以 ; 分隔。 |
CLAUDE_CODE_PLUGIN_DIR_WATCH |
环境变量 | 1 使长时间运行的非交互式会话在保存时重新加载 --plugin-dir mod |
prependPlugins, appendPlugins |
托管设置。仅在没有托管设置的机器上、且用户未使用 Team 或 Enterprise 套餐登录时,才可在用户设置中使用。 | 插件 id 列表,例如 acme-guard@acme-tools。prependPlugins 中的 mod 在用户安装的每个 mod 之前运行,appendPlugins 中的 mod 在之后运行,均按列出的顺序。请参阅 mod 运行顺序。 |
allowManagedModsOnly |
托管设置,作为内置守卫的选项 | 只加载算作您组织的 mod 以及 Claude Code 内置的 mod。用户的设置 hook 会继续运行。 |
allowModsToOverrideDenyRules |
托管设置,作为内置守卫的选项 | 允许用户安装的 mod 批准被 deny 规则拒绝的工具调用 |
allowManagedHooksOnly |
托管设置 | 阻止不属于您组织的 hook 和已安装的 mod。请参阅哪些会继续运行。 |
disableAllHooks |
任何设置文件 | 在托管设置中,来自已安装插件的任何 mod 或 hook 都不会运行。在您自己的设置中,您组织管理的内容会继续运行。请参阅 disableAllHooks。 |
disableSideloadFlags |
托管设置 | 在启动时拒绝 --plugin-dir 和 --plugin-url |
pluginConfigs |
用户设置或托管设置 | 保存 mod 的 userConfig 值,以插件 id 为键,例如 acme-guard@acme-tools;对于使用 --plugin-dir 加载的 mod,则以其名称加 @inline 为键,例如 first-mod@inline |
sec-default@builtin 是 Claude Code 内置的守卫,在 /plugin 和调试日志中显示为 cc-plugin-sec-default。在有托管设置的机器上,或对于使用 Team 或 Enterprise 套餐登录的用户,它会在用户安装的每个 mod 之前加载。如果设置了托管的 prependPlugins,则只有当该列表指定了该守卫时它才会加载,并位于列出的位置。其源代码位于 Claude Code 仓库的 mods/sec-default 目录中。
命令
这些命令和标志用于加载、检查和测试 mod。claude 命令在您的 shell 中运行,/ 命令在 Claude Code 输入框中运行。表中的 <directory> 代表您输入的路径,如 claude plugin validate ./first-mod。方括号表示可选参数。
| 命令 | 作用 |
|---|---|
/plugin |
当有非内置的 mod 加载时,在其标签页下方显示一行,例如 1 mod active · first-mod |
claude plugin validate <directory> |
读取插件的清单和 hook 模块,并报告错误、它处理的事件以及它发出的 mods API 调用。--strict 将警告视为错误,--json 打印机器可读的报告。 |
claude plugin test [directory] |
运行该目录(如果未指定目录,则为当前目录)下名称以 .test.ts 或 .test.tsx 结尾的每个文件。有测试失败时以状态 1 退出。 |
claude --plugin-dir <directory> |
为一个会话加载插件目录,并在您保存时重新加载其 hook 模块。重复该标志可加载多个目录。 |
/reload-plugins |
在您运行时重新加载插件 |