claude_agent 0.4.3 → 0.6.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: d5fe04480d4ac9e3510d30da98968e5775161e41fad4bdea29cf57b057c98a23
4
- data.tar.gz: 1aca1e25aadbde128676a0182648df8fb8b6da1e81db8a82d1ea82d035ff00d5
3
+ metadata.gz: 4d11f6fa8fa6ecc4b00e0bb6f7913582d0ac8675f649f2d5b423306660a44247
4
+ data.tar.gz: 1c7259588ea2b823ad06c7f263830418a590b5488c7db3d9d825b3e46b31495a
5
5
  SHA512:
6
- metadata.gz: 4c657079b59bcd095f3216f99da72d14f326df8b44cab8deb9d618bcf22c589978d319e75d33c4bc8876a81deb77e89f93a28b9d45a08f95e37952a05cf753f0
7
- data.tar.gz: 9992a0c69e842bd7fd11556b00c8944ff69eb14d418cd8b2cb81ce36cf8cdd74d46f58bd08651e47f028e3b9fe35d98c16bb52f9b3953b513781b1070d426ee5
6
+ metadata.gz: e57643b8293c0cba79fb96322daa1c8fd08a068664f63bad5a6787f9731e60232ff0ee806698ff79707c4a000dd600bfc1e459ea9a0933e7685e5b5fefd87911
7
+ data.tar.gz: 6ac435262b2489ef696db91db6440e8df9f8000e09a46b97cc80decdda1b04cedfcd561a6d56e8b09aa8d373fa223f1ecdad2ff08f82ba9ea350375dd5772eed
data/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2026-01-30
11
+
12
+ ### Added
13
+ - `FilesPersistedEvent` message type for file persistence confirmation (TypeScript SDK v0.2.25 parity)
14
+ - `claudeai-proxy` MCP server type support via Hash-based config passthrough
15
+
16
+ ### Changed
17
+ - Updated SPEC.md to reference TypeScript SDK v0.2.25 and Python SDK v0.1.25
18
+
19
+ ## [0.5.0] - 2026-01-25
20
+
21
+ ### Added
22
+ - `HookStartedMessage` for hook lifecycle visibility
23
+ - `HookProgressMessage` for hook progress updates
24
+ - `ToolUseSummaryMessage` for tool use summaries
25
+ - `mcp_reconnect` and `mcp_toggle` control methods for MCP server lifecycle management
26
+ - `hook_id`, `output`, and `outcome` fields on `HookResponseMessage`
27
+ - Helper methods on `HookResponseMessage`: `success?`, `error?`, `cancelled?`
28
+
10
29
  ## [0.4.3] - 2026-01-18
11
30
 
12
31
  ### Changed
data/SPEC.md CHANGED
@@ -3,10 +3,12 @@
3
3
  This document provides a comprehensive specification of the Claude Agent SDK, comparing feature parity across the official TypeScript and Python SDKs with this Ruby implementation.
4
4
 
5
5
  **Reference Versions:**
6
- - TypeScript SDK: v0.2.12 (npm package)
7
- - Python SDK: v0.1.20 from GitHub (commit 05d2eb4)
6
+ - TypeScript SDK: v0.2.25 (npm package)
7
+ - Python SDK: v0.1.25 from GitHub (commit 1bf665c)
8
8
  - Ruby SDK: This repository
9
9
 
10
+ **Last Updated:** 2026-01-30
11
+
10
12
  ---
11
13
 
12
14
  ## Table of Contents
@@ -58,15 +60,15 @@ Configuration options for SDK queries and clients.
58
60
  | `strictMcpConfig` | ✅ | ❌ | ✅ | Strict validation of MCP config |
59
61
  | `hooks` | ✅ | ✅ | ✅ | Hook callbacks |
60
62
  | `agents` | ✅ | ✅ | ✅ | Custom subagent definitions |
63
+ | `agent` | ✅ | ❌ | ✅ | Agent name for main thread |
61
64
  | `cwd` | ✅ | ✅ | ✅ | Working directory |
62
65
  | `additionalDirectories` | ✅ | ✅ | ✅ | Extra allowed directories |
63
66
  | `env` | ✅ | ✅ | ✅ | Environment variables |
64
67
  | `sandbox` | ✅ | ✅ | ✅ | Sandbox settings |
65
- | `settings` | ✅ | | ✅ | Settings file path or JSON string (e.g., plansDirectory) |
68
+ | `settings` | ✅ | | ✅ | Settings file path or JSON string (e.g., plansDirectory) |
66
69
  | `settingSources` | ✅ | ✅ | ✅ | Which settings to load |
67
70
  | `plugins` | ✅ | ✅ | ✅ | Plugin configurations |
68
71
  | `betas` | ✅ | ✅ | ✅ | Beta features (e.g., context-1m-2025-08-07) |
69
- | `agent` | ✅ | ❌ | ✅ | Agent name for main thread |
70
72
  | `abortController` | ✅ | ❌ | ✅ | Cancellation controller |
71
73
  | `stderr` | ✅ | ✅ | ✅ | Stderr callback |
72
74
  | `spawnClaudeCodeProcess` | ✅ | ❌ | ✅ | Custom spawn function |
@@ -85,20 +87,24 @@ Configuration options for SDK queries and clients.
85
87
 
86
88
  Messages exchanged between SDK and CLI.
87
89
 
