Alerts user when Claude stops (task complete, needs input, etc.) with context about what completed. Works on Mac (osascript alert), Linux (notify-send/zenity), and Windows (PowerShell MessageBox). Follows same optional install pattern as statusline: - Prompts in interactive mode if existing hook detected - --force-notify to replace existing - --no-notify to skip installation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
70 lines
2.3 KiB
Bash
Executable File
70 lines
2.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# GSD Completion Notification Hook
|
|
# Cross-platform alert when Claude stops (task complete, needs input, etc.)
|
|
|
|
input=$(cat)
|
|
session_id=$(echo "$input" | jq -r '.session_id // empty')
|
|
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
|
transcript_path=$(echo "$input" | jq -r '.transcript_path // empty')
|
|
|
|
# Extract project name
|
|
project="Claude Code"
|
|
if [[ -n "$cwd" ]]; then
|
|
project=$(basename "$cwd")
|
|
fi
|
|
|
|
# Try to get context from GSD state file
|
|
message=""
|
|
state_file="$cwd/.planning/STATE.md"
|
|
if [[ -f "$state_file" ]]; then
|
|
phase=$(grep -m1 "^current_phase:" "$state_file" 2>/dev/null | sed 's/^current_phase: *//')
|
|
status=$(grep -m1 "^status:" "$state_file" 2>/dev/null | sed 's/^status: *//')
|
|
if [[ -n "$phase" && -n "$status" ]]; then
|
|
message="Phase $phase: $status"
|
|
fi
|
|
fi
|
|
|
|
# Fallback: check todo list for current/completed task
|
|
if [[ -z "$message" && -n "$session_id" ]]; then
|
|
todo_file=$(ls -t "$HOME/.claude/todos/${session_id}"*.json 2>/dev/null | head -1)
|
|
if [[ -f "$todo_file" ]]; then
|
|
# Get most recently completed task, or in-progress task
|
|
completed=$(jq -r '[.[] | select(.status=="completed")] | last | .content // empty' "$todo_file" 2>/dev/null)
|
|
if [[ -n "$completed" ]]; then
|
|
message="Completed: $completed"
|
|
else
|
|
in_progress=$(jq -r '.[] | select(.status=="in_progress") | .content' "$todo_file" 2>/dev/null | head -1)
|
|
if [[ -n "$in_progress" ]]; then
|
|
message="Paused: $in_progress"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Fallback: generic message
|
|
if [[ -z "$message" ]]; then
|
|
message="Ready for input"
|
|
fi
|
|
|
|
# Send notification based on OS
|
|
case "$(uname -s)" in
|
|
Darwin)
|
|
osascript -e "display alert \"GSD: $project\" message \"$message\" as informational" &>/dev/null &
|
|
;;
|
|
Linux)
|
|
if command -v notify-send &>/dev/null; then
|
|
notify-send "GSD: $project" "$message" --urgency=normal
|
|
elif command -v zenity &>/dev/null; then
|
|
zenity --info --title="GSD: $project" --text="$message" &
|
|
fi
|
|
;;
|
|
MINGW*|CYGWIN*|MSYS*)
|
|
# Windows via PowerShell
|
|
if command -v powershell.exe &>/dev/null; then
|
|
powershell.exe -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('$message', 'GSD: $project', 'OK', 'Information')" &>/dev/null &
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
exit 0
|