43 lines
1.5 KiB
Bash
Executable file
43 lines
1.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# on-phase-change.sh — PostToolUse hook for phase file write detection.
|
|
#
|
|
# Called by Claude Code after every Bash|Write tool execution.
|
|
# Detects writes (not reads) to the phase file and writes a timestamp
|
|
# marker so monitor_phase_loop can react immediately instead of waiting
|
|
# for the next mtime-based poll.
|
|
#
|
|
# Usage (in .claude/settings.json):
|
|
# {"type": "command", "command": "this-script /path/to/phase-file /path/to/marker"}
|
|
#
|
|
# Args: $1 = phase file path, $2 = marker file path
|
|
|
|
phase_file="${1:-}"
|
|
marker_file="${2:-}"
|
|
|
|
[ -z "$phase_file" ] && exit 0
|
|
[ -z "$marker_file" ] && exit 0
|
|
|
|
input=$(cat) # consume hook JSON from stdin
|
|
|
|
# Fast path: skip if phase file not referenced at all
|
|
printf '%s' "$input" | grep -qF "$phase_file" || exit 0
|
|
|
|
# Parse tool type and detect writes only (ignore reads like cat/head)
|
|
tool_name=$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
|
|
case "$tool_name" in
|
|
Write)
|
|
# Write tool: check if file_path targets the phase file
|
|
file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
[ "$file_path" = "$phase_file" ] && date +%s > "$marker_file"
|
|
;;
|
|
Bash)
|
|
# Bash tool: check if the decoded command contains a redirect (>)
|
|
# targeting the phase file — distinguishes writes from reads
|
|
command_str=$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
if printf '%s' "$command_str" | grep -qF "$phase_file" \
|
|
&& printf '%s' "$command_str" | grep -q '>'; then
|
|
date +%s > "$marker_file"
|
|
fi
|
|
;;
|
|
esac
|