88
- | Message Type | TypeScript | Python | Ruby | Notes |
89
- |--------------------------|:----------:|:------:|:----:|---------------------------------|
90
- | `UserMessage` | ✅ | ✅ | ✅ | User input |
91
- | `UserMessageReplay` | ✅ | ❌ | ✅ | Replayed user message on resume |
92
- | `AssistantMessage` | ✅ | ✅ | ✅ | Claude response |
93
- | `SystemMessage` | ✅ | ✅ | ✅ | System/init messages |
94
- | `ResultMessage` | ✅ | ✅ | ✅ | Final result with usage |
95
- | `StreamEvent` | ✅ | ✅ | ✅ | Partial streaming events |
96
- | `CompactBoundaryMessage` | ✅ | ❌ | ✅ | Conversation compaction marker |
97
- | `StatusMessage` | ✅ | ❌ | ✅ | Status updates (compacting) |
98
- | `ToolProgressMessage` | ✅ | ❌ | ✅ | Long-running tool progress |
99
- | `HookResponseMessage` | ✅ | ❌ | ✅ | Hook execution output |
100
- | `AuthStatusMessage` | ✅ | ❌ | ✅ | Authentication status |
101
- | `TaskNotificationMessage`| ✅ | ❌ | ✅ | Background task completion |
90
+ | Message Type | TypeScript | Python | Ruby | Notes |
91
+ |---------------------------|:----------:|:------:|:----:|------------------------------------|
92
+ | `UserMessage` | ✅ | ✅ | ✅ | User input |
93
+ | `UserMessageReplay` | ✅ | ❌ | ✅ | Replayed user message on resume |
94
+ | `AssistantMessage` | ✅ | ✅ | ✅ | Claude response |
95
+ | `SystemMessage` | ✅ | ✅ | ✅ | System/init messages |
96
+ | `ResultMessage` | ✅ | ✅ | ✅ | Final result with usage |
97
+ | `StreamEvent` | ✅ | ✅ | ✅ | Partial streaming events |
98
+ | `CompactBoundaryMessage` | ✅ | ❌ | ✅ | Conversation compaction marker |
99
+ | `StatusMessage` | ✅ | ❌ | ✅ | Status updates (compacting) |
100
+ | `ToolProgressMessage` | ✅ | ❌ | ✅ | Long-running tool progress |
101
+ | `HookStartedMessage` | ✅ | ❌ | ✅ | Hook execution started |
102
+ | `HookProgressMessage` | ✅ | ❌ | ✅ | Hook progress during execution |
103
+ | `HookResponseMessage` | ✅ | ❌ | ✅ | Hook execution output |
104
+ | `AuthStatusMessage` | ✅ | ❌ | ✅ | Authentication status |
105
+ | `TaskNotificationMessage` | ✅ | ❌ | ✅ | Background task completion |
106
+ | `ToolUseSummaryMessage` | ✅ | ❌ | ✅ | Summary of tool use (collapsed) |
107
+ | `FilesPersistedEvent` | ✅ | ❌ | ✅ | File persistence confirmation |
102
108
 
103
109
  ### Message Fields
104
110
 
@@ -131,6 +137,34 @@ Messages exchanged between SDK and CLI.
131
137
  | `error_max_budget_usd` | ✅ | ✅ | ✅ | Budget exceeded |
132
138
  | `error_max_structured_output_retries` | ✅ | ❌ | ✅ | Structured output retries exceeded |
133
139
 
140
+ #### HookResponseMessage Fields
141
+
142
+ | Field | TypeScript | Python | Ruby | Notes |
143
+ |--------------|:----------:|:------:|:----:|------------------------------------------|
144
+ | `uuid` | ✅ | ❌ | ✅ | Message UUID |
145
+ | `session_id` | ✅ | ❌ | ✅ | Session ID |
146
+ | `hook_id` | ✅ | ❌ | ✅ | Unique hook execution ID |
147
+ | `hook_name` | ✅ | ❌ | ✅ | Hook name |
148
+ | `hook_event` | ✅ | ❌ | ✅ | Event type (PreToolUse, PostToolUse...) |
149
+ | `output` | ✅ | ❌ | ✅ | Combined output string |
150
+ | `stdout` | ✅ | ❌ | ✅ | Standard output |
151
+ | `stderr` | ✅ | ❌ | ✅ | Standard error |
152
+ | `exit_code` | ✅ | ❌ | ✅ | Hook process exit code |
153
+ | `outcome` | ✅ | ❌ | ✅ | 'success' / 'error' / 'cancelled' |
154
+
155
+ #### HookProgressMessage Fields
156
+
157
+ | Field | TypeScript | Python | Ruby | Notes |
158
+ |--------------|:----------:|:------:|:----:|------------------------------------------|
159
+ | `uuid` | ✅ | ❌ | ✅ | Message UUID |
160
+ | `session_id` | ✅ | ❌ | ✅ | Session ID |
161
+ | `hook_id` | ✅ | ❌ | ✅ | Unique hook execution ID |
162
+ | `hook_name` | ✅ | ❌ | ✅ | Hook name |
163
+ | `hook_event` | ✅ | ❌ | ✅ | Event type |
164
+ | `output` | ✅ | ❌ | ✅ | Combined output so far |
165
+ | `stdout` | ✅ | ❌ | ✅ | Standard output so far |
166
+ | `stderr` | ✅ | ❌ | ✅ | Standard error so far |
167
+
134
168
  ---
135
169
 
136
170
  ## 3. Content Blocks
@@ -179,12 +213,14 @@ Bidirectional control protocol for SDK-CLI communication.
179
213
  | `can_use_tool` | ✅ | ✅ | ✅ | Permission callback |
180
214
  | `hook_callback` | ✅ | ✅ | ✅ | Execute hook callback |
181
215
  | `set_permission_mode` | ✅ | ✅ | ✅ | Change permission mode |
182
- | `set_model` | ✅ | | ✅ | Change model |
216
+ | `set_model` | ✅ | | ✅ | Change model |
183
217
  | `set_max_thinking_tokens` | ✅ | ❌ | ✅ | Change thinking tokens limit |
184
218
  | `rewind_files` | ✅ | ✅ | ✅ | Rewind file checkpoints |
185
219
  | `mcp_message` | ✅ | ✅ | ✅ | Route MCP message |
186
220
  | `mcp_set_servers` | ✅ | ❌ | ✅ | Dynamically set MCP servers |
187
- | `mcp_status` | ✅ | | ✅ | Get MCP server status |
221
+ | `mcp_status` | ✅ | | ✅ | Get MCP server status |
222
+ | `mcp_reconnect` | ✅ | ❌ | ✅ | Reconnect to MCP server |
223
+ | `mcp_toggle` | ✅ | ❌ | ✅ | Enable/disable MCP server |
188
224
  | `supported_commands` | ✅ | ❌ | ✅ | Get available slash commands |
