agentic-loop 3.2.10 → 3.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/ralph/loop.sh +80 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-loop",
3
- "version": "3.2.10",
3
+ "version": "3.3.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/loop.sh CHANGED
@@ -182,6 +182,7 @@ run_loop() {
182
182
  local total_attempts=0
183
183
  local skipped_stories=()
184
184
  local start_time
185
+ local session_started=false # Track if we've started a Claude session
185
186
  start_time=$(date +%s)
186
187
 
187
188
  while [[ $iteration -lt $max_iterations ]]; do
@@ -236,6 +237,8 @@ run_loop() {
236
237
  echo " Saved failure context to: $RALPH_DIR/failures/$story.txt"
237
238
  mkdir -p "$RALPH_DIR/failures"
238
239
  cp "$RALPH_DIR/last_failure.txt" "$RALPH_DIR/failures/$story.txt" 2>/dev/null || true
240
+ # Clear failure context so it doesn't leak into next story
241
+ rm -f "$RALPH_DIR/last_failure.txt"
239
242
  skipped_stories+=("$story")
240
243
  # Mark as skipped (not passed, but move on)
241
244
  jq --arg id "$story" '(.stories[] | select(.id==$id)) |= . + {skipped: true}' "$RALPH_DIR/prd.json" > "$RALPH_DIR/prd.json.tmp" && mv "$RALPH_DIR/prd.json.tmp" "$RALPH_DIR/prd.json"
@@ -262,14 +265,21 @@ run_loop() {
262
265
  return 1
263
266
  }
264
267
 
268
+ # Only load failure context if it's for the CURRENT story (prevents stale context leaks)
265
269
  local failure_context=""
266
270
  if [[ -f "$RALPH_DIR/last_failure.txt" ]]; then
267
- failure_context=$(cat "$RALPH_DIR/last_failure.txt")
271
+ # Check if failure context is for this story (first line contains story ID)
272
+ if grep -q "for $story" "$RALPH_DIR/last_failure.txt" 2>/dev/null; then
273
+ failure_context=$(cat "$RALPH_DIR/last_failure.txt")
274
+ else
275
+ # Stale context from different story - clear it
276
+ rm -f "$RALPH_DIR/last_failure.txt"
277
+ fi
268
278
  fi
269
279
 
270
280
  # Temporarily disable errexit to capture build_prompt errors
271
281
  set +e
272
- build_prompt "$story" "$failure_context" > "$prompt_file" 2>&1
282
+ build_prompt "$story" "$failure_context" "$session_started" > "$prompt_file" 2>&1
273
283
  local build_status=$?
274
284
  set -e
275
285
 
@@ -314,18 +324,27 @@ run_loop() {
314
324
  local timeout_seconds
315
325
  timeout_seconds=$(get_config '.maxSessionSeconds' "$DEFAULT_TIMEOUT_SECONDS")
316
326
 
317
- # Run Claude with output visible on terminal
318
- if ! cat "$prompt_file" | run_with_timeout "$timeout_seconds" claude -p --dangerously-skip-permissions --verbose; then
327
+ # Run Claude - first story gets fresh session, subsequent continue the session
328
+ local claude_cmd="claude -p --dangerously-skip-permissions --verbose"
329
+ if [[ "$session_started" == "true" ]]; then
330
+ claude_cmd="claude --continue -p --dangerously-skip-permissions --verbose"
331
+ fi
332
+
333
+ if ! cat "$prompt_file" | run_with_timeout "$timeout_seconds" $claude_cmd; then
319
334
  print_warning "Claude session ended (timeout or error)"
320
335
  log_progress "$story" "TIMEOUT" "Claude session ended after ${timeout_seconds}s"
321
336
  rm -f "$prompt_file"
322
337
 
338
+ # Session may be broken - reset for next attempt
339
+ session_started=false
340
+
323
341
  # If running specific story, exit on failure
324
342
  [[ -n "$specific_story" ]] && return 1
325
343
  continue
326
344
  fi
327
345
 
328
346
  rm -f "$prompt_file"
347
+ session_started=true # Mark session as active for subsequent stories
329
348
 
330
349
  # 5. Run migrations BEFORE verification (tests need DB schema)
331
350
  if ! run_migrations_if_needed "$pre_story_sha"; then
@@ -602,6 +621,52 @@ _inject_architecture() {
602
621
  echo "- Scripts go in scripts/, docs go in docs/"
603
622
  }
604
623
 
624
+ # Helper: Build delta prompt for continuing session
625
+ # Minimal context - just new story + any failure info
626
+ _build_delta_prompt() {
627
+ local story="$1"
628
+ local story_json="$2"
629
+ local failure_context="${3:-}"
630
+
631
+ echo ""
632
+ echo "---"
633
+ echo ""
634
+
635
+ # If this is a retry (failure context exists), note it
636
+ if [[ -n "$failure_context" ]]; then
637
+ echo "## Retry: Fix the errors below"
638
+ echo ""
639
+ echo '```'
640
+ echo "$failure_context"
641
+ echo '```'
642
+ echo ""
643
+ else
644
+ # New story - note previous completion
645
+ local completed_count
646
+ completed_count=$(jq '[.stories[] | select(.passes==true)] | length' "$RALPH_DIR/prd.json" 2>/dev/null || echo "0")
647
+ if [[ "$completed_count" -gt 0 ]]; then
648
+ echo "## Previous stories complete. Moving to next story."
649
+ echo ""
650
+ # Suggest compact if we've done several stories
651
+ if [[ "$completed_count" -ge 3 ]]; then
652
+ echo "*Consider running /compact if context feels heavy.*"
653
+ echo ""
654
+ fi
655
+ fi
656
+ fi
657
+
658
+ echo "## Current Story"
659
+ echo ""
660
+ echo '```json'
661
+ echo "$story_json"
662
+ echo '```'
663
+
664
+ # Include file guidance for the new story
665
+ _inject_file_guidance "$story_json"
666
+ _inject_story_scale "$story_json"
667
+ _inject_styleguide "$story_json"
668
+ }
669
+
605
670
  # Helper: Inject failure context from previous iteration
606
671
  _inject_failure_context() {
607
672
  local failure_context="$1"
@@ -644,17 +709,25 @@ _inject_developer_dna() {
644
709
  }
645
710
 
646
711
  # Build the prompt with story context injected
712
+ # Usage: build_prompt <story_id> [failure_context] [is_continuation]
647
713
  build_prompt() {
648
714
  local story="$1"
649
715
  local failure_context="${2:-}"
650
-
651
- # Read base PROMPT.md
652
- cat "$PROMPT_FILE"
716
+ local is_continuation="${3:-false}"
653
717
 
654
718
  # Get story JSON once
655
719
  local story_json
656
720
  story_json=$(jq --arg id "$story" '.stories[] | select(.id==$id)' "$RALPH_DIR/prd.json")
657
721
 
722
+ if [[ "$is_continuation" == "true" ]]; then
723
+ # Delta prompt for continuing session - just new story context
724
+ _build_delta_prompt "$story" "$story_json" "$failure_context"
725
+ return
726
+ fi
727
+
728
+ # Full prompt for fresh session
729
+ cat "$PROMPT_FILE"
730
+
658
731
  # Inject all sections
659
732
  _inject_story_context "$story_json"
660
733
  _inject_file_guidance "$story_json"