Mingyu's Library主页
2026年10月5日

第 38 课:新功能速用 —— Mods(v2.1.287 / v2.1.289)

📅 2026-10-05 10-01 发布的 v2.1.287 带来了本月最大的 Claude Code 新能力:Mods——能改写 Claude Code 自身行为的插件(10-04 的 v2.1.289 是安全与渲染方面的修复版)。 场景还原:你想在 Claude Code 里看到"这轮已经调了几次工具"或"这条 rm -rf 到底会删什么",以前只能靠 settings hooks 起个 shell 脚本——它能放行/拦截,却没法在界面里画东西,也没法在不占模型回合的情况下响应一个命令。Mods 就是补这个缺口:代码直接跑在 Claude Code 进程里。 前置:第 4 课(Hooks)、第 17 课(插件与 Marketplace)、第 19 课(Skills)。 来源:Mods overview · Create a mod · v2.1.287 解读


技巧 1(基础):先确认版本,认识「内置 Mods」

解决的问题:不知道 Mods 是不是已经在你机器上跑了,也不知道哪些功能其实就是 Mod。

Mods 需要 v2.1.287+,默认开启。Claude Code 自己的一些功能(如 /diff、AGENTS.md 加载)就是内置 Mod。

claude --version            # 需 >= 2.1.287
# 会话里:
/plugin                     # Installed 页 → 「Built-in」下列出内置 mods;顶部一行 "N mod active"
/plugin enable cc-plugin-you-should-know@builtin   # 可选:开启旁路 agent,长任务里提醒你可能漏掉的点

you-should-know 默认关闭;它会在 Claude 干活时用一个旁路 agent 盯着,发现值得提醒的事就在提示框上方给你一条备注。

📖 Mods built into Claude Code

技巧 2(上手):10 分钟写出你的第一个 Mod

解决的问题:想要一个"工具调用计数器 + /tally 命令",却不知道 Mod 的文件结构。

一个 Mod 就是三个文件的插件,无需 Node、打包器或构建步骤:

mkdir -p first-mod/.claude-plugin first-mod/hooks
cat > first-mod/.claude-plugin/plugin.json <<'JSON'
{ "name": "first-mod", "version": "0.1.0", "description": "Count tool calls" }
JSON
cat > first-mod/hooks/hooks.json <<'JSON'
{ "description": "first-mod hooks module", "modules": ["./register.js"] }
JSON
cat > first-mod/hooks/register.js <<'JS'
let calls = 0
export function register(on) {
  on('session.start', async ($, e, next) => {
    await $.command.register({ name: 'tally', description: 'Show tool call count' })
    return next(e)
  })
  on('tool.call', async ($, e, next) => {
    calls += 1
    $.ui.invalidate('ui.render')
    return next(e)
  })
  on('command.run', { command: 'tally' }, async () => ({ text: 'Claude has made ' + calls + ' tool calls' }))
  on('ui.render', { component: 'Spinner' }, async ($, e, next) =>
    next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } }))
}
JS
claude --plugin-dir ./first-mod        # 仅本会话加载,改文件会热重载
claude -p "/tally" --plugin-dir ./first-mod   # 无头验证命令

每个 hook 拿到三个参数:$(mods API)、e(事件数据)、next(放行给后续处理)。对事件有三种态度:观察(return next(e))、改写(next({...e, 改动}))、接管(不调 next、直接返回结果)。

📖 Create a mod

技巧 3(进阶):装之前先"体检",出问题有三道急停

解决的问题:Mod 是以你的权限运行的代码,不是沙箱里的配置——装第三方 Mod 前得知道它能碰什么。

官方明确:Mod 能读写你的文件、读环境变量里的密钥、看到每条 prompt 和工具调用、甚至在你被询问前批准工具调用;Mod 不受沙箱约束,也不能改权限弹窗本身的显示。

# 不运行代码,静态列出它订阅了哪些事件、调用了哪些 API:
git clone <某个 mod 仓库> && claude plugin validate ./some-mod
#   ❯ ./register.js hooks: tool.call, ui.render{component=Spinner}
#   ❯ ./register.js calls: $.ui.invalidate

# 三道急停:
#  1) /plugin → Installed 里停用/卸载单个 mod
#  2) claude --safe-mode                       # 本次会话关掉所有已安装 mod 与自定义项
#  3) ~/.claude/settings.json: { "disableAllHooks": true }   # 所有会话关闭(也会停 settings hooks 和自定义 status line)

重点看 calls: 行里有没有读文件、起进程、发网络请求。内置 Mod 不受这三个开关影响。

📖 Decide whether to trust a mod

技巧 4(高阶):让 Claude 替你写 Mod,并用测试和官方样例收尾

解决的问题:不想自己啃事件清单,又希望产出可测试、可分享的 Mod。

# 会话里直接描述需求(Claude 会按内置 plugin-authoring skill 写到 ~/.claude/dev-mods/<会话ID>/):
> make a mod that shows the current git branch above the prompt
# 或手动加载技能:/plugin-authoring
# 首个文件保存时会问是否开启热重载,选「Enable for this session」
# 把满意的 mod 拷出来长期用,并写测试(无需会话/网络):
cp -r ~/.claude/dev-mods/<id>/git-branch ~/mods/git-branch
claude --plugin-dir ~/mods/git-branch
cd ~/mods/git-branch && claude plugin test      # 运行 tests/*.test.ts

官方样例在 anthropics/claude-code-playground 的 claude-code/mods:blast-radius(拦截 rm -rf/force push 并展示影响范围,带"继续/取消"按钮)、token-weather(在提示框上方画上下文窗口预报)、replay-theater(/replay 回放上一轮的文件编辑)。注意:claude -p、VS Code 面板里 hook 会跑但不会"画"界面。

📖 Test a mod · 样例仓库


顺带:升级前要知道的两个变更(v2.1.287)

来源:Classmethod · v2.1.287

今日实操(10-15 分钟)

  1. 升级到 ≥2.1.287,用技巧 2 的代码建 first-mod,claude --plugin-dir ./first-mod 启动。
  2. 让 Claude 读两个文件,观察 spinner 后出现 tool calls: N;输入 /tally 看到计数。
  3. 保持会话不关,把 ' · tool calls: ' 改成 ' · tools used: ',保存。
  4. 对它跑一次 claude plugin validate ./first-mod。

验收标准:spinner 文案在不重启会话的情况下热更新;validate 输出里 hooks: 行含 tool.call 与 ui.render{component=Spinner},calls: 行只有 $.command.register、$.ui.invalidate 两项。