Merge pull request 'fix: fix: stop hook should nudge Claude when PHASE file is empty — prevents silent exit without PHASE:done (#585)' (#599) from fix/issue-585 into main
This commit is contained in:
commit
c1110e5e48
2 changed files with 36 additions and 2 deletions
|
|
@ -66,6 +66,11 @@ create_agent_session() {
|
|||
local hook_script="${FACTORY_ROOT}/lib/hooks/on-idle-stop.sh"
|
||||
if [ -x "$hook_script" ]; then
|
||||
local hook_cmd="${hook_script} ${idle_marker}"
|
||||
# When a phase file is available, pass it and the session name so the
|
||||
# hook can nudge Claude if it returns to the prompt without signalling.
|
||||
if [ -n "$phase_file" ]; then
|
||||
hook_cmd="${hook_script} ${idle_marker} ${phase_file} ${session}"
|
||||
fi
|
||||
if [ -f "$settings" ]; then
|
||||
# Append our Stop hook to existing project settings
|
||||
jq --arg cmd "$hook_cmd" '
|
||||
|
|
@ -443,6 +448,7 @@ agent_kill_session() {
|
|||
rm -f "/tmp/claude-idle-${session}.ts"
|
||||
rm -f "/tmp/phase-changed-${session}.marker"
|
||||
rm -f "/tmp/claude-exited-${session}.ts"
|
||||
rm -f "/tmp/claude-nudge-${session}.count"
|
||||
}
|
||||
|
||||
# Read the current phase from a phase file, stripped of whitespace.
|
||||
|
|
|
|||
|
|
@ -5,10 +5,38 @@
|
|||
# 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"}
|
||||
# {"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
|
||||
[ -n "${1:-}" ] && date +%s > "$1"
|
||||
|
||||
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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue