claude-code-notifier
工作原理 指南 常见问题
◐简体中文
English العربية Deutsch Español Français עברית Italiano 日本語 한국어 Nederlands Polski Português (Brasil) Русский Türkçe Tiếng Việt 简体中文 繁體中文
开始使用
全部指南

Claude Code Stop hook:在 Claude 完成时执行命令

更新于 2026年10月31日 · 阅读约 6 分钟
本页内容 01Stop 何时触发,何时不触发 02最简单的 Stop hook 03hook 收到的内容 04把 Claude 的最后一条消息放进通知 05让 Claude 继续工作 06失败时也发通知 07Claude Code Notifier 的定位 08常见问题

Claude Code 的 Stop hook 会在主 Claude agent 每次回复结束时执行命令,所以很适合用来发送“已完成”通知、记录结果或运行检查。你中断 Claude 时它不会运行;如果某一轮因 API 错误结束,触发的则是 StopFailure。hook 会通过 last_assistant_message 拿到 Claude 的最后一条消息,也可以返回 decision: "block" 并附上 reason,让 Claude 继续工作而不是停下。

01Stop 何时触发,何时不触发

Stop 在每一轮结束时都会触发,而不只是在整个任务完成时。Claude Code 并没有“任务”的概念,它只知道 Claude 停止了回复、正在等你输入。一个简短的问题会触发一次 Stop,两小时的重构也一样只触发一次。

以下情况不会触发:

  • 按下 Esc 或以其他方式中断本轮时;
  • 本轮因 API 错误结束时,例如触发速率限制、服务过载或认证失败。这类情况下 Claude Code 会触发 StopFailure,并带有可用于匹配的 error 字段(rate_limit、overloaded、server_error 等);
  • subagent 完成时。那对应的是 SubagentStop。

Stop 不支持 matcher,添加的 matcher 都会被忽略,hook 每一轮都会运行。

02最简单的 Stop hook

把下面的配置加到 ~/.claude/settings.json,就能在 Claude 每次完成时执行命令。这个例子会在 macOS 上播放提示音:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Mac、Windows 和 Linux 上的桌面通知命令,请参阅如何在 Claude Code 完成时收到通知。本文接下来讲的是如何利用 hook 的输入和输出。

03hook 收到的内容

除了通用字段(session_id、transcript_path、cwd、permission_mode、hook_event_name),Stop hook 还会收到:

字段内容
last_assistant_messageClaude 本轮最后一条回复的文本
stop_hook_active如果 Claude 已经因为 Stop hook 的拦截而在继续工作,则为 true
background_tasks仍在运行的任务,例如后台 shell 或 subagent
session_crons本会话中已计划的唤醒,例如来自 /loop

请使用 last_assistant_message,不要去读 transcript 文件。transcript 是异步写入的,hook 运行时可能还没写入最后一条消息。

通过 background_tasks 和 session_crons 可以判断会话是真的结束了,还是只是暂停、等后台任务再次唤醒。通知脚本可以先确认两者都为空,再提示“已完成”。

04把 Claude 的最后一条消息放进通知

这个脚本(适用于 macOS 和 Linux,需要 jq)会显示 Claude 回复的开头部分,如果后台任务还在运行则不发通知:

#!/bin/bash
# ~/.claude/hooks/notify-done.sh
input=$(cat)

# Skip if background tasks are still in flight
busy=$(jq '(.background_tasks // []) | length' <<<"$input")
[ "$busy" -gt 0 ] && exit 0

msg=$(jq -r '(.last_assistant_message // "Claude has finished")
             | gsub("\\s+"; " ") | .[0:140]' <<<"$input")

if command -v osascript >/dev/null 2>&1; then
  osascript -e 'on run argv' \
            -e 'display notification (item 1 of argv) with title "Claude has finished"' \
            -e 'end run' "$msg"
elif command -v notify-send >/dev/null 2>&1; then
  notify-send "Claude has finished" "$msg"
fi
exit 0

保存脚本,运行 chmod +x ~/.claude/hooks/notify-done.sh,然后让 hook 指向它:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-done.sh" }]
      }
    ]
  }
}

这个脚本总是以 0 退出。这点很重要:在 Stop 中,退出码 2 表示“不要停止”,如果通知脚本意外以 2 退出,Claude 就会一直工作下去。

05让 Claude 继续工作

Stop 是可以拦截的事件之一。拦截停止意味着 Claude 会继续本轮工作,并把你给出的原因作为下一条指令。有两种做法:

  • 以 2 退出,Claude 会把你的 stderr 当作原因;或者
  • 以 0 退出并输出 JSON:
{
  "decision": "block",
  "reason": "The test suite is failing. Run npm test, fix the failures, then finish."
}

如果 hook 是在给出指导而不是报告错误,也可以用 hookSpecificOutput.additionalContext 让对话继续,这样 transcript 会将其标记为 Stop hook 反馈,而不是 hook 错误:

{
  "hookSpecificOutput": {
    "hookEventName": "Stop",
    "additionalContext": "Please run the test suite before finishing"
  }
}

避免无限循环

一个总是拦截的 Stop hook 会让 Claude 永远停不下来。有两重保护:

  1. 一旦 Claude 已经因为 Stop hook 而在继续工作,stop_hook_active 就会是 true。检查它并提前退出。
  2. 如果 Stop hook 连续拦截八次且中间没有任何工具调用,Claude Code 会强制结束本轮。可以通过环境变量 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 提高这个上限。

