在 tmux 里,Claude Code 的桌面通知无法到达外层 terminal,除非你在 ~/.tmux.conf 中加上 set -g allow-passthrough on。这能解决 attach 状态下的问题。一旦 detach,就没有 terminal 在显示这个会话,屏幕上自然也没有东西能提醒你,但 Claude Code 仍在运行,hook 也照常触发。想从 detached 会话收到消息,就要用通过网络发送 push(推到手机或聊天应用)的 hook,而不是依赖 terminal 的 hook。
01Attach 状态:让通知穿过 tmux
tmux 位于 Claude Code 和你的 terminal 之间,默认会吞掉 Claude Code 用于桌面通知的转义序列。Anthropic 的 terminal 指南给出了下面这段 ~/.tmux.conf 配置:
set -g allow-passthrough on
set -g focus-events on
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'
在正在运行的 server 上应用:
tmux source-file ~/.tmux.conf
allow-passthrough 让通知和进度更新能够到达外层 terminal。其余几行用于修复 Shift+Enter 换行。配置好之后,凡是在 tmux 外能显示 Claude Code 通知的 terminal(Ghostty、Kitty,以及开启了提醒的 iTerm2),在 tmux 里也能显示。
返回 terminalSequence 的 hook 也是一样。Anthropic 的 hooks 参考文档说明,这些序列由 Claude Code 自己写出,在 tmux 和 GNU screen 中都能工作。macOS、Linux 和 SSH 指南中有示例。
02已 attach 但在另一个窗口:用 bell
如果 Claude Code 在一个 tmux 窗口里运行,而你在另一个窗口工作,bell 就是个简单的信号。让 Claude Code 始终发送 bell:
{
"preferredNotifChannel": "terminal_bell"
}
然后在 ~/.tmux.conf 中让 tmux 响应它:
setw -g monitor-bell on
set -g bell-action other
set -g visual-bell off
monitor-bell(默认开启)会标记响过 bell 的窗口,tmux 会在状态栏用 ! 标出。bell-action other 会把当前窗口之外的其他窗口的 bell 转发给你的 terminal,让 terminal 发出提示音或弹跳图标。改用 any 则连当前窗口也包括在内。把 visual-bell 设为 on 会在 tmux 中显示一条消息,而不是转发 bell。
03标明是哪个会话需要你
同时跑着好几个会话时,一条只写着“Claude 需要你”的通知没多大用。hook 运行在 pane 的环境中,因此可以向 tmux 查询会话名和窗口名。下面这个 Linux 示例会把它们显示在桌面通知里:
#!/bin/bash
msg=$(jq -r '.message // "Claude Code needs your attention"')
where=""
if [ -n "$TMUX_PANE" ]; then
where=$(tmux display-message -p -t "$TMUX_PANE" '#S:#W')
fi
notify-send "Claude Code ${where}" "$msg"
保存为 ~/.claude/hooks/notify-tmux.sh,对它执行 chmod +x,然后作为 Notification 或 Stop hook 的命令。#S 是会话名,#W 是窗口名;用 tmux new -s api-refactor 给会话命名,通知就能告诉你该去哪里。把 notify-send 换成你所在平台的命令,或者换成 push。多会话指南介绍了更多区分会话的方法。
04Detached 状态:你需要 push
detach 正是 tmux 的意义所在:启动一个长任务,detach,然后走人。Claude Code 会在 detached 会话中继续工作。但此时没有 terminal 来显示转义序列或 bell;如果 tmux server 是通过 SSH 启动的,桌面通知命令可能也无处可发。
发起网络请求的 hook 不在乎有没有人 attach。任何 push 服务都行。ntfy 指南和 Telegram、Slack 和 Discord 指南里都有可以直接粘贴的 hook。这些只能告诉你发生了什么,无法回复 Claude,所以权限 prompt 仍要等你用 tmux attach -t api-refactor 重新 attach 后才能处理。
05Claude Code Notifier 的定位
Claude Code Notifier 是基于 Claude Code hook 构建的独立工具(由 TouchTap 开发,并非 Anthropic 出品)。它的免费命令行工具 ccn 支持 Mac、Windows 和 Linux。由于它挂接的是 Claude Code 而不是 terminal,所以无论在 tmux、screen 还是普通 shell 中,attach 还是 detach,表现都一样:
curl -fsSL https://claudecodenotifier.com/install.sh | sh
在桌面机器上,Claude 完成任务、需要权限或提出问题时,它会显示桌面通知。配对手机后,同样的事件会通过 TouchTap 的加密中继以 push 通知送达,适用于任何运行 ccn 的机器,包括你通过 SSH 登录的服务器。
手机补上了 detached 会话留下的空缺。出现权限请求时,你可以在手机上选择允许一次、本次会话内允许或拒绝,Claude 无需你重新 attach 就能继续。Claude 提问时你可以选一个答案,Claude 完成后可以立刻发送下一条指令。如果你在最近 30 秒内有过输入,就不会等待手机,terminal 照常询问。如果你不在,terminal 会等待手机的回复,最长等待时间由你设定(hold_ceiling_seconds),一碰键盘就立即停止等待。
参见配对手机、离开长时间运行的任务和 ccn 页面。手机 App 需要订阅或买断;详见定价。
06GNU screen
在这方面 screen 和 tmux 差不多。Anthropic 的 hooks 参考文档说明,hook 的 terminalSequence 输出在 screen 中可以正常工作;当你没在看的窗口响起 bell 时,screen 也会显示一条消息。detached 的 screen 会话和 detached 的 tmux 有同样的问题:屏幕上什么都没有,所以要用 push。
07常见问题
为什么 Claude Code 的通知在 tmux 里不显示?
除非开启 passthrough,否则 tmux 会拦截 Claude Code 使用的转义序列。在 ~/.tmux.conf 中加入 set -g allow-passthrough on,然后运行 tmux source-file ~/.tmux.conf。
从 tmux detach 之后,Claude Code 还会继续运行吗?
会。进程仍在 tmux server 中运行,hook 也照常触发。只是那些依赖已 attach 终端的通知收不到了。
在 detach 状态的 tmux 会话里怎么收到通知?
用一个通过网络发送 push 的 hook,比如 ntfy、聊天工具的 webhook,或者 Claude Code Notifier 的手机 app。终端转义序列和响铃都需要有已 attach 的客户端。
不重新 attach 能批准权限请求吗?
普通的 push 服务做不到。用 Claude Code Notifier 并配对手机后,可以直接在手机上允许或拒绝请求,detach 的会话会继续运行。
怎么知道是哪个 tmux 会话在等我?
给会话起名,并把名字写进通知里。hook 可以用 tmux display-message -p -t "$TMUX_PANE" '#S:#W' 读取。