File of the day

A Claude Code hook that shows the start of every reply in a notification

Slava Sazhin 15 October 2026 3 min read

When Claude Code finishes a reply, a notification with its first words pops up in the corner of the screen, so you can work in another window.

Today's file is a Claude Code hook for people who give Claude a task and go to another window. Then you either keep coming back to check whether it has finished, or you come back half an hour later and find it stopped in the first minute with a question for you. With this hook every finished reply shows up as a notification in the corner of the screen with the start of the reply, so you can tell "Done, all tests pass" from "Should I delete the old folder?" without leaving the window you are in.

How it works

It is a Stop hook: Claude Code runs it each time a reply ends and passes it the text of the reply. The hook removes the Markdown marks *, ` and #, joins the lines into one, keeps the first 120 characters and shows them in a macOS notification with the title "Claude Code" and the subtitle "Reply ready". An empty reply shows "Work finished". The reply reaches the notification as plain text, never as part of a command, so a reply that quotes code or a web page cannot run anything: we fed the hook 21 sample replies with quotes, $( ), backticks and AppleScript commands in them, and each one arrived as text. The hook never stops Claude, the notification is all it does.

What we changed

One line. A reply that starts with a dash, a bulleted list for example, was handed to the notification command as if it were one of its options. On Linux, where the note has Claude swap osascript for notify-send, such a reply showed no notification at all, only an "Unknown option" error that nobody sees. The hook now drops dashes and spaces at the start of the text, so "- Fixed the bug" shows as "Fixed the bug", and dashes inside the text stay. The same trim covers osascript on a Mac and the command of any other system.

What to know

  • The hook runs after every reply, in claude -p runs too: a job you start on a schedule also ends with a notification.
  • The notification shows the start of the reply as it is. If Claude puts a password or a customer's name in its first line, it appears in the corner of the screen and stays in Notification Center.
  • Not on a Mac: step 6 of the note has Claude swap in your system's notification command. In our tests Claude wrote notify-send on Linux (4 times of 4) and a PowerShell notification on Windows (2 of 2), each time passing the reply as text.

Install

One file goes into ~/.claude/hooks/ and is connected in ~/.claude/settings.json as a Stop hook. That folder holds Claude's own settings, so Claude asks before it writes there: answer Yes. The note below then has Claude check that jq is installed and send one test notification, and you allow notifications for Script Editor in System Settings, Notifications: on a Mac, notifications from scripts arrive under that name. Then close Claude Code and open it again, because hooks are read at startup. The check: ask "Reply in one line: notifications work" and switch to another window right away. A few seconds later a "Claude Code" notification with the start of the reply appears in the corner of the screen.

notify-done.sh 1 KB Download
#!/bin/bash
# Stop hook: when Claude Code finishes a reply, a Mac notification pops up
# with the start of that reply. The hook never stops Claude's work.
INPUT=$(cat)
# Leading dashes are dropped: a reply that starts with "-" would be read as an option of the notification command.
MSG=$(printf '%s' "$INPUT" | jq -r '(.last_assistant_message // "") | gsub("[*`#]"; "") | gsub("\\s+"; " ") | sub("^[ -]+"; "") | .[0:120]' 2>/dev/null)
[ -z "$MSG" ] && MSG="Work finished"
osascript - "$MSG" >/dev/null 2>&1 <<'EOF'
on run argv
display notification (item 1 of argv) with title "Claude Code" subtitle "Reply ready"
end run
EOF
exit 0
how-to-install.md 1 KB Download
# How to know Claude is done without sitting at the screen

1. Ask Claude: "Put the downloaded file notify-done.sh in the folder ~/.claude/hooks/ and make it executable."
2. Ask Claude: "Add ~/.claude/hooks/notify-done.sh to ~/.claude/settings.json as a Stop hook."
3. Ask Claude: "Check that jq is installed on this computer, and install it if it is not."
4. On a Mac, ask Claude: "Run the command osascript -e 'display notification "test"'."
5. Then open "System Settings", go to "Notifications", find "Script Editor" in the list and turn on "Allow Notifications".
6. If your computer is not a Mac, ask Claude: "In the file ~/.claude/hooks/notify-done.sh, replace osascript with my system's notification command."
7. Close Claude Code and open it again: hooks are read at startup.

Check:

1. Ask Claude: "Reply in one line: notifications work" and switch to another window right away.
2. A few seconds later, a "Claude Code" notification with the start of the reply pops up in the corner of the screen.

Was this article worth your time?

Give Claude a computer of its own

Your own Linux machine with Claude Code on it, working around the clock while your laptop is shut. From $3.49 a month.

Contact the Combobulating team