/ ralph / afk.sh
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