Changelog

View Source

All 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.

[Unreleased]

[0.16.0] - 2026-01-27

Added

  • :env option - 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

[0.15.0] - 2026-01-26

Added

  • Session history reading - Read and parse conversation history from session files ([ad737ea])
  • JSON encoding for all structs - Implement Jason.Encoder and JSON.Encoder protocols ([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/1 or string interpolation ([b3a9571])
    • TextBlock - returns the text content
    • ThinkingBlock - returns the thinking content
    • AssistantMessage - concatenates all text blocks from the message
    • PartialAssistantMessage - 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_id option - Specify a custom UUID as the session ID for conversations ([2f2c919])
  • :disable_slash_commands option - Disable all skills/slash commands ([16f96b4])
  • :no_session_persistence option - Disable session persistence so sessions are not saved to disk ([16f96b4])
  • New permission modes - :delegate, :dont_ask, and :plan added to :permission_mode option ([16f96b4])
  • New usage tracking fields - cache_creation, service_tier, web_fetch_requests, cost_usd, context_window, max_output_tokens in result and assistant message usage ([bed060b])
  • New system message fields - claude_code_version, agents, skills, plugins for enhanced session metadata ([bed060b])

Fixed

  • SystemMessage slash_commands and output_style parsing - Fields were always empty/default ([bed060b])
  • ResultMessage model_usage parsing - Per-model token counts and costs were always 0/nil ([bed060b])

[0.13.3] - 2026-01-14

Changed

  • ResultMessage optional fields use sensible defaults - model_usage defaults to %{} and permission_denials defaults to [] instead of nil ([cda582b])

Fixed

  • ResultMessage.result is now optional - Error messages from the CLI may contain an errors array instead of a result field. The field no longer crashes when nil and displays errors appropriately ([c06e825])

[0.13.2] - 2026-01-08

Fixed

  • ToolResultBlock content parsing - When CLI returns content as a list of text blocks, they are now parsed into TextBlock structs instead of raw maps ([5361e2d])

[0.13.1] - 2026-01-07

Changed

  • Simplified test stub naming - Default stub name changed from ClaudeCode.Session to ClaudeCode ([2fd244f])
    • Config: adapter: {ClaudeCode.Test, ClaudeCode} instead of {ClaudeCode.Test, ClaudeCode.Session}
    • Stubs: ClaudeCode.Test.stub(ClaudeCode, fn ...) instead of stub(ClaudeCode.Session, fn ...)
    • Custom names still supported for multiple stub behaviors in same test

Added

  • tool_result/2 accepts maps - Maps are automatically JSON-encoded ([6d9fca6])
    • Example: ClaudeCode.Test.tool_result(%{status: "success", data: [1, 2, 3]})

Fixed

  • tool_result content format - Content is now [TextBlock.t()] instead of plain string ([dfba539])
    • Matches MCP CallToolResult format where content is an array of content blocks
    • Fixes compatibility with code expecting content: [%{"type" => "text", "text" => ...}]

[0.13.0] - 2026-01-07

Added

  • ClaudeCode.Test module - Req.Test-style test helpers for mocking Claude responses ([9f78103])
    • stub/2 - Register function or static message stubs for test isolation
    • allow/3 - Share stubs with spawned processes for async tests
    • set_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 NimbleOwnership for process-based isolation with async: true support
  • ClaudeCode.Test.Factory module - 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
  • 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 answer
    • collect/1 - Returns structured summary with text, thinking, tool_calls, and result
    • tap/2 - Side-effect function for logging/monitoring without filtering the stream
    • on_tool_use/2 - Callback invoked for each tool use, useful for progress indicators

Changed

  • collect/1 returns tool_calls instead of tool_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_uses to summary.tool_calls and update iteration to handle tuples

Removed

  • buffered_text/1 stream helper - Use final_text/1 or collect/1 instead ([4a1ee97])

[0.11.0] - 2026-01-07

Changed

  • Renamed StreamEventMessage to PartialAssistantMessage - Aligns with TypeScript SDK naming (SDKPartialAssistantMessage)
    • ClaudeCode.Message.StreamEventMessageClaudeCode.Message.PartialAssistantMessage
    • The struct still uses type: :stream_event to match the wire format
    • Helper function renamed: stream_event?/1partial_assistant_message?/1

Added

  • :fork_session option - Create a new session ID when resuming a conversation
    • Use with :resume to branch a conversation: start_link(resume: session_id, fork_session: true)
    • Original session continues unchanged, fork gets its own session ID after first query

[0.9.0] - 2026-01-06

Changed

  • BREAKING: Simplified public API - Renamed and reorganized query functions ([e7ca31a])
    • query_stream/3stream/3 - Primary API for session-based streaming queries
    • query/3 (session-based sync) → Removed - Use stream/3 instead
    • query/2 (new) - One-off convenience function with auto session management
    • Migration: Replace ClaudeCode.query(session, prompt) with ClaudeCode.stream(session, prompt) |> Enum.to_list()
    • Migration: Replace ClaudeCode.query_stream(session, prompt) with ClaudeCode.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, :global tuples) ([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

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_stack
    • ResultMessage: :session_id, :duration_ms, :usage, :parent_message_id, :sequence_id
    • UserMessage: :priority, :sequence_id, :finalize_stack

Fixed

  • :mcp_servers option validation - Fixed handling of MCP server configurations ([0c7e849])

[0.7.0] - 2026-01-02

Added

  • :strict_mcp_config option - 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

Changed

  • BREAKING: ClaudeCode.query now 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 use result.result to access the response text
    • Result implements String.Chars, so IO.puts(result) prints just the text

Removed

  • :input_format option - No longer exposed in public API ([c7ebab2])
  • :output_format option - No longer exposed in public API ([c7ebab2])

[0.6.0] - 2025-12-31

Added

  • :mcp_servers module 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_servers as the primary configuration method
  • :json_schema option - JSON Schema for structured output validation ([485513f])
    • Accepts a map (auto-encoded to JSON) or pre-encoded JSON string
    • Maps to --json-schema CLI flag
  • :max_budget_usd option - Maximum dollar amount to spend on API calls ([5bf996a])
    • Accepts float or integer values
    • Maps to --max-budget-usd CLI flag
  • :tools option - Specify available tools from the built-in set ([5bf996a])
    • Use :default for all tools, [] to disable all, or a list of tool names
    • Maps to --tools CLI flag
  • :agent option - Agent name for the session ([5bf996a])
    • Different from :agents which defines custom agent configurations
    • Maps to --agent CLI flag
  • :betas option - Beta headers to include in API requests ([5bf996a])
    • Accepts a list of beta feature names
    • Maps to --betas CLI flag

Removed

  • query_async/3 - Removed push-based async API in favor of query_stream/3
    • query_stream/3 provides a more idiomatic Elixir Stream-based API
    • For push-based messaging (LiveView, GenServers), wrap query_stream/3 in a Task
    • See Phoenix integration guide for migration examples
  • Advanced Streaming API - Removed low-level streaming functions
    • receive_messages/2 - Use query_stream/3 instead
    • receive_response/2 - Use query_stream/3 |> ClaudeCode.Stream.until_result() instead
    • interrupt/2 - To cancel, use Task.shutdown/2 on the consuming task

Changed

  • ClaudeCode.Stream - Now uses pull-based messaging internally instead of process mailbox

[0.5.0] - 2025-12-30

Removed

  • :permission_handler option - Removed unimplemented option from session schema

Added

Changed

[0.4.0] - 2025-10-02

Added

  • Custom agents support - :agents option for defining agent configurations
  • Settings options - :settings and :setting_sources for team settings

Changed

  • :api_key now optional - CLI handles ANTHROPIC_API_KEY fallback

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_KEY environment variable fallback

Changed

  • BREAKING: Renamed API functions:
    • query_sync/3query/3
    • query/3query_stream/3
  • start_link/1 options 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 to query/3 in later version)
    • Streaming queries with native Elixir streams via query/3 (renamed to query_stream/3 in later version)
    • Async queries with query_async/3 for 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:

  • 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
  • Architecture documentation explaining CLI integration
  • 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