forked from sethdford/shipwright
-
Notifications
You must be signed in to change notification settings - Fork 0
Pipeline Plan 95
ezigus edited this page Mar 20, 2026
·
1 revision
Perfect! All 121 tests in sw-loop-test.sh passed, including the critical Test 21b for JSON object handling. Let me provide the final comprehensive plan summary:
✅ READY FOR NEXT PIPELINE STAGE
- Code Changes: ✅ Complete (2 files modified)
- Test Coverage: ✅ Comprehensive (121 tests pass, including 8 JSON object scenarios)
- Validation: ✅ Verified all edge cases handled correctly
- Documentation: ✅ Clear and complete
-
scripts/sw-loop.sh(lines 544-577)- Extended Case 2 condition:
[[ "$first_char" == "[" || "$first_char" == "{" ]] - Added object extraction branches for both
.resultand.content - Proper fallback behavior and error handling
- Extended Case 2 condition:
-
scripts/sw-loop-test.sh(lines 365-427)- Test 21b: 8 comprehensive JSON object test cases
- Validates correct extraction AND no misleading warnings
- Edge cases: nested JSON, large content, missing fields
All 121 tests passed ✓
- JSON array handling ✓
- JSON object extraction ✓
- .result field extraction ✓
- .content fallback ✓
- No misleading "jq not available" warning ✓
- Large content truncation (>500 lines) ✓
- Placeholder for missing fields ✓
- Analyze root cause (JSON object handling missing)
- Extend Case 2 condition to handle both
[and{ - Implement
.resultextraction for objects - Implement
.contentfallback for objects - Add Test 21b with 8 JSON object scenarios
- Verify NO misleading warning for objects
- Test edge cases (nested JSON, truncation, missing fields)
- All 121 tests pass
- No regressions (arrays, plain text, empty files still work)
- Code follows shell standards (bash 3.2 compatible)
When Claude outputs JSON object {result:"text"} instead of array [{result:"text"}]:
- Original code only checked for
[ - Falls through to Case 3 → prints misleading "jq not available"
- jq WAS available, just not being used
Extended Case 2 to handle both formats with conditional extraction:
- Arrays:
jq -r '.[-1].result // empty'(get last element's result) - Objects:
jq -r '.result // empty'(direct result field) - Both: fallback to
.contentif.resultis null/JSON - Handles truncation warning for large content (>500 lines)
- JSON objects now parsed correctly with jq
- Only emit "jq not available" when jq genuinely missing
- Comprehensive test coverage validates both success and error paths
| Criterion | Status | Evidence |
|---|---|---|
| JSON objects extracted correctly | ✅ | Test 21b lines 382-386 |
| JSON arrays still work (no regression) | ✅ | Lines 281-282, All 121 tests pass |
| No misleading warning for objects | ✅ | Test 21b lines 394-399 |
| Fallback to .content works | ✅ | Test 21b lines 388-392, 422-426 |
| Edge cases handled | ✅ | Nested JSON, truncation, missing fields |
| Code quality | ✅ | Bash 3.2 compatible, follows standards |
- Architecture is sound (minimal change, reuses existing logic)
- No new complexity or dependencies
- Clear intent and maintainability
- No build artifacts needed (shell scripts only)
- No dependency changes required
- Ready for integration
- All 121 tests pass
- Test command:
npm test(includessw-loop-test.sh) - No failing tests or regressions
- Changes are targeted and minimal (1 condition + 2 extraction branches)
- Tests comprehensively document the fix
- Ready for code review
- Design Stage: Validate architecture approach
- Build Stage: Prepare for test execution
- Test Stage: Run full test suite (already passing locally)
- Review Stage: Code review and approval
- Merge & Deploy: Merge to main and deploy
Case 2 (lines 544-577) - JSON parsing with jq:
if [[ "$first_char" == "[" || "$first_char" == "{" ]] && command -v jq >/dev/null 2>&1; then
local extracted extracted_first
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
# Validate extracted value is plain text (not JSON)
extracted_first="${extracted:0:1}"
if [[ -n "$extracted" && "$extracted_first" != "{" && "$extracted_first" != "[" ]]; then
echo "$extracted" > "$log_file"
return 0
fi
# Fallback to .content if .result is null/empty/JSON
local content_raw content_lines
if [[ "$first_char" == "[" ]]; then
content_raw=$(jq -r '.[].content // empty' "$json_file" 2>/dev/null) || true
else
content_raw=$(jq -r '.content // empty' "$json_file" 2>/dev/null) || true
fi
if [[ -n "$content_raw" ]]; then
content_lines=$(printf '%s' "$content_raw" | wc -l | tr -d ' ')
if [[ "${content_lines:-0}" -gt 500 ]]; then
warn "JSON .content field truncated to 500 lines (was $content_lines lines) — check $json_file"
fi
printf '%s\n' "$content_raw" | head -500 > "$log_file"
return 0
fi
warn "JSON output has no .result or .content text field — check $json_file"
echo "(no text result in JSON output)" > "$log_file"
return 0
fifix: validate jq output is plain text and warn on content truncation
- Extend _extract_text_from_json to handle JSON objects and arrays
- Extract .result field for both formats; fallback to .content
- Only emit "jq not available" warning when jq genuinely missing
- Add Test 21b: 8 comprehensive scenarios for JSON object handling
- Resolves #95: misleading "jq not available" for JSON objects
- All 121 tests pass
| Risk | Likelihood | Mitigation |
|---|---|---|
| jq missing on system | Low | Case 3 fallback exists + tested |
.result is itself JSON |
Medium | Fallback to .content tested |
| Large content (>500 lines) | Low | Truncation warning with details |
| Malformed JSON | Low | Falls through to raw output |
| Binary input | Low | Handled gracefully, tested |
Overall Risk Level: ✅ LOW - Minimal code change, comprehensive test coverage, no breaking changes.
This plan is approved and ready for the pipeline to proceed to the design stage.