You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today, when createCliSubprocessCodingAgentDriver in packages/gittensory-engine/src/miner/cli-subprocess-driver.ts sees a non-zero exit from the claude CLI, 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}) that the CLI emits on some non-zero exits. src/selfhost/ai.ts already has a proven claudeErrorStatus-style parser for this exact envelope shape against the identical claude binary, so this is a port, not new design.
Dependencies
None — independently shippable. This is the Claude-side counterpart to the Codex JSONL-parsing issue in this same batch (C17); the two touch the same file but different options.command branches and can land in either order.
Requirements
Port a claudeErrorStatus-style parser from src/selfhost/ai.ts into packages/gittensory-engine/src/miner/cli-subprocess-driver.ts.
When options.command is claude, attempt to parse the captured stdout for the {is_error, api_error_status} JSON envelope on a non-zero exit.
When the envelope is present and parseable, fold a precise status (e.g. claude_code_no_oauth_token) into the driver's returned error instead of the generic exit-code string.
When the envelope is absent or fails to parse, fall back to today's ${command}_exit_${code}: ${stderr.slice(0,500)} behavior unchanged.
Ensure the parsed/folded error value continues to pass through the existing redactSecrets call before being returned.
Do not touch attempt/governor control-flow, retry logic, or any state outside the error-message construction itself — this issue changes only what the driver reports, not what happens next.
Deliverables / Acceptance Criteria
claudeErrorStatus-style parser added to cli-subprocess-driver.ts (ported from src/selfhost/ai.ts)
Driver wiring: envelope parsed only when options.command === 'claude', folded into the returned error when found
Fallback to the existing raw stderr-slice shape preserved when no envelope is found
Confirmed the folded error still passes through redactSecrets
No changes to attempt/governor control-flow files
Test Coverage Requirements
This PR must ship with full test coverage for every changed line and branch — the repo's Codecov patch gate requires 99%+ coverage and the house standard is to aim for 100%, including both sides of every conditional/nullish-coalescing branch introduced. Add: (1) unit tests covering the new parser's success path (valid {is_error, api_error_status} envelope folded into a precise status) and failure paths (envelope absent, envelope malformed/unparseable, non-claude command falls through untouched), (2) an invariant test asserting the driver never returns an error value containing an unredacted secret-shaped pattern regardless of which branch produced it, and (3) a regression test reproducing the current uninformative-error behavior to confirm it's specifically the claude_code_no_oauth_token-style case that improves, not a general behavior change.
Expected Outcome
An operator whose claude-cli-driven attempt fails will see a precise, actionable status (e.g. "no OAuth token") instead of a raw truncated stderr slice, letting them fix the actual problem without digging into logs.
Context
Today, when
createCliSubprocessCodingAgentDriverinpackages/gittensory-engine/src/miner/cli-subprocess-driver.tssees 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}) that the CLI emits on some non-zero exits.src/selfhost/ai.tsalready has a provenclaudeErrorStatus-style parser for this exact envelope shape against the identicalclaudebinary, so this is a port, not new design.Dependencies
None — independently shippable. This is the Claude-side counterpart to the Codex JSONL-parsing issue in this same batch (C17); the two touch the same file but different
options.commandbranches and can land in either order.Requirements
claudeErrorStatus-style parser fromsrc/selfhost/ai.tsintopackages/gittensory-engine/src/miner/cli-subprocess-driver.ts.options.commandisclaude, attempt to parse the captured stdout for the{is_error, api_error_status}JSON envelope on a non-zero exit.claude_code_no_oauth_token) into the driver's returned error instead of the generic exit-code string.${command}_exit_${code}: ${stderr.slice(0,500)}behavior unchanged.redactSecretscall before being returned.Deliverables / Acceptance Criteria
claudeErrorStatus-style parser added tocli-subprocess-driver.ts(ported fromsrc/selfhost/ai.ts)options.command === 'claude', folded into the returned error when foundredactSecretsTest Coverage Requirements
This PR must ship with full test coverage for every changed line and branch — the repo's Codecov patch gate requires 99%+ coverage and the house standard is to aim for 100%, including both sides of every conditional/nullish-coalescing branch introduced. Add: (1) unit tests covering the new parser's success path (valid
{is_error, api_error_status}envelope folded into a precise status) and failure paths (envelope absent, envelope malformed/unparseable, non-claudecommand falls through untouched), (2) an invariant test asserting the driver never returns an error value containing an unredacted secret-shaped pattern regardless of which branch produced it, and (3) a regression test reproducing the current uninformative-error behavior to confirm it's specifically theclaude_code_no_oauth_token-style case that improves, not a general behavior change.Expected Outcome
An operator whose
claude-cli-driven attempt fails will see a precise, actionable status (e.g. "no OAuth token") instead of a raw truncated stderr slice, letting them fix the actual problem without digging into logs.Links & Resources
packages/gittensory-engine/src/miner/cli-subprocess-driver.tssrc/selfhost/ai.ts(source of theclaudeErrorStatus-style parser to port)--json#4836 (a distinct, separate change to--jsonoutput formatting, not error-message content)