feat(miner-hands): parse Claude Code's JSON error envelope in the CLI-subprocess driver (#5168)#5256
Conversation
…-subprocess driver (JSONbored#5168) Ports src/selfhost/ai.ts's claudeErrorStatus parser into cli-subprocess-driver.ts (redeclared, not imported, per this file's no-src-import convention). On a non-zero exit from claude, the driver now parses stdout for the {is_error, api_error_status} envelope and folds a precise claude_code_error_<status> into the returned error, falling back to subtype then "unknown" when api_error_status is absent. When the envelope is absent, malformed, or the command isn't "claude", the existing raw exit-code/stderr-slice error is unchanged. The folded error passes through redactSecrets like every other error path in this driver.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5256 +/- ##
=======================================
Coverage 94.36% 94.36%
=======================================
Files 474 474
Lines 40081 40089 +8
Branches 14614 14617 +3
=======================================
+ Hits 37821 37829 +8
Misses 1585 1585
Partials 675 675
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-12 12:09:46 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
createCliSubprocessCodingAgentDriversees a non-zero exit from theclaudeCLI, the only error shape it produces is${command}_exit_${code}: ${stderr.slice(0,500)}-- it never inspects Claude Code's own structured JSON error envelope ({is_error, api_error_status}).claudeErrorStatus-style parser fromsrc/selfhost/ai.tsintopackages/gittensory-engine/src/miner/cli-subprocess-driver.ts(redeclared, not imported -- this package stays standalone per the file's own header comment).options.command === "claude"and the exit is non-zero, the driver now parses stdout for the envelope. If found (is_error === true), it folds a preciseclaude_code_error_<status>into the returned error (falling back tosubtypethen"unknown"whenapi_error_statusis absent), instead of the generic exit-code string.claude, the existing raw${command}_exit_${code}: <stderr slice>behavior is unchanged.redactSecretscall every other error path in this driver already uses.Test plan
npx vitest run test/unit/cli-subprocess-driver.test.ts-- 17/17 passing, including the newdescribe("Claude Code JSON error-envelope diagnostics (#5168)", ...)block: valid envelope folded into a precise status,subtypefallback,"unknown"fallback when both are absent, no-envelope regression (today's raw stderr-slice behavior preserved), valid-JSON-but-is_error: falsefalls through unchanged, non-claudecommand never inspects the envelope, and an invariant that a folded error is never left unredacted when it contains a known secret value.npx vitest run test/contract/coding-agent-driver-parity.test.ts-- 18/18 passing (unaffected).npx vitest run test/unit/coding-agent-miner.test.ts-- 57/57 passing (unaffected).npm --workspace @jsonbored/gittensory-engine run build-- clean.npm run typecheck-- clean.COVERAGE_NO_THRESHOLDS=1 npx vitest run test/unit/cli-subprocess-driver.test.ts --coverage --coverage.include="packages/gittensory-engine/src/miner/cli-subprocess-driver.ts"-- 100% statements/branches/functions/lines.npm run docs:drift-check-- clean.npm run test:coveragelocally (shared/resource-contended machine); relying on CI's Codecov patch-coverage gate plus the isolated-coverage check above.Fixes #5168.