When Claude finishes a response but hasn't written to the PHASE file, the stop hook now injects a nudge into the tmux session instead of just marking idle. This gives Claude another chance to complete the phase protocol before the monitor loop times out. Key changes: - on-idle-stop.sh: check phase file emptiness, nudge via tmux (max 2) - agent-session.sh: pass phase_file + session to stop hook, clean up nudge counter on session teardown Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
42 lines
1.7 KiB
Bash
Executable file
42 lines
1.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# on-idle-stop.sh — Stop hook for dark-factory agent sessions.
|
|
#
|
|
# Called by Claude Code when it finishes a response. Writes a timestamp
|
|
# to a marker file so monitor_phase_loop can detect idle sessions
|
|
# without fragile tmux pane scraping.
|
|
#
|
|
# When a phase file is provided and exists but is empty, Claude likely
|
|
# returned to the prompt without following the phase protocol. Instead
|
|
# of marking idle, inject a nudge into the tmux session (up to 2 times).
|
|
#
|
|
# Usage (in .claude/settings.json):
|
|
# {"type": "command", "command": "this-script /tmp/claude-idle-SESSION.ts [PHASE_FILE SESSION_NAME]"}
|
|
#
|
|
# Args: $1 = marker file path
|
|
# $2 = phase file path (optional)
|
|
# $3 = tmux session name (optional)
|
|
|
|
cat > /dev/null # consume hook JSON from stdin
|
|
|
|
MARKER="${1:-}"
|
|
[ -z "$MARKER" ] && exit 0
|
|
|
|
PHASE_FILE="${2:-}"
|
|
SESSION_NAME="${3:-}"
|
|
|
|
# If phase file is provided, exists, and is empty — Claude forgot to signal.
|
|
# Nudge via tmux instead of marking idle (up to 2 attempts).
|
|
if [ -n "$PHASE_FILE" ] && [ -n "$SESSION_NAME" ] && [ -f "$PHASE_FILE" ] && [ ! -s "$PHASE_FILE" ]; then
|
|
NUDGE_FILE="/tmp/claude-nudge-${SESSION_NAME}.count"
|
|
NUDGE_COUNT=$(cat "$NUDGE_FILE" 2>/dev/null || echo 0)
|
|
if [ "$NUDGE_COUNT" -lt 2 ]; then
|
|
echo $(( NUDGE_COUNT + 1 )) > "$NUDGE_FILE"
|
|
tmux send-keys -t "$SESSION_NAME" \
|
|
"You returned to the prompt without writing to the PHASE file. Checklist: (1) Did you complete the commit-and-pr step? (2) Did you write PHASE:done or PHASE:awaiting_ci to ${PHASE_FILE}? If no file changes were needed, write PHASE:done now." Enter
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Normal idle mark — either no phase file, phase already has content,
|
|
# or nudge limit reached.
|
|
date +%s > "$MARKER"
|