claude-agent-sdk 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52b6649f2a72ef33e746d168e4016dcc72c1439157fbe5b971edbd55b0a0d404
4
- data.tar.gz: a344cc38d96ef7185630c1e1518a5cf6d08a855f40b39092728236d5a48df50d
3
+ metadata.gz: '03965bed10e6220b6f00d32ad789aa5c743c7c74f5625f046bd58c0137f1ccae'
4
+ data.tar.gz: c1460d6d10d52ddb5e0ece51e3b5eab2c6d5962d8a7ead7a07661e1ee63aaf99
5
5
  SHA512:
6
- metadata.gz: 18a32d856585a36aa39a9aa586829a305c099cd4686a338e6f1df5310490abb81808821940a6be5d6c830a1fc86cb1cd95dab5ca8e2c5737574e3e91da513f5f
7
- data.tar.gz: c6dadb9b32d373e1fac9246b5bafc8456f3779cf0187abceb7bd85ecdd96b823c95c49c751db9bcd4b384ceb34141057b9e48d4540366d1e3d7d951a69e0aa7f
6
+ metadata.gz: 52e72c3cf52957c54965300787f213add70236025b7fd5de309aabba4fcb9243e1ff973141f4c0ae85aefddf3b182ac49a737a2696bd5f57893ca031af70999d
7
+ data.tar.gz: 3472c21997df7a77cf96eafd6f08671f77574321b23cbb8128d81364b2c523b64617c624c63f70a7a64f0bd6e1d3de807430bfd570e12ba989dda80163704417
data/CHANGELOG.md CHANGED
@@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.10.0] - 2026-03-20
9
+
10
+ Port of Python SDK v0.1.48 features for feature parity.
11
+
12
+ ### Added
13
+
14
+ #### Session Mutations
15
+ - `ClaudeAgentSDK.rename_session(session_id:, title:, directory:)` — rename a session by appending a custom-title JSONL entry
16
+ - `ClaudeAgentSDK.tag_session(session_id:, tag:, directory:)` — tag a session (pass `nil` to clear); tags are Unicode-sanitized
17
+ - `SessionMutations` module with `rename_session`, `tag_session`, and internal Unicode sanitization helpers
18
+ - Ported from Python SDK's `_internal/session_mutations.py` with TOCTOU-safe `O_WRONLY | O_APPEND` file operations
19
+
20
+ #### AssistantMessage Usage
21
+ - `usage` attribute on `AssistantMessage` — token usage data from the API response
22
+ - `MessageParser` populates `usage` from `data.dig(:message, :usage)`
23
+
24
+ #### AgentDefinition Fields
25
+ - `skills`, `memory`, `mcp_servers` attributes on `AgentDefinition`
26
+ - Serialized as `skills`, `memory`, `mcpServers` (camelCase) in the CLI wire protocol initialize request
27
+
28
+ #### TaskUsage Typed Class
29
+ - `TaskUsage` class with `total_tokens`, `tool_uses`, `duration_ms` attributes
30
+ - `TaskUsage.from_hash` factory supporting symbol, string, camelCase, and snake_case keys
31
+
32
+ ### Removed
33
+
34
+ #### FGTS Environment Variable
35
+ - Removed auto-setting of `CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING` environment variable when `include_partial_messages` is enabled — Python SDK v0.1.48 reverted this because it causes HTTP 400 errors on LiteLLM proxies, Bedrock, and Vertex with Claude 4.5 models. The `--include-partial-messages` CLI flag remains the correct mechanism.
36
+
8
37
  ## [0.9.0] - 2026-03-12
9
38
 
10
39
  Port of Python SDK v0.1.48 parity improvements.
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/claude-agent-sdk.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/claude-agent-sdk)
8
8
 
9
- ### Feature Parity with Python SDK (v0.1.46)
9
+ ### Feature Parity with Python SDK (v0.1.48)
10
10
 
11
11
  | Feature | Python | Ruby |
12
12
  |---------|:------:|:----:|
@@ -25,11 +25,13 @@
25
25
  | Beta features (1M context) | ✅ | ✅ |
26
26
  | File checkpointing & rewind | ✅ | ✅ |
