SpyBara
Go Premium

plugins/mods/reference.md 2026-10-01 23:59 UTC to 2026-10-02 10:59 UTC

This page contains 326 additions and 0 deletions.

2026
Fri 2 11:59

mod 参考

Claude Code mod 的完整参考:hook 模块布局、事件、mods API 方法、渲染位置、按使用入口划分的元素、限制和设置。

查阅 mod 可以处理的任何事件、可以调用的任何 mods API 方法,或可以在其中绘制的任何渲染位置,适用于 v2.1.287 起的 Claude Code CLI 和 Desktop 应用。每个条目给出名称和一行描述,如有相应的指南章节,还会链接到该章节。

文件

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 在您运行时重新加载插件