189
225
  | `supported_models` | ✅ | ❌ | ✅ | Get available models |
190
226
  | `account_info` | ✅ | ❌ | ✅ | Get account information |
@@ -212,7 +248,7 @@ Event hooks for intercepting and modifying SDK behavior.
212
248
  |----------------------|:----------:|:------:|:----:|---------------------------|
213
249
  | `PreToolUse` | ✅ | ✅ | ✅ | Before tool execution |
214
250
  | `PostToolUse` | ✅ | ✅ | ✅ | After tool execution |
215
- | `PostToolUseFailure` | ✅ | | ✅ | After tool failure |
251
+ | `PostToolUseFailure` | ✅ | | ✅ | After tool failure |
216
252
  | `Notification` | ✅ | ❌ | ✅ | System notifications |
217
253
  | `UserPromptSubmit` | ✅ | ✅ | ✅ | User message submitted |
218
254
  | `SessionStart` | ✅ | ❌ | ✅ | Session starts |
@@ -230,7 +266,7 @@ Event hooks for intercepting and modifying SDK behavior.
230
266
  |-------------------------------|:----------:|:------:|:----:|
231
267
  | `PreToolUseHookInput` | ✅ | ✅ | ✅ |
232
268
  | `PostToolUseHookInput` | ✅ | ✅ | ✅ |
233
- | `PostToolUseFailureHookInput` | ✅ | | ✅ |
269
+ | `PostToolUseFailureHookInput` | ✅ | | ✅ |
234
270
  | `NotificationHookInput` | ✅ | ❌ | ✅ |
235
271
  | `UserPromptSubmitHookInput` | ✅ | ✅ | ✅ |
236
272
  | `SessionStartHookInput` | ✅ | ❌ | ✅ |
@@ -264,8 +300,8 @@ Event-specific fields returned via `hookSpecificOutput`:
264
300
 
265
301
  | Field | TypeScript | Python | Ruby | Notes |
266
302
  |----------------------------|:----------:|:------:|:----:|------------------------------------|
267
- | `permissionDecision` | ✅ | | ✅ | `allow`, `deny`, or `ask` |
268
- | `permissionDecisionReason` | ✅ | | ✅ | Reason for permission decision |
303
+ | `permissionDecision` | ✅ | | ✅ | `allow`, `deny`, or `ask` |
304
+ | `permissionDecisionReason` | ✅ | | ✅ | Reason for permission decision |
269
305
  | `updatedInput` | ✅ | ✅ | ✅ | Modified tool input |
270
306
  | `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
271
307
 
@@ -273,14 +309,14 @@ Event-specific fields returned via `hookSpecificOutput`:
273
309
 
274
310
  | Field | TypeScript | Python | Ruby | Notes |
275
311
  |------------------------|:----------:|:------:|:----:|----------------------------------|
276
- | `additionalContext` | ✅ | | ✅ | Context string returned to model |
312
+ | `additionalContext` | ✅ | | ✅ | Context string returned to model |
277
313
  | `updatedMCPToolOutput` | ✅ | ❌ | ✅ | Modified MCP tool output |
278
314
 
279
315
  #### PostToolUseFailureHookSpecificOutput
280
316
 
281
317
  | Field | TypeScript | Python | Ruby | Notes |
282
318
  |---------------------|:----------:|:------:|:----:|----------------------------------|
283
- | `additionalContext` | ✅ | | ✅ | Context string returned to model |
319
+ | `additionalContext` | ✅ | | ✅ | Context string returned to model |
284
320
 
285
321
  #### SessionStartHookSpecificOutput
286
322
 
@@ -304,7 +340,7 @@ Event-specific fields returned via `hookSpecificOutput`:
304
340
 
305
341
  | Field | TypeScript | Python | Ruby | Notes |
306
342
  |---------------------|:----------:|:------:|:----:|----------------------------------|
307
- | `additionalContext` | ✅ | | ✅ | Context string returned to model |
343
+ | `additionalContext` | ✅ | | ✅ | Context string returned to model |
308
344
 
309
345
  #### PermissionRequestHookSpecificOutput
310
346
 
@@ -312,6 +348,12 @@ Event-specific fields returned via `hookSpecificOutput`:
312
348
  |------------|:----------:|:------:|:----:|------------------------------------------|
313
349
  | `decision` | ✅ | ❌ | ✅ | `{ behavior: 'allow'/'deny', ... }` obj |
314
350
 
351
+ #### NotificationHookSpecificOutput
352
+
353
+ | Field | TypeScript | Python | Ruby | Notes |
354
+ |---------------------|:----------:|:------:|:----:|----------------------------------|
355
+ | `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
356
+
315
357
  ### Hook Matcher
316
358
 
317
359
  | Field | TypeScript | Python | Ruby |
@@ -395,12 +437,13 @@ Model Context Protocol server support.
395
437
 
396
438
  ### MCP Server Types
397
439
 
398
- | Type | TypeScript | Python | Ruby | Notes |
399
- |---------|:----------:|:------:|:----:|-----------------------|
400
- | `stdio` | ✅ | ✅ | ✅ | Subprocess with stdio |
401
- | `sse` | ✅ | ✅ | ✅ | Server-sent events |
402
- | `http` | ✅ | ✅ | ✅ | HTTP transport |
403
- | `sdk` | ✅ | ✅ | ✅ | In-process SDK server |
440
+ | Type | TypeScript | Python | Ruby | Notes |
441
+ |------------------|:----------:|:------:|:----:|----------------------------------|
442
+ | `stdio` | ✅ | ✅ | ✅ | Subprocess with stdio |
443
+ | `sse` | ✅ | ✅ | ✅ | Server-sent events |
444
+ | `http` | ✅ | ✅ | ✅ | HTTP transport |
445
+ | `sdk` | ✅ | ✅ | ✅ | In-process SDK server |
446
+ | `claudeai-proxy` | ✅ | ❌ | ✅ | Claude.ai proxy server (managed) |
404
447
 
405
448
  ### MCP Server Config Fields
