Skip to content

Releases: tone4hook/headless-coding-agent-sdk

v0.4.0

03 May 11:32

Choose a tag to compare

Highlights (breaking pre-1.0)

  • error.code taxonomy: error events now stamp a typed CoderErrorCode (rate_limit, auth_expired, context_too_large, network_error, timeout, binary_not_found, tool_crash, protocol_error, stalled, interrupted, unknown) plus a best-effort retryable hint. cancelled events optionally carry 'interrupted'/'stalled'. Per-adapter classifiers in src/adapters/{claude,codex,gemini}/classify.ts.
  • stallTimeoutMs: new RunOpts.stallTimeoutMs aborts a run if no normalized event is emitted for N ms; synthesizes an error with code: '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 with cleanEnv: false; extend deny list via additionalDenyEnv.
  • detached spawn + tree-kill fallback: child CLIs now run in their own POSIX process group; killProcessTree falls back to process.kill(-pid) when tree-kill errors, so grandchildren are reliably reaped.
  • Claude isolation preset: isolation: 'strict' | 'project' | 'user'. Strict mode mints a per-spawn CLAUDE_CONFIG_DIR (via extraEnv, never mutates process.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 with createWorktree / pruneStaleWorktrees.
  • UsageStats normalization: added reasoningTokens; Codex now extracts cache + reasoning token breakdown; Gemini extracts cached + thoughts tokens. New src/pricing.ts with estimateCostUsd (returns undefined for unknown models — no NaN).

Notable behavior changes

  • Env sanitation is on by default. Pass cleanEnv: false to restore prior pass-through behavior.
  • error events now require code (was optional string).
  • RunResult.error.code is typed as CoderErrorCode.

206 tests, build + typecheck clean.

v0.3.0 — Codex adapter

03 May 03:40

Choose a tag to compare

Added

  • Codex adapter — third supported CLI alongside claude and gemini. New src/adapters/codex/ module (flags, index, translate) plus factory wiring and re-exports.
  • Process-tree teardown helper at src/transport/processTree.ts (with tree-kill typings) — used by spawn.ts to terminate child process trees cleanly.
  • Schema additions in src/types.ts and src/adapters/shared/spec.ts to accommodate Codex-specific options without breaking existing Claude / Gemini call sites.

Changed

  • src/transport/spawn.ts updated to support process-tree teardown.
  • src/adapters/shared/thread.ts, claude/flags.ts, gemini/flags.ts adjusted for the unified three-adapter shape.

Tests

  • New test/codex-flags.test.ts and test/translate-codex.test.ts; existing flag/spawn/factory tests updated. All 144 tests passing.

v0.2.1 — spawn stdin EOF fix

26 Apr 15:22

Choose a tag to compare

Fixed

  • fix(transport): close stdin at EOF when no payload providedspawnCli now sends EOF on child.stdin when no opts.stdin is supplied. Eliminates the ~3s/turn latency the Claude CLI incurred while waiting for possible stream-json stdin input before falling back to the argv -p prompt.

Per-turn time-to-first-event drops from ~3.3s to ~300ms — the chat feel goes from "noticeably sluggish" to "snappy."

Commits

  • dd3de80 fix(transport): close stdin at EOF when no payload provided
  • 925e6fd chore: bump version to 0.2.1

v0.2.0 — UX-parity additions

26 Apr 14:21

Choose a tag to compare

Three additive features that close the parity gap with a hand-rolled HeadlessSession-style integration. All changes are strictly additive — existing consumers keep working.

Added

  • SharedStartOpts.unsetEnv?: string[] — env-var names to delete from the spawn env after extraEnv is merged. Empty-string extraEnv values are preserved as legitimate values, so stripping requires this explicit list. Common use: remove stale ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN / CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX to force the CLI's OAuth / keychain fallback.
  • New CoderStreamEvent variant { type: 'stderr'; line: string } — every stderr line from the CLI subprocess is surfaced live as an event before done. The stderr buffer attached to CliExitError on non-zero exit is preserved unchanged. ⚠️ Exhaustive switch consumers will see a TS error and need a new case 'stderr'.
  • Claude RunOpts.streamPartialMessages is now wired end-to-end. When set, Claude is invoked with --include-partial-messages, and each content_block_delta text-delta is translated into { type: 'message', role: 'assistant', text: <chunk>, delta: true }. The final aggregated message at message_stop continues to be emitted with delta: false, and RunResult.text filters delta:true chunks to avoid double-counting. Gemini silently ignores the flag. Thinking deltas are skipped in this version.

Internal

  • composeEnv(parentEnv, extraEnv?, unsetEnv?) helper exported from src/transport/spawn.ts — single source of truth for child-env composition.
  • mergeStdoutStderr(stdout, stderr) async generator added in src/transport/lines.ts — merges two AsyncIterable<string> into a tagged { src, line } stream preserving arrival order.

Verified against

  • claude 2.1.118
  • gemini 0.38.2

Tests

123/123 (was 107). Code-reviewer signed off both passes (spec compliance + code quality) on every phase.

Still deferred

  • Interactive permission callback (interactivePermissions on RunOpts) — needs CLI prompt-protocol work.
  • Long-lived single-subprocess thread mode (--input-format stream-json over stdin) — optional perf win.

v0.1.1

26 Apr 02:23

Choose a tag to compare

Full Changelog: v0.1.0...v0.1.1

v0.1.0

24 Apr 10:57

Choose a tag to compare