feat(hooks): add cross-platform completion notification hook
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>
This commit is contained in:
69
hooks/gsd-notify.sh
Executable file
69
hooks/gsd-notify.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user