406
449
 
@@ -554,40 +597,41 @@ Public API surface for SDK clients.
554
597
  | One-shot query function | ✅ `query()` | ✅ `query()` | ✅ `ClaudeAgent.query()` | Simple prompts |
555
598
  | Returns async generator | ✅ | ✅ | ✅ (Enumerator) | Streaming messages |
556
599
 
557
- ### Query Control Methods (TypeScript)
600
+ ### Query Control Methods
558
601
 
559
602
  | Method | TypeScript | Python | Ruby | Notes |
560
603
  |--------------------------|:----------:|:------:|:----:|------------------------|
561
- | `interrupt()` | ✅ | | ✅ | Interrupt execution |
562
- | `setPermissionMode()` | ✅ | | ✅ | Change permission mode |
563
- | `setModel()` | ✅ | | ✅ | Change model |
604
+ | `interrupt()` | ✅ | | ✅ | Interrupt execution |
605
+ | `setPermissionMode()` | ✅ | | ✅ | Change permission mode |
606
+ | `setModel()` | ✅ | | ✅ | Change model |
564
607
  | `setMaxThinkingTokens()` | ✅ | ❌ | ✅ | Set thinking limit |
565
608
  | `supportedCommands()` | ✅ | ❌ | ✅ | Get slash commands |
566
609
  | `supportedModels()` | ✅ | ❌ | ✅ | Get available models |
567
- | `mcpServerStatus()` | ✅ | | ✅ | Get MCP status |
610
+ | `mcpServerStatus()` | ✅ | | ✅ | Get MCP status |
568
611
  | `accountInfo()` | ✅ | ❌ | ✅ | Get account info |
569
612
  | `rewindFiles()` | ✅ | ✅ | ✅ | Rewind file changes |
570
613
  | `setMcpServers()` | ✅ | ❌ | ✅ | Dynamic MCP servers |
571
- | `streamInput()` | ✅ | | ✅ | Stream user input |
614
+ | `streamInput()` | ✅ | | ✅ | Stream user input |
615
+ | `close()` | ✅ | ✅ | ✅ | Close query/session |
572
616
 
573
617
  ### Client Class
574
618
 
575
- | Feature | TypeScript | Python | Ruby | Notes |
576
- |----------------------|:----------:|:-------------------:|:-----------------------:|--------------------------------|
577
- | Multi-turn client | ❌ | ✅ `ClaudeSDKClient` | ✅ `ClaudeAgent::Client` | Interactive sessions |
578
- | `connect()` | N/A | ✅ | ✅ | Start session |
579
- | `disconnect()` | N/A | ✅ | ✅ | End session |
580
- | `send_message()` | N/A | ✅ | ✅ | Send user message |
581
- | `receive_response()` | N/A | ✅ | ✅ | Receive until result |
582
- | `stream_input()` | N/A | ❌ | ✅ | Stream input messages |
583
- | `abort!()` | N/A | ❌ | ✅ | Abort operations |
584
- | Control methods | N/A | Partial | ✅ | All TypeScript control methods |
619
+ | Feature | TypeScript | Python | Ruby | Notes |
620
+ |----------------------|:----------:|:-------------------:|:-----------------------:|----------------------------------------------------------------------------------|
621
+ | Multi-turn client | ❌ | ✅ `ClaudeSDKClient` | ✅ `ClaudeAgent::Client` | Interactive sessions |
622
+ | `connect()` | N/A | ✅ | ✅ | Start session |
623
+ | `disconnect()` | N/A | ✅ | ✅ | End session |
624
+ | `send_message()` | N/A | ✅ | ✅ | Send user message |
625
+ | `receive_response()` | N/A | ✅ | ✅ | Receive until result |
626
+ | `stream_input()` | N/A | ❌ | ✅ | Stream input messages |
627
+ | `abort!()` | N/A | ❌ | ✅ | Abort operations |
628
+ | Control methods | N/A | Partial | ✅ | interrupt, setPermissionMode, setModel, rewindFiles (Python); all methods (Ruby) |
585
629
 
586
630
  ### Transport
587
631
 
588
632
  | Feature | TypeScript | Python | Ruby | Notes |
589
633
  |-----------------------|:----------:|:------:|:----:|--------------------------|
590
- | `Transport` interface | ✅ | | ✅ | Transport abstraction |
634
+ | `Transport` interface | ✅ | | ✅ | Transport abstraction |
591
635
  | Process transport | ✅ | ✅ | ✅ | Subprocess communication |
592
636
  | Custom spawn | ✅ | ❌ | ✅ | VM/container support |
593
637
 
@@ -611,24 +655,38 @@ Public API surface for SDK clients.
611
655
  - Adds `deno` as supported executable option
612
656
  - Includes experimental `criticalSystemReminder_EXPERIMENTAL` for agent definitions
613
657
  - `SessionStartHookInput` includes `model` field
614
- - v0.2.12 adds `Setup` hook event for init/maintenance
615
- - v0.2.12 adds `skills` and `maxTurns` to AgentDefinition
616
- - v0.2.12 adds `TaskNotificationMessage` for background task completion
617
- - v0.2.12 adds `user` option to SDKSessionOptions
658
+ - v0.2.12+ adds `Setup` hook event for init/maintenance
659
+ - v0.2.12+ adds `skills` and `maxTurns` to AgentDefinition
660
+ - v0.2.12+ adds `TaskNotificationMessage` for background task completion
661
+ - v0.2.12+ adds `user` option to SDKSessionOptions
662
+ - v0.2.19 adds `mcp_reconnect` and `mcp_toggle` control requests
663
+ - v0.2.19 adds `HookStartedMessage`, `HookProgressMessage`, and `ToolUseSummaryMessage`
664
+ - v0.2.25 adds `SDKFilesPersistedEvent` message type for file persistence confirmation
665
+ - v0.2.25 adds `McpClaudeAIProxyServerConfig` (`claudeai-proxy` type) for managed proxy servers
618
666
 
619
667
  ### Python SDK
