-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Plan 242
I now have a complete picture. Here's the implementation plan:
-
Missing JSON object handler (95% confidence) — Case 2 only checks
first_char == "["(array). When Claude outputs{"type":"result",...}(object), the condition is false, so jq is never tried. Control falls through to Case 3, which misleadingly blames jq availability. -
Incorrect condition ordering — Case 3's guard
first_char == "[" || first_char == "{"catches objects that Case 2 should have already handled. -
(Not applicable) — jq is actually missing. Ruled out: the
command -v jqcheck in Case 2 is never reached for objects, so jq availability is irrelevant.
-
File:
scripts/sw-loop.sh:561-608—_extract_text_from_json()function -
Line 579:
if [[ "$first_char" == "[" ]] && command -v jq— only handles arrays -
Line 599-600: Falls through for
{objects, prints misleading "jq not available" -
Existing tests: Tests 17-19 and 21 in
sw-loop-test.shcover empty files, valid JSON arrays, plain text, nested arrays, and binary — but no test for JSON object input
| File | Action |
|---|---|
scripts/sw-loop.sh |
Extend Case 2 to handle JSON objects ({...}) alongside arrays ([...]) |
scripts/sw-loop-test.sh |
Add test for JSON object extraction + fix Case 3 warning message test |
In scripts/sw-loop.sh lines 578-603, restructure the JSON parsing to:
- Check if
first_charis[or{AND jq is available (single combined guard) - Inside the block, branch on array vs object for the jq expression:
- Array:
jq -r '.[-1].result // empty'(existing) - Object:
jq -r '.result // empty'(new)
- Array:
- Share the rest of the extraction logic (
.contentfallback, placeholder)
# Case 2: Valid JSON (array or object) — extract with jq if [[ "$first_char" == "[" || "$first_char" == "{" ]] && command -v jq >/dev/null 2>&1; then local extracted if [[ "$first_char" == "[" ]]; then extracted=$(jq -r '.[-1].result // empty' "$json_file" 2>/dev/null) || true else extracted=$(jq -r '.result // empty' "$json_file" 2>/dev/null) || true fi if [[ -n "$extracted" ]]; then echo "$extracted" > "$log_file" return 0 fi # jq succeeded but result was null/empty — try .content or raw text if [[ "$first_char" == "[" ]]; then extracted=$(jq -r '.[].content // empty' "$json_file" 2>/dev/null | head -500) || true else extracted=$(jq -r '.content // empty' "$json_file" 2>/dev/null | head -500) || true fi if [[ -n "$extracted" ]]; then echo "$extracted" > "$log_file" return 0 fi # JSON parsed but no text found warn "JSON output has no .result field — check $json_file" echo "(no text result in JSON output)" > "$log_file" return 0 fi
Case 3 now only triggers when jq is genuinely unavailable (since Case 2 handles both [ and { when jq exists). The message is now accurate, but add a clarifying distinction:
# Case 3: Looks like JSON but no jq — can't parse, use raw if [[ "$first_char" == "[" || "$first_char" == "{" ]]; then warn "JSON output but jq not available — using raw output" cp "$json_file" "$log_file" return 0 fi
This message is now correct because it's only reached when command -v jq actually fails.
Add a new test case after the existing Test 19 (plain text passthrough) block that verifies:
- JSON object
{"type":"result","result":"Object extraction works",...}→ extracts "Object extraction works" - No "jq not available" warning is emitted
- Task 1: Modify Case 2 guard in
_extract_text_from_jsonto accept both[and{first chars - Task 2: Add object-specific jq expressions (
jq -r '.result // empty'andjq -r '.content // empty') - Task 3: Verify Case 3 warning is now only reachable when jq is genuinely missing (no code change needed — the logic is now correct by construction)
- Task 4: Add test in
sw-loop-test.shfor JSON object extraction (.resultfield) - Task 5: Add test for JSON object with
.contentfield (fallback path) - Task 6: Add test verifying no false "jq not available" warning for JSON objects
- Task 7: Run
sw-loop-test.shto verify all existing + new tests pass
-
Unit test (JSON object with
.result): Feed{"type":"result","result":"Hello from object","subtype":"success"}→ verify output contains "Hello from object" -
Unit test (JSON object with
.content): Feed{"content":"Fallback content"}→ verify output contains "Fallback content" - Warning suppression test: Run extraction on a JSON object and capture stderr → verify "jq not available" does NOT appear
- Regression: Run existing tests 15-21 unchanged → all pass
-
Run full test suite:
./scripts/sw-loop-test.sh
-
_extract_text_from_jsoncorrectly extracts.resultfrom both[...]and{...}JSON - No misleading "jq not available" warning when jq IS available
- Case 3 warning only fires when jq is genuinely missing
- New tests cover JSON object extraction (
.resultand.contentfallback) - All existing
sw-loop-test.shtests continue to pass - No Bash 3.2 compatibility violations in the change
This is Option A from the issue description (extend Case 2), which is the correct approach because:
- It fixes the root cause (jq never tried for objects), not just the symptom (wrong message)
- It makes JSON object output from Claude actually work, extracting clean text instead of passing raw JSON through
- The change is minimal — same jq patterns, just branching on
[vs{