Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion ralph-loop/hooks/capture-response.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,17 @@ if [[ -z "$RESPONSE_TEXT" ]]; then
fi

# Check for <promise>TEXT</promise> in the response
PROMISE_TEXT=$(echo "$RESPONSE_TEXT" | perl -0777 -pe 's/.*?<promise>(.*?)<\/promise>.*/$1/s; s/^\s+|\s+$//g; s/\s+/ /g' 2>/dev/null || echo "")
PROMISE_TEXT=$(
printf '%s' "$RESPONSE_TEXT" |
perl -0777 -ne '
if (/<promise>(.*?)<\/promise>/s) {
my $promise = $1;
$promise =~ s/^\s+|\s+$//g;
$promise =~ s/\s+/ /g;
print $promise;
}
' 2>/dev/null || true
)

if [[ -n "$PROMISE_TEXT" ]] && [[ "$PROMISE_TEXT" = "$COMPLETION_PROMISE" ]]; then
touch "$DONE_FLAG"
Expand Down
56 changes: 56 additions & 0 deletions ralph-loop/hooks/tests/capture-response.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash

set -euo pipefail

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
HOOK="$SCRIPT_DIR/../capture-response.sh"
TEST_PROJECT=$(mktemp -d)
STATE_DIR="$TEST_PROJECT/.cursor/ralph"
DONE_FLAG="$STATE_DIR/done"

cleanup() {
rm -rf "$TEST_PROJECT"
}
trap cleanup EXIT

mkdir -p "$STATE_DIR"
cat >"$STATE_DIR/scratchpad.md" <<'EOF'
---
iteration: 1
max_iterations: 10
completion_promise: "ALL TESTS PASS"
---
Run the requested task.
EOF

run_case() {
local name=$1
local response=$2
local expected=$3
local actual="absent"

rm -f "$DONE_FLAG"
jq -n --arg text "$response" '{text: $text}' |
CURSOR_PROJECT_DIR="$TEST_PROJECT" bash "$HOOK"

if [[ -f "$DONE_FLAG" ]]; then
actual="present"
fi

if [[ "$actual" != "$expected" ]]; then
echo "FAIL: $name (expected done flag $expected, got $actual)" >&2
return 1
fi

echo "PASS: $name"
}

run_case "untagged matching text" "ALL TESTS PASS" "absent"
run_case "tagged matching text" \
"Finished: <promise>ALL TESTS PASS</promise>" "present"
run_case "tagged text with normalized whitespace" \
$'<promise>\n ALL TESTS\n PASS \n</promise>' "present"
run_case "tagged non-matching text" \
"<promise>TESTS FAILED</promise>" "absent"
run_case "missing closing tag" "<promise>ALL TESTS PASS" "absent"
run_case "empty response" "" "absent"