620
- - Full source available (v0.1.20)
621
- - Fewer control protocol features than TypeScript
622
- - Does not support SessionStart/SessionEnd/Notification hooks due to setup limitations
668
+ - Full source available (v0.1.25)
669
+ - Now has `Transport` abstract class and several query control methods
670
+ - Supports `interrupt()`, `set_permission_mode()`, `set_model()`, `rewind_files()`, `stream_input()`, `close()`, `get_mcp_status()` in query
671
+ - Client also supports `interrupt()`, `set_permission_mode()`, `set_model()`, `rewind_files()`
672
+ - Does not support SessionStart/SessionEnd/Notification/SubagentStart/PermissionRequest/Setup hooks
623
673
  - Missing several permission modes (delegate, dontAsk)
674
+ - Missing `allowDangerouslySkipPermissions`, `persistSession`, `resumeSessionAt`, `strictMcpConfig`
675
+ - Missing `init`/`initOnly`/`maintenance` Setup hook options
624
676
  - `excludedCommands` in sandbox now supported
625
- - `tool_use_id` now included in PreToolUseHookInput
677
+ - v0.1.25 adds `PostToolUseFailure` hook event support
678
+ - v0.1.25 adds `permissionDecisionReason` to `PreToolUseHookSpecificOutput`
679
+ - `additionalContext` supported in `UserPromptSubmitHookSpecificOutput`
680
+ - `PreToolUseHookInput` does not include `tool_use_id` (unlike TypeScript)
681
+ - `ToolPermissionContext` missing `blockedPath`, `decisionReason`, `toolUseID`, `agentID`
626
682
 
627
683
  ### Ruby SDK (This Repository)
628
- - Full TypeScript SDK feature parity achieved
684
+ - Full TypeScript SDK feature parity
629
685
  - Ruby-idiomatic patterns (Data.define, snake_case)
630
686
  - Complete control protocol support
631
687
  - Dedicated Client class for multi-turn conversations
632
688
  - Full hook event support including all 13 events
633
689
  - Full V2 Session API support (unstable)
634
690
  - `executable`/`executableArgs` marked N/A (JS runtime options not applicable to Ruby)
691
+ - Added: `FilesPersistedEvent` message type (new in TS v0.2.25)
692
+ - `claudeai-proxy` MCP server type handled transparently via Hash-based config passthrough (new in TS v0.2.25)
@@ -289,6 +289,42 @@ module ClaudeAgent
289
289
  @protocol.set_mcp_servers(servers)
290
290
  end
291
291
 
292
+ # Reconnect to an MCP server (TypeScript SDK parity)
293
+ #
294
+ # Attempts to reconnect to a disconnected or errored MCP server.
295
+ #
296
+ # @param server_name [String] Name of the MCP server to reconnect
297
+ # @return [Hash] Response from the CLI
298
+ #
299
+ # @example
300
+ # client.mcp_reconnect("my-server")
301
+ #
302
+ def mcp_reconnect(server_name)
303
+ require_connection!
304
+
305
+ @protocol.mcp_reconnect(server_name)
306
+ end
307
+
308
+ # Enable or disable an MCP server (TypeScript SDK parity)
309
+ #
310
+ # Toggles an MCP server on or off without removing its configuration.
311
+ #
312
+ # @param server_name [String] Name of the MCP server to toggle
313
+ # @param enabled [Boolean] Whether to enable (true) or disable (false) the server
314
+ # @return [Hash] Response from the CLI
315
+ #
316
+ # @example Enable a server
317
+ # client.mcp_toggle("my-server", enabled: true)
318
+ #
319
+ # @example Disable a server
320
+ # client.mcp_toggle("my-server", enabled: false)
321
+ #
322
+ def mcp_toggle(server_name, enabled:)
323
+ require_connection!
324
+
325
+ @protocol.mcp_toggle(server_name, enabled: enabled)
326
+ end
327
+
292
328
  private
293
329
 
294
330
  def require_connection!
@@ -363,6 +363,38 @@ module ClaudeAgent
363
363
  )
364
364
  end
365
365
 
366
+ # Reconnect to an MCP server (TypeScript SDK parity)
367
+ #
368
+ # Attempts to reconnect to a disconnected or errored MCP server.
369
+ #
370
+ # @param server_name [String] Name of the MCP server to reconnect
371
+ # @return [Hash] Response from the CLI
372
+ #
373
+ # @example
374
+ # protocol.mcp_reconnect("my-server")
375
+ #
376
+ def mcp_reconnect(server_name)
377
+ send_control_request(subtype: "mcp_reconnect", serverName: server_name)
378
+ end
379
+
380
+ # Enable or disable an MCP server (TypeScript SDK parity)
381
+ #
382
+ # Toggles an MCP server on or off without removing its configuration.
383
+ #
384
+ # @param server_name [String] Name of the MCP server to toggle
385
+ # @param enabled [Boolean] Whether to enable (true) or disable (false) the server
386
+ # @return [Hash] Response from the CLI
387
+ #
388
+ # @example Enable a server
389
+ # protocol.mcp_toggle("my-server", enabled: true)
390
+ #
391
+ # @example Disable a server
392
+ # protocol.mcp_toggle("my-server", enabled: false)
393
+ #
394
+ def mcp_toggle(server_name, enabled:)
395
+ send_control_request(subtype: "mcp_toggle", serverName: server_name, enabled: enabled)
396
+ end
397
+
366
398
  # Dynamically set MCP servers for this session (TypeScript SDK parity)
367
399
  #
368
400
  # This replaces the current set of dynamically-added MCP servers.
@@ -11,7 +11,7 @@ module ClaudeAgent
11
11
  # Parse a raw message hash into a typed message object
12
12
  #
13
13
  # @param raw [Hash] Raw message from CLI
14
- # @return [UserMessage, UserMessageReplay, AssistantMessage, SystemMessage, ResultMessage, StreamEvent, CompactBoundaryMessage, StatusMessage, ToolProgressMessage, HookResponseMessage, AuthStatusMessage, TaskNotificationMessage]
14
+ # @return [UserMessage, UserMessageReplay, AssistantMessage, SystemMessage, ResultMessage, StreamEvent, CompactBoundaryMessage, StatusMessage, ToolProgressMessage, HookResponseMessage, AuthStatusMessage, TaskNotificationMessage, HookStartedMessage, HookProgressMessage, ToolUseSummaryMessage, FilesPersistedEvent]
15
15
  # @raise [MessageParseError] If message cannot be parsed
