diff --git a/plugins/ralph-loop/hooks/stop-hook.sh b/plugins/ralph-loop/hooks/stop-hook.sh index 955a664..bf3a1ff 100755 --- a/plugins/ralph-loop/hooks/stop-hook.sh +++ b/plugins/ralph-loop/hooks/stop-hook.sh @@ -77,39 +77,19 @@ if ! grep -q '"role":"assistant"' "$TRANSCRIPT_PATH"; then exit 0 fi -# Extract last assistant message with explicit error handling -LAST_LINE=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1) -if [[ -z "$LAST_LINE" ]]; then - echo "⚠️ Ralph loop: Failed to extract last assistant message" >&2 - echo " Ralph loop is stopping." >&2 - rm "$RALPH_STATE_FILE" - exit 0 -fi - -# Parse JSON with error handling -LAST_OUTPUT=$(echo "$LAST_LINE" | jq -r ' - .message.content | - map(select(.type == "text")) | - map(.text) | - join("\n") -' 2>&1) - -# Check if jq succeeded -if [[ $? -ne 0 ]]; then - echo "⚠️ Ralph loop: Failed to parse assistant message JSON" >&2 - echo " Error: $LAST_OUTPUT" >&2 - echo " This may indicate a transcript format issue" >&2 - echo " Ralph loop is stopping." >&2 - rm "$RALPH_STATE_FILE" - exit 0 -fi - -if [[ -z "$LAST_OUTPUT" ]]; then - echo "⚠️ Ralph loop: Assistant message contained no text content" >&2 - echo " Ralph loop is stopping." >&2 - rm "$RALPH_STATE_FILE" - exit 0 -fi +# Extract the most recent assistant text block. +# +# Claude Code writes each content block (text/tool_use/thinking) as its own +# JSONL line, all with role=assistant. `tail -1` alone would often grab a +# tool_use or thinking block, leaving no text to check. Instead, slurp all +# assistant lines, flatten to text blocks only, and take the last one. +# +# `last // ""` yields empty string when no text blocks exist (e.g. a turn +# that is all tool calls). That's fine: empty text means no tag, +# so the loop simply continues. +LAST_OUTPUT=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | jq -rs ' + map(.message.content[]? | select(.type == "text") | .text) | last // "" +' 2>/dev/null) || LAST_OUTPUT="" # Check for completion promise (only if set) if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then