Releases: dn00/clarp
Release list
v0.1.12
Windows support, never-hang hardening, and a round of native-parity fixes — every behavioral claim verified against recorded native claude -p ground truth or on the windows-latest CI runner.
Windows works now (#12, fixes #1)
clarp -p "test" previously hung forever on Windows: claude.cmd runs through cmd.exe, so node-pty reports the wrapper's pid while the real Claude process is a grandchild — clarp polled a session status file that never exists. clarp now discovers Claude's real session file by working directory + recency, validates process ancestry so concurrent same-cwd runs can't adopt each other's sessions, and pins it once found. findClaude also handles the native installer's claude.exe, and transcript paths handle backslashes. Verified end-to-end on Windows CI via a real-PTY probe (now a permanent regression test).
Never hangs silently
- A startup watchdog now arms unconditionally until Claude is first observed (generous 120s, separate from the 30s in-turn timeout) and emits a terminal
result(subtypeerror) on failure — stream-json consumers always get a parseable terminator instead of a truncated stream. (#12) - Prompt dispatch has a deadline: if Claude's TUI eats the typed prompt (its status file reports idle a beat before the input box accepts keystrokes), clarp re-sends once — self-healing the race invisibly — then fails with a terminal error result instead of wedging. (#16)
Native parity (#15)
--max-turnsnow matches native semantics: it counts assistant API rounds inside the agentic loop, not user prompts; on exhaustion clarp reportsresultsubtypeerror_max_turns(is_error: true, noresultfield,num_turns= rounds) and exits 1.initializeandset_permission_modecontrol requests are acknowledged (SDK clients no longer stall on the handshake), using native's nestedcontrol_responseshape{type, response: {subtype, request_id, response}}. The interrupt and context-usage acks migrated to the same shape — breaking for consumers that parsed clarp's old flat ack shape.- Turn-level backend API errors (e.g. invalid model) report subtype
successwithis_error: trueand exit 1, matching native — previously subtypeerrorand exit 0 in stream-json mode. - Thinking blocks now carry their
signature(accumulated fromsignature_delta), needed by consumers that replay assistant content to the API.
Parity infrastructure (#14)
Recorded native ground truth for the 7-case interrupt matrix and a Task-subagent round-trip (captured before claude -p moved to metered API pricing), joining the existing golden capture sets. Replay-based parity testing (npm run parity:replay) diffs clarp against these recordings without ever spawning native. The parity policy (contract / consumed fields / on-demand / won't-fix-by-design) is documented in goldens/PARITY-GAPS.md.
Reliability
- CI retries
npm cito absorb npm's optional-dependency install flake. - 437 tests (≈90 added since 0.1.11), green on the 3-OS × 3-Node matrix.
v0.1.11
Hardening and parity release: observation core, permission flow, and a golden-capture parity harness.
Observation hardening (#9)
- Proxy never appends fabricated JSON once a response has started — it severs the connection instead. Added
error/abortedhandlers on the upstream stream and client backpressure on the observed SSE path. - Persistent
StringDecoderon the proxy SSE and transcript-tail paths, so a multibyte UTF-8 character split across network/poll chunks is no longer corrupted in clarp's observed output. Bytes forwarded to Claude were always untouched. - Unknown content-block types (
server_tool_use,redacted_thinking, future kinds) pass through raw instead of being dropped, and only delta-accumulated input is JSON-parsed — a raw block carrying a literal stringinputis preserved verbatim.
Permission-flow parity (#11)
- Intercept
--permission-prompt-toolso the interactive TUI never receives a print-mode flag it can't honor. - Gate
can_use_toolemission on stream-json input and output plus the stdio tool; otherwise auto-deny via the pty so the turn completes (native deny-by-default) instead of wedging on an unanswerable dialog. - Accept SDK-nested
control_responseshapes alongside the flat legacy shape, preservingupdatedInputso the modified-input guard can fire; deny allows whoseupdatedInputdiffers from the requested input (clarp can't inject rewritten input into the TUI dialog). - Resolve permission against a fresh
tool_useid with a brief retry — covering the race wherewaitingis observed before the tool finishes assembling, and preventing a stale tool from being approved against a newly focused dialog. Auto-deny a pending permission on stdin EOF. - Emit native
usertool_result events reshaped from transcript lines.
Parity testing harness (#10)
- Golden native captures plus replay-mode parity testing: record native
claude -pground truth once, then diff clarp against the saved summaries offline (no native invocation), with per-run isolated workspaces.
v0.1.10
Fixes
- Narrow the queued readiness timeout so ordinary queued work does not kill a legitimate long-running Claude turn
- Keep startup/no-safe-ready and unresolved permission waits timeout-eligible so queued stdin cannot hang forever
- Add regression tests for long-running turns with queued prompts and queued set_model commands
v0.1.9
Fixes
- Restore the 30s readiness timeout for queued prompt/slash operations when Claude never reaches a safe ready state.
- Add regression coverage so queued stdin cannot hang forever if initial Claude readiness is never observed.
Validation
- CI passed on macOS, Ubuntu, and Windows across Node 20/22/24.
- Local validation: npm test, npm run build, git diff --check, npm pack --dry-run.
v0.1.8
Fixes
- Fix macOS fresh installs where
node-pty'sspawn-helperloses its executable bit and Clarp exits withposix_spawnp failed - Add install-time and launch-time repair for the affected
node-ptymacOS helper while upstream stable npm releases still ship the bad mode
v0.1.7
Fixes
- Improve stream-json interrupt parity with
claude -p - Preserve queued prompts across interrupt, zero-delay prompt, and immediate follow-up races
- Match native interrupted result, SIGINT, duplicate interrupt response, and interrupted-only exit behavior
- Route prompt, interrupt, permission, and slash-command writes through the session operation queue
- Add interrupt parity cases and PTY interrupt probe tooling
v0.1.6
v0.1.5
- Harden stream-json turn queue under bursty multi-turn input
- Preserve queued prompts while waiting for Claude readiness
- Treat startup/idle interrupt and stop_task controls as no-ops
- Parse trailing stream-json input on EOF without requiring a final newline