16
16
  def parse(raw)
17
17
  type = raw["type"]
@@ -32,6 +32,12 @@ module ClaudeAgent
32
32
  parse_hook_response_message(raw)
33
33
  when "task_notification"
34
34
  parse_task_notification_message(raw)
35
+ when "hook_started"
36
+ parse_hook_started_message(raw)
37
+ when "hook_progress"
38
+ parse_hook_progress_message(raw)
39
+ when "files_persisted"
40
+ parse_files_persisted_event(raw)
35
41
  else
36
42
  parse_system_message(raw)
37
43
  end
@@ -43,6 +49,8 @@ module ClaudeAgent
43
49
  parse_tool_progress_message(raw)
44
50
  when "auth_status"
45
51
  parse_auth_status_message(raw)
52
+ when "tool_use_summary"
53
+ parse_tool_use_summary_message(raw)
46
54
  else
47
55
  raise MessageParseError.new("Unknown message type: #{type}", raw_message: raw)
48
56
  end
@@ -243,11 +251,14 @@ module ClaudeAgent
243
251
  HookResponseMessage.new(
244
252
  uuid: raw["uuid"] || "",
245
253
  session_id: fetch_dual(raw, :session_id, ""),
254
+ hook_id: fetch_dual(raw, :hook_id),
246
255
  hook_name: fetch_dual(raw, :hook_name, ""),
247
256
  hook_event: fetch_dual(raw, :hook_event, ""),
248
257
  stdout: raw["stdout"] || "",
249
258
  stderr: raw["stderr"] || "",
250
- exit_code: fetch_dual(raw, :exit_code)
259
+ output: raw["output"] || "",
260
+ exit_code: fetch_dual(raw, :exit_code),
261
+ outcome: raw["outcome"]
251
262
  )
252
263
  end
253
264
 
@@ -271,5 +282,47 @@ module ClaudeAgent
271
282
  summary: raw["summary"] || ""
272
283
  )
273
284
  end
285
+
286
+ def parse_hook_started_message(raw)
287
+ HookStartedMessage.new(
288
+ uuid: raw["uuid"] || "",
289
+ session_id: fetch_dual(raw, :session_id, ""),
290
+ hook_id: fetch_dual(raw, :hook_id, ""),
291
+ hook_name: fetch_dual(raw, :hook_name, ""),
292
+ hook_event: fetch_dual(raw, :hook_event, "")
293
+ )
294
+ end
295
+
296
+ def parse_hook_progress_message(raw)
297
+ HookProgressMessage.new(
298
+ uuid: raw["uuid"] || "",
299
+ session_id: fetch_dual(raw, :session_id, ""),
300
+ hook_id: fetch_dual(raw, :hook_id, ""),
301
+ hook_name: fetch_dual(raw, :hook_name, ""),
302
+ hook_event: fetch_dual(raw, :hook_event, ""),
303
+ stdout: raw["stdout"] || "",
304
+ stderr: raw["stderr"] || "",
305
+ output: raw["output"] || ""
306
+ )
307
+ end
308
+
309
+ def parse_tool_use_summary_message(raw)
310
+ ToolUseSummaryMessage.new(
311
+ uuid: raw["uuid"] || "",
312
+ session_id: fetch_dual(raw, :session_id, ""),
313
+ summary: raw["summary"] || "",
314
+ preceding_tool_use_ids: fetch_dual(raw, :preceding_tool_use_ids, [])
315
+ )
316
+ end
317
+
318
+ def parse_files_persisted_event(raw)
319
+ FilesPersistedEvent.new(
320
+ uuid: raw["uuid"] || "",
321
+ session_id: fetch_dual(raw, :session_id, ""),
322
+ files: raw["files"] || [],
323
+ failed: raw["failed"] || [],
324
+ processed_at: fetch_dual(raw, :processed_at)
325
+ )
326
+ end
274
327
  end
275
328
  end
@@ -337,30 +337,47 @@ module ClaudeAgent
337
337
  # msg = HookResponseMessage.new(
338
338
  # uuid: "msg-123",
339
339
  # session_id: "session-abc",
340
+ # hook_id: "hook-456",
340
341
  # hook_name: "my-hook",
341
342
  # hook_event: "PreToolUse",
342
343
  # stdout: "Hook output",
343
344
  # stderr: "",
344
- # exit_code: 0
345
+ # output: "Combined output",
346
+ # exit_code: 0,
347
+ # outcome: "success"
345
348
  # )
349
+ # msg.success? # => true
350
+ # msg.error? # => false
351
+ # msg.cancelled? # => false
352
+ #
353
+ # Outcome values:
354
+ # - "success" - Hook completed successfully
355
+ # - "error" - Hook encountered an error
356
+ # - "cancelled" - Hook was cancelled
346
357
  #
347
358
  HookResponseMessage = Data.define(
348
359
  :uuid,
349
360
  :session_id,
361
+ :hook_id,
350
362
  :hook_name,
351
363
  :hook_event,
352
364
  :stdout,
353
365
  :stderr,
354
- :exit_code
366
+ :output,
367
+ :exit_code,
368
+ :outcome
355
369
  ) do
356
370
  def initialize(
357
371
  uuid:,
358
372
  session_id:,
373
+ hook_id: nil,
359
374
  hook_name:,
360
375
  hook_event:,
361
376
  stdout: "",
362
377
  stderr: "",
363
- exit_code: nil
378
+ output: "",
379
+ exit_code: nil,
380
+ outcome: nil
364
381
  )
365
382
  super
366
383
  end
@@ -368,6 +385,24 @@ module ClaudeAgent
368
385
  def type
369
386
  :hook_response
370
387
  end
