Desktop notification hook for Claude Code that alerts you when Claude needs attention — even when you're in another tmux window.
- Terminal bell — fires on every notification for visual bell / tmux activity monitoring
- Desktop notification —
notify-sendpopup with the project path and event type; per-pane deduplication using--replace-idso notifications update in place instead of stacking - Sound alert — plays
bell.ogavia PulseAudio with a 3-second per-pane debounce - tmux coordinates — notification title includes
[session:window.pane](e.g.[0:2.1]) so you know exactly which pane needs you
| Event | Title |
|---|---|
| Permission request | Permission Required [0:2.1] |
| Claude finished / idle | Claude Ready [0:2.1] |
| Elicitation dialog | Input Needed [0:2.1] |
| Auth complete | Auth Complete [0:2.1] |
Tested on:
- Fedora 43 Sway Atomic (Wayland)
- tmux 3.5a with oh-my-tmux
- zsh 5.9 with oh-my-zsh
Dependencies:
jq # JSON parsing
libnotify # notify-send
pulseaudio # paplay
tmux # pane identification
Install on Fedora Atomic:
sudo rpm-ostree install jq libnotify pulseaudio-utils tmuxgit clone https://github.com/mzaran/claude-code-alert.git
cd claude-code-alert
bash install.shThen restart Claude Code.
- Copy
notify.shto~/.claude/hooks/notify.shand make it executable:
mkdir -p ~/.claude/hooks
cp notify.sh ~/.claude/hooks/notify.sh
chmod +x ~/.claude/hooks/notify.sh- Add to
~/.claude/settings.json:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/notify.sh",
"async": true
}
]
}
]
}
}Claude Code fires a Notification hook event (as JSON on stdin) whenever it needs your attention. The hook:
- Reads the JSON payload and maps
notification_typeto a human-readable title - Queries tmux for the current pane's coordinates (
session:window.pane) using$TMUX_PANE - Fires a terminal bell (
\a) - Sends a desktop notification via
notify-send— the--replace-idis derived from the tmux pane number so multiple notifications from the same pane update in place - Plays a sound via
paplaywith a 3-second cooldown per pane to avoid audio spam