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/ralph/api.sh DELETED
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env bash
2
- # shellcheck shell=bash
3
- # api.sh - API validation for backend stories
4
-
5
- # Parse an endpoint string into method and path
6
- # Usage: parse_endpoint "POST /api/users" "http://localhost:3000"
7
- # Sets: ENDPOINT_METHOD, ENDPOINT_PATH, ENDPOINT_URL
8
- parse_endpoint() {
9
- local endpoint="$1"
10
- local base_url="${2:-}"
11
-
12
- # Defaults
13
- ENDPOINT_METHOD="GET"
14
- ENDPOINT_PATH="$endpoint"
15
- ENDPOINT_URL=""
16
-
17
- # Parse method if present (e.g., "POST /api/contact")
18
- if [[ "$endpoint" =~ ^(GET|POST|PUT|PATCH|DELETE)[[:space:]]+(.*) ]]; then
19
- ENDPOINT_METHOD="${BASH_REMATCH[1]}"
20
- ENDPOINT_PATH="${BASH_REMATCH[2]}"
21
- fi
22
-
23
- # Build full URL
24
- if [[ "$ENDPOINT_PATH" =~ ^https?:// ]]; then
25
- ENDPOINT_URL="$ENDPOINT_PATH"
26
- elif [[ -n "$base_url" ]]; then
27
- ENDPOINT_URL="${base_url}${ENDPOINT_PATH}"
28
- fi
29
- }
30
-
31
- # Check if endpoint is a WebSocket (can't be tested with HTTP)
32
- is_websocket_endpoint() {
33
- local endpoint="$1"
34
- [[ "$endpoint" =~ ^wss?:// ]] || [[ "$endpoint" =~ ^(GET|POST|PUT|PATCH|DELETE)[[:space:]]+wss?:// ]]
35
- }
36
-
37
- # Validate API endpoints for a backend story
38
- run_api_validation() {
39
- local story="$1"
40
-
41
- # Get API endpoints from story
42
- local endpoints
43
- endpoints=$(jq -r --arg id "$story" '.stories[] | select(.id==$id) | .apiEndpoints[]?' "$RALPH_DIR/prd.json" 2>/dev/null)
44
-
45
- if [[ -z "$endpoints" ]]; then
46
- echo " (no apiEndpoints defined, skipping API validation)"
47
- return 0
48
- fi
49
-
50
- # Get base URL from config or use default
51
- local base_url
52
- base_url=$(get_config '.api.baseUrl' "http://localhost:3000")
53
-
54
- local failed=0
55
-
56
- echo " Validating API endpoints..."
57
-
58
- while IFS= read -r endpoint; do
59
- [[ -z "$endpoint" ]] && continue
60
-
61
- # Skip WebSocket endpoints - they can't be tested with HTTP curl
62
- if is_websocket_endpoint "$endpoint"; then
63
- echo " Skipping WebSocket endpoint: $endpoint (use integration tests)"
64
- continue
65
- fi
66
-
67
- # Parse endpoint into method, path, and full URL
68
- parse_endpoint "$endpoint" "$base_url"
69
-
70
- echo -n " $ENDPOINT_METHOD $ENDPOINT_PATH... "
71
-
72
- # Make the request
73
- local response_code
74
- response_code=$(curl -sf -m "$CURL_TIMEOUT_SECONDS" -o /dev/null -w "%{http_code}" -X "$ENDPOINT_METHOD" "$ENDPOINT_URL" 2>/dev/null)
75
-
76
- if [[ "$response_code" =~ ^2[0-9][0-9]$ ]]; then
77
- print_success "$response_code"
78
- elif [[ "$response_code" == "000" ]]; then
79
- print_error "connection failed"
80
- failed=1
81
- elif [[ "$response_code" == "422" || "$response_code" == "400" ]]; then
82
- # 422/400 = endpoint exists but needs params - don't fail verification
83
- print_warning "$response_code (needs params)"
84
- elif [[ "$response_code" == "401" || "$response_code" == "403" ]]; then
85
- # Auth required - endpoint exists
86
- print_warning "$response_code (auth required)"
87
- else
88
- print_error "$response_code"
89
- failed=1
90
- fi
91
- done <<< "$endpoints"
92
-
93
- return $failed
94
- }
95
-
96
- # Run comprehensive API tests for a story
97
- run_api_tests() {
98
- local story="$1"
99
-
100
- # Get test steps that look like API calls
101
- local test_steps
102
- test_steps=$(jq -r --arg id "$story" '.stories[] | select(.id==$id) | .testSteps[]?' "$RALPH_DIR/prd.json" 2>/dev/null)
103
-
104
- if [[ -z "$test_steps" ]]; then
105
- return 0
106
- fi
107
-
108
- local failed=0
109
- local log_file
110
- log_file=$(create_temp_file ".log") || return 1
111
-
112
- echo " Running API test steps..."
113
-
114
- while IFS= read -r step; do
115
- [[ -z "$step" ]] && continue
116
-
117
- # Check if this looks like a curl command or API test
118
- if [[ "$step" =~ ^curl ]]; then
119
- echo -n " $step... "
120
-
121
- if safe_exec "$step" "$log_file"; then
122
- print_success "passed"
123
- else
124
- print_error "failed"
125
- echo ""
126
- echo " Response:"
127
- tail -"$MAX_OUTPUT_PREVIEW_LINES" "$log_file" | sed 's/^/ /'
128
- failed=1
129
- fi
130
- fi
131
- done <<< "$test_steps"
132
-
133
- rm -f "$log_file"
134
- return $failed
135
- }
136
-
137
- # Validate error handling for API
138
- run_api_error_tests() {
139
- local story="$1"
140
-
141
- # Get error handling requirements
142
- local error_handling
143
- error_handling=$(jq -r --arg id "$story" '.stories[] | select(.id==$id) | .errorHandling[]?' "$RALPH_DIR/prd.json" 2>/dev/null)
144
-
145
- if [[ -z "$error_handling" ]]; then
146
- return 0
147
- fi
148
-
149
- # Get base URL and endpoints
150
- local base_url
151
- base_url=$(get_config '.api.baseUrl' "http://localhost:3000")
152
-
153
- local endpoints
154
- endpoints=$(jq -r --arg id "$story" '.stories[] | select(.id==$id) | .apiEndpoints[0]?' "$RALPH_DIR/prd.json" 2>/dev/null)
155
-
156
- if [[ -z "$endpoints" ]]; then
157
- return 0
158
- fi
159
-
160
- # Skip WebSocket endpoints
161
- if is_websocket_endpoint "$endpoints"; then
162
- echo " Skipping error tests for WebSocket endpoint"
163
- return 0
164
- fi
165
-
166
- # Parse endpoint (default to POST for error tests)
167
- parse_endpoint "$endpoints" "$base_url"
168
- [[ "$ENDPOINT_METHOD" == "GET" ]] && ENDPOINT_METHOD="POST"
169
-
170
- local failed=0
171
-
172
- echo " Testing API error handling..."
173
-
174
- # Test common error cases
175
- while IFS= read -r error_case; do
176
- [[ -z "$error_case" ]] && continue
177
-
178
- # Check for 400 tests (bad input)
179
- if [[ "$error_case" =~ 400 ]]; then
180
- echo -n " Testing 400 (bad request)... "
181
-
182
- local response_code
183
- response_code=$(curl -sf -m "$CURL_TIMEOUT_SECONDS" -o /dev/null -w "%{http_code}" \
184
- -X "$ENDPOINT_METHOD" \
185
- -H "Content-Type: application/json" \
186
- -d '{}' \
187
- "$ENDPOINT_URL" 2>/dev/null)
188
-
189
- if [[ "$response_code" == "400" ]]; then
190
- print_success "correctly returns 400"
191
- else
192
- print_warning "got $response_code (expected 400)"
193
- failed=1
194
- fi
195
- fi
196
-
197
- # Check for 401 tests (unauthorized)
198
- if [[ "$error_case" =~ 401 ]]; then
199
- echo -n " Testing 401 (unauthorized)... "
200
-
201
- local response_code
202
- response_code=$(curl -sf -m "$CURL_TIMEOUT_SECONDS" -o /dev/null -w "%{http_code}" \
203
- -X "$ENDPOINT_METHOD" \
204
- "$ENDPOINT_URL" 2>/dev/null)
205
-
206
- if [[ "$response_code" == "401" ]]; then
207
- print_success "correctly returns 401"
208
- else
209
- print_warning "got $response_code (expected 401)"
210
- failed=1
211
- fi
212
- fi
213
- done <<< "$error_handling"
214
-
215
- return $failed
216
- }
@@ -1,135 +0,0 @@
1
- # Browser Verify Skill
2
-
3
- Verify that a web page loads correctly using real browser automation (Playwright).
4
-
5
- ## Purpose
6
-
7
- This skill launches a real Chromium browser to verify pages work correctly. Unlike asking Claude to "imagine" what a page looks like, this actually:
8
-
9
- - Loads the page in a real browser
10
- - Detects JavaScript console errors
11
- - Detects failed network requests
12
- - Checks for error messages on the page ("Oops!", "Something went wrong")
13
- - Verifies required elements exist
14
- - Takes screenshots for evidence
15
- - Tests mobile viewport
16
-
17
- ## When to Use
18
-
19
- Use this skill for **frontend story verification**:
20
- - After implementing a UI feature
21
- - To verify a page loads without errors
22
- - To check that required elements render
23
- - To test mobile responsiveness
24
-
25
- ## Usage
26
-
27
- ```bash
28
- npx tsx ralph/browser-verify/verify.ts <url> [options]
29
- ```
30
-
31
- ### Options
32
-
33
- | Option | Description | Default |
34
- |--------|-------------|---------|
35
- | `--selectors '["#app", ".btn"]'` | Required elements (JSON array) | `[]` |
36
- | `--screenshot <path>` | Save screenshot to path | none |
37
- | `--timeout <ms>` | Page load timeout | 30000 |
38
- | `--headless` | Run without visible browser | true |
39
- | `--no-headless` | Show browser window | false |
40
- | `--check-console` | Fail on console errors | true |
41
- | `--no-check-console` | Ignore console errors | false |
42
- | `--mobile` | Use mobile viewport (375x667) | false |
43
- | `--viewport <W>x<H>` | Custom viewport size | 1280x720 |
44
-
45
- ### Examples
46
-
47
- **Basic page check:**
48
- ```bash
49
- npx tsx ralph/browser-verify/verify.ts http://localhost:3000/dashboard
50
- ```
51
-
52
- **Check specific elements exist:**
53
- ```bash
54
- npx tsx ralph/browser-verify/verify.ts http://localhost:3000/login \
55
- --selectors '["#email", "#password", "button[type=submit]"]'
56
- ```
57
-
58
- **Take screenshot and check mobile:**
59
- ```bash
60
- npx tsx ralph/browser-verify/verify.ts http://localhost:3000/dashboard \
61
- --screenshot .ralph/screenshots/dashboard.png \
62
- --mobile
63
- ```
64
-
65
- **Debug mode (visible browser):**
66
- ```bash
67
- npx tsx ralph/browser-verify/verify.ts http://localhost:3000/dashboard \
68
- --no-headless
69
- ```
70
-
71
- ## Output
72
-
73
- Returns JSON to stdout:
74
-
75
- ```json
76
- {
77
- "pass": true,
78
- "errors": [],
79
- "warnings": ["Page loaded slowly (3500ms)"],
80
- "screenshot": ".ralph/screenshots/dashboard.png",
81
- "title": "Dashboard - MyApp",
82
- "elementsFound": ["#app", ".header", ".sidebar"],
83
- "elementsMissing": [],
84
- "consoleErrors": [],
85
- "networkErrors": [],
86
- "loadTime": 1234
87
- }
88
- ```
89
-
90
- ### Exit Codes
91
-
92
- - `0` - Verification passed
93
- - `1` - Verification failed (check `errors` array)
94
-
95
- ## What It Catches
96
-
97
- | Issue | How It's Detected |
98
- |-------|-------------------|
99
- | Page won't load | Connection refused, timeout |
100
- | JavaScript errors | Console error messages |
101
- | Failed API calls | Network request failures, 4xx/5xx responses |
102
- | Error pages | Text matching "Oops!", "Something went wrong", etc. |
103
- | Missing elements | Selector not found in DOM |
104
- | Slow pages | Load time > 5 seconds (warning) |
105
-
106
- ## Integration with Ralph
107
-
108
- Ralph automatically uses this skill for frontend story verification:
109
-
110
- 1. Story has `testUrl` defined
111
- 2. Ralph calls `verify.ts` with the URL
112
- 3. Optionally checks `selectors` from story config
113
- 4. Takes screenshot for evidence
114
- 5. Fails verification if errors detected
115
-
116
- ## Requirements
117
-
118
- - Node.js 18+
119
- - Playwright (`npx playwright install chromium`)
120
-
121
- ## Troubleshooting
122
-
123
- **"Cannot find module 'playwright'"**
124
- ```bash
125
- npm install playwright
126
- npx playwright install chromium
127
- ```
128
-
129
- **"Browser closed unexpectedly"**
130
- - Try with `--no-headless` to see what's happening
131
- - Check if the URL is accessible
132
-
133
- **"Timeout waiting for page"**
134
- - Increase timeout: `--timeout 60000`
135
- - Check if dev server is running