Last active
May 3, 2026 18:58
-
-
Save SimonMayerhofer/2443d78d0a6ae6e2a2c0c3f8d8fb5854 to your computer and use it in GitHub Desktop.
Claude Code notification hook - only notify when terminal window is not active (macOS, supports iTerm2+tmux, VS Code/Cursor)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Notify only if the terminal window running Claude Code is not visible | |
| # Usage: notify-if-inactive.sh <event_type> | |
| # event_type: permission_prompt, idle_prompt, elicitation_dialog | |
| event_type="${1:-notification}" | |
| case "$event_type" in | |
| permission_prompt) message="Waiting for permission" ;; | |
| idle_prompt) message="Task complete" ;; | |
| elicitation_dialog) message="Has a question for you" ;; | |
| *) message="Needs your attention" ;; | |
| esac | |
| project_name=$(basename "$PWD") | |
| visible=true | |
| frontmost=$(osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true' 2>/dev/null) | |
| if [ -n "$ITERM_SESSION_ID" ]; then | |
| if ! echo "$frontmost" | grep -qi "iterm"; then | |
| visible=false | |
| fi | |
| elif [ "$TERM_PROGRAM" = "vscode" ]; then | |
| if ! echo "$frontmost" | grep -qi "cursor\|code"; then | |
| visible=false | |
| else | |
| folder_name=$(basename "$PWD") | |
| active_title=$(osascript -e "tell application \"System Events\" to get name of front window of process \"$frontmost\"" 2>/dev/null) | |
| if [ -n "$active_title" ] && [ -n "$folder_name" ] && ! echo "$active_title" | grep -qF "$folder_name"; then | |
| visible=false | |
| fi | |
| fi | |
| fi | |
| if [ -n "$ITERM_SESSION_ID" ] && [ "$visible" = true ]; then | |
| if [ -n "$TMUX" ]; then | |
| window_name=$(osascript -e 'tell application "iTerm2" to get name of current window' 2>/dev/null) | |
| if ! echo "$window_name" | grep -qF "[tmux]"; then | |
| visible=false | |
| fi | |
| else | |
| our_tty=$(tty 2>/dev/null) | |
| active_tty=$(osascript -e 'tell application "iTerm2" to get tty of current session of current tab of current window' 2>/dev/null) | |
| if [ -n "$our_tty" ] && [ "$active_tty" != "$our_tty" ]; then | |
| visible=false | |
| fi | |
| fi | |
| fi | |
| if [ -n "$TMUX" ] && [ "$visible" = true ]; then | |
| our_index=$(tmux display-message -t "$TMUX_PANE" -p '#{window_index}' 2>/dev/null) | |
| active_index=$(tmux list-windows -f '#{==:#{window_active},1}' -F '#{window_index}' 2>/dev/null) | |
| if [ -n "$our_index" ] && [ -n "$active_index" ] && [ "$our_index" != "$active_index" ]; then | |
| visible=false | |
| fi | |
| fi | |
| if [ "$visible" = false ]; then | |
| if [ "$event_type" != "idle_prompt" ]; then | |
| afplay /System/Library/Sounds/Frog.aiff & | |
| fi | |
| osascript -e "display notification \"$message\" with title \"Claude Code\" subtitle \"$project_name\"" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment