File of the day

A Claude Code hook that tells you by sound whose move is next

Slava Sazhin 29 September 2026 3 min read

A Claude Code Stop hook ends a reply with a short tone: a ringing one when the work is done, a lower one when your decision or action is needed.

Today's file is a Claude Code hook for people who give Claude a task and go to another window. Then you either come back every few minutes to see whether it has finished, or Claude waits half an hour for a yes it asked for in its last line. The hook ends the reply with a short tone, and the tone tells you which of the two it is: the work is done, or Claude needs you.

How it works

Before its last message Claude writes one word into the signal file of its session, /tmp/claude_signal_<session id>. done means the work is closed and nothing is needed from you: a ringing tone. need means your move: a decision, access, something to do by hand or a look at the result: a lower tone. When the reply ends, the Stop hook reads the word, plays the tone and deletes the file. No file or an empty file means silence. An unknown word counts as need: an extra call costs less than a missed one.

A tone and not a voice, because the neighbours hear a voice too and a tone carries exactly one meaning. The hook never blocks Claude: the sound is its only action.

What to change

Quiet hours: from 20:00 to 9:00 by the computer clock the hook stays silent, and the note below sets your own, for example 22 to 8. The two sounds are made from the macOS system sounds Glass and Purr and played with afplay. If your computer is not a Mac, the note asks Claude to replace afplay with the player of your system.

Install

One file goes into ~/.claude/hooks/ and is connected in ~/.claude/settings.json as a Stop hook. The note below then has Claude make the two sounds, check that jq is installed, add a rule to ~/.claude/CLAUDE.md to write the word as its last action, and allow two things without confirmation: writing the signal file and the command echo $CLAUDE_CODE_SESSION_ID that gives Claude its session number. Without the second permission Claude Code stops for your confirmation of that command at the end of every reply, because the command contains a $. Then restart Claude Code. The check: ask Claude to write need and you hear the low tone after its reply, then the same with done and the ringing one.

The files

sound-signal.sh 3 KB Download
#!/bin/bash
# Stop hook: a short sound at the end of a Claude reply tells whose move is next.
# A voice is heard by the neighbours and gets annoying, while a tone carries exactly one meaning.
#
# The signal does not fire on a timer. It sounds only if Claude, before its last
# message, put a word into the signal file /tmp/claude_signal_<session_id>:
#   done - the work is closed, nothing is needed from you (a ringing tone);
#   need - you are needed next: a decision, access, a manual action, a look (a lower tone).
# No file or an empty file - the hook stays silent.
# An unknown word counts as need: you will survive an extra call,
# while a missed one leaves you waiting at a silent window.
# Never blocks (exit 0): the sound is its only action.

INPUT=$(cat)
SID=$(echo "$INPUT" | jq -r '.session_id // "default"' 2>/dev/null)
[ -z "$SID" ] && SID="default"

SOUND_DIR="$HOME/.claude/sounds"

# Quiet hours: from QUIET_FROM to QUIET_TO by the computer clock there is no sound.
QUIET_FROM=20
QUIET_TO=9

# 10# - decimal parsing, otherwise 08 and 09 are read as invalid octal.
h=$((10#$(date +%H)))
# Quiet hours across midnight (from 22 to 8) and within the day (from 1 to 6) are counted differently.
if [ "$QUIET_FROM" -gt "$QUIET_TO" ]; then
    { [ "$h" -ge "$QUIET_FROM" ] || [ "$h" -lt "$QUIET_TO" ]; } && exit 0
else
    { [ "$h" -ge "$QUIET_FROM" ] && [ "$h" -lt "$QUIET_TO" ]; } && exit 0
fi

# The signal file with the word. No word - we stay silent.
SIGNAL_FILE="/tmp/claude_signal_${SID}"
[ -f "$SIGNAL_FILE" ] || exit 0

# The word: the first word of the first non-empty line, at most 32 bytes, lowercase.
# The carriage return is removed, otherwise a word from a Windows file will not match.
# An empty file is not a signal: delete it and stay silent.
MARK=$(head -c 32 "$SIGNAL_FILE" | tr -d '\000\r' | tr -s ' \t\n' '\n' | grep -m 1 . | tr '[:upper:]' '[:lower:]')
if [ -z "$MARK" ]; then
    rm -f "$SIGNAL_FILE"
    exit 0
fi

case "$MARK" in
    done) FILE="$SOUND_DIR/done.wav" ;;
    *)    FILE="$SOUND_DIR/need.wav" ;;
esac

# No sound file - the word is not deleted: the signal plays as soon as the sounds are back in place.
[ -f "$FILE" ] || exit 0
rm -f "$SIGNAL_FILE"

nohup afplay "$FILE" >/dev/null 2>&1 &
exit 0
how-to-install.md 2 KB Download
# How to install the sound signal

1. Ask Claude: "Put the downloaded file sound-signal.sh into the folder ~/.claude/hooks/ and make it executable".
2. Ask Claude: "Make two short sounds in the folder ~/.claude/sounds: done.wav from the system sound Glass and need.wav from the system sound Purr".
3. Ask Claude: "Connect ~/.claude/hooks/sound-signal.sh in ~/.claude/settings.json as a Stop hook".
4. Ask Claude: "Write a rule into ~/.claude/CLAUDE.md: when you hand over work, as the last action before the reply find the session number with the command echo $CLAUDE_CODE_SESSION_ID and write one word with the file writing tool into the file /tmp/claude_signal_<session number>: done if nothing is needed from me, or need if my decision, access or action is needed".
5. Ask Claude: "In ~/.claude/settings.json allow without confirmation writing to the files /tmp/claude_signal_* and /private/tmp/claude_signal_* and the command echo $CLAUDE_CODE_SESSION_ID, with the rules Edit(//tmp/claude_signal_*), Edit(//private/tmp/claude_signal_*) and Bash(echo $CLAUDE_CODE_SESSION_ID)".
6. Ask Claude: "Check that jq is on the computer, and if it is not, install it".
7. Ask Claude: "In the file ~/.claude/hooks/sound-signal.sh set my quiet hours: from 22 to 8".
8. If the computer is not a Mac, ask Claude: "In the file ~/.claude/hooks/sound-signal.sh replace afplay with the sound player of my system".
9. Restart Claude Code.

Check outside quiet hours:

1. Ask Claude: "Write the word need into the signal file of this session and reply with one line".
2. After the reply a low tone sounds.
3. Ask Claude the same with the word done.
4. After the reply a ringing tone sounds.

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 €2.99 a month.

Contact the Combobulating team