agentic-loop 3.18.1 → 3.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/ralph.sh +6 -0
- package/package.json +1 -1
- package/ralph/init.sh +2 -0
- package/ralph/loop.sh +84 -0
package/bin/ralph.sh
CHANGED
|
@@ -142,6 +142,12 @@ main() {
|
|
|
142
142
|
echo "Stop signal sent. Ralph will stop after current story completes."
|
|
143
143
|
echo "(Use Ctrl+C to force stop immediately)"
|
|
144
144
|
;;
|
|
145
|
+
skip)
|
|
146
|
+
# Signal the loop to skip the current story and move to the next one
|
|
147
|
+
mkdir -p "$RALPH_DIR"
|
|
148
|
+
touch "$RALPH_DIR/.skip"
|
|
149
|
+
echo "Skip signal sent. Ralph will skip the current story when Claude finishes."
|
|
150
|
+
;;
|
|
145
151
|
status)
|
|
146
152
|
ralph_status "$@"
|
|
147
153
|
;;
|
package/package.json
CHANGED
package/ralph/init.sh
CHANGED
|
@@ -744,6 +744,8 @@ Commands:
|
|
|
744
744
|
run Run autonomous loop until all stories pass
|
|
745
745
|
run --max <n> Run with max iterations (default: 20)
|
|
746
746
|
run --fast Skip code review for faster iterations
|
|
747
|
+
stop Stop loop after current story finishes
|
|
748
|
+
skip Skip the current story, move to next
|
|
747
749
|
status Show current feature and story status
|
|
748
750
|
check Run verification checks only
|
|
749
751
|
verify <story-id> Verify a specific story
|
package/ralph/loop.sh
CHANGED
|
@@ -391,6 +391,10 @@ PATTERN: <pattern>"
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
run_loop() {
|
|
394
|
+
# Trap Ctrl+C to stop the loop cleanly.
|
|
395
|
+
# Creates .stop file so the loop exits at the next iteration check, then kills children.
|
|
396
|
+
trap 'echo ""; print_warning "Ctrl+C received — stopping loop..."; touch "$RALPH_DIR/.stop"; trap - INT; kill -INT $$' INT
|
|
397
|
+
|
|
394
398
|
local max_iterations="$DEFAULT_MAX_ITERATIONS"
|
|
395
399
|
local specific_story=""
|
|
396
400
|
local fast_mode=false
|
|
@@ -748,6 +752,33 @@ run_loop() {
|
|
|
748
752
|
|
|
749
753
|
rm -f "$claude_output_log"
|
|
750
754
|
|
|
755
|
+
# Check for skip signal (user ran `ralph skip` while Claude was running)
|
|
756
|
+
if [[ -f "$RALPH_DIR/.skip" ]]; then
|
|
757
|
+
rm -f "$RALPH_DIR/.skip"
|
|
758
|
+
print_warning "Skip signal received — skipping $story"
|
|
759
|
+
log_progress "$story" "SKIPPED" "User requested skip"
|
|
760
|
+
skipped_stories+=("$story")
|
|
761
|
+
jq --arg id "$story" '(.stories[] | select(.id==$id)) |= . + {skipped: true, skipReason: "user skipped"}' \
|
|
762
|
+
"$RALPH_DIR/prd.json" > "$RALPH_DIR/prd.json.tmp" && mv "$RALPH_DIR/prd.json.tmp" "$RALPH_DIR/prd.json"
|
|
763
|
+
last_story=""
|
|
764
|
+
consecutive_failures=0
|
|
765
|
+
consecutive_timeouts=0
|
|
766
|
+
session_started=false
|
|
767
|
+
rm -f "$prompt_file"
|
|
768
|
+
continue
|
|
769
|
+
fi
|
|
770
|
+
|
|
771
|
+
# Check for stop signal (user ran `ralph stop` or Ctrl+C while Claude was running)
|
|
772
|
+
if [[ -f "$RALPH_DIR/.stop" ]]; then
|
|
773
|
+
rm -f "$RALPH_DIR/.stop" "$prompt_file"
|
|
774
|
+
print_warning "Stop signal received. Exiting gracefully."
|
|
775
|
+
local passed failed
|
|
776
|
+
passed=$(jq '[.stories[] | select(.passes==true)] | length' "$RALPH_DIR/prd.json" 2>/dev/null || echo "0")
|
|
777
|
+
failed=$(jq '[.stories[] | select(.passes==false)] | length' "$RALPH_DIR/prd.json" 2>/dev/null || echo "0")
|
|
778
|
+
send_notification "🛑 Ralph stopped: $passed passed, $failed remaining"
|
|
779
|
+
return 0
|
|
780
|
+
fi
|
|
781
|
+
|
|
751
782
|
if [[ $claude_exit_code -ne 0 ]]; then
|
|
752
783
|
((consecutive_timeouts++))
|
|
753
784
|
print_warning "Claude session ended (timeout or error) - timeout $consecutive_timeouts/$max_timeouts"
|
|
@@ -950,6 +981,36 @@ startup_checklist() {
|
|
|
950
981
|
fi
|
|
951
982
|
}
|
|
952
983
|
|
|
984
|
+
# Helper: Check if files listed in a story's files.create/files.modify already exist on disk
|
|
985
|
+
# Returns newline-separated list of existing files (empty string if none)
|
|
986
|
+
_check_story_files_exist() {
|
|
987
|
+
local story_id="$1"
|
|
988
|
+
local prd_file="$RALPH_DIR/prd.json"
|
|
989
|
+
[[ ! -f "$prd_file" ]] && return
|
|
990
|
+
|
|
991
|
+
local file_list
|
|
992
|
+
file_list=$(jq -r --arg id "$story_id" '
|
|
993
|
+
.stories[] | select(.id == $id) |
|
|
994
|
+
((.files.create // []) + (.files.modify // [])) | .[]
|
|
995
|
+
' "$prd_file" 2>/dev/null) || return
|
|
996
|
+
|
|
997
|
+
[[ -z "$file_list" ]] && return
|
|
998
|
+
|
|
999
|
+
local existing=""
|
|
1000
|
+
while IFS= read -r f; do
|
|
1001
|
+
[[ -z "$f" ]] && continue
|
|
1002
|
+
if [[ -f "$f" ]]; then
|
|
1003
|
+
if [[ -z "$existing" ]]; then
|
|
1004
|
+
existing="$f"
|
|
1005
|
+
else
|
|
1006
|
+
existing="$existing"$'\n'"$f"
|
|
1007
|
+
fi
|
|
1008
|
+
fi
|
|
1009
|
+
done <<< "$file_list"
|
|
1010
|
+
|
|
1011
|
+
[[ -n "$existing" ]] && echo "$existing"
|
|
1012
|
+
}
|
|
1013
|
+
|
|
953
1014
|
# Helper: Build delta prompt for continuing session
|
|
954
1015
|
# Minimal context - just story ID + any failure info
|
|
955
1016
|
_build_delta_prompt() {
|
|
@@ -964,6 +1025,15 @@ _build_delta_prompt() {
|
|
|
964
1025
|
if [[ -n "$failure_context" ]]; then
|
|
965
1026
|
echo "## Retry: Fix the errors below"
|
|
966
1027
|
echo ""
|
|
1028
|
+
|
|
1029
|
+
# Check if story files already exist — if so, skip re-implementation
|
|
1030
|
+
local existing_files
|
|
1031
|
+
existing_files=$(_check_story_files_exist "$story")
|
|
1032
|
+
if [[ -n "$existing_files" ]]; then
|
|
1033
|
+
echo "**The code is ALREADY WRITTEN.** Do NOT rewrite. Fix ONLY the errors below, then verify."
|
|
1034
|
+
echo ""
|
|
1035
|
+
fi
|
|
1036
|
+
|
|
967
1037
|
echo "Read \`.ralph/last_failure.txt\` for full error details."
|
|
968
1038
|
echo ""
|
|
969
1039
|
echo '```'
|
|
@@ -1039,6 +1109,20 @@ build_prompt() {
|
|
|
1039
1109
|
echo ""
|
|
1040
1110
|
echo "## Previous Iteration Failed"
|
|
1041
1111
|
echo ""
|
|
1112
|
+
|
|
1113
|
+
# Check if story files already exist — if so, skip re-implementation
|
|
1114
|
+
local existing_files
|
|
1115
|
+
existing_files=$(_check_story_files_exist "$story")
|
|
1116
|
+
if [[ -n "$existing_files" ]]; then
|
|
1117
|
+
echo "**IMPORTANT: The code for this story is ALREADY WRITTEN.** These files exist:"
|
|
1118
|
+
echo '```'
|
|
1119
|
+
echo "$existing_files"
|
|
1120
|
+
echo '```'
|
|
1121
|
+
echo "Do NOT rewrite or re-implement. Read the existing code, then fix ONLY the"
|
|
1122
|
+
echo "specific errors below. Go straight to verification after fixing."
|
|
1123
|
+
echo ""
|
|
1124
|
+
fi
|
|
1125
|
+
|
|
1042
1126
|
echo "Read \`.ralph/last_failure.txt\` for details. Key error:"
|
|
1043
1127
|
echo ""
|
|
1044
1128
|
echo '```'
|