Repository navigation
v0.37.0
The last 0.x release before 1.0 (roadmap). No runtime behaviour changes — only new warnings for things 1.0 will reject. Run your suite on 0.37 with warnings visible before moving to 1.0:
- A misspelled key on a value type you build (
HookMatcher,AgentDefinition,SandboxSettings, MCP server configs, permission results, hook outputs, …) now warns once, pointing at your call; 1.0 raisesArgumentError. msg[:name]/ camelCase readers reaching a non-attribute method (e.g.msg[:to_h]) warn once; in 1.0 they only reach attributes.- The 1.0 SemVer surface is now visible: SDK internals are tagged
@api privateand hidden from the API docs, and the documented contracts (Hash-key rule,mcp_status/context_usagereturn Hashes,Type#[]) are written down.
Changed
- Docs: pre-1.0 contracts written down (#126). No code changes.
Client#mcp_status/#get_mcp_statusand#context_usage/#get_context_usagereturn the CLI's raw Hash with camelCase Symbol keys.docs/types.mdhad describedMcpStatusResponseas the response type; it is the optional typed view, viaMcpStatusResponse.parse(client.mcp_status), and there is no typed context-usage class (docs/client.md). A new "Hash keys" section indocs/types.mdstates one rule: Hashes passed through from the live CLI stream (origin,usage,model_usage, hooktool_input,can_use_toolinput, SDK MCP tool args, control responses) have Symbol keys spelled as on the wire, and Hashes read from transcripts or aSessionStore(SessionMessage#message,get_subagent_metadata, store keys and entries) have String keys. The docs, examples and bundled skill drop theirh[:key] || h['key']fallbacks in favour of the one correct form.Type#[],#[]=and the camelCase readers are documented as public API, including that#[]=changes the object you received.docs/sessions.mddocumentsClaudeAgentSDK.project_key_for_directoryandClaudeAgentSDK.fold_session_summaryfor adapter authors, andimport_session_to_store's batching (batch_size:defaults to 500 entries, and a batch also ends at about 1 MiB). - SDK internals are now tagged
@api privateand hidden from the YARD docs (#126). The tagged namespaces areQuery,MessageParser,TranscriptMirrorBatcher,Sessions,SessionMutations,SessionResume,MaterializedResume,SessionSummary,SessionStores,OptionWarningsandFiberBoundary, including everything nested in them. Some public classes also have internal members, and those are tagged individually:SubprocessCLITransport's methods outside theTransportinterface and its constants;CommandBuilder's constants (.newand#buildstay public);CLIInstaller::Http,Platform,ReleaseandMetadataand the installer's constants other thanPINNED_CLI_VERSION;SdkMcpServer#handle_json,#handle_messageandSdkMcpServer::ToolInputSchema;Client#query_handler; andClaudeAgentSDK::OBSERVER_INTERFACE. Their public faces are unchanged:ClaudeAgentSDK.offload,fold_session_summary, the session functions andSDKSessionInfo/SessionMessageremain public. Nothing changes at runtime. No method or constant was renamed, removed or made private, so every existing call keeps working. From 1.0, SemVer coversdocs/and the YARD API without@api private; objects tagged@api privateare not covered and may change in any release.CONTRIBUTING.mdhas a new "What is public API" section. lib/claude_agent_sdk/types.rbis split into one file per area underlib/claude_agent_sdk/types/(messages, hooks, options, ...). The code moved without edits andtypes.rbstill loads every part, sorequire 'claude_agent_sdk/types'and every class and constant are unchanged; no API change (#126).Type's internal machinery is tagged@api privateand leaves the rendered docs:Type#dup_for_options,Type.deep_dup_for_options,Type::OptionValue,Type.inspect_filtered,Type.inspect_filtered_attributes, and the newType.strict_attributes/.strict_attributes?/.declare_attributes/.attribute?/.attribute_names. They are not part of the SemVer surface.Type#[],#[]=, the camelCase readers,#to_h,.wrapand.from_hashstay public (#126).
Deprecated
- Unknown keys on user-constructed types. The value types you build and pass in (option values such as
AgentDefinition,SandboxSettings, the thinking configs and the MCP server configs;HookMatcher; hook outputs;PermissionResultAllow/PermissionResultDeny;PermissionUpdate;PermissionRuleValue) silently dropped a misspelled key, soHookMatcher.new(matchr: 'Bash')quietly built a matcher with nomatcherset..newand#[]=now warn once per class and key, at the caller's line:ClaudeAgentSDK::HookMatcher: unknown attribute :matchr ignored; this will raise ArgumentError in 1.0 (known: hooks, matcher, timeout). In 1.0 they raiseArgumentError, asClaudeAgentOptionsalready does. camelCase and String keys and a type's own discriminator (type,hook_event_name,behavior) are accepted, soklass.new(value.to_h)round-trips silently. Types parsed from CLI output (messages, content blocks, hook inputs) and every construction through.from_hash/.wrapstay lenient, so a newer CLI's extra fields never warn; permission suggestions from the CLI are now hydrated throughPermissionUpdate.wrapfor that reason. Full list indocs/types.md(#126). Type#[],#[]=and camelCase methods reaching something other than an attribute. They are public API for a type's attributes (itsattr_*fields, the backward-compatibleRateLimitEvent#data, predicates such asoptions.forkSession?, and any method your own code adds to a subclass, mixin or instance), but they resolved any public method:msg[:to_h]returned a Hash,msg['freeze']froze the message,msg.toHcalled#to_h. Such a call still works but warns once per class and name, e.g.ClaudeAgentSDK::ResultMessage#[]: :to_h is not an attribute; Type#[] will only read attributes in 1.0. In 1.0 a name that is not an attribute behaves like an undefined one:#[]returnsnil,#[]=ignores it (raises on the types above), a camelCase call raisesNoMethodError, andrespond_to?saysfalse. Names that are not methods at all keep today's behaviour and do not warn.UserMessage#text/AssistantMessage#textare convenience methods, not attributes (#126).
Check your app before 1.0
# warnings are on by default; make sure your test runner doesn't silence them
bundle exec rspec 2>&1 | grep -E "unknown attribute|is not an attribute|deprecated"What's changed
- #133 Split types.rb into lib/claude_agent_sdk/types/ (no API change) — @ya-luotao
- #136 Warn on unknown keys and non-attribute access on Type (0.37; enforced in 1.0) — @ya-luotao
- #134 Tag leaked SDK internals @api private — @ya-luotao
- #135 Write down the pre-1.0 contracts — @ya-luotao
- #137 Turn Metrics back on everywhere; delete .rubocop_todo.yml — @ya-luotao
Roadmap to 1.0: #126
Full Changelog: v0.36.0...v0.37.0
gem install claude-agent-sdk -v 0.37.0