agentic-loop 3.1.4 → 3.1.6
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/package.json +1 -1
- package/ralph/hooks/protect-prd.sh +11 -0
- package/ralph/loop.sh +6 -19
- package/ralph/verify/tests.sh +16 -0
- package/ralph/verify.sh +4 -128
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Hook: PreToolUse matcher: "Edit|Write"
|
|
4
4
|
#
|
|
5
5
|
# Allows: /prd, /idea commands (they create .prd-edit-allowed marker)
|
|
6
|
+
# Allows: Ralph loop fixing test steps (detected by last_failure.txt)
|
|
6
7
|
# Blocks: Accidental edits during normal coding
|
|
7
8
|
|
|
8
9
|
set -euo pipefail
|
|
@@ -19,6 +20,16 @@ if [[ "$FILE_PATH" == *"prd.json"* ]]; then
|
|
|
19
20
|
exit 0
|
|
20
21
|
fi
|
|
21
22
|
|
|
23
|
+
# Allow if Ralph is in a retry loop with a RECENT failure (within 10 min)
|
|
24
|
+
# This lets Ralph fix broken test steps, but not stale failures from old sessions
|
|
25
|
+
if [[ -f ".ralph/last_failure.txt" ]]; then
|
|
26
|
+
file_age=$(( $(date +%s) - $(stat -f %m ".ralph/last_failure.txt" 2>/dev/null || echo 0) ))
|
|
27
|
+
if [[ $file_age -lt 600 ]]; then # 10 minutes
|
|
28
|
+
echo '{"continue": true}'
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
22
33
|
echo "BLOCKED: prd.json is managed by Ralph. Use /prd or /idea to add stories." >&2
|
|
23
34
|
exit 2 # Exit code 2 = blocking error
|
|
24
35
|
fi
|
package/ralph/loop.sh
CHANGED
|
@@ -337,24 +337,17 @@ run_loop() {
|
|
|
337
337
|
|
|
338
338
|
# 6. Run verification pipeline
|
|
339
339
|
echo ""
|
|
340
|
-
|
|
340
|
+
# Capture verification output for failure context
|
|
341
|
+
local verify_log="$RALPH_DIR/last_verification.log"
|
|
342
|
+
set -o pipefail
|
|
343
|
+
if run_verification "$story" 2>&1 | tee "$verify_log"; then
|
|
341
344
|
# Mark story as complete
|
|
342
345
|
update_json "$RALPH_DIR/prd.json" \
|
|
343
346
|
--arg id "$story" '(.stories[] | select(.id==$id) | .passes) = true'
|
|
344
347
|
|
|
345
348
|
# Clear failure context on success
|
|
346
349
|
rm -f "$RALPH_DIR/last_failure.txt"
|
|
347
|
-
rm -f "$RALPH_DIR/
|
|
348
|
-
rm -f "$RALPH_DIR/last_review_failure.json"
|
|
349
|
-
rm -f "$RALPH_DIR/last_test_failure.log"
|
|
350
|
-
rm -f "$RALPH_DIR/last_lint_failure.log"
|
|
351
|
-
rm -f "$RALPH_DIR/last_typescript_failure.log"
|
|
352
|
-
rm -f "$RALPH_DIR/last_build_failure.log"
|
|
353
|
-
rm -f "$RALPH_DIR/last_go_failure.log"
|
|
354
|
-
rm -f "$RALPH_DIR/last_rust_failure.log"
|
|
355
|
-
rm -f "$RALPH_DIR/last_playwright_failure.log"
|
|
356
|
-
rm -f "$RALPH_DIR/last_browser_failure.json"
|
|
357
|
-
rm -f "$RALPH_DIR/last_precommit_failure.log"
|
|
350
|
+
rm -f "$RALPH_DIR/last_verification.log"
|
|
358
351
|
|
|
359
352
|
# Auto-commit if git is available
|
|
360
353
|
if command -v git &>/dev/null && [[ -d ".git" ]]; then
|
|
@@ -600,17 +593,11 @@ _inject_failure_context() {
|
|
|
600
593
|
echo ""
|
|
601
594
|
echo "## Previous Iteration Failed"
|
|
602
595
|
echo ""
|
|
603
|
-
echo "
|
|
596
|
+
echo "Fix the errors below. If a PRD test step is broken, you can fix it in .ralph/prd.json."
|
|
604
597
|
echo ""
|
|
605
598
|
echo '```'
|
|
606
599
|
echo "$failure_context"
|
|
607
600
|
echo '```'
|
|
608
|
-
echo ""
|
|
609
|
-
echo "### What to do:"
|
|
610
|
-
echo "1. Read the error messages carefully"
|
|
611
|
-
echo "2. Identify the root cause"
|
|
612
|
-
echo "3. Fix the issue (do not just retry the same approach)"
|
|
613
|
-
echo "4. Run verification again"
|
|
614
601
|
}
|
|
615
602
|
|
|
616
603
|
# Helper: Inject signs (learned patterns)
|
package/ralph/verify/tests.sh
CHANGED
|
@@ -58,8 +58,13 @@ verify_prd_criteria() {
|
|
|
58
58
|
|
|
59
59
|
local failed=0
|
|
60
60
|
local log_file
|
|
61
|
+
local prd_failure_log="$RALPH_DIR/last_prd_failure.log"
|
|
61
62
|
log_file=$(create_temp_file ".log") || return 1
|
|
62
63
|
|
|
64
|
+
# Clear previous PRD failure log
|
|
65
|
+
rm -f "$prd_failure_log"
|
|
66
|
+
|
|
67
|
+
local step_index=0
|
|
63
68
|
while IFS= read -r step; do
|
|
64
69
|
[[ -z "$step" ]] && continue
|
|
65
70
|
|
|
@@ -72,8 +77,19 @@ verify_prd_criteria() {
|
|
|
72
77
|
echo ""
|
|
73
78
|
echo " Output:"
|
|
74
79
|
tail -"$MAX_OUTPUT_PREVIEW_LINES" "$log_file" | sed 's/^/ /'
|
|
80
|
+
|
|
81
|
+
# Save failure details for retry context
|
|
82
|
+
{
|
|
83
|
+
echo "PRD test step $step_index failed for $story:"
|
|
84
|
+
echo " Command: $step"
|
|
85
|
+
echo " Error output:"
|
|
86
|
+
tail -30 "$log_file" | sed 's/^/ /'
|
|
87
|
+
echo ""
|
|
88
|
+
} >> "$prd_failure_log"
|
|
89
|
+
|
|
75
90
|
failed=1
|
|
76
91
|
fi
|
|
92
|
+
((step_index++)) || true
|
|
77
93
|
done <<< "$test_steps"
|
|
78
94
|
|
|
79
95
|
rm -f "$log_file"
|
package/ralph/verify.sh
CHANGED
|
@@ -197,138 +197,14 @@ run_verification() {
|
|
|
197
197
|
# Save failure context for next iteration
|
|
198
198
|
save_failure_context() {
|
|
199
199
|
local story="$1"
|
|
200
|
-
|
|
201
200
|
local context_file="$RALPH_DIR/last_failure.txt"
|
|
202
201
|
|
|
203
202
|
{
|
|
204
|
-
echo "===
|
|
205
|
-
echo "Timestamp: $(date -Iseconds 2>/dev/null || date)"
|
|
203
|
+
echo "=== Verification failed for $story ==="
|
|
206
204
|
echo ""
|
|
207
|
-
|
|
208
|
-
if [[ -f "$RALPH_DIR/
|
|
209
|
-
|
|
210
|
-
echo "Database migrations failed. Fix the migration or the code causing it:"
|
|
211
|
-
tail -50 "$RALPH_DIR/last_migration_failure.log"
|
|
212
|
-
echo ""
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
if [[ -f "$RALPH_DIR/last_review_failure.json" ]]; then
|
|
216
|
-
echo "--- Code Review Failure ---"
|
|
217
|
-
echo "Issues found by code review:"
|
|
218
|
-
jq -r '.issues[] | "- [\(.severity)] \(.category): \(.message)\n File: \(.file // "unknown"):\(.line // "?")\n Fix: \(.suggestion // "See above")"' "$RALPH_DIR/last_review_failure.json" 2>/dev/null
|
|
219
|
-
echo ""
|
|
220
|
-
fi
|
|
221
|
-
|
|
222
|
-
if [[ -f "$RALPH_DIR/last_test_failure.log" ]]; then
|
|
223
|
-
echo "--- Test Failure ---"
|
|
224
|
-
tail -50 "$RALPH_DIR/last_test_failure.log"
|
|
225
|
-
echo ""
|
|
226
|
-
fi
|
|
227
|
-
|
|
228
|
-
if [[ -f "$RALPH_DIR/last_playwright_failure.log" ]]; then
|
|
229
|
-
echo "--- Playwright Failure ---"
|
|
230
|
-
tail -50 "$RALPH_DIR/last_playwright_failure.log"
|
|
231
|
-
echo ""
|
|
232
|
-
fi
|
|
233
|
-
|
|
234
|
-
if [[ -f "$RALPH_DIR/last_browser_failure.json" ]]; then
|
|
235
|
-
echo "--- Browser Validation Failure ---"
|
|
236
|
-
jq -r '"Errors: " + (.errors | join(", "))' "$RALPH_DIR/last_browser_failure.json" 2>/dev/null
|
|
237
|
-
jq -r '"Console errors: " + (.consoleErrors | join(", "))' "$RALPH_DIR/last_browser_failure.json" 2>/dev/null
|
|
238
|
-
jq -r '"Missing elements: " + (.elementsMissing | join(", "))' "$RALPH_DIR/last_browser_failure.json" 2>/dev/null
|
|
239
|
-
echo ""
|
|
240
|
-
fi
|
|
241
|
-
|
|
242
|
-
if [[ -f "$RALPH_DIR/last_lint_failure.log" ]]; then
|
|
243
|
-
echo "--- Lint Failure ---"
|
|
244
|
-
echo "Fix these lint errors. The auto-fixer couldn't resolve them, but you can:"
|
|
245
|
-
echo ""
|
|
246
|
-
cat "$RALPH_DIR/last_lint_failure.log"
|
|
247
|
-
echo ""
|
|
248
|
-
echo "Common fixes:"
|
|
249
|
-
echo " - E722 bare except: Change 'except:' to 'except Exception:'"
|
|
250
|
-
echo " - F401 unused import: Remove the unused import"
|
|
251
|
-
echo " - F841 unused variable: Remove or use the variable"
|
|
252
|
-
echo ""
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
if [[ -f "$RALPH_DIR/last_typescript_failure.log" ]]; then
|
|
256
|
-
echo "--- TypeScript Failure ---"
|
|
257
|
-
echo "Fix these TypeScript type errors:"
|
|
258
|
-
echo ""
|
|
259
|
-
cat "$RALPH_DIR/last_typescript_failure.log"
|
|
260
|
-
echo ""
|
|
261
|
-
echo "Common fixes:"
|
|
262
|
-
echo " - TS2322: Type mismatch - ensure assigned value matches expected type"
|
|
263
|
-
echo " - TS2339: Property not found - check spelling or add to interface"
|
|
264
|
-
echo " - TS2345: Argument type mismatch - cast or fix the argument type"
|
|
265
|
-
echo " - TS7006: Implicit any - add explicit type annotation"
|
|
266
|
-
echo ""
|
|
267
|
-
fi
|
|
268
|
-
|
|
269
|
-
if [[ -f "$RALPH_DIR/last_build_failure.log" ]]; then
|
|
270
|
-
echo "--- Build Failure ---"
|
|
271
|
-
echo "Fix these build errors:"
|
|
272
|
-
echo ""
|
|
273
|
-
cat "$RALPH_DIR/last_build_failure.log"
|
|
274
|
-
echo ""
|
|
275
|
-
echo "Common causes:"
|
|
276
|
-
echo " - Import errors: Check file paths and exports"
|
|
277
|
-
echo " - SSR issues (Next.js): Use dynamic imports for client-only code"
|
|
278
|
-
echo " - Missing dependencies: Run npm install"
|
|
279
|
-
echo ""
|
|
280
|
-
fi
|
|
281
|
-
|
|
282
|
-
if [[ -f "$RALPH_DIR/last_go_failure.log" ]]; then
|
|
283
|
-
echo "--- Go Failure ---"
|
|
284
|
-
echo "Fix these Go errors:"
|
|
285
|
-
echo ""
|
|
286
|
-
cat "$RALPH_DIR/last_go_failure.log"
|
|
287
|
-
echo ""
|
|
288
|
-
echo "Common fixes:"
|
|
289
|
-
echo " - Unused variable: Remove or use with _ prefix"
|
|
290
|
-
echo " - Undefined: Check imports and spelling"
|
|
291
|
-
echo " - Type mismatch: Ensure types align or use type assertion"
|
|
292
|
-
echo ""
|
|
293
|
-
fi
|
|
294
|
-
|
|
295
|
-
if [[ -f "$RALPH_DIR/last_rust_failure.log" ]]; then
|
|
296
|
-
echo "--- Rust Failure ---"
|
|
297
|
-
echo "Fix these Rust errors:"
|
|
298
|
-
echo ""
|
|
299
|
-
cat "$RALPH_DIR/last_rust_failure.log"
|
|
300
|
-
echo ""
|
|
301
|
-
echo "Common fixes:"
|
|
302
|
-
echo " - Unused variable: Prefix with _ or remove"
|
|
303
|
-
echo " - Borrow checker: Check ownership and lifetimes"
|
|
304
|
-
echo " - Missing trait: Add #[derive(...)] or impl"
|
|
305
|
-
echo ""
|
|
306
|
-
fi
|
|
307
|
-
|
|
308
|
-
if [[ -f "$RALPH_DIR/last_precommit_failure.log" ]]; then
|
|
309
|
-
echo "--- Pre-commit / Lint Failure ---"
|
|
310
|
-
echo "Fix these errors before the story can be completed:"
|
|
311
|
-
echo ""
|
|
312
|
-
# Extract actual error lines (not warnings-only or file modification messages)
|
|
313
|
-
grep -E "^error:|: error:|Error:|SyntaxError|✖ [0-9]+ problems|^[^:]+:[0-9]+:[0-9]+: [EF][0-9]+" "$RALPH_DIR/last_precommit_failure.log" | head -30
|
|
314
|
-
# If no errors shown, show the full log tail
|
|
315
|
-
if ! grep -qE "^error:|: error:|Error:|SyntaxError|✖ [0-9]+ problems" "$RALPH_DIR/last_precommit_failure.log"; then
|
|
316
|
-
echo "(Full output):"
|
|
317
|
-
tail -40 "$RALPH_DIR/last_precommit_failure.log"
|
|
318
|
-
fi
|
|
319
|
-
echo ""
|
|
320
|
-
fi
|
|
321
|
-
|
|
322
|
-
if [[ -f "$RALPH_DIR/last_fastapi_response_check.log" ]]; then
|
|
323
|
-
echo "--- FastAPI Response Model Failure ---"
|
|
324
|
-
echo "Add Pydantic response_model to these endpoints for proper Swagger docs:"
|
|
325
|
-
echo ""
|
|
326
|
-
cat "$RALPH_DIR/last_fastapi_response_check.log"
|
|
327
|
-
echo ""
|
|
328
|
-
echo "Fix by adding response_model parameter or return type annotation:"
|
|
329
|
-
echo ' @router.get("/items", response_model=list[ItemSchema])'
|
|
330
|
-
echo " async def get_items() -> list[ItemSchema]:"
|
|
331
|
-
echo ""
|
|
205
|
+
# Just include the verification output - Claude can figure out what went wrong
|
|
206
|
+
if [[ -f "$RALPH_DIR/last_verification.log" ]]; then
|
|
207
|
+
tail -100 "$RALPH_DIR/last_verification.log"
|
|
332
208
|
fi
|
|
333
209
|
} > "$context_file"
|
|
334
210
|
}
|