388
+
389
+ # Check if hook completed successfully
390
+ # @return [Boolean]
391
+ def success?
392
+ outcome == "success"
393
+ end
394
+
395
+ # Check if hook encountered an error
396
+ # @return [Boolean]
397
+ def error?
398
+ outcome == "error"
399
+ end
400
+
401
+ # Check if hook was cancelled
402
+ # @return [Boolean]
403
+ def cancelled?
404
+ outcome == "cancelled"
405
+ end
371
406
  end
372
407
 
373
408
  # Auth status message (TypeScript SDK parity)
@@ -468,6 +503,154 @@ module ClaudeAgent
468
503
  end
469
504
  end
470
505
 
506
+ # Hook started message (TypeScript SDK parity)
507
+ #
508
+ # Sent when a hook execution starts.
509
+ #
510
+ # @example
511
+ # msg = HookStartedMessage.new(
512
+ # uuid: "msg-123",
513
+ # session_id: "session-abc",
514
+ # hook_id: "hook-456",
515
+ # hook_name: "my-hook",
516
+ # hook_event: "PreToolUse"
517
+ # )
518
+ #
519
+ HookStartedMessage = Data.define(
520
+ :uuid,
521
+ :session_id,
522
+ :hook_id,
523
+ :hook_name,
524
+ :hook_event
525
+ ) do
526
+ def initialize(
527
+ uuid:,
528
+ session_id:,
529
+ hook_id:,
530
+ hook_name:,
531
+ hook_event:
532
+ )
533
+ super
534
+ end
535
+
536
+ def type
537
+ :hook_started
538
+ end
539
+ end
540
+
541
+ # Hook progress message (TypeScript SDK parity)
542
+ #
543
+ # Reports progress during hook execution.
544
+ #
545
+ # @example
546
+ # msg = HookProgressMessage.new(
547
+ # uuid: "msg-123",
548
+ # session_id: "session-abc",
549
+ # hook_id: "hook-456",
550
+ # hook_name: "my-hook",
551
+ # hook_event: "PreToolUse",
552
+ # stdout: "Hook output so far...",
553
+ # stderr: "",
554
+ # output: "Combined output"
555
+ # )
556
+ #
557
+ HookProgressMessage = Data.define(
558
+ :uuid,
559
+ :session_id,
560
+ :hook_id,
561
+ :hook_name,
562
+ :hook_event,
563
+ :stdout,
564
+ :stderr,
565
+ :output
566
+ ) do
567
+ def initialize(
568
+ uuid:,
569
+ session_id:,
570
+ hook_id:,
571
+ hook_name:,
572
+ hook_event:,
573
+ stdout: "",
574
+ stderr: "",
575
+ output: ""
576
+ )
577
+ super
578
+ end
579
+
580
+ def type
581
+ :hook_progress
582
+ end
583
+ end
584
+
585
+ # Tool use summary message (TypeScript SDK parity)
586
+ #
587
+ # Contains a summary of tool use for collapsed display.
588
+ #
589
+ # @example
590
+ # msg = ToolUseSummaryMessage.new(
591
+ # uuid: "msg-123",
592
+ # session_id: "session-abc",
593
+ # summary: "Read 3 files",
594
+ # preceding_tool_use_ids: ["tool-1", "tool-2", "tool-3"]
595
+ # )
596
+ #
597
+ ToolUseSummaryMessage = Data.define(
598
+ :uuid,
599
+ :session_id,
600
+ :summary,
601
+ :preceding_tool_use_ids
602
+ ) do
603
+ def initialize(
604
+ uuid:,
605
+ session_id:,
606
+ summary:,
607
+ preceding_tool_use_ids: []
608
+ )
609
+ super
610
+ end
611
+
612
+ def type
613
+ :tool_use_summary
614
+ end
615
+ end
616
+
617
+ # Files persisted event (TypeScript SDK v0.2.25 parity)
618
+ #
619
+ # Sent when files are persisted to storage during a session.
620
+ # Contains lists of successfully persisted files and any failures.
621
+ #
622
+ # @example
623
+ # msg = FilesPersistedEvent.new(
624
+ # uuid: "msg-123",
625
+ # session_id: "session-abc",
626
+ # files: [{ "filename" => "test.rb", "file_id" => "file-456" }],
627
+ # failed: [],
628
+ # processed_at: "2026-01-30T12:00:00Z"
629
+ # )
630
+ # msg.files.first["filename"] # => "test.rb"
631
+ #
632
+ FilesPersistedEvent = Data.define(
633
+ :uuid,
634
+ :session_id,
635
+ :files,
636
+ :failed,
637
+ :processed_at
638
+ ) do
639
+ def initialize(
640
+ uuid:,
641
+ session_id:,
642
+ files: [],
643
+ failed: [],
644
+ processed_at: nil
645
+ )
646
+ super
647
+ end
648
+
649
+ def type
650
+ :files_persisted
651
+ end
652
+ end
653
+
471
654
  # All message types
472
655
  MESSAGE_TYPES = [
473
656
  UserMessage,
@@ -481,6 +664,10 @@ module ClaudeAgent
481
664
  ToolProgressMessage,
482
665
  HookResponseMessage,
483
666
  AuthStatusMessage,
484
- TaskNotificationMessage
667
+ TaskNotificationMessage,
668
+ HookStartedMessage,
669
+ HookProgressMessage,
670
+ ToolUseSummaryMessage,
671
+ FilesPersistedEvent
485
672
  ].freeze
486
673
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeAgent
4
- VERSION = "0.4.3"
4
+ VERSION = "0.6.0"
5
5
  end
data/sig/claude_agent.rbs CHANGED
@@ -393,7 +393,7 @@ module ClaudeAgent
393
393
  CONTENT_BLOCK_TYPES: Array[Class]
394
394
 
395
395
  # Message types
396
- type message = UserMessage | UserMessageReplay | AssistantMessage | SystemMessage | ResultMessage | StreamEvent | CompactBoundaryMessage | StatusMessage | ToolProgressMessage | HookResponseMessage | AuthStatusMessage
396
+ type message = UserMessage | UserMessageReplay | AssistantMessage | SystemMessage | ResultMessage | StreamEvent | CompactBoundaryMessage | StatusMessage | ToolProgressMessage | HookResponseMessage | AuthStatusMessage | TaskNotificationMessage | HookStartedMessage | HookProgressMessage | ToolUseSummaryMessage | FilesPersistedEvent
397
397
 
