Changelog
View SourceAll notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.36.3] - 2026-03-30 | 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])
[0.36.2] - 2026-03-30 | 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])
[0.36.1] - 2026-03-29 | 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])
[0.36.0] - 2026-03-29 | CC 2.1.76
Added
:inherit_envoption — Controls which system environment variables are inherited by the CLI subprocess. Defaults to:all(inherit everything except CLAUDECODE, 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" ... endPort 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 eliminatesshell_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.
[0.35.0] - 2026-03-26 | 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])
[0.34.0] - 2026-03-26 | 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])
[0.33.1] - 2026-03-20 | 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])
[0.33.0] - 2026-03-15 | CC 2.1.76
Added
- MCP backend abstraction — New ClaudeCode.MCP.Backend behaviour allows pluggable MCP library backends. Ships with
Backend.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 — The
tool/3macro now 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, and ClaudeCode.Session.conversation/2 — replaced by
get_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])
[0.32.2] - 2026-03-14 | 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.
[0.32.1] - 2026-03-14 | CC 2.1.76
Fixed
- Documentation fixes: corrected stop reason docs, permissions and user inputs docs, and typespec for
:allow/:denyin hook responses.
[0.32.0] - 2026-03-14 | CC 2.1.76
Added
- ClaudeCode.Hook.DebugLogger module — A diagnostic hook that logs every invocation with event name, tool name, and available input keys. Register it for any hook event to observe what the CLI sends. Includes ClaudeCode.Hook.DebugLogger.Permissive variant for
:can_use_toolthat returns:allow. ([9d75ed8])
Changed
- Breaking:
hermes_mcpis now a required dependency (was optional). It was already required at compile time forClaudeCode.MCP.Server. If your project does not use MCP features, you will now pull inhermes_mcpas a transitive dependency — no code changes are needed. - Breaking: Removed
ClaudeCode.MCP.available?/0andClaudeCode.MCP.require_hermes!/0— no longer needed withhermes_mcprequired. - Bumped bundled CLI version to 2.1.76. ([15fdff2])
Fixed
- MCP parameter validation —
ClaudeCode.MCP.Routernow validates tool parameters against their schema using Hermes/Peri before execution, returning JSONRPC-32602errors for invalid input. Previously, invalid parameters were passed directly toexecute/2. - MCP PreToolUse hooks —
PreToolUsehooks now apply to in-process MCP tool calls, matching themcp__<server>__<tool>naming convention. Previously, MCP tools bypassed the hook system entirely. ClaudeCode.Adapter.Portbuffer overflow false positive — The buffer overflow check now runs after extracting complete lines, not before. Previously, a burst of many small complete JSON messages arriving in a single chunk could trigger a false overflow even though only the remaining incomplete buffer should count against the limit.ClaudeCode.MCP.Routergeneric notification handling — Handle all JSONRPC 2.0 notification types (notifications/*) instead of onlynotifications/initialized. Previously, other notification types likenotifications/cancelledwould crash with aFunctionClauseErrorbecausejsonrpc_error/3requires an"id"field that notifications don't have.ClaudeCode.Test.stub/2shared ownership —stub/2now works correctly when the session name has a shared owner, updating the stub instead of raising. ([95524e0])
Added
- Restored
:can_use_tooloption — Single permission callback invoked before every tool execution. Simpler alternative toPreToolUsehooks when you don't need matchers. Accepts a module implementingClaudeCode.Hookor a 2-arity function. Mutually exclusive with:permission_prompt_tool. See the Hooks guide. ClaudeCode.Hook.Outputmodule family — Structured hook output types replacing the flatClaudeCode.Hook.Responsemodule. Each hook event has a dedicated output struct (ClaudeCode.Hook.Output.PreToolUse,ClaudeCode.Hook.Output.PostToolUse, etc.) withto_wire/1for CLI serialization. Includescoerce/2for mapping shorthand returns (:ok,{:allow, opts},{:deny, opts}, etc.) to the correct wire format.ClaudeCode.Hook.PermissionDecision.Allow/ClaudeCode.Hook.PermissionDecision.Deny— Permission decision structs shared by:can_use_toolandPermissionRequesthooks.mix claude_code.setup_tokentask — New mix task that runsclaude setup-tokento configure an OAuth token via an interactive browser flow. Allocates a PTY to support the CLI's terminal UI on both macOS and Linux. ([aff71ca])ClaudeCode.Pluginmodule — Plugin management functions wrappingclaude pluginCLI commands:list/1,install/2,uninstall/2,enable/2,disable/2,disable_all/1,update/2.ClaudeCode.Plugin.Marketplacemodule — Marketplace management functions wrappingclaude plugin marketplaceCLI commands:list/1,add/2,remove/1,update/1.ClaudeCode.Plugin.CLImodule — Shared CLI execution helper for plugin and marketplace commands.
[0.31.0] - 2026-03-11 | CC 2.1.72
Added
- Shorthand syntax for
:hooksoption — Accept bare modules and 2-arity functions directly in hook lists (e.g.,hooks: %{PreToolUse: [MyApp.Guard]}), removing the need for map wrappers in the common case. The full map form remains available for matchers, timeouts, and:where. SeeClaudeCode.Optionsand the Hooks guide.
Removed
- Breaking: Removed the
:can_use_tooloption. UsePreToolUsehooks instead, which provide the same permission decision capability through the standard hooks API. The CLI no longer sendscan_use_toolcontrol requests — all permission decisions are routed through hook callbacks. Migrate by moving your callback intohooks: %{PreToolUse: [your_callback]}. - Removed
handle_can_use_tool/2from the adapter control handler - Removed
ClaudeCode.Hook.Response.to_can_use_tool_wire/1 - Removed
can_use_toolfield from the hook registry struct - Changed hook registry constructor from arity-2 to arity-1 (no longer accepts a
can_use_toolparameter)
[0.30.0] - 2026-03-11 | CC 2.1.72
Breaking release — This release reorganizes the public API and module structure for long-term clarity. See the Changed section for a migration summary.
Added
New features
- 9 new content block types —
ClaudeCode.Content.ServerToolUseBlock,ClaudeCode.Content.ServerToolResultBlock,ClaudeCode.Content.MCPToolUseBlock,ClaudeCode.Content.MCPToolResultBlock,ClaudeCode.Content.ImageBlock,ClaudeCode.Content.DocumentBlock,ClaudeCode.Content.RedactedThinkingBlock,ClaudeCode.Content.CompactionBlock, andClaudeCode.Content.ContainerUploadBlockfor parsing all CLI content types. ([80e2d0c]) - Forward-compatible message parsing — Unknown content block types and message types are now preserved as maps instead of being silently dropped, preventing data loss when the CLI adds new types. ([80e2d0c])
- Extensible parser registries — Application config options
:content_parsers,:message_parsers, and:system_parsersallow registering custom parser functions for new CLI types without forking the SDK. ([80e2d0c]) - New control API functions —
ClaudeCode.Session.set_mcp_servers/2,ClaudeCode.Session.mcp_reconnect/2,ClaudeCode.Session.mcp_toggle/3, andClaudeCode.Session.stop_task/2for runtime session control. ([10c4c3e], [3ff858e]) - Initialize response accessors —
ClaudeCode.Session.supported_commands/1,ClaudeCode.Session.supported_models/1,ClaudeCode.Session.supported_agents/1, andClaudeCode.Session.account_info/1return typed structs from the initialization handshake. ([3ff858e]) - Typed response structs — New
ClaudeCode.Session.SlashCommand,ClaudeCode.Model.Info,ClaudeCode.Session.AgentInfo,ClaudeCode.Session.AccountInfo, andClaudeCode.MCP.Statusstructs for structured access to CLI responses. ([e3725a4], [90cb40e], [baaf9a7]) - Inbound control request handling —
ClaudeCode.Adapter.Portnow handles CLI-initiatedelicitationrequests (logged, returns error) andcancelrequests (cancels pending control requests). ([d565e20]) :dry_runoption forClaudeCode.Session.rewind_files/2— Preview which files would be rewound without actually reverting them. ([9d9e8ac])ClaudeCode.cli_version/0— Returns the configured CLI version the SDK is using. ([dd2a771])ClaudeCode.Model.Effortmodule — Shared type (t()) andparse/1function for effort levels (:low,:medium,:high,:max).ClaudeCode.Model.Info.supported_effort_levelsnow returns atoms instead of strings. ([718b0b5])
New struct fields (CLI 2.1.72 sync)
ClaudeCode.Message.SystemMessage.FilesPersisted— Addedfailedandprocessed_atfields. ([f215376])ClaudeCode.Message.RateLimitEvent— Addedoverage_status,overage_resets_at,overage_disabled_reason,is_using_overage,surpassed_threshold, andrate_limit_typefields. ([412c802])ClaudeCode.Sandbox— Addedenable_weaker_network_isolationfield. ([a84106d])ClaudeCode.Message.SystemMessage.TaskProgress— Added optional:summaryfield (AI-generated progress summary, emitted whenagentProgressSummariesis enabled). ([89126bb])ClaudeCode.Message.SystemMessage.TaskStarted— Added optional:promptfield (the prompt that started the task). ([89126bb])ClaudeCode.Model.Info— Added optional:supports_auto_modefield (boolean, defaults tofalse). ([89126bb])
Fixed
- Race condition in
ClaudeCode.Sessionqueued request error handling — When the CLI adapter failed before the stream caller registered as a subscriber, the error was silently lost and the stream would halt normally instead of raising. ([d52f77d]) - Atom-safe map key conversion from CLI JSON payloads — Replaced unbounded
String.to_atomwithsafe_atomize_keys/1(usesbinary_to_existing_atom) for map keys parsed from external CLI input. Unknown keys stay as strings instead of creating new atoms, preventing atom table exhaustion. ([3c9dc90]) ClaudeCode.Message.AssistantMessagenow parses:refusalstop reason — Aligns withClaudeCode.Message.ResultMessageand the stop_reason typespec. ([28c15a3])- Streaming docs/examples corrected — Documentation and examples now consistently show partial streaming configured at session start and streamed with
ClaudeCode.stream/2orClaudeCode.stream/3.
Changed
API restructure and module reorganization
The top-level ClaudeCode module is now slimmed to 4 core functions: start_link/1, stream/3, query/2, stop/1. All session management, runtime configuration, MCP management, and introspection functions moved to ClaudeCode.Session. The GenServer implementation moved to Session.Server (internal module). ([b5a37b1])
Module moves (old → new):
| Old location | New location |
|---|---|
| ClaudeCode.get_session_id/1 | ClaudeCode.Session.session_id/1 |
| ClaudeCode.get_mcp_status/1 | ClaudeCode.Session.mcp_status/1 |
| ClaudeCode.get_server_info/1 | ClaudeCode.Session.server_info/1 |
| ClaudeCode.Types | Extracted to ClaudeCode.Session.PermissionMode, ClaudeCode.Session.PermissionDenial, ClaudeCode.Model.Usage, ClaudeCode.Usage |
| ClaudeCode.StopReason | Inlined into ClaudeCode.Message as stop_reason() type and parse_stop_reason/1 |
| ClaudeCode.PermissionMode | ClaudeCode.Session.PermissionMode |
| ClaudeCode.PermissionDenial | ClaudeCode.Session.PermissionDenial |
| ClaudeCode.AccountInfo | ClaudeCode.Session.AccountInfo |
| ClaudeCode.AgentInfo | ClaudeCode.Session.AgentInfo |
| ClaudeCode.SlashCommand | ClaudeCode.Session.SlashCommand |
| ClaudeCode.McpServerStatus | ClaudeCode.MCP.Status |
| ClaudeCode.McpSetServersResult | Replaced with typed map |
| ClaudeCode.RewindFilesResult | Replaced with typed map |
| System message subtypes (e.g., CompactBoundaryMessage) | ClaudeCode.Message.SystemMessage.* namespace (e.g., ClaudeCode.Message.SystemMessage.CompactBoundary) |
New system message subtype: ClaudeCode.Message.SystemMessage.Init extracted from SystemMessage. ([80e2d0c])
Other changes
ClaudeCode.Session.server_info/1returns atom-keyed map — Uses atom keys (%{commands: [...], models: [...], agents: [...], account: %AccountInfo{}, ...}) instead of string keys. ([8bc23e3])ClaudeCode.Session.mcp_status/1returns[ClaudeCode.MCP.Status.t()]— Returns the server list directly instead of%{"servers" => [...]}. ([ffa1b81])ClaudeCode.Session.rewind_files/2returns a typed map — Returns a typed map instead of a raw map. ([7acdfd5], [baaf9a7])ClaudeCode.Model.Infoboolean fields default tofalse— Fields likesupports_thinking,supports_computer_use, etc. now default tofalseinstead ofnil. ([f6b38e5])- Upgraded bundled CLI to 2.1.72 ([89126bb])
Removed
ClaudeCode.Typesmodule — See module moves table above. ([80e2d0c])ClaudeCode.McpSetServersResultandClaudeCode.RewindFilesResultstructs — Replaced with typed maps returned directly from the control protocol. ([baaf9a7])set_max_thinking_tokenscontrol-plane function — Removed the deprecated mid-sessionset_max_thinking_tokenscontrol command (matches TS SDK deprecation). Use the:thinkingsession option instead. ([b5a37b1])
[0.29.0] - 2026-03-02 | CC 2.1.62
Added
- Typed
ClaudeCode.Sandboxstructs for sandbox configuration — The:sandboxoption now accepts%ClaudeCode.Sandbox{}structs (with nestedClaudeCode.Sandbox.FilesystemandClaudeCode.Sandbox.Networksub-structs) in addition to raw maps and keyword lists. Structs handle camelCase key normalization automatically and implementJason.Encoder/JSON.Encoder. ([09e6b5c])
[0.28.0] - 2026-03-02 | CC 2.1.62
Added
- Distributed callback proxy for MCP tools and hooks — When using
ClaudeCode.Adapter.Node, in-process MCP tools and hooks now work across nodes. MCP tool requests route from the sandbox node back to the app node transparently. Hooks support a:whereoption on matcher configs (:localto run on the app node,:remoteto run on the sandbox node — defaults to:local). The:can_use_toolpermission callback always executes locally. Configurable:callback_timeout(default: 30s) on the adapter, with graceful degradation if the proxy process dies. ([f0a51de])
[0.27.0] - 2026-02-28 | CC 2.1.62
Added
ClaudeCode.Adapter.Nodefor distributed sessions — Offload CLI processes to dedicated sandbox servers via Erlang distribution, so your app server stays lightweight and scales independently of CLI resource consumption. Addadapter: {ClaudeCode.Adapter.Node, [node: :"claude@sandbox"]}toClaudeCode.start_link/1— everything else (ClaudeCode.stream/3,ClaudeCode.Streamutilities, session resumption) works unchanged. See Distributed Sessions. ([9accfd2])
Changed
ClaudeCode.Adapter.Localrenamed toClaudeCode.Adapter.Port— The local CLI adapter and its nested modules (Installer,Resolver) now live underClaudeCode.Adapter.Port. Update any direct references:ClaudeCode.Adapter.Local→ClaudeCode.Adapter.Port. ([9accfd2])- Session merges top-level opts into adapter config — Session-level options (
:cwd,:model,:system_prompt, etc.) are now automatically merged into the adapter config. The adapter tuple only needs adapter-specific options (e.g.,:node,:cookie). ([9accfd2])
[0.26.0] - 2026-02-27 | CC 2.1.62
Added
All subagent frontmatter fields on
ClaudeCode.Agent— Addeddisallowed_tools,permission_mode,max_turns,skills,mcp_servers,hooks,memory,background, andisolationfields. Uses existingClaudeCode.Types.permission_mode()atoms and new atom types formemory(:user | :project | :local) andisolation(:worktree). Also addsagent/1test factory toClaudeCode.Test.Factory. ([1e2fb95])- Result metadata in
ClaudeCode.Stream.collect/1— The summary map now includessession_id,usage,total_cost_usd,stop_reason, andnum_turnsfrom the result message, so callers can track costs, resume sessions, and understand why a conversation ended. ([7444177]) replay_user_messagesoption — Support the--replay-user-messagesCLI flag which re-emits user messages from stdin back on stdout, useful for synchronization in bidirectional streaming conversations. ([caf6c1d])is_replayandis_syntheticfields onClaudeCode.Message.UserMessage— Track whether a user message is a replay or synthetic message from the CLI. Both fields default tonil.
Changed
- Bundled CLI version bumped to 2.1.62 — Updated from 2.1.59 to 2.1.62.
- Removed
:request_timeout, renamed:stream_timeoutback to:timeout— Since:request_timeouthas been removed (useTask.yieldfor wall-clock caps externally), there's only one timeout again, so the simpler:timeoutname is restored. Default remains:infinity. The:stream_timeoutand:request_timeoutoptions are no longer accepted. :max_output_tokensinClaudeCode.Message.AssistantMessageerror type — Added explicit typespec entry and match clause for themax_output_tokenserror, previously handled by a catch-all.
Fixed
- Interrupt sent before closing port — On terminate, the adapter now sends an interrupt control request to the CLI before closing the port, preventing continued API token consumption. ([3a93f43])
- User environment variables take precedence over SDK defaults — Fixed
Map.mergeorder so user-provided environment variables override SDK-injected ones instead of the reverse. ([7385c03])
[0.25.0] - 2026-02-26 | CC 2.1.59
Added
- 5 new CLI message types — Parse
rate_limit_event,tool_progress,tool_use_summary,auth_status, andprompt_suggestionmessages instead of silently dropping them. ([0724eef]) ClaudeCode.Stream.filter_type/2support for new types — Filter streams by:rate_limit_event,:tool_progress,:tool_use_summary,:auth_status, and:prompt_suggestion. ([75e5a1b])- Factory functions for new message types —
rate_limit_event/1,tool_progress_message/1,tool_use_summary_message/1,auth_status_message/1,prompt_suggestion_message/1available inClaudeCode.Test.Factory. ([75e5a1b])
Changed
RateLimitEvent.statusis now an atom — Thestatusfield inrate_limit_infois parsed to:allowed,:allowed_warning, or:rejectedinstead of raw strings. ([75e5a1b])
Fixed
- Queries rejected immediately when adapter has failed — Previously, if the adapter process crashed, queries would hang until timeout. Now they return
{:error, {:adapter_not_running, reason}}immediately. ([17a6b89])
[0.24.0] - 2026-02-26 | CC 2.1.59
Added
:stream_timeoutoption — New name for the per-message stream timeout (max wait for the next message). Replaces:timeoutfor clarity alongside:request_timeout.:dangerously_skip_permissionsoption — Directly bypass all permission checks. Unlike:allow_dangerously_skip_permissionswhich only enables bypassing as an option, this flag activates it immediately. Recommended only for sandboxed environments with no internet access.
Changed
- Bundled CLI version bumped to 2.1.59 — Updated from 2.1.49 to 2.1.59.
--setting-sourcesalways sent — The SDK now always sends--setting-sources ""when no setting sources are configured, matching the Python SDK behavior. This prevents unintended default setting source loading.
[0.23.0] - 2026-02-22 | CC 2.1.49
Added
:request_timeoutoption — Configurable wall-clock timeout for entire requests from start to finish. Previously hardcoded at 300 seconds, making long-running agentic tasks (MCP tool calls, large file generation) impossible beyond 5 minutes. Available at session, query, and app-config levels. ([d1b6f02])
[0.22.0] - 2026-02-20 | CC 2.1.49
Added
:maxeffort level — The:effortoption now accepts:maxin addition to:low,:medium, and:high, aligning with the Python SDK.
Changed
- Bundled CLI version bumped to 2.1.49 — Updated from 2.1.42 to 2.1.49.
Fixed
- Doc warnings for hidden Hook.Response module — Fixed references in the hooks guide that generated documentation warnings. ([6402c7a])
- Documentation guides synced with official Agent SDK docs — Updated 16 guides to match the latest official documentation, including restructured file-checkpointing, new hook fields, fixed broken plugin links, and updated terminology. ([67f7d52])
[0.21.0] - 2026-02-14 | CC 2.1.42
Added
:thinkingoption — Idiomatic Elixir API for extended thinking configuration. Supports:adaptive,:disabled, and{:enabled, budget_tokens: N}. Takes precedence over the now-deprecated:max_thinking_tokens. ([fa6b39d]):effortoption — Control effort level per session or query with:low,:medium, or:high. ([fa6b39d])callerfield onToolUseBlock— Parses the optionalcallermetadata from tool use content blocks. ([93de892])speedfield onResultMessageusage — Captures thespeedfield from CLI usage data when present. ([93de892])context_managementon stream events —PartialAssistantMessagenow parsescontext_managementdata from stream events. ([93de892]):refusalstop reason —ResultMessagenow parses the"refusal"stop reason from the CLI. ([a7a7cfc])
Changed
- Bundled CLI version bumped to 2.1.42 ([789a813])
:max_thinking_tokensdeprecated — Still works, but emits aLogger.warningdirecting users to the new:thinkingoption. ([fa6b39d])- Hook callback input keys atomized — Hook callbacks now receive atom-keyed maps (e.g.,
%{tool_name: "Bash"}) instead of string-keyed maps. ([0fcc415])
Fixed
:setting_sourcesdocumentation — Corrected example to use strings (["user", "project", "local"]) instead of atoms. ([bc2ba7a])
[0.20.0] - 2026-02-10 | CC 2.1.38
Added
- Assigns for in-process MCP tools — Pass per-session context (e.g.,
current_scopefrom LiveView) to tools via:assignsin the server config. Tools usingexecute/2can readframe.assigns. ([a156aae])- Usage:
mcp_servers: %{"tools" => %{module: MyTools, assigns: %{scope: scope}}} - Tools using
execute/1are unaffected; mix both forms freely in the same server module
- Usage:
Changed
ClaudeCode.Tool.Serverrenamed toClaudeCode.MCP.Server— Unified MCP namespace so all MCP-related modules live underClaudeCode.MCP.*([bda2260])- Update
use ClaudeCode.Tool.Server→use ClaudeCode.MCP.Serverin your tool definitions - The DSL (
tool,field,execute) is unchanged
- Update
- Custom tools guide rewritten — Aligned with official SDK docs structure; in-process tool examples now use the simpler
execute/1form ([5db0e0a])
Removed
ClaudeCode.ToolCallback— Removed the:tool_callbackoption andClaudeCode.ToolCallbackmodule. Use:hookswithPostToolUseevents instead. See the Hooks guide for migration examples.ClaudeCode.MCP.Config— Legacy module for generating temporary MCP config files. The adapter now builds--mcp-configJSON inline. ([bda2260])- Old
ClaudeCode.MCP.Server(HTTP GenServer) — Legacy HTTP-based MCP server wrapper, replaced by the in-process control protocol. ([bda2260])
Fixed
- SDK MCP server initialization failures — Added missing
versionto MCPserverInforesponse and fixed crash on JSONRPC notifications (noidfield). In-process tool servers now connect successfully. ([2c746a1]) - Hermes MCP tool examples in docs — Corrected to use the actual
schema+execute/2API andcomponentregistration instead of the non-functionaldefinition/0+call/1pattern ([dcf2f41])
[0.19.0] - 2026-02-10 | CC 2.1.38
Added
BEAM-native extensibility
Hooks, permissions, and MCP tools that run inside your application process — no external subprocesses required.
- In-process hooks and permission control ([22da55c], [f36b270], [a6034d0], [5faf1f2], [e3bdbc9], [df300a9])
ClaudeCode.Hookbehaviour - Define hook modules implementingcall/2for lifecycle events (PreToolUse, PostToolUse, Stop, UserPromptSubmit, PreCompact, Notification, etc.):can_use_tooloption - Permission callback (module or 2-arity function) invoked before tool execution; returns:allow,{:deny, reason}, or{:allow, updated_input}:hooksoption - Lifecycle hook configurations as a map of event names to matcher/callback pairs
- In-process MCP tool servers ([5c049d4], [2b156c4], [f1a4420])
ClaudeCode.Tool.Servermacro - Concise DSL for declaring tools with typed schemas and execute callbacks, generating HermesServer.ComponentmodulesClaudeCode.MCP.Router- JSONRPC dispatcher that routesinitialize,tools/list, andtools/callrequests to in-process tool modules- Auto-detects
Tool.Servermodules in:mcp_serversand emitstype: "sdk"config, routing through the control protocol instead of spawning a subprocess
Subagents
ClaudeCode.Agentstruct - Idiomatic builder for subagent configurations ([1d0188b])ClaudeCode.Agent.new/1accepts keyword options::name,:description,:prompt,:model,:tools- Pass a list of Agent structs to the
:agentsoption instead of raw maps - Implements
Jason.EncoderandJSON.Encoderprotocols; raw map format still supported
Session control and new options
- ClaudeCode.interrupt/1 - Fire-and-forget signal to cancel a running generation mid-stream ([5c04495])
:extra_args- Pass-through arbitrary CLI flags not covered by named options ([5c04495]):max_buffer_size- Protection against unbounded buffer growth from large JSON responses. Default: 1MB ([5c04495])
[0.18.0] - 2026-02-10 | CC 2.1.37
Breaking
- SDK bundles its own CLI binary by default - The SDK now downloads and manages its own Claude CLI in
priv/bin/, auto-installing on first use. To use a globally installed CLI instead, setcli_path: :globalor pass an explicit path likecli_path: "/usr/local/bin/claude". The bundled version defaults to the latest CLI version tested with the SDK, configurable viacli_version. SeeClaudeCode.Optionsfor details.
# config.exs
config :claude_code, cli_path: :globalAdded
Control protocol
Runtime control of sessions without restarting. See Sessions — Runtime Control.
- ClaudeCode.set_model/2 - Change the model mid-conversation ([7ba2007])
- ClaudeCode.set_permission_mode/2 - Change the permission mode mid-conversation ([7ba2007])
- ClaudeCode.get_mcp_status/1 - Query MCP server connection status ([7ba2007])
- ClaudeCode.get_server_info/1 - Get server info cached from handshake ([228c57f])
- ClaudeCode.rewind_files/2 - Rewind files to a checkpoint. See File Checkpointing. ([7ba2007])
- Returns
{:error, :not_supported}for adapters without control protocol support - Initialize handshake - Adapter sends
initializerequest on startup, transitions through:initializing→:ready. Agents are now delivered through the handshake (matching the Python SDK) instead of as a CLI flag. See Subagents. ([228c57f], [2a4473b])
New options
:sandbox- Sandbox config for bash isolation (map merged into--settings). See Secure Deployment. ([5f48858]):enable_file_checkpointing- Track file changes for rewinding. See File Checkpointing. ([5f48858]):allow_dangerously_skip_permissions- Required guard forpermission_mode: :bypass_permissions. See Permissions. ([c9dc6fa]):file- File resources (repeatable, format:file_id:path) ([d6c1869]):from_pr- Resume session linked to a PR ([d6c1869]):debug/:debug_file- Debug mode with optional filter and log file ([d6c1869])
Adapter system
Swappable backends for different execution environments.
ClaudeCode.Adapterbehaviour - 4 callbacks:start_link/2,send_query/4,health/1,stop/1([1582644])- Adapter notification helpers -
notify_message/2,notify_done/2,notify_error/2,notify_status/2([1704326]) ClaudeCode.health/1 - Check adapter health (
:healthy|:degraded|{:unhealthy, reason}). See Hosting. ([383dda6])
CLI management
mix claude_code.install- Install the bundled CLI binary, auto-updating on version mismatch. ([6e7c837])mix claude_code.path- Print resolved binary path, e.g.$(mix claude_code.path) /login([94b5143])mix claude_code.uninstall- Remove the bundled CLI binary ([6e7c837])
Changed
:cli_pathresolution modes -:bundled(default),:global, or explicit path string. SeeClaudeCode.Options. ([94b5143])- Async adapter provisioning -
start_link/1returns immediately; CLI setup runs in the background. Queries queue until ready. ([f1a0875], [91ee60d], [6a60eb4]) - Schema alignment with CLI v2.1.37 - New fields across message types ([482c603], [42b6c27])
AssistantMessage.error(:authentication_failed,:billing_error,:rate_limit,:invalid_request,:server_error,:unknown)UserMessage.tool_use_result,ResultMessage.stop_reason,AssistantMessageusageinference_geoSystemMessagehandles all subtypes (init, hook_started, hook_response);pluginssupports object format
[0.17.0] 2026-02-01 | CC 2.1.29
Added
:max_thinking_tokensoption - Maximum tokens for thinking blocks (integer)- Available for both session and query options
- Maps to
--max-thinking-tokensCLI flag
:continueoption - Continue the most recent conversation in the current directory (boolean)- Maps to
--continueCLI flag - Aligns with Python/TypeScript SDK
continueoption
- Maps to
:pluginsoption - Load custom plugins from local paths (list of paths or maps)- Accepts
["./my-plugin"]or[%{type: :local, path: "./my-plugin"}] - Plugin type uses atom
:local(only supported type currently) - Maps to multiple
--plugin-dirCLI flags - Aligns with Python/TypeScript SDK
pluginsoption
- Accepts
:output_formatoption - Structured output format configuration (replaces:json_schema)- Format:
%{type: :json_schema, schema: %{...}} - Currently only
:json_schematype is supported - Maps to
--json-schemaCLI flag - Aligns with Python/TypeScript SDK
outputFormatoption
- Format:
context_managementfield in AssistantMessage - Support for context window management metadata in assistant messages ([f4ea348])- CLI installer - Automatic CLI binary management following phoenixframework/esbuild patterns
mix claude_code.install- Mix task to install CLI with--version,--if-missing,--forceflagsClaudeCode.Installermodule for programmatic CLI management- Uses official Anthropic install scripts (https://claude.ai/install.sh)
- Binary resolution checks: explicit path → bundled → PATH → common locations
:cli_pathoption - Specify a custom path to the Claude CLI binary- Configuration options for CLI management:
cli_version- Version to install (default: SDK's tested version)cli_path- Explicit path to CLI binary (highest priority)cli_dir- Directory for downloaded binary (default: priv/bin/)
[0.16.0] - 2026-01-27
Added
:envoption - Pass custom environment variables to the CLI subprocess ([aa2d3eb])- Merge precedence: system env → user
:env→ SDK vars →:api_key - Useful for MCP tools that need specific env vars or custom PATH configurations
- Aligns with Python SDK's environment handling
- Merge precedence: system env → user
[0.15.0] - 2026-01-26
Added
- Session history reading - Read and parse conversation history from session files ([ad737ea])
- ClaudeCode.conversation/2 - Read conversation (user/assistant messages) by session ID
ClaudeCode.History.list_projects/1- List all projects with session historyClaudeCode.History.list_sessions/1- List all sessions for a projectClaudeCode.History.read_session/2- Read all raw entries from a session (low-level)
- JSON encoding for all structs - Implement
Jason.EncoderandJSON.Encoderprotocols ([a511d5c])- All message types: SystemMessage, AssistantMessage, UserMessage, ResultMessage, PartialAssistantMessage, CompactBoundaryMessage
- All content blocks: TextBlock, ThinkingBlock, ToolUseBlock, ToolResultBlock
- Nil values are automatically excluded from encoded output
- String.Chars for messages and content blocks - Use
to_string/1or string interpolation ([b3a9571])TextBlock- returns the text contentThinkingBlock- returns the thinking contentAssistantMessage- concatenates all text blocks from the messagePartialAssistantMessage- returns delta text (empty string for non-text deltas)
Changed
- Conversation message parsing refactored - Extracted to dedicated module with improved error logging ([22c381c])
[0.14.0] - 2026-01-15
Added
:session_idoption - Specify a custom UUID as the session ID for conversations ([2f2c919]):disable_slash_commandsoption - Disable all skills/slash commands ([16f96b4]):no_session_persistenceoption - Disable session persistence so sessions are not saved to disk ([16f96b4])- New permission modes -
:delegate,:dont_ask, and:planadded to:permission_modeoption ([16f96b4]) - New usage tracking fields -
cache_creation,service_tier,web_fetch_requests,cost_usd,context_window,max_output_tokensin result and assistant message usage ([bed060b]) - New system message fields -
claude_code_version,agents,skills,pluginsfor enhanced session metadata ([bed060b])
Fixed
- SystemMessage
slash_commandsandoutput_styleparsing - Fields were always empty/default ([bed060b]) - ResultMessage
model_usageparsing - Per-model token counts and costs were always 0/nil ([bed060b])
[0.13.3] - 2026-01-14
Changed
ResultMessageoptional fields use sensible defaults -model_usagedefaults to%{}andpermission_denialsdefaults to[]instead ofnil([cda582b])
Fixed
ResultMessage.resultis now optional - Error messages from the CLI may contain anerrorsarray instead of aresultfield. The field no longer crashes when nil and displays errors appropriately ([c06e825])
[0.13.2] - 2026-01-08
Fixed
ToolResultBlockcontent parsing - When CLI returns content as a list of text blocks, they are now parsed intoTextBlockstructs instead of raw maps ([5361e2d])
[0.13.1] - 2026-01-07
Changed
- Simplified test stub naming - Default stub name changed from
ClaudeCode.SessiontoClaudeCode([2fd244f])- Config:
adapter: {ClaudeCode.Test, ClaudeCode}instead of{ClaudeCode.Test, ClaudeCode.Session} - Stubs:
ClaudeCode.Test.stub(ClaudeCode, fn ...)instead ofstub(ClaudeCode.Session, fn ...) - Custom names still supported for multiple stub behaviors in same test
- Config:
Added
tool_result/2accepts maps - Maps are automatically JSON-encoded ([6d9fca6])- Example:
ClaudeCode.Test.tool_result(%{status: "success", data: [1, 2, 3]})
- Example:
Fixed
tool_resultcontent format - Content is now[TextBlock.t()]instead of plain string ([dfba539])- Matches MCP
CallToolResultformat where content is an array of content blocks - Fixes compatibility with code expecting
content: [%{"type" => "text", "text" => ...}]
- Matches MCP
[0.13.0] - 2026-01-07
Added
ClaudeCode.Testmodule - Req.Test-style test helpers for mocking Claude responses ([9f78103])stub/2- Register function or static message stubs for test isolationallow/3- Share stubs with spawned processes for async testsset_mode_to_shared/0- Enable shared mode for integration tests- Message helpers:
text/2,tool_use/3,tool_result/2,thinking/2,result/2,system/1 - Auto-generates system/result messages, links tool IDs, unifies session IDs
- Uses
NimbleOwnershipfor process-based isolation withasync: truesupport
ClaudeCode.Test.Factorymodule - Test data generation for all message and content types ([54dcfd7])- Struct factories:
assistant_message/1,user_message/1,result_message/1,system_message/1 - Content block factories:
text_block/1,tool_use_block/1,tool_result_block/1,thinking_block/1 - Stream event factories for partial message testing
- Convenience functions with positional arguments for common cases
- Struct factories:
- Testing guide - Comprehensive documentation for testing ClaudeCode integrations ([7dfe509])
[0.12.0] - 2026-01-07
Added
- New stream helpers for common use cases ([0775bd4])
final_text/1- Returns only the final result text, simplest way to get Claude's answercollect/1- Returns structured summary with text, thinking, tool_calls, and resulttap/2- Side-effect function for logging/monitoring without filtering the streamon_tool_use/2- Callback invoked for each tool use, useful for progress indicators
Changed
collect/1returnstool_callsinstead oftool_uses([7eebfeb])- Now returns
{tool_use, tool_result}tuples pairing each tool invocation with its result - If a tool use has no matching result, the result will be
nil - Migration: Change
summary.tool_usestosummary.tool_callsand update iteration to handle tuples
- Now returns
Removed
buffered_text/1stream helper - Usefinal_text/1orcollect/1instead ([4a1ee97])
[0.11.0] - 2026-01-07
Changed
- Renamed
StreamEventMessagetoPartialAssistantMessage- Aligns with TypeScript SDK naming (SDKPartialAssistantMessage)ClaudeCode.Message.StreamEventMessage→ClaudeCode.Message.PartialAssistantMessage- The struct still uses
type: :stream_eventto match the wire format - Helper function renamed:
stream_event?/1→partial_assistant_message?/1
Added
:fork_sessionoption - Create a new session ID when resuming a conversation- Use with
:resumeto branch a conversation:start_link(resume: session_id, fork_session: true) - Original session continues unchanged, fork gets its own session ID after first query
- Use with
[0.9.0] - 2026-01-06
Changed
- BREAKING: Simplified public API - Renamed and reorganized query functions ([e7ca31a])
query_stream/3→stream/3- Primary API for session-based streaming queriesquery/3(session-based sync) → Removed - Usestream/3insteadquery/2(new) - One-off convenience function with auto session management- Migration: Replace
ClaudeCode.query(session, prompt)withClaudeCode.stream(session, prompt) |> Enum.to_list() - Migration: Replace
ClaudeCode.query_stream(session, prompt)withClaudeCode.stream(session, prompt)
Added
- Concurrent request queuing - Multiple concurrent streams on same session are now properly queued and executed sequentially ([e7ca31a])
Fixed
- Named process handling - Stream cleanup now properly handles named processes (atoms,
:via,:globaltuples) ([e7ca31a])
[0.8.1] - 2026-01-06
Fixed
- Process cleanup on stop - Claude subprocess now properly terminates when calling
ClaudeCode.stop/1([a560ff1])
[0.8.0] - 2026-01-06
Changed
- BREAKING: Renamed message type modules - Added "Message" suffix for clarity
ClaudeCode.Message.Assistant→ClaudeCode.Message.AssistantMessageClaudeCode.Message.User→ClaudeCode.Message.UserMessageClaudeCode.Message.Result→ClaudeCode.Message.ResultMessageClaudeCode.Message.StreamEvent→ClaudeCode.Message.PartialAssistantMessage- New
ClaudeCode.Message.SystemMessageandClaudeCode.Message.CompactBoundaryMessagemessage types
- BREAKING: Renamed content block modules - Added "Block" suffix for consistency
ClaudeCode.Content.Text→ClaudeCode.Content.TextBlockClaudeCode.Content.ToolUse→ClaudeCode.Content.ToolUseBlockClaudeCode.Content.ToolResult→ClaudeCode.Content.ToolResultBlockClaudeCode.Content.Thinking→ClaudeCode.Content.ThinkingBlock
Added
- New system message fields - Support for additional Claude Code features
:output_style- Claude's configured output style:slash_commands- Available slash commands:uuid- Session UUID
- Extended message type fields - Better access to API response metadata
AssistantMessage::priority,:sequence_id,:finalize_stackResultMessage::session_id,:duration_ms,:usage,:parent_message_id,:sequence_idUserMessage::priority,:sequence_id,:finalize_stack
Fixed
:mcp_serversoption validation - Fixed handling of MCP server configurations ([0c7e849])
[0.7.0] - 2026-01-02
Added
:strict_mcp_configoption - Control MCP server loading behavior ([a095516])- When
true, ignores global MCP server configurations - Useful for disabling all MCP tools:
tools: [], strict_mcp_config: true - Or using only built-in tools:
tools: :default, strict_mcp_config: true
- When
Changed
- BREAKING:
ClaudeCode.querynow returns full%Result{}struct instead of just text- Before:
{:ok, "response text"}or{:error, {:claude_error, "message"}} - After:
{:ok, %ClaudeCode.Message.Result{result: "response text", ...}}or{:error, %ClaudeCode.Message.Result{is_error: true, ...}} - Provides access to metadata:
session_id,is_error,subtype,duration_ms,usage, etc. - Migration: Change
{:ok, text}to{:ok, result}and useresult.resultto access the response text ResultimplementsString.Chars, soIO.puts(result)prints just the text
- Before:
Removed
:input_formatoption - No longer exposed in public API ([c7ebab2]):output_formatoption - No longer exposed in public API ([c7ebab2])
[0.6.0] - 2025-12-31
Added
:mcp_serversmodule map format - Pass Hermes modules with custom environment variables ([63d4b72])- Simple form:
%{"tools" => MyApp.MCPServer} - Extended form with env:
%{"tools" => %{module: MyApp.MCPServer, env: %{"DEBUG" => "1"}}} - Custom env is merged with defaults (
MIX_ENV: "prod"), can override MIX_ENV - Updated MCP docs to recommend
mcp_serversas the primary configuration method
- Simple form:
:json_schemaoption - JSON Schema for structured output validation ([485513f])- Accepts a map (auto-encoded to JSON) or pre-encoded JSON string
- Maps to
--json-schemaCLI flag
:max_budget_usdoption - Maximum dollar amount to spend on API calls ([5bf996a])- Accepts float or integer values
- Maps to
--max-budget-usdCLI flag
:toolsoption - Specify available tools from the built-in set ([5bf996a])- Use
:defaultfor all tools,[]to disable all, or a list of tool names - Maps to
--toolsCLI flag
- Use
:agentoption - Agent name for the session ([5bf996a])- Different from
:agentswhich defines custom agent configurations - Maps to
--agentCLI flag
- Different from
:betasoption - Beta headers to include in API requests ([5bf996a])- Accepts a list of beta feature names
- Maps to
--betasCLI flag
Removed
query_async/3- Removed push-based async API in favor ofquery_stream/3query_stream/3provides a more idiomatic Elixir Stream-based API- For push-based messaging (LiveView, GenServers), wrap
query_stream/3in a Task - See Phoenix integration guide for migration examples
- Advanced Streaming API - Removed low-level streaming functions
receive_messages/2- Usequery_stream/3insteadreceive_response/2- Usequery_stream/3 |> ClaudeCode.Stream.until_result()insteadinterrupt/2- To cancel, useTask.shutdown/2on the consuming task
Changed
ClaudeCode.Stream- Now uses pull-based messaging internally instead of process mailbox
[0.5.0] - 2025-12-30
Removed
:permission_handleroption - Removed unimplemented option from session schema
Added
- Persistent streaming mode - Sessions use bidirectional stdin/stdout communication
- Auto-connect on first query, auto-disconnect on session stop
- Multi-turn conversations without subprocess restarts
- New
:resumeoption instart_link/1for resuming sessions - New ClaudeCode.get_session_id/1 and
ClaudeCode.Inputmodule
- Extended thinking support -
ClaudeCode.Content.Thinkingfor reasoning blocks- Stream utilities:
ClaudeCode.Stream.thinking_content/1,ClaudeCode.Stream.thinking_deltas/1 StreamEventhelpers:thinking_delta?/1,get_thinking/1
- Stream utilities:
- MCP servers map option -
:mcp_serversaccepts inline server configurations- Supports
stdio,sse, andhttptransport types
- Supports
- Character-level streaming -
include_partial_messages: trueoption- Stream utilities:
ClaudeCode.Stream.text_deltas/1,ClaudeCode.Stream.content_deltas/1 - Enables real-time streaming for LiveView applications
- Stream utilities:
- Tool callback -
:tool_callbackoption for logging/auditing tool usageClaudeCode.ToolCallbackmodule for correlating tool use and results
- Hermes MCP integration - Expose Elixir tools to Claude via MCP
- Optional dependency:
{:hermes_mcp, "~> 0.14", optional: true} ClaudeCode.MCP.Configfor generating MCP configurationClaudeCode.MCP.Serverfor starting Hermes MCP servers
- Optional dependency:
Changed
- Minimum Elixir version raised to 1.18
ClaudeCode.Stream.filter_type/2now supports:stream_eventand:text_delta
[0.4.0] - 2025-10-02
Added
- Custom agents support -
:agentsoption for defining agent configurations - Settings options -
:settingsand:setting_sourcesfor team settings
Changed
:api_keynow optional - CLI handlesANTHROPIC_API_KEYfallback
Fixed
- CLI streaming with explicit output-format support
[0.3.0] - 2025-06-16
Added
ClaudeCode.Supervisor- Production supervision for multiple Claude sessions- Static named sessions and dynamic session management
- Global, local, and registry-based naming
- OTP supervision with automatic restarts
[0.2.0] - 2025-06-16
Added
ANTHROPIC_API_KEYenvironment variable fallback
Changed
- BREAKING: Renamed API functions:
query_sync/3→query/3query/3→query_stream/3
start_link/1options now optional (defaults to[])
[0.1.0] - 2025-06-16
Added
Complete SDK Implementation (Phases 1-4):
- Session management with GenServer-based architecture
- Synchronous queries with
query_sync/3(renamed toquery/3in later version) - Streaming queries with native Elixir streams via
query/3(renamed toquery_stream/3in later version) - Async queries with
query_async/3for manual message handling - Complete message type parsing (system, assistant, user, result)
- Content block handling (text, tool use, tool result) with proper struct types
- Flattened options API with NimbleOptions validation
- Option precedence system: query > session > app config > defaults
- Application configuration support via
config :claude_code - Comprehensive CLI flag mapping for all Claude Code options
Core Modules:
ClaudeCode- Main interface with session managementClaudeCode.Session- GenServer for CLI subprocess managementClaudeCode.CLI- Binary detection and command buildingClaudeCode.Options- Options validation and CLI conversionClaudeCode.Stream- Stream utilities for real-time processingClaudeCode.Message- Unified message parsingClaudeCode.Content- Content block parsingClaudeCode.Types- Type definitions matching SDK schema
Message Type Support:
- System messages with session initialization
- Assistant messages with nested content structure
- User messages with proper content blocks
- Result messages with error subtypes
- Tool use and tool result content blocks
Streaming Features:
- Native Elixir Stream integration with backpressure handling
- Stream utilities:
text_content/1,tool_uses/1,filter_type/2 - Buffered text streaming with
buffered_text/1 - Concurrent streaming request support
- Proper stream cleanup and error handling
Configuration System:
- 15+ configuration options with full validation
- Support for API key, model, system prompt, allowed tools
- Permission mode options:
:default,:accept_edits,:bypass_permissions - Timeout, max turns, working directory configuration
- Custom permission handler support
- Query-level option overrides
Implementation Details
- Flattened options API for intuitive configuration
- Updated CLI flag mappings to match latest Claude Code CLI
- Enhanced error handling with proper message subtypes
- Shell wrapper implementation to prevent CLI hanging
- Proper JSON parsing for all message types
- Concurrent query isolation with dedicated ports
- Memory management for long-running sessions
- Session continuity across multiple queries
Security
- API keys passed via environment variables only
- Shell command injection prevention with proper escaping
- Subprocess isolation with dedicated ports per query
- No sensitive data in command arguments or logs
Documentation
- Complete module documentation with doctests
- Comprehensive README with installation and usage examples
- Streamlined roadmap focusing on current status and future enhancements
Testing
- 146+ comprehensive tests covering all functionality
- Unit tests for all modules with mock CLI support
- Integration tests with real CLI when available
- Property-based testing for message parsing
- Stream testing with concurrent scenarios
- Coverage reporting with ExCoveralls