agentic-loop 3.1.5 → 3.2.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/package.json +1 -1
- package/ralph/loop.sh +6 -27
- package/ralph/setup.sh +76 -11
- package/ralph/verify.sh +16 -284
- package/templates/PROMPT.md +26 -43
- package/ralph/api.sh +0 -216
- package/ralph/browser-verify/README.md +0 -135
- package/ralph/browser-verify/verify.ts +0 -450
- package/ralph/playwright.sh +0 -238
- package/ralph/verify/browser.sh +0 -324
- package/ralph/verify/review.sh +0 -152
package/package.json
CHANGED
package/ralph/loop.sh
CHANGED
|
@@ -337,25 +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"
|
|
358
|
-
rm -f "$RALPH_DIR/last_prd_failure.log"
|
|
350
|
+
rm -f "$RALPH_DIR/last_verification.log"
|
|
359
351
|
|
|
360
352
|
# Auto-commit if git is available
|
|
361
353
|
if command -v git &>/dev/null && [[ -d ".git" ]]; then
|
|
@@ -601,24 +593,11 @@ _inject_failure_context() {
|
|
|
601
593
|
echo ""
|
|
602
594
|
echo "## Previous Iteration Failed"
|
|
603
595
|
echo ""
|
|
604
|
-
echo "
|
|
596
|
+
echo "Fix the errors below. If a PRD test step is broken, you can fix it in .ralph/prd.json."
|
|
605
597
|
echo ""
|
|
606
598
|
echo '```'
|
|
607
599
|
echo "$failure_context"
|
|
608
600
|
echo '```'
|
|
609
|
-
echo ""
|
|
610
|
-
echo "### What to do:"
|
|
611
|
-
echo "1. Read the error messages carefully"
|
|
612
|
-
echo "2. Identify the root cause - is it your implementation OR a flawed test step?"
|
|
613
|
-
echo "3. Fix the issue (do not just retry the same approach)"
|
|
614
|
-
echo "4. Run verification again"
|
|
615
|
-
echo ""
|
|
616
|
-
echo "### If the test step itself is broken:"
|
|
617
|
-
echo "If the error is in the PRD test step (not your implementation), you CAN fix it:"
|
|
618
|
-
echo "1. Read .ralph/prd.json to find the story index and broken testStep"
|
|
619
|
-
echo "2. Use jq to update: \`jq '.stories[IDX].testSteps[N] = \"fixed\"' .ralph/prd.json > tmp && mv tmp .ralph/prd.json\`"
|
|
620
|
-
echo "3. Common test step bugs: missing imports, str() triggering lazy loading, wrong paths"
|
|
621
|
-
echo "4. ONLY fix the test command - do NOT change acceptance criteria or story scope"
|
|
622
601
|
}
|
|
623
602
|
|
|
624
603
|
# Helper: Inject signs (learned patterns)
|
package/ralph/setup.sh
CHANGED
|
@@ -340,7 +340,7 @@ EOF
|
|
|
340
340
|
fi
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
# Configure MCP (
|
|
343
|
+
# Configure MCP (Browser tools for verification)
|
|
344
344
|
setup_mcp() {
|
|
345
345
|
local claude_json="$HOME/.claude.json"
|
|
346
346
|
|
|
@@ -350,17 +350,82 @@ setup_mcp() {
|
|
|
350
350
|
# Create claude.json if it doesn't exist
|
|
351
351
|
[[ ! -f "$claude_json" ]] && echo '{}' > "$claude_json"
|
|
352
352
|
|
|
353
|
-
|
|
354
|
-
|
|
353
|
+
local added_any=false
|
|
354
|
+
|
|
355
|
+
# Add Playwright MCP if not configured
|
|
356
|
+
if ! jq -e '.mcpServers["playwright"]' "$claude_json" > /dev/null 2>&1; then
|
|
357
|
+
echo "Configuring MCP servers..."
|
|
358
|
+
local tmp
|
|
359
|
+
tmp=$(mktemp)
|
|
360
|
+
jq '.mcpServers["playwright"] = {
|
|
361
|
+
"command": "npx",
|
|
362
|
+
"args": ["-y", "@anthropic-ai/mcp-server-playwright"]
|
|
363
|
+
}' "$claude_json" > "$tmp" && mv "$tmp" "$claude_json"
|
|
364
|
+
echo " Added playwright MCP server (browser automation & testing)"
|
|
365
|
+
added_any=true
|
|
366
|
+
fi
|
|
355
367
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
368
|
+
# Add Chrome DevTools MCP if not configured
|
|
369
|
+
if ! jq -e '.mcpServers["chrome-devtools"]' "$claude_json" > /dev/null 2>&1; then
|
|
370
|
+
[[ "$added_any" == "false" ]] && echo "Configuring MCP servers..."
|
|
371
|
+
local tmp
|
|
372
|
+
tmp=$(mktemp)
|
|
373
|
+
jq '.mcpServers["chrome-devtools"] = {
|
|
374
|
+
"command": "npx",
|
|
375
|
+
"args": ["-y", "@anthropic-ai/mcp-server-chrome-devtools@0.0.5"]
|
|
376
|
+
}' "$claude_json" > "$tmp" && mv "$tmp" "$claude_json"
|
|
377
|
+
echo " Added chrome-devtools MCP server (debugging & inspection)"
|
|
378
|
+
added_any=true
|
|
379
|
+
fi
|
|
380
|
+
|
|
381
|
+
# Ask about test credentials
|
|
382
|
+
if [[ "$added_any" == "true" ]]; then
|
|
383
|
+
setup_test_credentials
|
|
384
|
+
fi
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
# Set up test credentials for browser automation
|
|
388
|
+
setup_test_credentials() {
|
|
389
|
+
echo ""
|
|
390
|
+
echo " Browser automation often needs login credentials for testing."
|
|
391
|
+
echo ""
|
|
392
|
+
read -r -p " Do you have test user credentials to configure? [y/N] " response
|
|
393
|
+
|
|
394
|
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
395
|
+
echo ""
|
|
396
|
+
echo " These will be stored in .env (already in .gitignore - never committed)"
|
|
397
|
+
echo ""
|
|
398
|
+
|
|
399
|
+
# Create .env if it doesn't exist
|
|
400
|
+
if [[ ! -f ".env" ]]; then
|
|
401
|
+
touch ".env"
|
|
402
|
+
echo " Created .env file"
|
|
403
|
+
fi
|
|
404
|
+
|
|
405
|
+
# Get credentials
|
|
406
|
+
read -r -p " Test user email: " test_email
|
|
407
|
+
read -r -s -p " Test user password: " test_password
|
|
408
|
+
echo ""
|
|
409
|
+
|
|
410
|
+
# Add to .env (append or update)
|
|
411
|
+
if grep -q "^RALPH_TEST_USER=" .env 2>/dev/null; then
|
|
412
|
+
# Update existing
|
|
413
|
+
local tmp
|
|
414
|
+
tmp=$(mktemp)
|
|
415
|
+
sed "s/^RALPH_TEST_USER=.*/RALPH_TEST_USER=$test_email/" .env > "$tmp" && mv "$tmp" .env
|
|
416
|
+
sed "s/^RALPH_TEST_PASSWORD=.*/RALPH_TEST_PASSWORD=$test_password/" .env > "$tmp" && mv "$tmp" .env
|
|
417
|
+
else
|
|
418
|
+
# Append new
|
|
419
|
+
echo "" >> .env
|
|
420
|
+
echo "# Test credentials for browser automation (auto-added by agentic-loop)" >> .env
|
|
421
|
+
echo "RALPH_TEST_USER=$test_email" >> .env
|
|
422
|
+
echo "RALPH_TEST_PASSWORD=$test_password" >> .env
|
|
423
|
+
fi
|
|
424
|
+
|
|
425
|
+
echo " Saved credentials to .env"
|
|
426
|
+
echo ""
|
|
427
|
+
echo " Note: .env is gitignored - your password will never be committed to git."
|
|
428
|
+
fi
|
|
364
429
|
}
|
|
365
430
|
|
|
366
431
|
# Set up pre-commit hooks
|
package/ralph/verify.sh
CHANGED
|
@@ -1,35 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# shellcheck shell=bash
|
|
3
|
-
# verify.sh -
|
|
3
|
+
# verify.sh - Lightweight verification for ralph
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# - verify/lint.sh - Auto-fix + lint checks
|
|
8
|
-
# - verify/tests.sh - Unit tests + PRD criteria
|
|
9
|
-
# - verify/browser.sh - Browser validation
|
|
10
|
-
|
|
11
|
-
# Validate required source files exist before sourcing
|
|
12
|
-
if [[ ! -f "$RALPH_LIB/playwright.sh" ]]; then
|
|
13
|
-
echo "Error: Missing $RALPH_LIB/playwright.sh" >&2
|
|
14
|
-
exit 1
|
|
15
|
-
fi
|
|
16
|
-
if [[ ! -f "$RALPH_LIB/api.sh" ]]; then
|
|
17
|
-
echo "Error: Missing $RALPH_LIB/api.sh" >&2
|
|
18
|
-
exit 1
|
|
19
|
-
fi
|
|
5
|
+
# Philosophy: Claude verifies its own work using MCP browser tools.
|
|
6
|
+
# Ralph just runs lint, tests, and testSteps from the PRD.
|
|
20
7
|
|
|
21
8
|
# Source verification modules
|
|
22
|
-
source "$RALPH_LIB/playwright.sh"
|
|
23
|
-
source "$RALPH_LIB/api.sh"
|
|
24
|
-
|
|
25
|
-
# Determine the directory where this script lives
|
|
26
9
|
VERIFY_DIR="${RALPH_LIB:-$(dirname "${BASH_SOURCE[0]}")}"
|
|
27
|
-
|
|
28
|
-
# Source modular verification components
|
|
29
|
-
source "$VERIFY_DIR/verify/review.sh"
|
|
30
10
|
source "$VERIFY_DIR/verify/lint.sh"
|
|
31
11
|
source "$VERIFY_DIR/verify/tests.sh"
|
|
32
|
-
source "$VERIFY_DIR/verify/browser.sh"
|
|
33
12
|
|
|
34
13
|
run_verification() {
|
|
35
14
|
local story="$1"
|
|
@@ -38,142 +17,33 @@ run_verification() {
|
|
|
38
17
|
print_info "=== Verification: $story ==="
|
|
39
18
|
echo ""
|
|
40
19
|
|
|
41
|
-
# Clear old failure logs (so smart-skip logic uses fresh state)
|
|
42
|
-
rm -f "$RALPH_DIR/last_precommit_failure.log" \
|
|
43
|
-
"$RALPH_DIR/last_test_failure.log" \
|
|
44
|
-
"$RALPH_DIR/last_review_failure.json" 2>/dev/null
|
|
45
|
-
|
|
46
|
-
# Check for fast mode
|
|
47
|
-
local fast_mode="${RALPH_FAST_MODE:-false}"
|
|
48
|
-
if [[ "$fast_mode" == "true" ]]; then
|
|
49
|
-
echo " (fast mode - skipping code review)"
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
# Determine story type (single jq call for all story info)
|
|
53
|
-
local story_json
|
|
54
|
-
story_json=$(jq --arg id "$story" '.stories[] | select(.id==$id)' "$RALPH_DIR/prd.json" 2>/dev/null)
|
|
55
|
-
|
|
56
|
-
local story_type has_test_url has_api_endpoints
|
|
57
|
-
story_type=$(echo "$story_json" | jq -r '.type // "frontend"')
|
|
58
|
-
has_test_url=$(echo "$story_json" | jq -r '.testUrl // empty')
|
|
59
|
-
has_api_endpoints=$(echo "$story_json" | jq -r '.apiEndpoints[0] // empty')
|
|
60
|
-
|
|
61
|
-
# Auto-detect type if not specified
|
|
62
|
-
if [[ -n "$has_api_endpoints" && -z "$has_test_url" ]]; then
|
|
63
|
-
story_type="backend"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
20
|
local failed=0
|
|
67
|
-
local lint_failed=0
|
|
68
|
-
local test_failed=0
|
|
69
21
|
|
|
70
22
|
# ========================================
|
|
71
|
-
# STEP 1:
|
|
23
|
+
# STEP 1: Run lint checks
|
|
72
24
|
# ========================================
|
|
73
|
-
|
|
74
|
-
if
|
|
75
|
-
|
|
76
|
-
elif [[ -f "$RALPH_DIR/last_precommit_failure.log" ]] || [[ -f "$RALPH_DIR/last_test_failure.log" ]]; then
|
|
77
|
-
# Skip review if last failure was lint/test - review won't help
|
|
78
|
-
skip_review=true
|
|
79
|
-
echo " [1/5] Skipping code review (last failure was lint/test)"
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
if [[ "$skip_review" == "false" ]]; then
|
|
83
|
-
echo " [1/5] Running code review..."
|
|
84
|
-
if ! run_code_review "$story"; then
|
|
85
|
-
failed=1
|
|
86
|
-
fi
|
|
25
|
+
echo " [1/3] Running lint checks..."
|
|
26
|
+
if ! run_configured_checks; then
|
|
27
|
+
failed=1
|
|
87
28
|
fi
|
|
88
29
|
|
|
89
30
|
# ========================================
|
|
90
|
-
# STEP 2
|
|
31
|
+
# STEP 2: Run unit tests
|
|
91
32
|
# ========================================
|
|
92
33
|
if [[ $failed -eq 0 ]]; then
|
|
93
34
|
echo ""
|
|
94
|
-
echo " [2/
|
|
95
|
-
|
|
96
|
-
# Create temp files for results
|
|
97
|
-
local lint_log test_log
|
|
98
|
-
lint_log=$(mktemp)
|
|
99
|
-
test_log=$(mktemp)
|
|
100
|
-
|
|
101
|
-
# Run lint in background
|
|
102
|
-
(run_configured_checks > "$lint_log" 2>&1; echo $? > "${lint_log}.exit") &
|
|
103
|
-
local lint_pid=$!
|
|
104
|
-
|
|
105
|
-
# Run tests in background
|
|
106
|
-
(run_unit_tests > "$test_log" 2>&1; echo $? > "${test_log}.exit") &
|
|
107
|
-
local test_pid=$!
|
|
108
|
-
|
|
109
|
-
# Wait for both
|
|
110
|
-
wait $lint_pid 2>/dev/null
|
|
111
|
-
wait $test_pid 2>/dev/null
|
|
112
|
-
|
|
113
|
-
# Check results
|
|
114
|
-
lint_failed=$(cat "${lint_log}.exit" 2>/dev/null || echo "1")
|
|
115
|
-
test_failed=$(cat "${test_log}.exit" 2>/dev/null || echo "1")
|
|
116
|
-
|
|
117
|
-
# Show lint output
|
|
118
|
-
echo " Lint:"
|
|
119
|
-
cat "$lint_log" | sed 's/^/ /'
|
|
120
|
-
|
|
121
|
-
# Show test output
|
|
122
|
-
echo " Tests:"
|
|
123
|
-
cat "$test_log" | sed 's/^/ /'
|
|
124
|
-
|
|
125
|
-
# Cleanup
|
|
126
|
-
rm -f "$lint_log" "${lint_log}.exit" "$test_log" "${test_log}.exit"
|
|
127
|
-
|
|
128
|
-
if [[ "$lint_failed" != "0" ]] || [[ "$test_failed" != "0" ]]; then
|
|
35
|
+
echo " [2/3] Running tests..."
|
|
36
|
+
if ! run_unit_tests; then
|
|
129
37
|
failed=1
|
|
130
38
|
fi
|
|
131
39
|
fi
|
|
132
40
|
|
|
133
41
|
# ========================================
|
|
134
|
-
# STEP 3: Run
|
|
135
|
-
# ========================================
|
|
136
|
-
if [[ $failed -eq 0 ]]; then
|
|
137
|
-
echo ""
|
|
138
|
-
if [[ "$story_type" == "backend" ]]; then
|
|
139
|
-
echo " [3/5] Running API tests..."
|
|
140
|
-
if ! run_api_validation "$story"; then
|
|
141
|
-
failed=1
|
|
142
|
-
elif ! run_api_error_tests "$story"; then
|
|
143
|
-
failed=1
|
|
144
|
-
fi
|
|
145
|
-
else
|
|
146
|
-
echo " [3/5] Running Playwright tests..."
|
|
147
|
-
if ! run_playwright_tests "$story"; then
|
|
148
|
-
failed=1
|
|
149
|
-
fi
|
|
150
|
-
fi
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
# ========================================
|
|
154
|
-
# STEP 4: Run browser validation (frontend) or API validation (backend)
|
|
42
|
+
# STEP 3: Run PRD test steps
|
|
155
43
|
# ========================================
|
|
156
44
|
if [[ $failed -eq 0 ]]; then
|
|
157
45
|
echo ""
|
|
158
|
-
|
|
159
|
-
echo " [4/5] Running API validation..."
|
|
160
|
-
if ! run_api_tests "$story"; then
|
|
161
|
-
failed=1
|
|
162
|
-
fi
|
|
163
|
-
else
|
|
164
|
-
echo " [4/5] Running browser validation..."
|
|
165
|
-
if ! run_browser_validation "$story"; then
|
|
166
|
-
failed=1
|
|
167
|
-
fi
|
|
168
|
-
fi
|
|
169
|
-
fi
|
|
170
|
-
|
|
171
|
-
# ========================================
|
|
172
|
-
# STEP 5: Run PRD test steps
|
|
173
|
-
# ========================================
|
|
174
|
-
if [[ $failed -eq 0 ]]; then
|
|
175
|
-
echo ""
|
|
176
|
-
echo " [5/5] Running PRD test steps..."
|
|
46
|
+
echo " [3/3] Running PRD test steps..."
|
|
177
47
|
if ! verify_prd_criteria "$story"; then
|
|
178
48
|
failed=1
|
|
179
49
|
fi
|
|
@@ -188,7 +58,6 @@ run_verification() {
|
|
|
188
58
|
return 0
|
|
189
59
|
else
|
|
190
60
|
print_error "=== Verification failed ==="
|
|
191
|
-
# Save failure context for next iteration
|
|
192
61
|
save_failure_context "$story"
|
|
193
62
|
return 1
|
|
194
63
|
fi
|
|
@@ -197,151 +66,14 @@ run_verification() {
|
|
|
197
66
|
# Save failure context for next iteration
|
|
198
67
|
save_failure_context() {
|
|
199
68
|
local story="$1"
|
|
200
|
-
|
|
201
69
|
local context_file="$RALPH_DIR/last_failure.txt"
|
|
202
70
|
|
|
203
71
|
{
|
|
204
|
-
echo "===
|
|
205
|
-
echo "Timestamp: $(date -Iseconds 2>/dev/null || date)"
|
|
72
|
+
echo "=== Verification failed for $story ==="
|
|
206
73
|
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 ""
|
|
332
|
-
fi
|
|
333
|
-
|
|
334
|
-
if [[ -f "$RALPH_DIR/last_prd_failure.log" ]]; then
|
|
335
|
-
echo "--- PRD Test Step Failure ---"
|
|
336
|
-
echo "A test step in the PRD failed. Either fix your implementation OR fix the test step:"
|
|
337
|
-
echo ""
|
|
338
|
-
cat "$RALPH_DIR/last_prd_failure.log"
|
|
339
|
-
echo ""
|
|
340
|
-
echo "If the test step itself is broken (not your code), you can fix it:"
|
|
341
|
-
echo " 1. Read .ralph/prd.json to find the story and testSteps array"
|
|
342
|
-
echo " 2. Fix the command (e.g., add missing imports for SQLAlchemy models)"
|
|
343
|
-
echo " 3. Update with: jq '.stories[IDX].testSteps[N] = \"fixed command\"' .ralph/prd.json > tmp && mv tmp .ralph/prd.json"
|
|
344
|
-
echo ""
|
|
74
|
+
# Just include the verification output - Claude can figure out what went wrong
|
|
75
|
+
if [[ -f "$RALPH_DIR/last_verification.log" ]]; then
|
|
76
|
+
tail -100 "$RALPH_DIR/last_verification.log"
|
|
345
77
|
fi
|
|
346
78
|
} > "$context_file"
|
|
347
79
|
}
|
package/templates/PROMPT.md
CHANGED
|
@@ -14,36 +14,38 @@ Before writing any code, verify:
|
|
|
14
14
|
|
|
15
15
|
For each story, you must:
|
|
16
16
|
|
|
17
|
-
### 1.
|
|
17
|
+
### 1. Implement the Feature
|
|
18
18
|
|
|
19
|
-
**For frontend stories:**
|
|
20
|
-
- Write a Playwright test that validates the acceptance criteria
|
|
21
|
-
- Include tests for error handling (API fails, validation errors)
|
|
22
|
-
- Include tests for empty/loading states
|
|
23
|
-
- Include accessibility checks (axe-core)
|
|
24
|
-
- Include mobile viewport test (375px)
|
|
25
|
-
|
|
26
|
-
**For backend stories:**
|
|
27
|
-
- Write unit tests for the business logic
|
|
28
|
-
- Write API tests that validate all endpoints
|
|
29
|
-
- Test error responses (400, 401, 500)
|
|
30
|
-
- Test validation rules
|
|
31
|
-
|
|
32
|
-
### 2. Implement the Feature
|
|
33
|
-
|
|
34
|
-
- Write code to make all tests pass
|
|
35
19
|
- Follow existing patterns in the codebase
|
|
36
20
|
- Handle ALL error cases defined in the story
|
|
37
21
|
- Implement loading states for async operations
|
|
38
22
|
|
|
23
|
+
### 2. Write Tests
|
|
24
|
+
|
|
25
|
+
- Write unit tests for the business logic
|
|
26
|
+
- Write tests that validate acceptance criteria
|
|
27
|
+
- Test error cases and edge cases
|
|
28
|
+
|
|
39
29
|
### 3. Verify It Actually Works
|
|
40
30
|
|
|
31
|
+
**You have browser tools - USE THEM to verify your work:**
|
|
32
|
+
|
|
33
|
+
**Playwright MCP** (testing & automation):
|
|
34
|
+
- `browser_navigate` - Go to a URL and get page content
|
|
35
|
+
- `browser_screenshot` - Take a screenshot to verify UI
|
|
36
|
+
- `browser_click` - Click elements to test interactions
|
|
37
|
+
- `browser_type` - Fill in forms to test inputs
|
|
38
|
+
- `browser_snapshot` - Get accessibility tree for a11y testing
|
|
39
|
+
|
|
40
|
+
**Chrome DevTools MCP** (debugging & inspection):
|
|
41
|
+
- Inspect DOM, check console for errors
|
|
42
|
+
- Debug network requests
|
|
43
|
+
- Check element styles and computed properties
|
|
44
|
+
|
|
41
45
|
**Do NOT say you're done until:**
|
|
42
46
|
- All unit tests pass
|
|
43
|
-
-
|
|
44
|
-
- You've opened the browser via MCP and visually verified
|
|
47
|
+
- You've opened the browser and visually verified the feature works
|
|
45
48
|
- Console has no errors
|
|
46
|
-
- It works on mobile (375px viewport)
|
|
47
49
|
- Error states are handled gracefully
|
|
48
50
|
|
|
49
51
|
## Rules
|
|
@@ -60,33 +62,14 @@ For each story, you must:
|
|
|
60
62
|
|
|
61
63
|
Before considering any story complete:
|
|
62
64
|
|
|
63
|
-
### Code
|
|
64
65
|
- [ ] All acceptance criteria are met
|
|
65
66
|
- [ ] All error handling from story is implemented
|
|
66
|
-
- [ ]
|
|
67
|
-
- [ ] Validation implemented (if backend)
|
|
68
|
-
- [ ] TypeScript compiles without errors
|
|
69
|
-
|
|
70
|
-
### Tests
|
|
67
|
+
- [ ] TypeScript/code compiles without errors
|
|
71
68
|
- [ ] Unit tests written and passing
|
|
72
|
-
- [ ] Playwright
|
|
73
|
-
- [ ]
|
|
74
|
-
- [ ] Error cases tested
|
|
75
|
-
- [ ] Edge cases tested (empty state, etc.)
|
|
76
|
-
|
|
77
|
-
### Browser/API Validation
|
|
78
|
-
- [ ] Browser check passes (frontend) - no console errors
|
|
79
|
-
- [ ] Mobile viewport works (375px)
|
|
80
|
-
- [ ] Accessibility passes (can Tab through, focus visible)
|
|
81
|
-
- [ ] API returns correct responses (backend)
|
|
82
|
-
|
|
83
|
-
### Documentation
|
|
84
|
-
- [ ] Updated `.ralph/progress.txt` with files created/modified
|
|
85
|
-
- [ ] Noted any key decisions or context for next story
|
|
86
|
-
|
|
87
|
-
### Quality
|
|
69
|
+
- [ ] **Browser verified** - used Playwright MCP to visually confirm it works
|
|
70
|
+
- [ ] No console errors
|
|
88
71
|
- [ ] Linting passes
|
|
89
|
-
- [ ]
|
|
72
|
+
- [ ] Updated `.ralph/progress.txt` with files created/modified
|
|
90
73
|
|
|
91
74
|
## If Verification Fails
|
|
92
75
|
|