Highlights (breaking pre-1.0)
- error.code taxonomy:
errorevents now stamp a typedCoderErrorCode(rate_limit,auth_expired,context_too_large,network_error,timeout,binary_not_found,tool_crash,protocol_error,stalled,interrupted,unknown) plus a best-effortretryablehint.cancelledevents optionally carry'interrupted'/'stalled'. Per-adapter classifiers insrc/adapters/{claude,codex,gemini}/classify.ts. - stallTimeoutMs: new
RunOpts.stallTimeoutMsaborts a run if no normalized event is emitted for N ms; synthesizes anerrorwithcode: 'stalled'. - env hygiene: host env is now sanitized by default before spawn (strips
NODE_OPTIONS,npm_*,CLAUDECODE, etc.); auth/proxy/CA-bundle vars preserved. Opt out withcleanEnv: false; extend deny list viaadditionalDenyEnv. - detached spawn + tree-kill fallback: child CLIs now run in their own POSIX process group;
killProcessTreefalls back toprocess.kill(-pid)whentree-killerrors, so grandchildren are reliably reaped. - Claude
isolationpreset:isolation: 'strict' | 'project' | 'user'. Strict mode mints a per-spawnCLAUDE_CONFIG_DIR(viaextraEnv, never mutatesprocess.env) plus an empty MCP config so user plugins don't load. - opt-in exit cleanup:
installExitCleanup()+trackForExitCleanup()reap spawned CLIs on host SIGINT/SIGTERM/SIGHUP/uncaughtException. @tone4hook/headless-coding-agent-sdk/worktree: new subpath export withcreateWorktree/pruneStaleWorktrees.- UsageStats normalization: added
reasoningTokens; Codex now extracts cache + reasoning token breakdown; Gemini extracts cached + thoughts tokens. Newsrc/pricing.tswithestimateCostUsd(returnsundefinedfor unknown models — no NaN).
Notable behavior changes
- Env sanitation is on by default. Pass
cleanEnv: falseto restore prior pass-through behavior. errorevents now requirecode(was optionalstring).RunResult.error.codeis typed asCoderErrorCode.
206 tests, build + typecheck clean.