6 6
7> Claude Code mod 的完整参考:hook 模块布局、事件、mods API 方法、渲染位置、按使用入口划分的元素、限制和设置。7> Claude Code mod 的完整参考:hook 模块布局、事件、mods API 方法、渲染位置、按使用入口划分的元素、限制和设置。
8 8
9查阅 [mod](/docs/zh-CN/plugins/mods/overview.md) 可以处理的任何事件、可以调用的任何 mods API 方法,或可以在其中绘制的任何渲染位置。条目涵盖 v2.1.290 起的 Claude Code CLI 和 Desktop 应用,以及 v2.1.299 起的 VS Code 扩展。每个条目给出名称和一行描述,如有相应的指南章节,还会链接到该章节。9查阅 [mod](https://code.claude.com/docs/zh-CN/plugins/mods/overview.md) 可以处理的任何事件、可以调用的任何 mods API 方法,或可以在其中绘制的任何渲染位置。条目涵盖 v2.1.290 起的 Claude Code CLI 和 Desktop 应用,以及 v2.1.299 起的 VS Code 扩展。每个条目给出名称和一行描述,如有相应的指南章节,还会链接到该章节。
10 10
11> [!NOTE]11> [!NOTE]
12>12>
13> 完整的参考是 Claude Code 的 [mod TypeScript 声明](https://github.com/anthropics/claude-code/blob/main/mods/types/claude-code.d.ts),其中描述了每个事件、方法和元素,并附有示例。GitHub 上的副本可能比您安装的 Claude Code 版本更旧。两者不一致时,请以 [Claude Code 为您的版本写入的副本](/docs/zh-CN/plugins/mods/create.md#get-the-types-for-your-build)为准。13> 完整的参考是 Claude Code 的 [mod TypeScript 声明](https://github.com/anthropics/claude-code/blob/main/mods/types/claude-code.d.ts),其中描述了每个事件、方法和元素,并附有示例。GitHub 上的副本可能比您安装的 Claude Code 版本更旧。两者不一致时,请以 [Claude Code 为您的版本写入的副本](https://code.claude.com/docs/zh-CN/plugins/mods/create.md#get-the-types-for-your-build)为准。
14 14
15## 文件15## 文件
16 16
18 18
19| 文件 | 必需 | 内容 |19| 文件 | 必需 | 内容 |
20| :- | :- | :- |20| :- | :- | :- |
21| `.claude-plugin/plugin.json` | 是 | 插件[清单](/docs/zh-CN/plugins/manifest-reference.md)。mod 不会添加任何必需字段。 |21| `.claude-plugin/plugin.json` | 是 | 插件[清单](https://code.claude.com/docs/zh-CN/plugins/manifest-reference.md)。mod 不会添加任何必需字段。 |
22| `hooks/hooks.json` | 是 | `modules`:一个数组,包含一个指向 hook 模块的路径(相对于此文件),如 `"modules": ["./register.js"]`。也可以在 `hooks` 下包含[设置 hook](/docs/zh-CN/hooks.md)。 |22| `hooks/hooks.json` | 是 | `modules`:一个数组,包含一个指向 hook 模块的路径(相对于此文件),如 `"modules": ["./register.js"]`。也可以在 `hooks` 下包含[设置 hook](https://code.claude.com/docs/zh-CN/hooks.md)。 |
23| hook 模块,例如 [`hooks/register.js`](/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) | 是 | mod 的入口点。导出 `register(on, options)`。文件名以 `.js`、`.mjs`、`.cjs`、`.jsx`、`.ts`、`.mts`、`.cts` 或 `.tsx` 结尾。是一个 ES 模块。 |23| hook 模块,例如 [`hooks/register.js`](https://code.claude.com/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) | 是 | mod 的入口点。导出 `register(on, options)`。文件名以 `.js`、`.mjs`、`.cjs`、`.jsx`、`.ts`、`.mts`、`.cts` 或 `.tsx` 结尾。是一个 ES 模块。 |
24| [`types/index.d.ts`](/docs/zh-CN/plugins/mods/interface#declare-the-values),由清单中的 `types` 指定 | 当 mod 使用 `$.state` 或向 mods API 添加命名空间时 | 声明 `PluginState` 值以及 mod 添加的任何命名空间 |24| [`types/index.d.ts`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#declare-the-values),由清单中的 `types` 指定 | 当 mod 使用 `$.state` 或向 mods API 添加命名空间时 | 声明 `PluginState` 值以及 mod 添加的任何命名空间 |
25| 名称以 `.test.ts` 或 `.test.tsx` 结尾的文件 | 否 | [`claude plugin test`](/docs/zh-CN/plugins/mods/test#write-a-test) 运行的测试 |25| 名称以 `.test.ts` 或 `.test.tsx` 结尾的文件 | 否 | [`claude plugin test`](https://code.claude.com/docs/zh-CN/plugins/mods/test#write-a-test) 运行的测试 |
26 26
27`register` 接收 `on` 和 `options`。`options` 包含清单所声明的 [`userConfig`](/docs/zh-CN/plugins/components#user-configuration) 字段的值,并已填入默认值。27`register` 接收 `on` 和 `options`。`options` 包含清单所声明的 [`userConfig`](https://code.claude.com/docs/zh-CN/plugins/components#user-configuration) 字段的值,并已填入默认值。
28 28
29## hook 函数29## hook 函数
30 30
31mod 通过在 `register` 内调用 `on` 来注册它的每个 hook(即事件处理程序)。`on` 接受事件名称、一个可选的[匹配器](/docs/zh-CN/plugins/mods/events.md#filter-which-events-a-hook-handles)(即对事件字段的过滤条件)以及 hook,如 `on('tool.call', { tool: 'Bash' }, async ($, e, next) => next(e))`。`on` 返回一个注册对象,它只有一个方法 `.catch(handler)`,用于设置该 hook 的[错误处理程序](/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。31mod 通过在 `register` 内调用 `on` 来注册它的每个 hook(即事件处理程序)。`on` 接受事件名称、一个可选的[匹配器](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#filter-which-events-a-hook-handles)(即对事件字段的过滤条件)以及 hook,如 `on('tool.call', { tool: 'Bash' }, async ($, e, next) => next(e))`。`on` 返回一个注册对象,它只有一个方法 `.catch(handler)`,用于设置该 hook 的[错误处理程序](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。
32 32
33| 参数 | 说明 |33| 参数 | 说明 |
34| :- | :- |34| :- | :- |
35| [`$`](/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | mods API:[mods API 方法](#mods-api-methods)中的所有方法。每次调用都要完整写出,先写命名空间再写方法,如 `$.fs.read('notes.md')`。 |35| [`$`](https://code.claude.com/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | mods API:[mods API 方法](#mods-api-methods)中的所有方法。每次调用都要完整写出,先写命名空间再写方法,如 `$.fs.read('notes.md')`。 |
36| [`e`](/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | 事件的输入,为深度冻结的纯数据。要更改它,请将副本传给 `next`。 |36| [`e`](https://code.claude.com/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | 事件的输入,为深度冻结的纯数据。要更改它,请将副本传给 `next`。 |
37| [`next(e)`](/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | 下一个处理程序,类似中间件。先运行此 hook 之后的 hook,再运行 Claude Code 的行为。解析为事件的结果。 |37| [`next(e)`](https://code.claude.com/docs/zh-CN/plugins/mods/events#how-a-hook-handles-an-event) | 下一个处理程序,类似中间件。先运行此 hook 之后的 hook,再运行 Claude Code 的行为。解析为事件的结果。 |
38| [`next.signal`](/docs/zh-CN/plugins/mods/api#stop-background-work) | 一个 `AbortSignal`,在事件被放弃时中止 |38| [`next.signal`](https://code.claude.com/docs/zh-CN/plugins/mods/api#stop-background-work) | 一个 `AbortSignal`,在事件被放弃时中止 |
39| `next.origin` | 触发该事件者的 `{ plugin, tier }`。Claude Code 自身为 `{ plugin: 'engine', tier: 'core' }`。mod 的 `tier` 是它在 [mod 运行顺序](/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)中的优先级组:`prepend`、`user`、`append` 或 `builtin`。 |39| `next.origin` | 触发该事件者的 `{ plugin, tier }`。Claude Code 自身为 `{ plugin: 'engine', tier: 'core' }`。mod 的 `tier` 是它在 [mod 运行顺序](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)中的优先级组:`prepend`、`user`、`append` 或 `builtin`。 |
40| `next.budget` | hook 的时间限制(以毫秒为单位):`next.budget.ms` 是总限制,`next.budget.remainingMs` 是当前剩余时间 |40| `next.budget` | hook 的时间限制(以毫秒为单位):`next.budget.ms` 是总限制,`next.budget.remainingMs` 是当前剩余时间 |
41| `next.to(e, tier)` | 跳到后面的层级,即 `append`、`builtin` 或 `core`。`next.to(e, 'append')` 会跳过用户安装的 mod。只有 `prependPlugins` 或 `appendPlugins` 中的 mod 才能调用它。 |41| `next.to(e, tier)` | 跳到后面的层级,即 `append`、`builtin` 或 `core`。`next.to(e, 'append')` 会跳过用户安装的 mod。只有 `prependPlugins` 或 `appendPlugins` 中的 mod 才能调用它。 |
42| `next.error` | 仅在 `.catch` 处理程序中可用。hook 失败时,`kind` 为 `throw` 或 `timeout`,`message` 是错误文本。当 hook 因事件来自该 hook 或您的 mod 在其 hook 之外的代码所发起的 mods API 调用内部而被跳过时,`kind` 为 `re-entry`。`re-entry` 需要 Claude Code v2.1.292 或更高版本。 |42| `next.error` | 仅在 `.catch` 处理程序中可用。hook 失败时,`kind` 为 `throw` 或 `timeout`,`message` 是错误文本。当 hook 因事件来自该 hook 或您的 mod 在其 hook 之外的代码所发起的 mods API 调用内部而被跳过时,`kind` 为 `re-entry`。`re-entry` 需要 Claude Code v2.1.292 或更高版本。 |
43| `next.error.cause` | 仅当 `kind` 为 `re-entry` 时设置。如果 `tool.call` 或 [`PreToolUse`](/docs/zh-CN/hooks#pretooluse) hook 更改了该事件所来自的 mods API 调用,或者 `agent.spawn` hook 更改了由该调用启动的 Agent,则为 `rewritten`。当触发该事件的是另一个 mod 添加到 mods API 的方法时,为 `lent`,除非同时适用 `rewritten`。`lent` 需要 Claude Code v2.1.292 或更高版本,`rewritten` 需要 v2.1.300 或更高版本。 |43| `next.error.cause` | 仅当 `kind` 为 `re-entry` 时设置。如果 `tool.call` 或 [`PreToolUse`](https://code.claude.com/docs/zh-CN/hooks#pretooluse) hook 更改了该事件所来自的 mods API 调用,或者 `agent.spawn` hook 更改了由该调用启动的 Agent,则为 `rewritten`。当触发该事件的是另一个 mod 添加到 mods API 的方法时,为 `lent`,除非同时适用 `rewritten`。`lent` 需要 Claude Code v2.1.292 或更高版本,`rewritten` 需要 v2.1.300 或更高版本。 |
44| `next.called` | 仅在 `.catch` 处理程序中可用。当 hook 已调用 `next` 时为 `true`。 |44| `next.called` | 仅在 `.catch` 处理程序中可用。当 hook 已调用 `next` 时为 `true`。 |
45 45
46## 事件46## 事件
55 55
56| 事件 | 触发时机 | hook 可以返回 |56| 事件 | 触发时机 | hook 可以返回 |
57| :- | :- | :- |57| :- | :- | :- |
58| [`tool.call`](/docs/zh-CN/plugins/mods/events#guard-or-change-a-tool-call) | 工具即将运行 | `next(e)`、`{ deny: reason }` 或 `{ result }` |58| [`tool.call`](https://code.claude.com/docs/zh-CN/plugins/mods/events#guard-or-change-a-tool-call) | 工具即将运行 | `next(e)`、`{ deny: reason }` 或 `{ result }` |
59| [`tool.check`](/docs/zh-CN/plugins/mods/events#where-settings-hooks-run-in-the-order) | Claude Code 在 `tool.call` 和 `PreToolUse` hook 之后决定是否允许运行某个工具调用。`next(e)` 解析为规则、权限模式和这些 hook 得出的决定。 | `next(e)` 或 `{ decision }`,其中 `decision` 设为 `allow`、`ask` 或 `deny`,并可附带可选的 `reason` |59| [`tool.check`](https://code.claude.com/docs/zh-CN/plugins/mods/events#where-settings-hooks-run-in-the-order) | Claude Code 在 `tool.call` 和 `PreToolUse` hook 之后决定是否允许运行某个工具调用。`next(e)` 解析为规则、权限模式和这些 hook 得出的决定。 | `next(e)` 或 `{ decision }`,其中 `decision` 设为 `allow`、`ask` 或 `deny`,并可附带可选的 `reason` |
60| `tool.describe` | 每个工具一次,在其描述首次发送给 Claude 时。对于 MCP 工具,当 Claude 通过[工具搜索](/docs/zh-CN/mcp.md#scale-with-mcp-tool-search)加载它时会再触发一次,此时 `e.description` 设为 Claude 针对已加载工具读取的文本。 | `{ description }`,可选择将 `isDeferred` 设为 `true` 以将该工具置于工具搜索之后,或设为 `false` 以预先加载它 |60| `tool.describe` | 每个工具一次,在其描述首次发送给 Claude 时。对于 MCP 工具,当 Claude 通过[工具搜索](https://code.claude.com/docs/zh-CN/mcp.md#scale-with-mcp-tool-search)加载它时会再触发一次,此时 `e.description` 设为 Claude 针对已加载工具读取的文本。 | `{ description }`,可选择将 `isDeferred` 设为 `true` 以将该工具置于工具搜索之后,或设为 `false` 以预先加载它 |
61 61
62#### `tool.check` 上的 Agent 和组织字段62#### `tool.check` 上的 Agent 和组织字段
63 63
64在 `tool.check` hook 中,读取以下字段可区分子代理的调用与主对话的调用,并查看您的组织是否要求对某个连接器工具进行批准:64在 `tool.check` hook 中,读取以下字段可区分子代理的调用与主对话的调用,并查看您的组织是否要求对某个连接器工具进行批准:
65 65
66* **`e.agentId`**:当[子代理](/docs/zh-CN/sub-agents.md)或[进程内队友](/docs/zh-CN/agent-teams.md#choose-a-display-mode)发出调用时设置,由主对话发出调用时则不存在66* **`e.agentId`**:当[子代理](https://code.claude.com/docs/zh-CN/sub-agents.md)或[进程内队友](https://code.claude.com/docs/zh-CN/agent-teams.md#choose-a-display-mode)发出调用时设置,由主对话发出调用时则不存在
67* **`e.ceiling`**:对于您的组织设为 `ask` 的连接器工具,其值为 `ask`,适用于[该设置能传达到 Claude Code 的会话](/docs/zh-CN/mcp.md#organization-controls-on-connector-tools)67* **`e.ceiling`**:对于您的组织设为 `ask` 的连接器工具,其值为 `ask`,适用于[该设置能传达到 Claude Code 的会话](https://code.claude.com/docs/zh-CN/mcp.md#organization-controls-on-connector-tools)
68 68
69在 `tool.check` 上,`e.agentId` 和 `e.ceiling` 需要 Claude Code v2.1.290 或更高版本。69在 `tool.check` 上,`e.agentId` 和 `e.ceiling` 需要 Claude Code v2.1.290 或更高版本。
70 70
71#### `tool.check` 上的 `e.isReadOnly` 字段71#### `tool.check` 上的 `e.isReadOnly` 字段
72 72
73在 `tool.check` hook 中,当工具报告此次调用为只读时,`e.isReadOnly` 为 `true`。否则该字段不存在,而不是 `false`。该值是工具自身的报告,因此在仅凭此字段批准某个调用之前,请先阅读[检查工具调用是否为只读](/docs/zh-CN/plugins/mods/events.md#check-whether-a-tool-call-is-read-only)。73在 `tool.check` hook 中,当工具报告此次调用为只读时,`e.isReadOnly` 为 `true`。否则该字段不存在,而不是 `false`。该值是工具自身的报告,因此在仅凭此字段批准某个调用之前,请先阅读[检查工具调用是否为只读](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#check-whether-a-tool-call-is-read-only)。
74 74
75在 `tool.check` 上,`e.isReadOnly` 需要 Claude Code v2.1.304 或更高版本。75在 `tool.check` 上,`e.isReadOnly` 需要 Claude Code v2.1.304 或更高版本。
76 76
80 80
81| 事件 | 触发时机 | hook 可以返回 |81| 事件 | 触发时机 | hook 可以返回 |
82| :- | :- | :- |82| :- | :- | :- |
83| [`prompt.submit`](/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 提交提示词时 | `next({ ...e, text })`、`next({ ...e, context })` 或 `{ drop: reason }` |83| [`prompt.submit`](https://code.claude.com/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 提交提示词时 | `next({ ...e, text })`、`next({ ...e, context })` 或 `{ drop: reason }` |
84| `prompt.fill`, `prompt.suggest` | 文本即将作为草稿或暗色建议进入输入框 | 更改了文本的 `next(e)` |84| `prompt.fill`, `prompt.suggest` | 文本即将作为草稿或暗色建议进入输入框 | 更改了文本的 `next(e)` |
85| `prompt.edit` | 用户编辑输入框 | `next(e)` |85| `prompt.edit` | 用户编辑输入框 | `next(e)` |
86| `prompt.autocomplete` | 用户在输入框中输入内容,且光标处有一个词结束。`e.token` 即该词。Claude Code 不会等待该 hook:其自身的自动补全行会先显示。 | `{ suggestions }`,一个由 `{ text, label, description }` 行组成的列表,显示在 Claude Code 自身的行下方。选择某一行会用其 `text` 覆盖该词。 |86| `prompt.autocomplete` | 用户在输入框中输入内容,且光标处有一个词结束。`e.token` 即该词。Claude Code 不会等待该 hook:其自身的自动补全行会先显示。 | `{ suggestions }`,一个由 `{ text, label, description }` 行组成的列表,显示在 Claude Code 自身的行下方。选择某一行会用其 `text` 覆盖该词。 |
87| `prompt.compose` | Claude Code 渲染系统提示词 | `{ sections }`,一个按发送顺序排列的 `{ id, text, scope }` 列表 |87| `prompt.compose` | Claude Code 渲染系统提示词 | `{ sections }`,一个按发送顺序排列的 `{ id, text, scope }` 列表 |
88| [`prompt.section`](/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 系统提示词的每个命名部分一次。`e.name` 是该部分在 `prompt.compose` 中的 `id`。 | `{ text }`,或 `{ text: null }` 以省略该部分 |88| [`prompt.section`](https://code.claude.com/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 系统提示词的每个命名部分一次。`e.name` 是该部分在 `prompt.compose` 中的 `id`。 | `{ text }`,或 `{ text: null }` 以省略该部分 |
89| [`prompt.context`](/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 每个对话一次,用于随第一条消息发送的上下文 | `{ blocks }` |89| [`prompt.context`](https://code.claude.com/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | 每个对话一次,用于随第一条消息发送的上下文 | `{ blocks }` |
90| `prompt.attachment` | Claude Code 为 Claude 添加一条它自己的消息,例如提醒。`e.type` 指明消息类型;对于类型声明中已声明的类型,`e.detail` 包含编写该文本所依据的事实。 | `{ text }`,或 `{ text: null }` 以省略它 |90| `prompt.attachment` | Claude Code 为 Claude 添加一条它自己的消息,例如提醒。`e.type` 指明消息类型;对于类型声明中已声明的类型,`e.detail` 包含编写该文本所依据的事实。 | `{ text }`,或 `{ text: null }` 以省略它 |
91| `prompt.mention` | Claude Code 即将读取提示词中 @ 提及的文件。需要 Claude Code v2.1.290 或更高版本。 | `next({ ...e, path })` 以读取其他文件,或 `{ deny: reason }` |91| `prompt.mention` | Claude Code 即将读取提示词中 @ 提及的文件。需要 Claude Code v2.1.290 或更高版本。 | `next({ ...e, path })` 以读取其他文件,或 `{ deny: reason }` |
92| [`skill.prompt`](/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | skill 的文本为 Claude 展开时 | `{ text }` |92| [`skill.prompt`](https://code.claude.com/docs/zh-CN/plugins/mods/events#rewrite-or-add-to-a-prompt) | skill 的文本为 Claude 展开时 | `{ text }` |
93| `attribution.text` | Claude Code 撰写提交或 Pull Request 的署名文本时 | `{ text }` |93| `attribution.text` | Claude Code 撰写提交或 Pull Request 的署名文本时 | `{ text }` |
94 94
95#### `skill.prompt` 上的来源和 frontmatter 字段95#### `skill.prompt` 上的来源和 frontmatter 字段
98 98
99| 字段 | 类型 | 包含的内容 |99| 字段 | 类型 | 包含的内容 |
100| :- | :- | :- |100| :- | :- | :- |
101| `e.source` | string | 提供该 skill 的来源:对于位于企业、个人或项目[位置](/docs/zh-CN/skills.md#where-skills-live)的 skill,分别为 `policySettings`、`userSettings` 或 `projectSettings`。其他来源给出 `plugin`、`mcp`、`syncedSkills` 或 `built-in` 之类的词。 |101| `e.source` | string | 提供该 skill 的来源:对于位于企业、个人或项目[位置](https://code.claude.com/docs/zh-CN/skills.md#where-skills-live)的 skill,分别为 `policySettings`、`userSettings` 或 `projectSettings`。其他来源给出 `plugin`、`mcp`、`syncedSkills` 或 `built-in` 之类的词。 |
102| `e.pluginName` | string | 对于 `e.source` 为 `plugin` 的 skill,为插件的名称 |102| `e.pluginName` | string | 对于 `e.source` 为 `plugin` 的 skill,为插件的名称 |
103| `e.path` | string | skill 的 `SKILL.md` 文件的绝对路径;对于以[命令文件](/docs/zh-CN/skills.md#where-skills-live)形式编写的 skill,则为其 `.md` 文件的绝对路径。当该 skill 在本机上没有文件时(如内置 skill)不存在。 |103| `e.path` | string | skill 的 `SKILL.md` 文件的绝对路径;对于以[命令文件](https://code.claude.com/docs/zh-CN/skills.md#where-skills-live)形式编写的 skill,则为其 `.md` 文件的绝对路径。当该 skill 在本机上没有文件时(如内置 skill)不存在。 |
104| `e.frontmatter` | object | skill 文件的 frontmatter,以纯数据形式提供 |104| `e.frontmatter` | object | skill 文件的 frontmatter,以纯数据形式提供 |
105| `e.frontmatterProblem` | string | `e.frontmatter` 缺少该文件的 frontmatter 或其中某个键的原因,如 `is a list or a single value, not a table`。当 `e.frontmatter` 包含完整的 frontmatter 或该 skill 没有 frontmatter 时不存在。 |105| `e.frontmatterProblem` | string | `e.frontmatter` 缺少该文件的 frontmatter 或其中某个键的原因,如 `is a list or a single value, not a table`。当 `e.frontmatter` 包含完整的 frontmatter 或该 skill 没有 frontmatter 时不存在。 |
106 106
107hook 可以将更改后的 `text` 或 `frontmatter` 传给 `next`:其后的 hook 会读取这两者,而 Claude 读取最终的 `text`。更改任何其他字段的 hook 会[失败](/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。107hook 可以将更改后的 `text` 或 `frontmatter` 传给 `next`:其后的 hook 会读取这两者,而 Claude 读取最终的 `text`。更改任何其他字段的 hook 会[失败](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。
108 108
109在 `skill.prompt` 上,`e.source`、`e.pluginName`、`e.path`、`e.frontmatter` 和 `e.frontmatterProblem` 需要 Claude Code v2.1.299 或更高版本。109在 `skill.prompt` 上,`e.source`、`e.pluginName`、`e.path`、`e.frontmatter` 和 `e.frontmatterProblem` 需要 Claude Code v2.1.299 或更高版本。
110 110
114 114
115| 事件 | 触发时机 | hook 可以返回 |115| 事件 | 触发时机 | hook 可以返回 |
116| :- | :- | :- |116| :- | :- | :- |
117| [`command.run`](/docs/zh-CN/plugins/mods/api#add-a-command) | 命令即将运行 | `{ text }`、`{}` 或 `next(e)` |117| [`command.run`](https://code.claude.com/docs/zh-CN/plugins/mods/api#add-a-command) | 命令即将运行 | `{ text }`、`{}` 或 `next(e)` |
118| `command.describe` | 每个命令一次,用于命令列表 | `{ description, argumentHint, isHidden }` |118| `command.describe` | 每个命令一次,用于命令列表 | `{ description, argumentHint, isHidden }` |
119| `config.set` | `/config` 行即将更改 | `next({ ...e, value })` 或 `{ deny: reason }` |119| `config.set` | `/config` 行即将更改 | `next({ ...e, value })` 或 `{ deny: reason }` |
120| `config.describe` | 每个 `/config` 行一次 | `{ label, description, isHidden }` |120| `config.describe` | 每个 `/config` 行一次 | `{ label, description, isHidden }` |
125 125
126| 事件 | 触发时机 | hook 可以返回 |126| 事件 | 触发时机 | hook 可以返回 |
127| :- | :- | :- |127| :- | :- | :- |
128| [`turn.start`](/docs/zh-CN/plugins/mods/events#follow-a-turn) | 轮次开始 | `next(e)` |128| [`turn.start`](https://code.claude.com/docs/zh-CN/plugins/mods/events#follow-a-turn) | 轮次开始 | `next(e)` |
129| [`turn.step`](/docs/zh-CN/plugins/mods/events#follow-a-turn) | 一个请求即将发往模型 | `yield* next(e)`,或 `next({ ...e, model })`、`next({ ...e, effort })` |129| [`turn.step`](https://code.claude.com/docs/zh-CN/plugins/mods/events#follow-a-turn) | 一个请求即将发往模型 | `yield* next(e)`,或 `next({ ...e, model })`、`next({ ...e, effort })` |
130| [`turn.complete`](/docs/zh-CN/plugins/mods/events#follow-a-turn) | 轮次结束 | `next(e)`,或 `{ text }` 以在回答下方显示一行 |130| [`turn.complete`](https://code.claude.com/docs/zh-CN/plugins/mods/events#follow-a-turn) | 轮次结束 | `next(e)`,或 `{ text }` 以在回答下方显示一行 |
131 131
132### 会话132### 会话
133 133
135 135
136| 事件 | 触发时机 | hook 可以返回 |136| 事件 | 触发时机 | hook 可以返回 |
137| :- | :- | :- |137| :- | :- | :- |
138| [`session.start`](/docs/zh-CN/plugins/mods/api#add-a-command-or-a-tool) | 每个已加载的 mod 一次,在第一个提示词之前触发,并在该 mod 重新加载后再次触发。`/clear`、`/resume` 或 `/branch` 之后不会触发。 | `next(e)` |138| [`session.start`](https://code.claude.com/docs/zh-CN/plugins/mods/api#add-a-command-or-a-tool) | 每个已加载的 mod 一次,在第一个提示词之前触发,并在该 mod 重新加载后再次触发。`/clear`、`/resume` 或 `/branch` 之后不会触发。 | `next(e)` |
139| `session.end` | 会话结束,或运行 `/clear`、`/resume` 或 `/branch` 时。`e.reason` 为 `clear`、`resume`、`logout`、`prompt_input_exit` 或 `other`。`/branch` 报告为 `resume`。 | `next(e)` |139| `session.end` | 会话结束,或运行 `/clear`、`/resume` 或 `/branch` 时。`e.reason` 为 `clear`、`resume`、`logout`、`prompt_input_exit` 或 `other`。`/branch` 报告为 `resume`。 | `next(e)` |
140| `session.compact` | 对话即将被压缩 | `{ skip: reason }` |140| `session.compact` | 对话即将被压缩 | `{ skip: reason }` |
141| [`session.receive`](/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions), [`session.send`](/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions) | 一条消息从另一个 Agent 或会话到达,或即将发往另一个 Agent 或会话。请参阅[在会话之间发送和接收消息](/docs/zh-CN/plugins/mods/api.md#send-and-receive-messages-between-sessions)。 | `receive` 返回 `{ consumed: reason }`,`send` 返回 `{ isDelivered: false, reason }` |141| [`session.receive`](https://code.claude.com/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions), [`session.send`](https://code.claude.com/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions) | 一条消息从另一个 Agent 或会话到达,或即将发往另一个 Agent 或会话。请参阅[在会话之间发送和接收消息](https://code.claude.com/docs/zh-CN/plugins/mods/api.md#send-and-receive-messages-between-sessions)。 | `receive` 返回 `{ consumed: reason }`,`send` 返回 `{ isDelivered: false, reason }` |
142| `session.append` | 对话保留的每一行一次,例如提示词、响应块、工具结果或通知,在存储之前触发 | 带有更改后 `message.content` 的 `next({ ...e, message })`,用于重写该行的文本块或其中 `tool_result` 块的 `content` |142| `session.append` | 对话保留的每一行一次,例如提示词、响应块、工具结果或通知,在存储之前触发 | 带有更改后 `message.content` 的 `next({ ...e, message })`,用于重写该行的文本块或其中 `tool_result` 块的 `content` |
143| `session.attach`, `session.detach` | 另一个应用连接到会话或从会话断开 | `next(e)` |143| `session.attach`, `session.detach` | 另一个应用连接到会话或从会话断开 | `next(e)` |
144| `session.measure` | 每个轮次之后,以及套餐限制的已用百分比发生变化时 | `next(e)` |144| `session.measure` | 每个轮次之后,以及套餐限制的已用百分比发生变化时 | `next(e)` |
150| 事件 | 触发时机 | hook 可以返回 |150| 事件 | 触发时机 | hook 可以返回 |
151| :- | :- | :- |151| :- | :- | :- |
152| `agent.offer` | 向 Claude 提供某个子代理类型 | `{ isOffered: false }` 以不提供它 |152| `agent.offer` | 向 Claude 提供某个子代理类型 | `{ isOffered: false }` 以不提供它 |
153| `agent.spawn` | 子代理或 [agent team](/docs/zh-CN/agent-teams.md) 队友即将启动。对于队友,`e.isTeammate` 为 `true`。 | `next({ ...e, model })` 以选择其模型,或 `{ deny: reason }` |153| `agent.spawn` | 子代理或 [agent team](https://code.claude.com/docs/zh-CN/agent-teams.md) 队友即将启动。对于队友,`e.isTeammate` 为 `true`。 | `next({ ...e, model })` 以选择其模型,或 `{ deny: reason }` |
154 154
155当 Claude 使用 [`SendMessage`](/docs/zh-CN/sub-agents#resume-subagents) 工具恢复子代理时,您的 `agent.spawn` hook 不会再次运行。要拒绝恢复子代理的 `SendMessage` 调用,请在 [`tool.call`](/docs/zh-CN/plugins/mods/events#guard-or-change-a-tool-call) hook 中匹配该工具。155当 Claude 使用 [`SendMessage`](https://code.claude.com/docs/zh-CN/sub-agents#resume-subagents) 工具恢复子代理时,您的 `agent.spawn` hook 不会再次运行。要拒绝恢复子代理的 `SendMessage` 调用,请在 [`tool.call`](https://code.claude.com/docs/zh-CN/plugins/mods/events#guard-or-change-a-tool-call) hook 中匹配该工具。
156 156
157### 界面157### 界面
158 158
159界面事件在 Claude Code 绘制渲染位置时,以及用户使用 mod 绘制的控件时触发。[在界面中绘制](/docs/zh-CN/plugins/mods/interface.md)展示了 `ui.render` hook 返回的内容:159界面事件在 Claude Code 绘制渲染位置时,以及用户使用 mod 绘制的控件时触发。[在界面中绘制](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md)展示了 `ui.render` hook 返回的内容:
160 160
161| 事件 | 触发时机 |161| 事件 | 触发时机 |
162| :- | :- |162| :- | :- |
163| [`ui.render`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | 某个[渲染位置](#render-sites)即将被绘制 |163| [`ui.render`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | 某个[渲染位置](#render-sites)即将被绘制 |
164| `ui.resolve` | mod 加载时,每个应用、渲染位置和 mod 各一次。其结果是 `$.ui.resolve(e)` 读取的元素表。 |164| `ui.resolve` | mod 加载时,每个应用、渲染位置和 mod 各一次。其结果是 `$.ui.resolve(e)` 读取的元素表。 |
165| [`ui.press`](/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing), [`ui.input`](/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing), [`ui.select`](/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing) | mod 绘制的 `Button`、`Input` 或 `Select` 被使用 |165| [`ui.press`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing), [`ui.input`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing), [`ui.select`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing) | mod 绘制的 `Button`、`Input` 或 `Select` 被使用 |
166| `ui.focus`, `ui.scroll` | 获得焦点的控件,或窗格或横栏的滚动位置即将更改 |166| `ui.focus`, `ui.scroll` | 获得焦点的控件,或窗格或横栏的滚动位置即将更改 |
167| `ui.close` | 窗格即将关闭。`e.id` 是该窗格,`e.origin.kind` 为 `plugin`、`person` 或 `unload`。 |167| `ui.close` | 窗格即将关闭。`e.id` 是该窗格,`e.origin.kind` 为 `plugin`、`person` 或 `unload`。 |
168| [`ui.message`](/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `Client` 元素向其 mod 发送数据 |168| [`ui.message`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `Client` 元素向其 mod 发送数据 |
169| [`ui.fault`](/docs/zh-CN/plugins/mods/interface#redraw-when-something-changes) | 您的 mod 绘制的 `Client` 元素加载、绘制或运行失败。`e.phase` 为 `load`、`render` 或 `run`,`e.reason` 是错误消息。需要 Claude Code v2.1.289 或更高版本。 |169| [`ui.fault`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#redraw-when-something-changes) | 您的 mod 绘制的 `Client` 元素加载、绘制或运行失败。`e.phase` 为 `load`、`render` 或 `run`,`e.reason` 是错误消息。需要 Claude Code v2.1.289 或更高版本。 |
170 170
171### 其他 mod171### 其他 mod
172 172
174 174
175| 事件 | 触发时机 | hook 可以返回 |175| 事件 | 触发时机 | hook 可以返回 |
176| :- | :- | :- |176| :- | :- | :- |
177| [`plugin.register`](/docs/zh-CN/plugins/mods/admin#enforce-a-policy-with-a-mod-of-your-own) | hook 模块即将加载。`e.uses` 列出它的事件、mods API 调用、环境变量和状态,与 `claude plugin validate` 打印的内容一致。每个调用都不带 `$.` 前缀,如 `fs.read`。 | `{ refuse: reason }` |177| [`plugin.register`](https://code.claude.com/docs/zh-CN/plugins/mods/admin#enforce-a-policy-with-a-mod-of-your-own) | hook 模块即将加载。`e.uses` 列出它的事件、mods API 调用、环境变量和状态,与 `claude plugin validate` 打印的内容一致。每个调用都不带 `$.` 前缀,如 `fs.read`。 | `{ refuse: reason }` |
178| `engine.create` | 正在为此 mod 构建 mods API | 更改后的 mods API,用于添加某个命名空间。`user` [层级](#the-hook-function)之外的 mod 还可以隐藏某个命名空间。 |178| `engine.create` | 正在为此 mod 构建 mods API | 更改后的 mods API,用于添加某个命名空间。`user` [层级](#the-hook-function)之外的 mod 还可以隐藏某个命名空间。 |
179 179
180当另一个 mod 的 hook 调用您在 `engine.create` 中添加的命名空间上的方法时,在该事件上的所有 hook 返回之前,您的方法发出的 `$` 调用都在该 hook 的上下文中运行。例如,相对路径基于该 hook 的工作目录解析,而当轮次正在等待该 hook 时,`$.prompt.submit` 会被拒绝。在此之后您的方法发出的调用将在您的 mod 自身的上下文中运行。180当另一个 mod 的 hook 调用您在 `engine.create` 中添加的命名空间上的方法时,在该事件上的所有 hook 返回之前,您的方法发出的 `$` 调用都在该 hook 的上下文中运行。例如,相对路径基于该 hook 的工作目录解析,而当轮次正在等待该 hook 时,`$.prompt.submit` 会被拒绝。在此之后您的方法发出的调用将在您的 mod 自身的上下文中运行。
189 189
190### 设置 hook 事件190### 设置 hook 事件
191 191
192每个[设置 hook 事件](/docs/zh-CN/hooks.md#hook-events)都是一个名为 `classic.<Event>` 的事件,如 `classic.Stop` 或 `classic.PostToolUse`。`e` 是该 hook 的 stdin JSON。192每个[设置 hook 事件](https://code.claude.com/docs/zh-CN/hooks.md#hook-events)都是一个名为 `classic.<Event>` 的事件,如 `classic.Stop` 或 `classic.PostToolUse`。`e` 是该 hook 的 stdin JSON。
193 193
194### mods API 调用194### mods API 调用
195 195
197 197
198## mods API 方法198## mods API 方法
199 199
200mods API 是每个 hook 接收的 `$` 参数。它的方法按命名空间分组,例如 `$.ui`。此表按名称列出每个命名空间的方法,因此 `$.ui` 行中的 `open` 就是调用 `$.ui.open(...)`。指南展示了常用方法的用法,而[您的构建版本的类型](/docs/zh-CN/plugins/mods/create.md#get-the-types-for-your-build)记录了每个方法并附有示例。200mods API 是每个 hook 接收的 `$` 参数。它的方法按命名空间分组,例如 `$.ui`。此表按名称列出每个命名空间的方法,因此 `$.ui` 行中的 `open` 就是调用 `$.ui.open(...)`。指南展示了常用方法的用法,而[您的构建版本的类型](https://code.claude.com/docs/zh-CN/plugins/mods/create.md#get-the-types-for-your-build)记录了每个方法并附有示例。
201 201
202| 命名空间 | 方法 |202| 命名空间 | 方法 |
203| :- | :- |203| :- | :- |
204| `$.plugin` | `name`、`root`:此插件的名称和目录 |204| `$.plugin` | `name`、`root`:此插件的名称和目录 |
205| [`$.ui`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `resolve`、`invalidate`、`open`、`close`、`panes`、`focus`、`scroll`、`toast`、`notify`、`status`、`log`、`notice`、`ask`、`copy`、`selection`、`blit` |205| [`$.ui`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `resolve`、`invalidate`、`open`、`close`、`panes`、`focus`、`scroll`、`toast`、`notify`、`status`、`log`、`notice`、`ask`、`copy`、`selection`、`blit` |
206| [`$.command`](/docs/zh-CN/plugins/mods/api#add-a-command) | `register`、`run`、`list` |206| [`$.command`](https://code.claude.com/docs/zh-CN/plugins/mods/api#add-a-command) | `register`、`run`、`list` |
207| [`$.tool`](/docs/zh-CN/plugins/mods/api#add-a-tool) | `register`、`call`、`check`、`list` |207| [`$.tool`](https://code.claude.com/docs/zh-CN/plugins/mods/api#add-a-tool) | `register`、`call`、`check`、`list` |
208| `$.agent` | `register`、`spawn`、`list`。`list()` 返回此会话的子代理和队友,每项都带有 `status`,其值为 `pending`、`running`、`waiting`、`idle`、`completed`、`failed` 或 `killed` 之一,其中 `idle` 和 `waiting` 需要 Claude Code v2.1.289 或更高版本。 |208| `$.agent` | `register`、`spawn`、`list`。`list()` 返回此会话的子代理和队友,每项都带有 `status`,其值为 `pending`、`running`、`waiting`、`idle`、`completed`、`failed` 或 `killed` 之一,其中 `idle` 和 `waiting` 需要 Claude Code v2.1.289 或更高版本。 |
209| [`$.model`](/docs/zh-CN/plugins/mods/api#call-a-model) | `complete`、`fork`、`classify` |209| [`$.model`](https://code.claude.com/docs/zh-CN/plugins/mods/api#call-a-model) | `complete`、`fork`、`classify` |
210| [`$.prompt`](/docs/zh-CN/plugins/mods/api#start-a-turn-from-a-background-job) | `submit`、`read`、`fill`、`suggest`、`compose`。Claude 读取来自 `submit({ text })` 的文本时,前面会有一句指明您的 mod 为发送者的话。`submit({ text, asUser: true })` 将文本作为用户自己的话发送,不带那句话。 |210| [`$.prompt`](https://code.claude.com/docs/zh-CN/plugins/mods/api#start-a-turn-from-a-background-job) | `submit`、`read`、`fill`、`suggest`、`compose`。Claude 读取来自 `submit({ text })` 的文本时,前面会有一句指明您的 mod 为发送者的话。`submit({ text, asUser: true })` 将文本作为用户自己的话发送,不带那句话。 |
211| `$.turn` | `abort` |211| `$.turn` | `abort` |
212| [`$.session`](/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions) | `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 }` 组成的列表。 |212| [`$.session`](https://code.claude.com/docs/zh-CN/plugins/mods/api#send-and-receive-messages-between-sessions) | `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 }` 组成的列表。 |
213| `$.config` | `list`、`set` |213| `$.config` | `list`、`set` |
214| [`$.settings`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `read` |214| [`$.settings`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `read` |
215| [`$.env`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `get`、`set` |215| [`$.env`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `get`、`set` |
216| [`$.fs`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `read`、`write`、`list`、`exists`、`stat`、`ancestors`。`write` 不是原子操作:它会原地替换文件内容,因此另一个进程可能读到只写了一部分的文件。请将多个会话都会更改的数据保存在 `$.store` 中。 |216| [`$.fs`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `read`、`write`、`list`、`exists`、`stat`、`ancestors`。`write` 不是原子操作:它会原地替换文件内容,因此另一个进程可能读到只写了一部分的文件。请将多个会话都会更改的数据保存在 `$.store` 中。 |
217| [`$.store`](/docs/zh-CN/plugins/mods/interface#keep-state) | `get`、`set`、`delete`、`keys`。一个由本机所有会话共享的键值存储。请参阅[从多个会话保存](/docs/zh-CN/plugins/mods/interface.md#save-from-more-than-one-session)。 |217| [`$.store`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#keep-state) | `get`、`set`、`delete`、`keys`。一个由本机所有会话共享的键值存储。请参阅[从多个会话保存](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#save-from-more-than-one-session)。 |
218| [`$.state`](/docs/zh-CN/plugins/mods/interface#keep-a-value-in-\$-state) | 响应式状态:`get`、`set`,以及从 `claude-code` 导入的辅助函数 `atom`、`read`、`update`、`derive` 和 `memberOf` |218| [`$.state`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#keep-a-value-in-\$-state) | 响应式状态:`get`、`set`,以及从 `claude-code` 导入的辅助函数 `atom`、`read`、`update`、`derive` 和 `memberOf` |
219| [`$.clock`](/docs/zh-CN/plugins/mods/api#run-work-in-the-background) | `now`、`sleep`、`after`、`every` |219| [`$.clock`](https://code.claude.com/docs/zh-CN/plugins/mods/api#run-work-in-the-background) | `now`、`sleep`、`after`、`every` |
220| [`$.http`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `fetch` |220| [`$.http`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `fetch` |
221| [`$.process`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `run`、`spawn` |221| [`$.process`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `run`、`spawn` |
222| [`$.mcp`](/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `call`、`connect`。`connect(server)` 连接您自己的插件清单中列出的 MCP 服务器。 |222| [`$.mcp`](https://code.claude.com/docs/zh-CN/plugins/mods/api#reach-files-processes-and-the-network) | `call`、`connect`。`connect(server)` 连接您自己的插件清单中列出的 MCP 服务器。 |
223| `$.audio` | `play`、`speak` |223| `$.audio` | `play`、`speak` |
224| `$.telemetry` | `log`、`mark`。仅当由 Claude Code 或内置 mod 发出调用时,才会发送记录。 |224| `$.telemetry` | `log`、`mark`。仅当由 Claude Code 或内置 mod 发出调用时,才会发送记录。 |
225 225
226## 渲染位置226## 渲染位置
227 227
228渲染位置是 Claude Code 界面中的扩展点。每一行是 `ui.render` hook 中 `e.component` 的一个值,并列出了 `e.props` 的字段以及渲染它的应用。`e.surface` 指明正在绘制的应用,例如 `terminal`、`desktop` 或 `vscode`。[更改 Claude Code 已绘制的内容](/docs/zh-CN/plugins/mods/interface.md#change-what-claude-code-already-draws)展示了 hook 在某个位置可以做什么,并为每种选择提供了示例。228渲染位置是 Claude Code 界面中的扩展点。每一行是 `ui.render` hook 中 `e.component` 的一个值,并列出了 `e.props` 的字段以及渲染它的应用。`e.surface` 指明正在绘制的应用,例如 `terminal`、`desktop` 或 `vscode`。[更改 Claude Code 已绘制的内容](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#change-what-claude-code-already-draws)展示了 hook 在某个位置可以做什么,并为每种选择提供了示例。
229 229
230在 VS Code 扩展中进行渲染需要扩展版本 2.1.299 或更高版本。[不获取功能标志](/docs/zh-CN/env-vars.md#features-that-need-feature-flag-fetching)的会话需要 2.1.304 或更高版本。[在 VS Code 扩展中绘制](/docs/zh-CN/plugins/mods/interface.md#draw-in-the-vs-code-extension)列出了该扩展在绘制上的不同之处。230在 VS Code 扩展中进行渲染需要扩展版本 2.1.299 或更高版本。[不获取功能标志](https://code.claude.com/docs/zh-CN/env-vars.md#features-that-need-feature-flag-fetching)的会话需要 2.1.304 或更高版本。[在 VS Code 扩展中绘制](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#draw-in-the-vs-code-extension)列出了该扩展在绘制上的不同之处。
231 231
232| 位置 | `e.props` | `e.requestId` | 渲染于 |232| 位置 | `e.props` | `e.requestId` | 渲染于 |
233| :- | :- | :- | :- |233| :- | :- | :- | :- |
234| [`Pane`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `title`、`isFocused`、`bodyColumns`、`placement`、`scroll`、`view` | 窗格的 `id` | 终端、Desktop、VS Code |234| [`Pane`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `title`、`isFocused`、`bodyColumns`、`placement`、`scroll`、`view` | 窗格的 `id` | 终端、Desktop、VS Code |
235| [`AbovePrompt`](/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `hasSurvey`、`isWorking`、`maxRows`、`bodyColumns`、`scroll`、`view` | 单一实例 | 终端、Desktop |235| [`AbovePrompt`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#pick-where-to-draw) | `hasSurvey`、`isWorking`、`maxRows`、`bodyColumns`、`scroll`、`view` | 单一实例 | 终端、Desktop |
236| `UserMessage` | `text`、`origin`、`isExpanded`,以及视来源而定的 `task` 或 `from` | 消息 id | 终端、Desktop、VS Code |236| `UserMessage` | `text`、`origin`、`isExpanded`,以及视来源而定的 `task` 或 `from` | 消息 id | 终端、Desktop、VS Code |
237| `AssistantMessage` | 回复的文本 | 消息 id | 终端、Desktop、VS Code |237| `AssistantMessage` | 回复的文本 | 消息 id | 终端、Desktop、VS Code |
238| `ToolUse`, `ToolResult`, `ToolGroup` | 工具的名称、输入和结果 | 工具调用 id | 终端、Desktop、VS Code |238| `ToolUse`, `ToolResult`, `ToolGroup` | 工具的名称、输入和结果 | 工具调用 id | 终端、Desktop、VS Code |
239| `CommandOutput` | `command`、`text` | 消息 id | 终端、Desktop |239| `CommandOutput` | `command`、`text` | 消息 id | 终端、Desktop |
240| [`AskUserQuestion`](/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) | 问题和选项 | 工具调用 id | 终端、Desktop、VS Code |240| [`AskUserQuestion`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) | 问题和选项 | 工具调用 id | 终端、Desktop、VS Code |
241| `ToolProgress` | `kind` | 工具调用 id | 终端 |241| `ToolProgress` | `kind` | 工具调用 id | 终端 |
242| [`Spinner`](/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) | `word`、`message`、`suffix`、`mode` | Agent id | 终端、Desktop、VS Code |242| [`Spinner`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) | `word`、`message`、`suffix`、`mode` | Agent id | 终端、Desktop、VS Code |
243| `TurnDuration` | `word`、`durationMs` | 消息 id | 终端 |243| `TurnDuration` | `word`、`durationMs` | 消息 id | 终端 |
244| `InfoNotice` | `text`、`command` | 消息 id | 终端 |244| `InfoNotice` | `text`、`command` | 消息 id | 终端 |
245| `SessionMode` | `modes` | 单一实例 | 终端、Desktop |245| `SessionMode` | `modes` | 单一实例 | 终端、Desktop |
251 251
252* **`Pane` 或横栏的宽度**:按 `e.props.bodyColumns` 绘制252* **`Pane` 或横栏的宽度**:按 `e.props.bodyColumns` 绘制
253* **会话记录旁的 `Pane` 的高度**:当 `e.props.placement` 为 `'dock'` 时,`e.props.scroll.bodyRows` 是该窗格可供您的树使用的行数253* **会话记录旁的 `Pane` 的高度**:当 `e.props.placement` 为 `'dock'` 时,`e.props.scroll.bodyRows` 是该窗格可供您的树使用的行数
254* **输入框上方的 `Pane` 的高度**:当 `e.props.placement` 为 `'inline'` 时,窗格会随您的树增高,直到达到上限,而 `bodyRows` 就是该上限。如需请求不同的上限,请参阅 [`$.ui.open` 的 `rows` 字段](/docs/zh-CN/plugins/mods/interface#open-a-pane-at-the-right-time)。254* **输入框上方的 `Pane` 的高度**:当 `e.props.placement` 为 `'inline'` 时,窗格会随您的树增高,直到达到上限,而 `bodyRows` 就是该上限。如需请求不同的上限,请参阅 [`$.ui.open` 的 `rows` 字段](https://code.claude.com/docs/zh-CN/plugins/mods/interface#open-a-pane-at-the-right-time)。
255 255
256比窗格更高的树会整体滚动。256比窗格更高的树会整体滚动。
257 257
258## 元素258## 元素
259 259
260元素是 `ui.render` hook 所返回的树的构建块,您可以从 `$.ui.resolve(e)` 获取它们。[用元素构建树](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)展示了常用元素以及终端如何绘制它们,[界面图库](/docs/zh-CN/plugins/mods/gallery.md)提供了大多数元素的截图。对勾表示该应用可以绘制该元素。260元素是 `ui.render` hook 所返回的树的构建块,您可以从 `$.ui.resolve(e)` 获取它们。[用元素构建树](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)展示了常用元素以及终端如何绘制它们,[界面图库](https://code.claude.com/docs/zh-CN/plugins/mods/gallery.md)提供了大多数元素的截图。对勾表示该应用可以绘制该元素。
261 261
262| 元素 | 主要 prop | 终端 | Desktop | VS Code |262| 元素 | 主要 prop | 终端 | Desktop | VS Code |
263| :- | :- | :-: | :-: | :-: |263| :- | :- | :-: | :-: | :-: |
264| [`Box`](/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `key`、flex 布局、[`gap`、`padding`、`margin`](#box-spacing-steps)、`width`、`height`、[`borderStyle`](#box-border-styles)、`backgroundColor`、`position`、`hover` | ✓ | ✓ | ✓ |264| [`Box`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `key`、flex 布局、[`gap`、`padding`、`margin`](#box-spacing-steps)、`width`、`height`、`minWidth`、`minHeight`、[`borderStyle`](#box-border-styles)、`borderColor`、`borderDimColor`、`backgroundColor`、`position`、`top`、`left`、`right`、`bottom`、`overflow`、`display`、`hover` | ✓ | ✓ | ✓ |
265| [`Text`](/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `color`、`backgroundColor`、[`bold`](#text-bold)、`italic`、`underline`、`dimColor`、`inverse`、`wrap`、[`size`、`weight`、`mono`、`tabular`](#text-typography) | ✓ | ✓ | ✓ |265| [`Text`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `color`、`backgroundColor`、[`bold`](#text-bold)、`italic`、`underline`、`strikethrough`、`dimColor`、`inverse`、`wrap`、[`size`、`weight`、`mono`、`tabular`](#text-typography)、`hover` | ✓ | ✓ | ✓ |
266| [`Button`](/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing) | `key`、`label`、`onPress`、`hotkey`、`plain`、`dimColor`、`autoFocus`、`action` | ✓ | ✓ | ✓ |266| [`Button`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#respond-to-presses-and-typing) | `key`、`label`、`onPress`、`hotkey`、`plain`、`dimColor`、`autoFocus`、`action`、`hover` | ✓ | ✓ | ✓ |
267| [`Link`](/docs/zh-CN/plugins/mods/interface#link-in-the-desktop-app) | `href`、`label`。请参阅[限制](#limits)。 | ✓ | ✓ | ✓ |267| [`Link`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#link-in-the-desktop-app) | `href`、`label`。请参阅[限制](#limits)。 | ✓ | ✓ | ✓ |
268| [`Code`](/docs/zh-CN/plugins/mods/gallery#show-code-and-changes) | `source`、`language`、`path`、`startLine`、`format`、`wrap` | ✓ | ✓ | ✓ |268| [`Code`](https://code.claude.com/docs/zh-CN/plugins/mods/gallery#show-code-and-changes) | `source`、`language`、`path`、`startLine`、`format`、`wrap` | ✓ | ✓ | ✓ |
269| `Markdown` | `text`、`key`、`dimColor`、`onLinkPress`、`pressableLinks` | ✓ | ✓ | ✓ |269| `Markdown` | `text`、`key`、`dimColor`、`onLinkPress`、`pressableLinks` | ✓ | ✓ | ✓ |
270| [`Input`](/docs/zh-CN/plugins/mods/interface#take-typed-input-and-draw-a-row-for-each-item) | `key`、`label`、`placeholder`、`value`、`submitLabel`、`onSubmit`、`onInput`、`autoFocus` | ✓ | ✓ | ✓ |270| [`Input`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#take-typed-input-and-draw-a-row-for-each-item) | `key`、`label`、`placeholder`、`value`、`submitLabel`、`onSubmit`、`onInput`、`autoFocus` | ✓ | ✓ | ✓ |
271| `Select` | `key`、`label`、`options`、`value`、`onSelect`、`autoFocus` | ✓ | ✓ | ✓ |271| `Select` | `key`、`label`、`options`、`value`、`onSelect`、`autoFocus` | ✓ | ✓ | ✓ |
272| `Svg` | 一个 SVG 文档,最多 131,072 个字符 | | ✓ | ✓ |272| `Svg` | 最多 131,072 个字符的 SVG 标记 `source`、`alt` 文本、`width`、`height` 以及 `isInteractive` | | ✓ | ✓ |
273| [`Client`](/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `module`、`key` | ✓ | ✓ | |273| [`Client`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#build-a-tree-from-elements) | `module`、`key`、`props`、`width`、`height`、`flexGrow` | ✓ | ✓ | |
274| [`Raster`](/docs/zh-CN/plugins/mods/interface#draw-a-grid-of-colored-cells) | `key`、`columns`(最多 512)、`rows`(最多 256)、`cells`。请参阅[绘制彩色单元格网格](/docs/zh-CN/plugins/mods/interface.md#draw-a-grid-of-colored-cells)。 | ✓ | | |274| [`Raster`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#draw-a-grid-of-colored-cells) | `key`、`columns`(最多 512)、`rows`(最多 256)、`cells`。请参阅[绘制彩色单元格网格](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#draw-a-grid-of-colored-cells)。 | ✓ | | |
275| `Image` | 最多 2 MiB 的 PNG 或 RGBA 字节,或文件路径,`columns` 和 `rows`(最多 255),以及 `alt` 文本。请参阅[哪些终端会绘制它](/docs/zh-CN/plugins/mods/gallery.md#image-and-client)。 | ✓ | | |275| `Image` | `key`、`source`(例如最多 2 MiB 的 PNG 或 RGBA 字节,或文件路径)、`columns` 和 `rows`(最多 255),以及 `alt` 文本。请参阅[哪些终端会绘制它](https://code.claude.com/docs/zh-CN/plugins/mods/gallery.md#image-and-client)。 | ✓ | | |
276 276
277更多 `Button` 规则:`action` 指定 Claude Code 自身的某个[快捷键操作](/docs/zh-CN/keybindings.md),当用户为该操作设置的绑定是组合键或带修饰键的按键时,该绑定会按下此按钮。当用户在空的输入框中只输入某个数字并停顿时,横栏中设置了该数字 `hotkey` 的按钮也会触发。当同一次绘制中的两个按钮指定相同的 `hotkey` 时,由后一个按钮获得它。`autoFocus` 在任何控件上都只接受 `true`,因此要关闭它,请省略该 prop。277更多 `Button` 规则:
278
279* **`action`**:指定 Claude Code 自身的某个[快捷键操作](https://code.claude.com/docs/zh-CN/keybindings.md),当用户为该操作设置的绑定是组合键或带修饰键的按键时,该绑定会按下此按钮
280* **横栏上的数字 hotkey**:当用户在空的输入框中只输入某个数字并停顿时,横栏中设置了该数字 `hotkey` 的按钮也会触发
281* **折叠的横栏**:当横栏处于[折叠](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#when-the-user-collapses-the-band)状态时,`action` 绑定和 hotkey 都不会按下其中的按钮
282* **两个按钮使用同一 hotkey**:当同一次绘制中的两个按钮指定相同的 `hotkey` 时,由后一个按钮获得它
283
284`autoFocus` 在任何控件上都只接受 `true`,因此要关闭它,请省略该 prop。
278 285
279VS Code 扩展会忽略某些元素 prop,并像您省略了这些 prop 一样绘制该元素:286VS Code 扩展会忽略某些元素 prop,并像您省略了这些 prop 一样绘制该元素:
280 287
281* **`Box`**:`position` 和 `hover`288* **`Box`**:`position` 及其 `top`、`left`、`right` 和 `bottom`,`alignSelf`、`borderDimColor` 和 `hover`
282* **`Text`**:`size`、`mono` 和 `tabular`289* **`Text`**:`size`、`mono`、`tabular` 和 `hover`
283* **`Button`**:`hotkey`、`plain`、`autoFocus` 和 `action`,因此用户在其中通过点击来按下按钮,或在按钮获得焦点后按 Enter290* **`Button`**:`hotkey`、`plain`、`autoFocus`、`action` 和 `hover`,因此用户在其中通过点击来按下按钮,或在按钮获得焦点后按 Enter
284* **`Code`**:`language`、`path`、`startLine`、`format` 和 `wrap`,因此代码绘制时不带颜色或行号,而 `format: 'diff'` 代码块会显示 diff 的原始文本291* **`Code`**:`language`、`path`、`startLine`、`format` 和 `wrap`,因此代码绘制时不带颜色或行号,而 `format: 'diff'` 代码块会显示 diff 的原始文本
285* **`Input` 和 `Select`**:`autoFocus`292* **`Input` 和 `Select`**:`autoFocus`
293* **`Svg`**:`isInteractive`
286 294
287### `Box` 边框样式295### `Box` 边框样式
288 296
317 325
318如果将 `gap`、`padding` 或 `margin` 设置为某个步长,该步长会同时应用于横向和纵向。例如,在终端和 VS Code 扩展中,`padding: 'md'` 表示左右两侧各两个单元格,上下各一行。326如果将 `gap`、`padding` 或 `margin` 设置为某个步长,该步长会同时应用于横向和纵向。例如,在终端和 VS Code 扩展中,`padding: 'md'` 表示左右两侧各两个单元格,上下各一行。
319 327
320步长名称需要 Claude Code v2.1.299 或更高版本。在更早的版本中,对于使用了步长名称的树,Claude Code 会[绘制它自己版本的该位置内容](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)来代替。328步长名称需要 Claude Code v2.1.299 或更高版本。在更早的版本中,对于使用了步长名称的树,Claude Code 会[绘制它自己版本的该位置内容](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)来代替。
321 329
322### `Text` 排版 prop330### `Text` 排版 prop
323 331
330| `mono` | `true`,请求使用应用的等宽字体 | 忽略:终端始终是等宽的 | 忽略,因此文本保持扩展自身的字体 |338| `mono` | `true`,请求使用应用的等宽字体 | 忽略:终端始终是等宽的 | 忽略,因此文本保持扩展自身的字体 |
331| `tabular` | `true`,请求使用等宽数字,使原地更新的数字或一列数字保持对齐 | 忽略:终端中的数字本来就占一个单元格宽 | 忽略 |339| `tabular` | `true`,请求使用等宽数字,使原地更新的数字或一列数字保持对齐 | 忽略:终端中的数字本来就占一个单元格宽 | 忽略 |
332 340
333这四个 prop 需要 Claude Code v2.1.299 或更高版本。在更早的版本中,对于设置了 `size`、`weight`、`mono` 或 `tabular` 的树,Claude Code 会[绘制它自己版本的该位置内容](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)来代替。341这四个 prop 需要 Claude Code v2.1.299 或更高版本。在更早的版本中,对于设置了 `size`、`weight`、`mono` 或 `tabular` 的树,Claude Code 会[绘制它自己版本的该位置内容](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)来代替。
334 342
335#### 用 `weight` 替换 `bold`343#### 用 `weight` 替换 `bold`
336 344
337`Text` 上的 `bold` 已弃用,建议改用 `weight`,但它仍然可用。要在未设置 `weight` 的 `Text` 上替换它,请将 `bold: true` 改为 `weight: 'semibold'`,在 Claude Code v2.1.299 或更高版本上效果相同。345`Text` 上的 `bold` 已弃用,建议改用 `weight`,但它仍然可用。要在未设置 `weight` 的 `Text` 上替换它,请将 `bold: true` 改为 `weight: 'semibold'`,在 Claude Code v2.1.299 或更高版本上效果相同。
338 346
339在早于 v2.1.299 的版本中,设置了 `weight` 的树不会绘制,Claude Code 会改为[绘制它自己版本的该位置内容](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)。如果您在 `Text` 上同时设置了 `bold` 和 `weight`,则 `bold` 不起作用。347在早于 v2.1.299 的版本中,设置了 `weight` 的树不会绘制,Claude Code 会改为[绘制它自己版本的该位置内容](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)。如果您在 `Text` 上同时设置了 `bold` 和 `weight`,则 `bold` 不起作用。
340 348
341## 限制349## 限制
342 350
346| :- | :- |354| :- | :- |
347| 单个事件中 hook 自身的执行时间,不计入在 `next` 内或在除 `$.clock.sleep` 之外的 mods API 调用中花费的时间 | 10 秒;对于 `prompt.edit` hook 为 50 毫秒 |355| 单个事件中 hook 自身的执行时间,不计入在 `next` 内或在除 `$.clock.sleep` 之外的 mods API 调用中花费的时间 | 10 秒;对于 `prompt.edit` hook 为 50 毫秒 |
348| `.catch` 处理程序的执行时间 | 1 秒 |356| `.catch` 处理程序的执行时间 | 1 秒 |
349| 所有 `session.end` hook 合计 | 与 [SessionEnd hook 预算](/docs/zh-CN/hooks.md#sessionend-input)相同,除非您更改,否则为 1.5 秒,从您设置中的 `SessionEnd` hook 完成时开始计算 |357| 所有 `session.end` hook 合计 | 与 [SessionEnd hook 预算](https://code.claude.com/docs/zh-CN/hooks.md#sessionend-input)相同,除非您更改,否则为 1.5 秒,从您设置中的 `SessionEnd` hook 完成时开始计算 |
350| `$.process.run` 超时时间 | 默认 30 秒,最长 10 分钟 |358| `$.process.run` 超时时间 | 默认 30 秒,最长 10 分钟 |
351| `$.model.complete` `maxTokens` | 默认 1024,最多 64,000 或模型的输出上限 |359| `$.model.complete` `maxTokens` | 默认 1024,最多 64,000 或模型的输出上限 |
352| `$.fs.read` 和 `$.fs.write` | 单个文件 4 MiB |360| `$.fs.read` 和 `$.fs.write` | 单个文件 4 MiB |
354| `$.http.fetch` 响应正文 | 4 MiB。`text` 保存前 4 MiB,其余部分不会被读取。当 `Content-Length` 标头声明的大小超出此限制时,该调用会改为被拒绝,拒绝原因以 `is over the 4194304-byte limit` 结尾,但经过所有重定向后的最后一个请求使用 `HEAD` 方法时除外。`HEAD` 例外需要 Claude Code v2.1.296 或更高版本。 |362| `$.http.fetch` 响应正文 | 4 MiB。`text` 保存前 4 MiB,其余部分不会被读取。当 `Content-Length` 标头声明的大小超出此限制时,该调用会改为被拒绝,拒绝原因以 `is over the 4194304-byte limit` 结尾,但经过所有重定向后的最后一个请求使用 `HEAD` 方法时除外。`HEAD` 例外需要 Claude Code v2.1.296 或更高版本。 |
355| 单次 `$.http.fetch` 调用(包括重定向和正文) | 30 秒 |363| 单次 `$.http.fetch` 调用(包括重定向和正文) | 30 秒 |
356| 单次 `$.http.fetch` 调用跟随的重定向次数 | 5 |364| 单次 `$.http.fetch` 调用跟随的重定向次数 | 5 |
357| hook 的 `drop` 原因或 `config.set` 的 `deny` 原因 | 4,096 个字符。更长的原因会被截去末尾部分,drop 或 deny 仍然生效。截断需要 Claude Code v2.1.292 或更高版本;在更早的版本中,该 hook 会改为[失败](/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。 |365| hook 的 `drop` 原因或 `config.set` 的 `deny` 原因 | 4,096 个字符。更长的原因会被截去末尾部分,drop 或 deny 仍然生效。截断需要 Claude Code v2.1.292 或更高版本;在更早的版本中,该 hook 会改为[失败](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#handle-a-hook-that-fails)。 |
358| 单个树中的文本 | 仅绘制前 100,000 个字符 |366| 单个树中的文本 | 仅绘制前 100,000 个字符 |
359| `Code` 的 `language` 或 `path`、`Select` 选项的 `value`,或 `Client` 的 `module` | 10,000 个字符。如果其中任何一项超出此长度,Claude Code 会[在该位置绘制其自身的版本](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)。 |367| `Code` 的 `language` 或 `path`、`Select` 选项的 `value`,或 `Client` 的 `module` | 10,000 个字符。如果其中任何一项超出此长度,Claude Code 会[在该位置绘制其自身的版本](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements)。 |
360| `Link` 的 `href` | 2,048 个字符。更长的 `href` 会导致整个树无法绘制。 |368| `Link` 的 `href` | 2,048 个字符。更长的 `href` 会导致整个树无法绘制。 |
361| `$.store` | JSON 总计 4 MiB |369| `$.store` | JSON 总计 4 MiB |
362| `$.session.messages()` | 最新的 4,096 个条目 |370| `$.session.messages()` | 最新的 4,096 个条目 |
375| :- | :- | :- |383| :- | :- | :- |
376| `CLAUDE_CODE_PLUGIN_DIRS` | 环境变量,或 `~/.claude/settings.json` 中的 `env` | 要像 `--plugin-dir` 那样加载的插件目录,用于无法传递标志的应用。以 `:` 分隔的绝对路径,在 Windows 上以 `;` 分隔。 |384| `CLAUDE_CODE_PLUGIN_DIRS` | 环境变量,或 `~/.claude/settings.json` 中的 `env` | 要像 `--plugin-dir` 那样加载的插件目录,用于无法传递标志的应用。以 `:` 分隔的绝对路径,在 Windows 上以 `;` 分隔。 |
377| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | 环境变量 | `1` 使长时间运行的非交互式会话在保存时重新加载 `--plugin-dir` mod |385| `CLAUDE_CODE_PLUGIN_DIR_WATCH` | 环境变量 | `1` 使长时间运行的非交互式会话在保存时重新加载 `--plugin-dir` mod |
378| `prependPlugins`, `appendPlugins` | 托管设置。仅在没有托管设置的机器上、且会话的凭据不是 Team 或 Enterprise `/login` 时,才可在用户设置中使用。 | 插件 id 列表,例如 `acme-guard@acme-tools`。`prependPlugins` 中的 mod 在用户安装的每个 mod 之前运行,`appendPlugins` 中的 mod 在之后运行,均按列出的顺序。请参阅 [mod 运行顺序](/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)。 |386| `prependPlugins`, `appendPlugins` | 托管设置。仅在没有托管设置的机器上、且会话的凭据不是 Team 或 Enterprise `/login` 时,才可在用户设置中使用。 | 插件 id 列表,例如 `acme-guard@acme-tools`。`prependPlugins` 中的 mod 在用户安装的每个 mod 之前运行,`appendPlugins` 中的 mod 在之后运行,均按列出的顺序。请参阅 [mod 运行顺序](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)。 |
379| `allowManagedModsOnly` | 托管设置,作为[内置守卫的选项](/docs/zh-CN/plugins/mods/admin.md#set-options-on-the-built-in-guard) | 只有[算作您组织的](/docs/zh-CN/plugins/mods/admin.md#install-your-organizations-mods) mod 以及 Claude Code 内置的 mod 会运行其 hook。用户的设置 hook 会继续运行。 |387| `allowManagedModsOnly` | 托管设置,作为[内置守卫的选项](https://code.claude.com/docs/zh-CN/plugins/mods/admin.md#set-options-on-the-built-in-guard) | 只有[算作您组织的](https://code.claude.com/docs/zh-CN/plugins/mods/admin.md#install-your-organizations-mods) mod 以及 Claude Code 内置的 mod 会运行其 hook。用户的设置 hook 会继续运行。 |
380| `allowModsToOverrideDenyRules` | 托管设置,作为[内置守卫的选项](/docs/zh-CN/plugins/mods/admin.md#set-options-on-the-built-in-guard) | 允许用户安装的 mod 批准被 `deny` 规则拒绝的工具调用 |388| `allowModsToOverrideDenyRules` | 托管设置,作为[内置守卫的选项](https://code.claude.com/docs/zh-CN/plugins/mods/admin.md#set-options-on-the-built-in-guard) | 允许用户安装的 mod 批准被 `deny` 规则拒绝的工具调用 |
381| `allowManagedHooksOnly` | 托管设置 | 阻止不属于您组织的 hook 和已安装的 mod。请参阅[哪些会继续运行](/docs/zh-CN/settings-reference.md#what-runs-under-allowmanagedhooksonly)。 |389| `allowManagedHooksOnly` | 托管设置 | 阻止不属于您组织的 hook 和已安装的 mod。请参阅[哪些会继续运行](https://code.claude.com/docs/zh-CN/settings-reference.md#what-runs-under-allowmanagedhooksonly)。 |
382| `disableAllHooks` | 任何设置文件 | 在托管设置中,来自已安装插件的任何 mod 或 hook 都不会运行。在您自己的设置中,您组织管理的内容会继续运行。请参阅 [`disableAllHooks`](/docs/zh-CN/settings-reference#disableallhooks)。 |390| `disableAllHooks` | 任何设置文件 | 在托管设置中,来自已安装插件的任何 mod 或 hook 都不会运行。在您自己的设置中,您组织管理的内容会继续运行。请参阅 [`disableAllHooks`](https://code.claude.com/docs/zh-CN/settings-reference#disableallhooks)。 |
383| `disableSideloadFlags` | 托管设置 | 在启动时拒绝 `--plugin-dir` 和 `--plugin-url` |391| `disableSideloadFlags` | 托管设置 | 在启动时拒绝 `--plugin-dir` 和 `--plugin-url` |
384| `pluginConfigs` | 用户设置或托管设置 | 保存 mod 的 `userConfig` 值,以插件 id 为键,例如 `acme-guard@acme-tools`;对于使用 `--plugin-dir` 加载的 mod,则以其名称加 `@inline` 为键,例如 `first-mod@inline` |392| `pluginConfigs` | 用户设置或托管设置 | 保存 mod 的 `userConfig` 值,以插件 id 为键,例如 `acme-guard@acme-tools`;对于使用 `--plugin-dir` 加载的 mod,则以其名称加 `@inline` 为键,例如 `first-mod@inline` |
385 393
386`sec-default@builtin` 是 Claude Code 内置的守卫,在 `/plugin` 和调试日志中显示为 `cc-plugin-sec-default`。在有托管设置的机器上,或在凭据为 Team 或 Enterprise [`/login`](/docs/zh-CN/authentication#authentication-precedence) 的会话中,它会在用户安装的每个 mod 之前加载。如果设置了托管的 `prependPlugins`,则只有当该列表指定了该守卫时它才会加载,并位于列出的位置。394`sec-default@builtin` 是 Claude Code 内置的守卫,在 `/plugin` 和调试日志中显示为 `cc-plugin-sec-default`。在有托管设置的机器上,或在凭据为 Team 或 Enterprise [`/login`](https://code.claude.com/docs/zh-CN/authentication#authentication-precedence) 的会话中,它会在用户安装的每个 mod 之前加载。如果设置了托管的 `prependPlugins`,则只有当该列表指定了该守卫时它才会加载,并位于列出的位置。
387 395
388其源代码位于 [Claude Code 仓库的 `mods/sec-default` 目录](https://github.com/anthropics/claude-code/tree/main/mods/sec-default)中。396其源代码位于 [Claude Code 仓库的 `mods/sec-default` 目录](https://github.com/anthropics/claude-code/tree/main/mods/sec-default)中。
389 397
393 401
394| 命令 | 作用 |402| 命令 | 作用 |
395| :- | :- |403| :- | :- |
396| [`/plugin`](/docs/zh-CN/plugins/mods/overview#see-which-mods-a-session-loaded) | 当有非内置的 mod 加载时,在其标签页下方显示一行,例如 `1 mod active · first-mod` |404| [`/plugin`](https://code.claude.com/docs/zh-CN/plugins/mods/overview#see-which-mods-a-session-loaded) | 当有非内置的 mod 加载时,在其标签页下方显示一行,例如 `1 mod active · first-mod` |
397| [`claude plugin validate <directory>`](/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod) | 读取插件的清单和 hook 模块,并报告错误、它处理的事件以及它发出的 mods API 调用。`--strict` 将警告视为错误,`--json` 打印机器可读的报告。 |405| [`claude plugin validate <directory>`](https://code.claude.com/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod) | 读取插件的清单和 hook 模块,并报告错误、它处理的事件以及它发出的 mods API 调用。`--strict` 将警告视为错误,`--json` 打印机器可读的报告。 |
398| [`claude plugin test [directory]`](/docs/zh-CN/plugins/mods/test#write-a-test) | 运行该目录(如果未指定目录,则为当前目录)下名称以 `.test.ts` 或 `.test.tsx` 结尾的每个文件。有测试失败时以状态 1 退出。 |406| [`claude plugin test [directory]`](https://code.claude.com/docs/zh-CN/plugins/mods/test#write-a-test) | 运行该目录(如果未指定目录,则为当前目录)下名称以 `.test.ts` 或 `.test.tsx` 结尾的每个文件。有测试失败时以状态 1 退出。 |
399| [`claude --plugin-dir <directory>`](/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) | 为一个会话加载插件目录,并在您保存时重新加载其 hook 模块。重复该标志可加载多个目录。 |407| [`claude --plugin-dir <directory>`](https://code.claude.com/docs/zh-CN/plugins/mods/create#write-a-mod-yourself) | 为一个会话加载插件目录,并在您保存时重新加载其 hook 模块。重复该标志可加载多个目录。 |
400| `/reload-plugins` | 在您运行时重新加载插件 |408| `/reload-plugins` | 在您运行时重新加载插件 |