Releases: guess/claude_code
v0.36.4 | CC 2.1.76
Fixed
- Streams now halt on terminal AssistantMessage errors — When the CLI encounters an unrecoverable error (rate limit, auth failure, billing), it previously entered an infinite loop emitting synthetic message pairs because the stream only halted on
ResultMessage. The stream now detectsAssistantMessagewith a non-nil error field and synthesizes aResultMessagewithis_error: true, soquery/2,final_text/1, andcollect/1all handle the error correctly. (ce727de) :can_use_toolcallback returning bare:allowor unmessaged:denyno longer triggers CLIZodError—PermissionDecision.Allow.to_wire/1now always emits"updatedInput"(defaulting to%{}when nil), andPermissionDecision.Deny.to_wire/1now always emits"message"(defaulting to""when nil). The Claude CLI's permission-response schema (Zod union) treats both fields as required on their respective arms, so omitting them caused every tool call routed throughcan_use_toolto fail validation. Verified against CLI 2.1.76. (c60799c)
v0.36.3 | CC 2.1.76
Fixed
ClaudeCode.History~/.claudepath evaluated at runtime — The default~/.claudedirectory was a module attribute computed at compile time, which could resolve to the wrong home directory in release builds or containerized environments. Now evaluated at runtime via a private function. ([90eb073])
v0.36.2 | CC 2.1.76
Fixed
--control-timeoutno longer sent to CLI — The:control_timeoutoption, which is internal to the Elixir SDK, was incorrectly passed to the CLI as a flag. ([5ac7a0a])- Silenced stray Plug messages in
CallbackProxy— When MCP tools execute in-process API calls via Dispatch, Plug sends messages to theCallbackProxyprocess, which OTP logged as errors. These harmless messages are now silently discarded. ([27087c4])
Changed
:extra_argschanged from list to map — The:extra_argsoption now accepts a map of%{flag => value}(or%{flag => true}for boolean flags) instead of a list, aligning with the Python SDK convention. ([5ac7a0a])
v0.36.1 | CC 2.1.76
Removed
- Query-level option overrides for
stream/3— Removed the ability to pass options tostream/3at call time. Since adopting the control protocol, the CLI subprocess ignores per-query option changes. All configuration should be set at session start viastart_link/1. ([addd8b4])
v0.36.0 | CC 2.1.76
Added
-
:inherit_envoption — Controls which system environment variables are inherited by the CLI subprocess. Defaults to:all(inherit everything exceptCLAUDECODE, matching Python SDK behavior). Set to a list of exact strings or{:prefix, "..."}tuples for selective inheritance, or[]to inherit nothing. See Secure Deployment. -
:envnow acceptsfalsevalues — Setting a key tofalsein the:envoption unsets that variable in the CLI subprocess, leveraging Erlang Port's native env unsetting. Useful for removing sensitive inherited vars:env: %{"RELEASE_COOKIE" => false}.
Fixed
- Hardened timing-sensitive tests — Replaced
Process.sleepcalls acrossClaudeCode.SessionTest,ClaudeCodeTest, andClaudeCode.SupervisorTestwith deterministic synchronization (MockCLI.poll_until/2,Process.monitor+assert_receive, synchronous:sys.get_statecalls). Corrected two supervisor tests that assumed empty config would crash the child —api_keyis now optional (defaults toANTHROPIC_API_KEYenv var), so the child starts successfully; tests now assertcount == 1to reflect current behavior.
Changed
-
MCP tool DSL — Tool descriptions moved from a positional argument into the block. This is a breaking change. ([44573a7])
# Before tool :add, "Add two numbers" do ... end # After tool :add do description "Add two numbers" ... end
-
Port spawning refactored to direct
spawn_executable—ClaudeCode.Adapter.Portnow spawns the CLI binary directly via Erlang's native:spawn_executablewith:args,:env, and:cdport options, replacing the previous/bin/sh -capproach that required hand-rolled shell escaping. This eliminatesClaudeCode.Adapter.Port.shell_escape/1,build_shell_command/4, and the@shell_safe_patternmodule attribute entirely. Environment variables, arguments, and paths with special characters (e.g.!,#,<,>,[,]) are now handled natively by the Erlang runtime without shell interpretation.
Fixed
-
CLI arg ordering for
:plugins,:add_dir, and:file— Flag/value pairs were reversed (e.g.,/path --plugin-dirinstead of--plugin-dir /path), causing the CLI to misinterpret arguments. -
Flaky
health/1provisioning test —ClaudeCode.Adapter.PortIntegrationTestnow accepts both{:unhealthy, :provisioning}and{:unhealthy, :not_connected}during startup, fixing a race condition where fast CI runners could resolve the CLI before the assertion.
v0.35.0 | CC 2.1.76
Added
- MCP test helpers — New
ClaudeCode.Test.mcp_list_tools/1,ClaudeCode.Test.mcp_call_tool/3,4, andClaudeCode.Test.mcp_request/2,3for testing MCP tool servers without JSONRPC boilerplate. ([5d920e0]) ClaudeCode.Session.execute/4— New optionalexecute/4callback on the Adapter behaviour for running arbitrary MFA calls through the adapter layer, enabling transparent local/remote execution.ClaudeCode.Session.get_messages/2andClaudeCode.Session.list_sessions/2now route through the Server for node-aware operation. ([aa3b54b])
Fixed
- Shell escape safety —
shell_escapenow quotes all non-safe characters instead of allowlisting known dangerous ones, preventing shell interpretation of!,#,<,>,?,[,],{,},*,~, tab, etc. ([0882139])
Changed
- MCP backend migrated from hermes to anubis — Internal MCP backend replaced
hermes_mcpwithanubis_mcp. No breaking changes to the public API. ([967216d])
v0.34.0 | CC 2.1.76
Changed
anubis_mcpupgraded to 1.0 and made a required dependency —anubis_mcphas been bumped from~> 0.17(optional) to~> 1.0(required). Users who depend on MCP functionality no longer need to explicitly addanubis_mcpto their deps. ([47a9afd])
v0.33.1 | CC 2.1.76
Changed
- Enhanced
can_use_toolcallback context — The:can_use_toolhook callback now receives additional context fields:cwd,session_id, andpermission_suggestions, enabling more informed permission decisions. (59ea547)
v0.33.0 | CC 2.1.76
Added
- MCP backend abstraction — New
ClaudeCode.MCP.Backendbehaviour allows pluggable MCP library backends. Ships withBackend.Anubis(new default) andBackend.Hermes(legacy). Both backends are optional — only compile when their respective library is loaded. Centralized backend detection viaClaudeCode.MCP.backend_for/1. ([4c69cbb]) - Enhanced session history (Python SDK parity) — New
ClaudeCode.History.list_sessions/1returns richClaudeCode.History.SessionInfometadata (summary, custom title, first prompt, git branch, cwd) using fast head/tail reads without full JSONL parsing. Supports worktree-aware scanning, deduplication, and:limit. ([bf93d7c]) - Chain-built message retrieval — New
ClaudeCode.History.get_messages/2andClaudeCode.Session.get_messages/2reconstruct conversations viaparentUuidchain walking, correctly handling branched and compacted conversations. ReturnsClaudeCode.History.SessionMessagestructs with parsed content blocks (TextBlock,ToolUseBlock, etc.). Supports:limitand:offsetpagination. ([bf93d7c]) ClaudeCode.History.SessionMessagestruct — Typed struct for history messages with:user/:assistantatom types, chain metadata (uuid,session_id), and parsed message content. ([bf93d7c])ClaudeCode.History.SessionInfostruct — Rich session metadata includingsession_id,summary,last_modified,file_size,custom_title,first_prompt,git_branch, andcwd. ([bf93d7c])ClaudeCode.History.sanitize_path/1— Python SDK-compatible path sanitization (replaces all non-alphanumeric chars with hyphens, handles long paths with hash suffix). ([bf93d7c])- Configurable
control_timeoutsession option — Max time in ms to wait for CLI control responses (e.g. initialize handshake, MCP server startup). Defaults to 60,000ms to match the Python SDK. Useful when MCP servers are slow to start. ([fb28a46], [6758caa])
Changed
- MCP tool macro rewrite —
ClaudeCode.MCP.Server.tool/3now generates standalone modules without Hermes dependency. Tools useexecute/2with(params, assigns)instead of Hermes frames. ([4c69cbb]) - MCP Router decoupled from Hermes — Router delegates all tool operations to the configured backend instead of importing Hermes modules directly. ([4c69cbb])
- Breaking: Removed
ClaudeCode.History.conversation/2,ClaudeCode.History.conversation_from_file/1, andClaudeCode.Session.conversation/2— replaced byget_messages/2which properly handles branched/compacted conversations viaparentUuidchain building. ([bf93d7c]) - Breaking: Removed
:callback_timeoutfromClaudeCode.Adapter.Node— proxy delegation for hooks and MCP now uses the unified:control_timeoutoption instead. If you were passing:callback_timeoutin adapter config, change it to:control_timeoutas a session option. ([6758caa])
v0.32.2 | CC 2.1.76
Fixed
mix claude_code.installversion check —ClaudeCode.Adapter.Port.Installer.version_of/1now retries once after 500ms on exit code 137 (SIGKILL). On macOS, Gatekeeper can kill a freshly-copied binary during initial code signature verification, causingclaude --versionto fail with empty output. This led to "Could not determine installed version" on every install and unnecessary reinstalls.