afk.sh
1 #!/bin/bash 2 set -eo pipefail 3 4 if [ -z "$1" ] || [ -z "$2" ]; then 5 echo "Usage: $0 <plan-and-prd> <iterations>" 6 exit 1 7 fi 8 9 # jq filter to extract streaming text from assistant messages 10 stream_text='select(.type == "assistant").message.content[]? | select(.type == "text").text // empty | gsub("\n"; "\r\n") | . + "\r\n\n"' 11 12 # jq filter to extract final result 13 final_result='select(.type == "result").result // empty' 14 15 for ((i=1; i<=$2; i++)); do 16 tmpfile=$(mktemp) 17 trap "rm -f $tmpfile" EXIT 18 19 commits=$(git log -n 5 --format="%H%n%ad%n%B---" --date=short 2>/dev/null || echo "No commits found") 20 prompt=$(cat ralph/prompt.md) 21 22 docker sandbox run claude . -- \ 23 --verbose \ 24 --print \ 25 --output-format stream-json \ 26 "Previous commits: $commits Plan and PRD: $1 $prompt" \ 27 | grep --line-buffered '^{' \ 28 | tee "$tmpfile" \ 29 | jq --unbuffered -rj "$stream_text" 30 31 result=$(jq -r "$final_result" "$tmpfile") 32 33 if [[ "$result" == *"<promise>NO MORE TASKS</promise>"* ]]; then 34 echo "Ralph complete after $i iterations." 35 exit 0 36 fi 37 done