下面这个 hook 会让 Claude 修复一次失败的测试,然后允许它停止:

#!/bin/bash
# ~/.claude/hooks/tests-must-pass.sh
input=$(cat)
[ "$(jq -r '.stop_hook_active' <<<"$input")" = "true" ] && exit 0

if ! npm test --silent >/dev/null 2>&1; then
  jq -nc '{decision: "block", reason: "npm test is failing. Fix the failures, then finish."}'
fi
exit 0

Hook 在会话的工作目录中运行,所以 npm test 会在你的项目里执行。检查要尽量快:默认情况下,command hook 最长可运行 600 秒,期间 Claude 会一直等待。

如果只是想让 Claude 朝某个目标持续工作、又不想写脚本,可以用 Claude Code 内置的 /goal 命令,它会自动为你设置一个仅限当前会话的 Stop hook。

06失败时也发通知

由于 API 错误不会触发 Stop,“已完成”提醒不会告诉你 Claude 因为速率限制而中止了。如果想收到这类通知,把同一个脚本也加到 StopFailure 下即可。它的输出和退出码都会被忽略,所以只能用来通知或记录日志。对于 StopFailure,last_assistant_message 中是错误信息,例如 "API Error: Rate limit reached"。

07Claude Code Notifier 的定位

用一个调用 push 服务的 Stop hook,就能在你离开时得知 Claude 已经完成,这个办法完全可行。如果想自己动手,可以从 ntfy 指南开始。

Claude Code Notifier 用的也是 Stop hook,区别只有一点:它能回传内容。它的免费命令行工具 ccn 支持 Mac、Windows 和 Linux,单独使用就能显示桌面通知。配对 iPhone 或 Android 应用后,每轮结束时你会立刻收到“Claude 已完成”的 push,还可以直接在手机上输入下一条指令。ccn 会通过 Stop hook 把它作为 Claude 的下一条指令返回,这样你不在键盘前会话也能继续。如果你在最近 30 秒内打过字,就不会等待手机输入。本工具为独立开发,并非 Anthropic 出品。相关工作流见离开长时间任务,安装请看 ccn 页面。

08常见问题

Stop hook 是在 Claude 完成整个任务时运行,还是每次回复后都运行?

每次回复后都会运行。无论请求大小,只要主 agent 结束响应,Stop 就会触发。如果需要知道是否还有后续工作在排队,可以检查输入中的 background_tasks 和 session_crons。

为什么我的 Stop hook 没有触发?

可能是你中断了这一轮,这样会跳过 Stop;也可能是这一轮因 API 错误结束,此时触发的是 StopFailure。否则,请确认 /hooks 中列出了你的 hook,并且脚本有可执行权限。其他情况见排查清单。

为什么我的 Stop hook 运行后 Claude 还在继续工作?

你的 hook 阻止了停止:要么以退出码 2 退出,要么输出了 decision: "block"。确保只做通知的 hook 始终以 0 退出,而所有会阻止停止的 hook 都先检查 stop_hook_active。

如何在 hook 中拿到 Claude 的最终回答?

从 stdin 的 JSON 中读取 last_assistant_message,例如用 jq -r '.last_assistant_message'。不要依赖 transcript_path:Stop 触发时,该文件里可能还没有最后一条消息。

Stop 和 SubagentStop 有什么区别?

Stop 针对主 agent。SubagentStop 在 subagent 完成时触发,按 agent 类型匹配,同样支持阻止相关的字段。“Claude 已完成”这类提醒应该放在 Stop 上。

Claude Code Notifier Claude Code 完成任务或需要你介入时,手机会收到 push,你可以直接在手机上批准、拒绝或回复。ccn 命令行工具在 Mac、Windows 和 Linux 上均可免费使用。
下载 iOS 版 下载 Android 版 安装 ccn

相关指南

  • 如何在 Claude Code 完成时收到通知用 Stop hook 提示“已完成”,用 Notification hook 提示“需要输入”。附 Mac、Windows 和 Linux 上可直接复制的配置,以及手机提醒方案。
  • Claude Code hook 详解:每个事件及其用途介绍 Claude Code hook 是什么、在 settings.json 中放在哪里、matcher、输入和退出码如何工作,以及每个 hook 事件的用途。
  • Claude Code Notification hook:何时触发、如何使用Claude Code 的 Notification hook 何时触发,permission_prompt 和 idle_prompt 的含义,它接收的输入,以及为什么会延迟触发。
  • 让 Claude Code 跑着,人走开:一套工作流处理 Claude Code 长任务的实用流程:让电脑保持唤醒,减少不必要的 prompt,在手机上收到通知并直接回复。
claude-code-notifier

Claude Code Notifier 是一款独立的第三方应用,与 Anthropic, PBC 无关联,亦未获其认可或赞助。“Claude”和“Claude Code”是 Anthropic, PBC 的商标。

应用 iOS 应用 Android 应用 适用于 macOS、Windows 和 Linux 的 ccn 全部指南
法律信息 隐私政策 服务条款 其他语言 © 2026 touchtap。保留所有权利。 TouchTap Ltd 注册于英格兰和威尔士,公司编号 13942589。