27
27
  | Session browsing (`list_sessions`, `get_session_messages`) | ✅ | ✅ |
28
+ | Session mutations (`rename_session`, `tag_session`) | ✅ | ✅ |
28
29
  | Task message types (started/progress/notification) | ✅ | ✅ |
29
30
  | MCP server control (reconnect/toggle/stop) | ✅ | ✅ |
30
31
  | Subagent context on hook inputs | ✅ | ✅ |
31
32
  | Typed MCP status response | ✅ | ✅ |
32
33
  | `stop_reason` on `ResultMessage` | ✅ | ✅ |
34
+ | `usage` on `AssistantMessage` | ✅ | ✅ |
33
35
  | Fallback model | ✅ | ✅ |
34
36
  | Plugin support | ✅ | ✅ |
35
37
  | Rails integration (configure block, ActionCable) | — | ✅ |
@@ -137,6 +139,7 @@ Both SDKs spawn `claude` CLI as a subprocess with stream-JSON over stdin/stdout.
137
139
  - [Sandbox Settings](#sandbox-settings)
138
140
  - [File Checkpointing & Rewind](#file-checkpointing--rewind)
139
141
  - [Session Browsing](#session-browsing)
142
+ - [Session Mutations](#session-mutations)
140
143
  - [Rails Integration](#rails-integration)
141
144
  - [Types](#types)
142
145
  - [Error Handling](#error-handling)
@@ -153,7 +156,7 @@ Add this line to your application's Gemfile:
153
156
  gem 'claude-agent-sdk', github: 'ya-luotao/claude-agent-sdk-ruby'
154
157
 
155
158
  # Or use a stable version from RubyGems
156
- gem 'claude-agent-sdk', '~> 0.8.0'
159
+ gem 'claude-agent-sdk', '~> 0.10.0'
157
160
  ```
158
161
 
159
162
  And then execute:
@@ -934,6 +937,39 @@ Each `SessionMessage` includes `type` (`"user"` or `"assistant"`), `uuid`, `sess
934
937
 
935
938
  > **Note:** Session browsing reads `~/.claude/projects/` JSONL files directly. It respects the `CLAUDE_CONFIG_DIR` environment variable and automatically detects git worktrees.
936
939
 
940
+ ## Session Mutations
941
+
942
+ Rename or tag sessions programmatically — no CLI subprocess required.
943
+
944
+ ### Renaming a Session
945
+
946
+ ```ruby
947
+ # Rename a session (appends a custom-title JSONL entry)
948
+ ClaudeAgentSDK.rename_session(
949
+ session_id: '550e8400-e29b-41d4-a716-446655440000',
950
+ title: 'My refactoring session',
951
+ directory: '/path/to/project' # optional
952
+ )
953
+ ```
954
+
955
+ ### Tagging a Session
956
+
957
+ ```ruby
958
+ # Tag a session (Unicode-sanitized before storing)
959
+ ClaudeAgentSDK.tag_session(
960
+ session_id: '550e8400-e29b-41d4-a716-446655440000',
961
+ tag: 'experiment'
962
+ )
963
+
964
+ # Clear a tag
965
+ ClaudeAgentSDK.tag_session(
966
+ session_id: '550e8400-e29b-41d4-a716-446655440000',
967
+ tag: nil
968
+ )
969
+ ```
970
+
971
+ > **Note:** Session mutations use append-only JSONL writes with `O_WRONLY | O_APPEND` (no `O_CREAT`) for TOCTOU safety. They are safe to call while the session is open in a CLI process.
972
+
937
973
  ## Rails Integration
938
974
 
939
975
  The SDK integrates well with Rails applications. Here are common patterns:
@@ -1120,7 +1156,8 @@ class AssistantMessage
1120
1156
  attr_accessor :content, # Array<ContentBlock>
1121
1157
  :model, # String
1122
1158
  :parent_tool_use_id,# String | nil
1123
- :error # String | nil ('authentication_failed', 'billing_error', 'rate_limit', 'invalid_request', 'server_error', 'unknown')
1159
+ :error, # String | nil ('authentication_failed', 'billing_error', 'rate_limit', 'invalid_request', 'server_error', 'unknown')
1160
+ :usage # Hash | nil - Token usage info from the API response
1124
1161
  end
1125
1162
  ```
1126
1163
 
@@ -1276,7 +1313,7 @@ end
1276
1313
  | `HookMatcher` | Hook configuration with matcher pattern and timeout |
1277
1314
  | `PermissionResultAllow` | Permission callback result to allow tool use |
1278
1315
  | `PermissionResultDeny` | Permission callback result to deny tool use |
1279
- | `AgentDefinition` | Agent definition with description, prompt, tools, model |
1316
+ | `AgentDefinition` | Agent definition with description, prompt, tools, model, skills, memory, mcp_servers |
1280
1317
  | `ThinkingConfigAdaptive` | Adaptive thinking mode (32,000 token default budget) |
1281
1318
  | `ThinkingConfigEnabled` | Enabled thinking with explicit `budget_tokens` |
1282
1319
  | `ThinkingConfigDisabled` | Disabled thinking (0 tokens) |
@@ -1290,6 +1327,7 @@ end
1290
1327
  | `McpServerInfo` | MCP server name and version |
1291
1328
  | `McpToolInfo` | MCP tool name, description, and annotations |
1292
1329
  | `McpToolAnnotations` | MCP tool annotation hints (`read_only`, `destructive`, `open_world`) |
1330
+ | `TaskUsage` | Typed usage data (`total_tokens`, `tool_uses`, `duration_ms`) with `from_hash` factory |
1293
1331
  | `SDKSessionInfo` | Session metadata from `list_sessions` |
1294
1332
  | `SessionMessage` | Single message from `get_session_messages` |
1295
1333
  | `SandboxSettings` | Sandbox settings for isolated command execution |
@@ -61,7 +61,8 @@ module ClaudeAgentSDK
61
61
  content: content_blocks,
62
62
  model: data.dig(:message, :model),
63
63
  parent_tool_use_id: data[:parent_tool_use_id],
64
- error: data[:error] # authentication_failed, billing_error, rate_limit, invalid_request, server_error, unknown
64
+ error: data[:error], # authentication_failed, billing_error, rate_limit, invalid_request, server_error, unknown
65
+ usage: data.dig(:message, :usage)
65
66
  )
66
67
  end
67
68
 
@@ -89,7 +89,10 @@ module ClaudeAgentSDK
89
89
  description: agent_def.description,
90
90
  prompt: agent_def.prompt,
91
91
  tools: agent_def.tools,
92
- model: agent_def.model
92
+ model: agent_def.model,
93
+ skills: agent_def.skills,
94
+ memory: agent_def.memory,
95
+ mcpServers: agent_def.mcp_servers
93
96
  }.compact
94
97
  end
95
98
  end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'sessions'
5
+
6
+ module ClaudeAgentSDK
7
+ # Session mutation functions: rename and tag sessions.
8
+ #
9
+ # Ported from Python SDK's _internal/session_mutations.py.
10
+ # Appends typed metadata entries to the session's JSONL file,
11
+ # matching the CLI pattern. Safe to call from any SDK host process.
12
+ module SessionMutations
13
+ module_function
14
+
15
+ # Rename a session by appending a custom-title entry.
16
+ #
17
+ # list_sessions reads the LAST custom-title from the file tail, so
18
+ # repeated calls are safe — the most recent wins.
19
+ #
20
+ # @param session_id [String] UUID of the session to rename
21
+ # @param title [String] New session title (whitespace stripped)
22
+ # @param directory [String, nil] Project directory path
23
+ # @raise [ArgumentError] if session_id is invalid or title is empty
24
+ # @raise [Errno::ENOENT] if the session file cannot be found
25
+ def rename_session(session_id:, title:, directory: nil)
26
+ raise ArgumentError, "Invalid session_id: #{session_id}" unless session_id.match?(Sessions::UUID_RE)
27
+
28
+ stripped = title.strip
29
+ raise ArgumentError, 'title must be non-empty' if stripped.empty?
30
+
31
+ data = "#{JSON.generate({ type: 'custom-title', customTitle: stripped, sessionId: session_id },
32
+ space_size: 0)}\n"
33
+
34
+ append_to_session(session_id, data, directory)
35
+ end
36
+
37
+ # Tag a session. Pass nil to clear the tag.
38
+ #
39
+ # Appends a {type:'tag',tag:<tag>,sessionId:<id>} JSONL entry.
40
+ # Tags are Unicode-sanitized before storing.
41
+ #
42
+ # @param session_id [String] UUID of the session to tag
43
+ # @param tag [String, nil] Tag string, or nil to clear
44
+ # @param directory [String, nil] Project directory path
45
+ # @raise [ArgumentError] if session_id is invalid or tag is empty after sanitization
46
+ # @raise [Errno::ENOENT] if the session file cannot be found
47
+ def tag_session(session_id:, tag:, directory: nil)
48
+ raise ArgumentError, "Invalid session_id: #{session_id}" unless session_id.match?(Sessions::UUID_RE)
49
+
50
+ if tag
51
+ sanitized = sanitize_unicode(tag).strip
52
+ raise ArgumentError, 'tag must be non-empty (use nil to clear)' if sanitized.empty?
53
+
54
+ tag = sanitized
55
+ end
56
+
57
+ data = "#{JSON.generate({ type: 'tag', tag: tag || '', sessionId: session_id },
58
+ space_size: 0)}\n"
59
+
60
+ append_to_session(session_id, data, directory)
61
+ end
62
+
63
+ # -- Private helpers --
64
+
65
+ def append_to_session(session_id, data, directory)
66
+ file_name = "#{session_id}.jsonl"
67
+
68
+ if directory
69
+ append_to_session_in_directory(session_id, data, file_name, directory)
70
+ else
71
+ append_to_session_global(session_id, data, file_name)
72
+ end
73
+ end
74
+
75
+ def append_to_session_in_directory(session_id, data, file_name, directory)
76
+ path = File.realpath(directory).unicode_normalize(:nfc)
77
+
78
+ # Try the exact/prefix-matched project directory first.
79
+ project_dir = Sessions.find_project_dir(path)
80
+ return if project_dir && try_append(File.join(project_dir, file_name), data)
81
+
82
+ # Worktree fallback
83
+ begin
84
+ worktree_paths = Sessions.detect_worktrees(path)
85
+ rescue StandardError
86
+ worktree_paths = []
87
+ end
88
+
89
+ found = worktree_paths.any? do |wt_path|
90
+ next false if wt_path == path
91
+
92
+ wt_project_dir = Sessions.find_project_dir(wt_path)
93
+ wt_project_dir && try_append(File.join(wt_project_dir, file_name), data)
94
+ end
95
+ return if found
96
+
97
+ raise Errno::ENOENT, "Session #{session_id} not found in project directory for #{directory}"
98
+ end
99
+
100
+ def append_to_session_global(session_id, data, file_name)
101
+ projects_dir = File.join(Sessions.config_dir, 'projects')
102
+ raise Errno::ENOENT, "Session #{session_id} not found (no projects directory)" unless File.directory?(projects_dir)
103
+
104
+ found = Dir.children(projects_dir).any? do |child|
105
+ candidate = File.join(projects_dir, child, file_name)
106
+ try_append(candidate, data)
107
+ end
108
+ return if found
109
+
110
+ raise Errno::ENOENT, "Session #{session_id} not found in any project directory"
111
+ end
112
+
113
+ # Try appending to a path.
114
+ #
115
+ # Opens with WRONLY | APPEND (no CREAT) so the open fails with
116
+ # ENOENT if the file does not exist. Returns false for missing
117
+ # files or zero-byte files; true on successful write.
118
+ def try_append(path, data)
119
+ file = File.open(path, File::WRONLY | File::APPEND)
120
+ begin
121
+ return false if file.stat.size.zero? # rubocop:disable Style/ZeroLengthPredicate
122
+
123
+ file.write(data)
124
+ true
125
+ ensure
126
+ file.close
127
+ end
128
+ rescue Errno::ENOENT, Errno::ENOTDIR
129
+ false
130
+ end
131
+
132
+ # Unicode sanitization — ported from Python SDK / TS sanitization.ts
133
+ #
134
+ # Iteratively applies NFKC normalization and strips format/private-use/
135
+ # unassigned characters until stable (max 10 iterations).
136
+ UNICODE_STRIP_RE = /[\u200b-\u200f\u202a-\u202e\u2066-\u2069\ufeff\ue000-\uf8ff]/
137
+ FORMAT_CATEGORIES = %w[Cf Co Cn].freeze
138
+
139
+ def sanitize_unicode(value)
140
+ current = value
141
+ 10.times do
142
+ previous = current
143
+ current = current.unicode_normalize(:nfkc)
144
+ current = current.each_char.reject { |c| FORMAT_CATEGORIES.include?(unicode_category(c)) }.join
145
+ current = current.gsub(UNICODE_STRIP_RE, '')
146
+ break if current == previous
147
+ end
148
+ current
149
+ end
150
+
151
+ # Returns the Unicode general category for a character (e.g., 'Cf', 'Lu', 'Ll').
152
+ def unicode_category(char)
153
+ # Ruby doesn't have a built-in unicodedata.category(), but we can
154
+ # check the specific categories we care about using regex properties.
155
+ return 'Cf' if char.match?(/\p{Cf}/)
156
+ return 'Co' if char.match?(/\p{Co}/)
157
+ return 'Cn' if char.match?(/\p{Cn}/)
158
+
159
+ 'Other'
160
+ end
161
+
162
+ private_class_method :append_to_session, :append_to_session_in_directory,
163
+ :append_to_session_global, :try_append, :sanitize_unicode, :unicode_category
164
+ end
165
+ end
@@ -491,9 +491,12 @@ module ClaudeAgentSDK
491
491
  end
492
492
 
493
493
  private_class_method :list_sessions_for_directory, :list_all_sessions,
494
- :deduplicate_sessions, :detect_worktrees,
494
+ :deduplicate_sessions,
495
495
  :find_session_file, :parse_jsonl_entries,
496
496
  :build_conversation_chain, :walk_to_leaf, :walk_to_root,
497
497
  :filter_visible_messages, :read_head_tail, :build_session_info
498
+
499
+ # These remain accessible for SessionMutations:
500
+ # config_dir, sanitize_path, find_project_dir, detect_worktrees
498
501
  end
499
502
  end
@@ -181,9 +181,6 @@ module ClaudeAgentSDK
181
181
  process_env = ENV.to_h.merge('CLAUDECODE' => nil, 'CLAUDE_AGENT_SDK_VERSION' => VERSION).merge(custom_env)
182
182
  process_env['CLAUDE_CODE_ENTRYPOINT'] ||= 'sdk-rb'
183
183
  process_env['CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING'] = 'true' if @options.enable_file_checkpointing
184
- if @options.include_partial_messages
185
- process_env['CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING'] ||= '1'
186
- end
187
184
  process_env['PWD'] = @cwd.to_s if @cwd
188
185
 
189
186
  # Determine stderr handling
@@ -104,13 +104,14 @@ module ClaudeAgentSDK
104
104
 
105
105
  # Assistant message with content blocks
106
106
  class AssistantMessage
107
- attr_accessor :content, :model, :parent_tool_use_id, :error
107
+ attr_accessor :content, :model, :parent_tool_use_id, :error, :usage
108
108
 
109
- def initialize(content:, model:, parent_tool_use_id: nil, error: nil)
109
+ def initialize(content:, model:, parent_tool_use_id: nil, error: nil, usage: nil)
110
110
  @content = content
111
111
  @model = model
112
112
  @parent_tool_use_id = parent_tool_use_id
113
113
  @error = error # One of: authentication_failed, billing_error, rate_limit, invalid_request, server_error, unknown
114
+ @usage = usage # Token usage info from the API response
114
115
  end
115
116
  end
116
117
 
@@ -127,6 +128,27 @@ module ClaudeAgentSDK
127
128
  # Task lifecycle notification statuses
128
129
  TASK_NOTIFICATION_STATUSES = %w[completed failed stopped].freeze
129
130
 
131
+ # Typed usage data for task progress and notifications
132
+ class TaskUsage
133
+ attr_accessor :total_tokens, :tool_uses, :duration_ms
134
+
135
+ def initialize(total_tokens: 0, tool_uses: 0, duration_ms: 0)
136
+ @total_tokens = total_tokens
137
+ @tool_uses = tool_uses
138
+ @duration_ms = duration_ms
139
+ end
140
+
141
+ def self.from_hash(hash)
142
+ return nil unless hash.is_a?(Hash)
143
+
144
+ new(
145
+ total_tokens: hash[:total_tokens] || hash['total_tokens'] || hash[:totalTokens] || hash['totalTokens'] || 0,
146
+ tool_uses: hash[:tool_uses] || hash['tool_uses'] || hash[:toolUses] || hash['toolUses'] || 0,
147
+ duration_ms: hash[:duration_ms] || hash['duration_ms'] || hash[:durationMs] || hash['durationMs'] || 0
148
+ )
149
+ end
150
+ end
151
+
130
152
  # Task started system message (subagent/background task started)
131
153
  class TaskStartedMessage < SystemMessage
132
154
  attr_accessor :task_id, :description, :uuid, :session_id, :tool_use_id, :task_type
@@ -285,13 +307,16 @@ module ClaudeAgentSDK
285
307
 
286
308
  # Agent definition configuration
287
309
  class AgentDefinition
288
- attr_accessor :description, :prompt, :tools, :model
310
+ attr_accessor :description, :prompt, :tools, :model, :skills, :memory, :mcp_servers
289
311
 
290
- def initialize(description:, prompt:, tools: nil, model: nil)
312
+ def initialize(description:, prompt:, tools: nil, model: nil, skills: nil, memory: nil, mcp_servers: nil)
291
313
  @description = description
292
314
  @prompt = prompt
293
315
  @tools = tools
294
316
  @model = model
317
+ @skills = skills # Array of skill names
318
+ @memory = memory # One of: 'user', 'project', 'local'
319
+ @mcp_servers = mcp_servers # Array of server names or config hashes
295
320
  end
296
321
  end
297
322
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeAgentSDK
4
- VERSION = '0.9.0'
4
+ VERSION = '0.10.0'
5
5
  end
@@ -11,6 +11,7 @@ require_relative 'claude_agent_sdk/query'
11
11
  require_relative 'claude_agent_sdk/sdk_mcp_server'
12
12
  require_relative 'claude_agent_sdk/streaming'
13
13
  require_relative 'claude_agent_sdk/sessions'
14
+ require_relative 'claude_agent_sdk/session_mutations'
14
15
  require 'async'
15
16
  require 'securerandom'
16
17
 
@@ -78,6 +79,22 @@ module ClaudeAgentSDK
78
79
  Sessions.get_session_messages(session_id: session_id, directory: directory, limit: limit, offset: offset)
79
80
  end
80
81
 
82
+ # Rename a session by appending a custom-title entry
83
+ # @param session_id [String] UUID of the session to rename
84
+ # @param title [String] New session title
85
+ # @param directory [String, nil] Project directory path
86
+ def self.rename_session(session_id:, title:, directory: nil)
87
+ SessionMutations.rename_session(session_id: session_id, title: title, directory: directory)
88
+ end
89
+
90
+ # Tag a session. Pass nil to clear the tag.
91
+ # @param session_id [String] UUID of the session to tag
92
+ # @param tag [String, nil] Tag string, or nil to clear
93
+ # @param directory [String, nil] Project directory path
94
+ def self.tag_session(session_id:, tag:, directory: nil)
95
+ SessionMutations.tag_session(session_id: session_id, tag: tag, directory: directory)
96
+ end
97
+
81
98
  def self.query(prompt:, options: nil, &block)
82
99
  return enum_for(:query, prompt: prompt, options: options) unless block
83
100
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude-agent-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Community Contributors
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-03-12 00:00:00.000000000 Z
10
+ date: 2026-03-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: async
@@ -109,6 +109,7 @@ files:
109
109
  - lib/claude_agent_sdk/message_parser.rb
110
110
  - lib/claude_agent_sdk/query.rb
111
111
  - lib/claude_agent_sdk/sdk_mcp_server.rb
112
+ - lib/claude_agent_sdk/session_mutations.rb
112
113
  - lib/claude_agent_sdk/sessions.rb
113
114
  - lib/claude_agent_sdk/streaming.rb
114
115
  - lib/claude_agent_sdk/subprocess_cli_transport.rb