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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-loop",
3
- "version": "3.18.1",
3
+ "version": "3.19.0",
4
4
  "description": "Autonomous AI coding loop - PRD-driven development with Claude Code",
5
5
  "author": "Allie Jones <allie@allthrive.ai>",
6
6
  "license": "MIT",
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 '```'