398
398
  MESSAGE_TYPES: Array[Class]
399
399
 
@@ -534,14 +534,20 @@ module ClaudeAgent
534
534
  class HookResponseMessage
535
535
  attr_reader uuid: String
536
536
  attr_reader session_id: String
537
+ attr_reader hook_id: String?
537
538
  attr_reader hook_name: String
538
539
  attr_reader hook_event: String
539
540
  attr_reader stdout: String
540
541
  attr_reader stderr: String
542
+ attr_reader output: String
541
543
  attr_reader exit_code: Integer?
544
+ attr_reader outcome: String?
542
545
 
543
- def initialize: (uuid: String, session_id: String, hook_name: String, hook_event: String, ?stdout: String, ?stderr: String, ?exit_code: Integer?) -> void
546
+ def initialize: (uuid: String, session_id: String, ?hook_id: String?, hook_name: String, hook_event: String, ?stdout: String, ?stderr: String, ?output: String, ?exit_code: Integer?, ?outcome: String?) -> void
544
547
  def type: () -> :hook_response
548
+ def success?: () -> bool
549
+ def error?: () -> bool
550
+ def cancelled?: () -> bool
545
551
  end
546
552
 
547
553
  # Auth status message (TypeScript SDK parity)
@@ -556,6 +562,72 @@ module ClaudeAgent
556
562
  def type: () -> :auth_status
557
563
  end
558
564
 
565
+ # Task notification message (TypeScript SDK parity)
566
+ class TaskNotificationMessage
567
+ attr_reader uuid: String
568
+ attr_reader session_id: String
569
+ attr_reader task_id: String
570
+ attr_reader status: String
571
+ attr_reader output_file: String
572
+ attr_reader summary: String
573
+
574
+ def initialize: (uuid: String, session_id: String, task_id: String, status: String, output_file: String, summary: String) -> void
575
+ def type: () -> :task_notification
576
+ def completed?: () -> bool
577
+ def failed?: () -> bool
578
+ def stopped?: () -> bool
579
+ end
580
+
581
+ # Hook started message (TypeScript SDK parity)
582
+ class HookStartedMessage
583
+ attr_reader uuid: String
584
+ attr_reader session_id: String
585
+ attr_reader hook_id: String
586
+ attr_reader hook_name: String
587
+ attr_reader hook_event: String
588
+
589
+ def initialize: (uuid: String, session_id: String, hook_id: String, hook_name: String, hook_event: String) -> void
590
+ def type: () -> :hook_started
591
+ end
592
+
593
+ # Hook progress message (TypeScript SDK parity)
594
+ class HookProgressMessage
595
+ attr_reader uuid: String
596
+ attr_reader session_id: String
597
+ attr_reader hook_id: String
598
+ attr_reader hook_name: String
599
+ attr_reader hook_event: String
600
+ attr_reader stdout: String
601
+ attr_reader stderr: String
602
+ attr_reader output: String
603
+
604
+ def initialize: (uuid: String, session_id: String, hook_id: String, hook_name: String, hook_event: String, ?stdout: String, ?stderr: String, ?output: String) -> void
605
+ def type: () -> :hook_progress
606
+ end
607
+
608
+ # Tool use summary message (TypeScript SDK parity)
609
+ class ToolUseSummaryMessage
610
+ attr_reader uuid: String
611
+ attr_reader session_id: String
612
+ attr_reader summary: String
613
+ attr_reader preceding_tool_use_ids: Array[String]
614
+
615
+ def initialize: (uuid: String, session_id: String, summary: String, ?preceding_tool_use_ids: Array[String]) -> void
616
+ def type: () -> :tool_use_summary
617
+ end
618
+
619
+ # Files persisted event (TypeScript SDK v0.2.25 parity)
620
+ class FilesPersistedEvent
621
+ attr_reader uuid: String
622
+ attr_reader session_id: String
623
+ attr_reader files: Array[Hash[String, String]]
624
+ attr_reader failed: Array[Hash[String, String]]
625
+ attr_reader processed_at: String?
626
+
627
+ def initialize: (uuid: String, session_id: String, ?files: Array[Hash[String, String]], ?failed: Array[Hash[String, String]], ?processed_at: String?) -> void
628
+ def type: () -> :files_persisted
629
+ end
630
+
559
631
  # Message parser
560
632
  class MessageParser
561
633
  def initialize: () -> void
@@ -765,6 +837,8 @@ module ClaudeAgent
765
837
  def rewind_files: (String user_message_id, ?dry_run: bool) -> RewindFilesResult
766
838
  def set_max_thinking_tokens: (Integer? tokens) -> Hash[String, untyped]
767
839
  def set_mcp_servers: (Hash[String, untyped] servers) -> McpSetServersResult
840
+ def mcp_reconnect: (String server_name) -> Hash[String, untyped]
841
+ def mcp_toggle: (String server_name, enabled: bool) -> Hash[String, untyped]
768
842
  def supported_commands: () -> Array[SlashCommand]
769
843
  def supported_models: () -> Array[ModelInfo]
770
844
  def mcp_server_status: () -> Array[McpServerStatus]
@@ -798,6 +872,8 @@ module ClaudeAgent
798
872
  def rewind_files: (String user_message_id, ?dry_run: bool) -> RewindFilesResult
799
873
  def set_max_thinking_tokens: (Integer? tokens) -> Hash[String, untyped]
800
874
  def set_mcp_servers: (Hash[String, untyped] servers) -> McpSetServersResult
875
+ def mcp_reconnect: (String server_name) -> Hash[String, untyped]
876
+ def mcp_toggle: (String server_name, enabled: bool) -> Hash[String, untyped]
801
877
  def supported_commands: () -> Array[SlashCommand]
802
878
  def supported_models: () -> Array[ModelInfo]
803
879
  def mcp_server_status: () -> Array[McpServerStatus]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Carr