claude_agent 0.7.16 → 0.7.18

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: df8d1374efdac7201f83dd2afc3b0042c44162b5ba58c650305b58c63c60397e
4
- data.tar.gz: 957bd07189e6d3cf46771367088e9897ce993d2d2944d6108afd1352e2f19f01
3
+ metadata.gz: 564803b88efd1e1690c1d44078c2dc9ddf10e8d74fc48cbacee1705843a50ef8
4
+ data.tar.gz: 03e53177abed5def635fad5152f7ec9046e9d16280df70200b9f1b53d8bd647b
5
5
  SHA512:
6
- metadata.gz: 8dc4b9ec494ac9337b7860f4250361366184f6ca983c3b5f9754ac5050966708f0d220a6b5975dff49ab4badd47e6f24b3104467b2a9e511cc3e95114f3cb5fc
7
- data.tar.gz: fe0357e27da9036fe90a740fecaa64eb5ce95736e7c5566cef0e746080eb014e9a55adb17372b34520d1985fa5d838806cc57e395170c8e2e1766a95563c0336
6
+ metadata.gz: a376e0f0ae1f9089500495998a00859c309c24c9256705df1c0310990534881a3faa3b469c1787dbb48ebb30714e40da3444ac8a5229e04c1de85a25332df7db
7
+ data.tar.gz: 35ae9feec317af0aac43cb5557d756442138889e0ada2eeff55b5536843f6a47120a1bc841575ca137734a5335266707c8766b0baf26750cb1031fcba256ab60
data/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.18] - 2026-03-20
11
+
12
+ ### Added
13
+ - `StopFailure` hook event with `StopFailureInput` type (`error`, `error_details`, `last_assistant_message` fields) for handling API error-triggered stops (TypeScript SDK v0.2.80 parity)
14
+ - `on_stop_failure` DSL method on `HookRegistry` for the new event
15
+
16
+ ## [0.7.17] - 2026-03-17
17
+
18
+ ### Added
19
+ - `APIRetryMessage` system message type with `attempt`, `max_retries`, `retry_delay_ms`, `error_status`, and `error` fields (TypeScript SDK v0.2.77 parity)
20
+ - `title` and `display_name` fields on `ToolPermissionContext` for richer permission prompt context (TypeScript SDK v0.2.77 parity)
21
+ - `allow_read` and `allow_managed_read_paths_only` fields on `SandboxFilesystemConfig` for re-allowing reads within deny regions (TypeScript SDK v0.2.77 parity)
22
+
10
23
  ## [0.7.16] - 2026-03-15
11
24
 
12
25
  ## [0.7.15] - 2026-03-15
data/SPEC.md CHANGED
@@ -3,11 +3,11 @@
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.76 (npm package)
7
- - Python SDK: from GitHub (commit 302ceb6)
6
+ - TypeScript SDK: v0.2.80 (npm package)
7
+ - Python SDK: from GitHub (commit 13e119a)
8
8
  - Ruby SDK: This repository
9
9
 
10
- **Last Updated:** 2026-03-15
10
+ **Last Updated:** 2026-03-20
11
11
 
12
12
  ---
13
13
 
@@ -116,9 +116,20 @@ Messages exchanged between SDK and CLI.
116
116
  | `FilesPersistedEvent` | ✅ | ❌ | ✅ | File persistence confirmation |
117
117
  | `ElicitationCompleteMessage` | ✅ | ❌ | ✅ | MCP elicitation completed |
118
118
  | `LocalCommandOutputMessage` | ✅ | ❌ | ✅ | Local command output |
119
+ | `APIRetryMessage` | ✅ | ❌ | ✅ | API retry notification (v0.2.77) |
119
120
 
120
121
  ### Message Fields
121
122
 
123
+ #### APIRetryMessage
124
+
125
+ | Field | TypeScript | Python | Ruby | Notes |
126
+ |-------------------|:----------:|:------:|:----:|------------------------------------------|
127
+ | `attempt` | ✅ | ❌ | ✅ | Current retry attempt number |
128
+ | `max_retries` | ✅ | ❌ | ✅ | Maximum retry count |
129
+ | `retry_delay_ms` | ✅ | ❌ | ✅ | Delay before retry in milliseconds |
130
+ | `error_status` | ✅ | ❌ | ✅ | HTTP status code (null for conn errors) |
131
+ | `error` | ✅ | ❌ | ✅ | Error type (AssistantMessageError) |
132
+
122
133
  #### ResultMessage
123
134
 
124
135
  | Field | TypeScript | Python | Ruby | Notes |
@@ -425,6 +436,7 @@ Event hooks for intercepting and modifying SDK behavior.
425
436
  | `SessionStart` | ✅ | ✅ | ✅ | Session starts |
426
437
  | `SessionEnd` | ✅ | ❌ | ✅ | Session ends |
427
438
  | `Stop` | ✅ | ✅ | ✅ | Agent stops |
439
+ | `StopFailure` | ✅ | ❌ | ✅ | Agent stops due to API error |
428
440
  | `SubagentStart` | ✅ | ✅ | ✅ | Subagent starts (Py v0.1.29) |
429
441
  | `SubagentStop` | ✅ | ✅ | ✅ | Subagent stops |
430
442
  | `PreCompact` | ✅ | ✅ | ✅ | Before compaction |
@@ -452,6 +464,7 @@ Event hooks for intercepting and modifying SDK behavior.
452
464
  | `SessionStartHookInput` | ✅ | ❌ | ✅ |
453
465
  | `SessionEndHookInput` | ✅ | ❌ | ✅ |
454
466
  | `StopHookInput` | ✅ | ✅ | ✅ |
467
+ | `StopFailureHookInput` | ✅ | ❌ | ✅ |
455
468
  | `SubagentStartHookInput` | ✅ | ✅ | ✅ |
456
469
  | `SubagentStopHookInput` | ✅ | ✅ | ✅ |
457
470
  | `PreCompactHookInput` | ✅ | ✅ | ✅ |
@@ -485,6 +498,14 @@ Event hooks for intercepting and modifying SDK behavior.
485
498
  | `stop_hook_active` | ✅ | ✅ | ✅ | Whether stop hook is active |
486
499
  | `last_assistant_message` | ✅ | ❌ | ✅ | Last assistant message text (v0.2.51+) |
487
500
 
501
+ #### StopFailureHookInput Fields
502
+
503
+ | Field | TypeScript | Python | Ruby | Notes |
504
+ |--------------------------|:----------:|:------:|:----:|----------------------------------------|
505
+ | `error` | ✅ | ❌ | ✅ | API error type (AssistantMessageError) |
506
+ | `error_details` | ✅ | ❌ | ✅ | Additional error details |
507
+ | `last_assistant_message` | ✅ | ❌ | ✅ | Last assistant message text |
508
+
488
509
  #### SubagentStopHookInput Fields
489
510
 
490
511
  | Field | TypeScript | Python | Ruby | Notes |
@@ -666,6 +687,8 @@ Permission handling and updates.
666
687
  | `toolUseID` | ✅ | ❌ | ✅ | Tool call ID |
667
688
  | `agentID` | ✅ | ❌ | ✅ | Subagent ID if applicable |
668
689
  | `description` | ✅ | ❌ | ✅ | Human-readable tool description (v0.2.75) |
690
+ | `title` | ✅ | ❌ | ✅ | Full permission prompt sentence (v0.2.77) |
691
+ | `displayName` | ✅ | ❌ | ✅ | Short noun phrase for tool action (v0.2.77) |
669
692
 
670
693
  ---
671
694
 
@@ -748,7 +771,7 @@ Session management and resumption.
748
771
  |------------------------|:----------:|:------:|:----:|--------------------------------------------------|
749
772
  | `listSessions()` | ✅ | ✅ | ✅ | List past sessions with metadata (v0.2.53) |
750
773
  | `getSessionMessages()` | ✅ | ✅ | ✅ | Read session transcript messages (v0.2.59) |
751
- | `getSessionInfo()` | ✅ | | ✅ | Get single session metadata (v0.2.75) |
774
+ | `getSessionInfo()` | ✅ | | ✅ | Get single session metadata (v0.2.75) |
752
775
  | `renameSession()` | ✅ | ✅ | ✅ | Rename a session (v0.2.74) |
753
776
  | `tagSession()` | ✅ | ✅ | ✅ | Tag a session (v0.2.75) |
754
777
  | `forkSession()` | ✅ | ❌ | ✅ | Fork/branch a session (v0.2.76) |
@@ -792,22 +815,22 @@ Session management and resumption.
792
815
  | `firstPrompt` | ✅ | ✅ | ✅ | First meaningful user prompt |
793
816
  | `gitBranch` | ✅ | ✅ | ✅ | Git branch at end of session |
794
817
  | `cwd` | ✅ | ✅ | ✅ | Working directory for session |
795
- | `tag` | ✅ | | ✅ | User-set tag (v0.2.75) |
796
- | `createdAt` | ✅ | | ✅ | Creation time in ms (v0.2.75) |
818
+ | `tag` | ✅ | | ✅ | User-set tag (v0.2.75) |
819
+ | `createdAt` | ✅ | | ✅ | Creation time in ms (v0.2.75) |
797
820
 
798
821
  #### ForkSessionOptions
799
822
 
800
823
  | Field | TypeScript | Python | Ruby | Notes |
801
824
  |------------------|:----------:|:------:|:----:|------------------------------------------------|
802
- | `dir` | ✅ | ❌ | | Project directory |
803
- | `upToMessageId` | ✅ | ❌ | | Slice transcript up to this UUID (inclusive) |
804
- | `title` | ✅ | ❌ | | Custom title for the fork |
825
+ | `dir` | ✅ | ❌ | | Project directory |
826
+ | `upToMessageId` | ✅ | ❌ | | Slice transcript up to this UUID (inclusive) |
827
+ | `title` | ✅ | ❌ | | Custom title for the fork |
805
828
 
806
829
  #### ForkSessionResult
807
830
 
808
831
  | Field | TypeScript | Python | Ruby | Notes |
809
832
  |-------------|:----------:|:------:|:----:|--------------------------------|
810
- | `sessionId` | ✅ | ❌ | | New forked session UUID |
833
+ | `sessionId` | ✅ | ❌ | | New forked session UUID |
811
834
 
812
835
  ### V2 Session API (Unstable)
813
836
 
@@ -826,17 +849,18 @@ Custom subagent definitions.
826
849
 
827
850
  ### AgentDefinition
828
851
 
829
- | Field | TypeScript | Python | Ruby | Notes |
830
- |---------------------------------------|:----------:|:------:|:----:|--------------------------------------------|
831
- | `description` | ✅ | ✅ | ✅ | When to use agent |
832
- | `prompt` | ✅ | ✅ | ✅ | Agent system prompt |
833
- | `tools` | ✅ | ✅ | ✅ | Allowed tools |
834
- | `disallowedTools` | ✅ | ❌ | ✅ | Blocked tools |
835
- | `model` | ✅ | ✅ | ✅ | Model override (sonnet/opus/haiku/inherit) |
836
- | `mcpServers` | ✅ | | ✅ | Agent-specific MCP servers |
837
- | `criticalSystemReminder_EXPERIMENTAL` | ✅ | ❌ | ✅ | Critical reminder (experimental) |
838
- | `skills` | ✅ | | ✅ | Skills to preload into agent context |
839
- | `maxTurns` | | | | Max agentic turns before stopping |
852
+ | Field | TypeScript | Python | Ruby | Notes |
853
+ |---------------------------------------|:----------:|:------:|:----:|----------------------------------------------|
854
+ | `description` | ✅ | ✅ | ✅ | When to use agent |
855
+ | `prompt` | ✅ | ✅ | ✅ | Agent system prompt |
856
+ | `tools` | ✅ | ✅ | ✅ | Allowed tools |
857
+ | `disallowedTools` | ✅ | ❌ | ✅ | Blocked tools |
858
+ | `model` | ✅ | ✅ | ✅ | Model override (sonnet/opus/haiku/inherit) |
859
+ | `mcpServers` | ✅ | | ✅ | Agent-specific MCP servers |
860
+ | `criticalSystemReminder_EXPERIMENTAL` | ✅ | ❌ | ✅ | Critical reminder (experimental) |
861
+ | `skills` | ✅ | | ✅ | Skills to preload into agent context |
862
+ | `memory` | | | | Memory scope for agent (Python-only v0.1.49) |
863
+ | `maxTurns` | ✅ | ❌ | ✅ | Max agentic turns before stopping |
840
864
 
841
865
  ---
842
866
 
@@ -861,11 +885,13 @@ Sandbox configuration for command execution isolation.
861
885
 
862
886
  ### SandboxFilesystemConfig
863
887
 
864
- | Field | TypeScript | Python | Ruby |
865
- |--------------|:----------:|:------:|:----:|
866
- | `allowWrite` | ✅ | ❌ | ✅ |
867
- | `denyWrite` | ✅ | ❌ | ✅ |
868
- | `denyRead` | ✅ | ❌ | ✅ |
888
+ | Field | TypeScript | Python | Ruby |
889
+ |-----------------------------|:----------:|:------:|:----:|
890
+ | `allowWrite` | ✅ | ❌ | ✅ |
891
+ | `denyWrite` | ✅ | ❌ | ✅ |
892
+ | `denyRead` | ✅ | ❌ | ✅ |
893
+ | `allowRead` | ✅ | ❌ | ✅ |
894
+ | `allowManagedReadPathsOnly` | ✅ | ❌ | ✅ |
869
895
 
870
896
  ### SandboxNetworkConfig
871
897
 
@@ -922,7 +948,7 @@ Public API surface for SDK clients.
922
948
  |------------------------|:----------:|:------:|:----:|--------------------------------------------|
923
949
  | `listSessions()` | ✅ | ✅ | ✅ | List past sessions with metadata (v0.2.53) |
924
950
  | `getSessionMessages()` | ✅ | ✅ | ✅ | Read session transcript (v0.2.59) |
925
- | `getSessionInfo()` | ✅ | | ✅ | Get single session metadata (v0.2.75) |
951
+ | `getSessionInfo()` | ✅ | | ✅ | Get single session metadata (v0.2.75) |
926
952
  | `renameSession()` | ✅ | ✅ | ✅ | Rename a session (v0.2.74) |
927
953
  | `tagSession()` | ✅ | ✅ | ✅ | Tag a session (v0.2.75) |
928
954
  | `forkSession()` | ✅ | ❌ | ✅ | Fork/branch a session (v0.2.76) |
@@ -991,64 +1017,22 @@ Public API surface for SDK clients.
991
1017
  ## Notes
992
1018
 
993
1019
  ### TypeScript SDK
994
- - Primary reference for API surface (most comprehensive)
995
- - Source is bundled/minified, but `sdk.d.ts` provides complete type definitions
996
- - Includes unstable V2 session API
1020
+ - Primary reference for API surface `sdk.d.ts` provides complete type definitions
997
1021
  - `executable`/`executableArgs` are JS-specific (`node`/`bun`/`deno`)
998
1022
  - Does NOT have `user`, `init`/`initOnly`/`maintenance` as typed Options (use `extraArgs` or `settingSources`)
999
- - `ApiKeySource` includes `'oauth'`
1000
- - v0.2.45: Added `TaskStartedMessage`, `RateLimitEvent` message types
1001
- - v0.2.47: Added `promptSuggestions` option and `PromptSuggestionMessage`
1002
- - v0.2.49: Added `ConfigChange` hook event, `SandboxFilesystemConfig`, ModelInfo capability fields
1003
- - v0.2.50: Added `WorktreeCreate`/`WorktreeRemove` hook events, `apply_flag_settings` control request
1004
- - v0.2.51: Added `TaskProgressMessage`, `StopHookInput.last_assistant_message`, `SubagentStopHookInput.last_assistant_message`
1005
- - v0.2.52: Added `mcp_authenticate`/`mcp_clear_auth` control requests for MCP server authentication
1006
- - v0.2.53: Added `listSessions()` for discovering and listing past sessions with `SDKSessionInfo` metadata
1007
- - v0.2.54 – v0.2.58: CLI parity updates (no new SDK-facing features)
1008
- - v0.2.59: Added `getSessionMessages()` for reading session transcript history with pagination (limit/offset)
1009
- - v0.2.61 – v0.2.62: CLI parity updates (no new SDK-facing features)
1010
- - v0.2.63: Added `supportedAgents()` method on Query, fixed `pathToClaudeCodeExecutable` PATH resolution
1011
- - v0.2.64 – v0.2.68: CLI parity updates (no new SDK-facing features)
1012
- - v0.2.69: Added `toolConfig` option (askUserQuestion preview format), `supportsFastMode` in ModelInfo, `agent_id`/`agent_type` on BaseHookInput, `InstructionsLoaded` hook event
1013
- - v0.2.70: Made `AgentToolInput.subagent_type` optional (defaults to general-purpose), fixed HTTP MCP servers
1014
- - v0.2.71: CLI parity update; `settings` now a typed Option (string path or `Settings` object)
1015
- - v0.2.72: Added `agentProgressSummaries` option for periodic AI-generated progress summaries
1016
- - v0.2.73: Fixed `options.env` being overridden by `~/.claude/settings.json`
1017
- - v0.2.74: Added `renameSession()` for renaming session files
1018
- - v0.2.75: Added `tag`/`createdAt` fields on `SDKSessionInfo`; `getSessionInfo()` for single-session lookup; `offset` on `listSessions` for pagination; `tagSession()` for tagging sessions; `supportsAutoMode` in `ModelInfo`; `description` on `SDKControlPermissionRequest`; `prompt` on `SDKTaskStartedMessage`; `fast_mode_state` on `SDKControlInitializeResponse`; `queued_to_running` status on `AgentToolOutput`
1019
- - v0.2.76: Added `forkSession(sessionId, opts?)` for branching conversations from a point; `cancel_async_message` control subtype to drop queued user messages; `PostCompact` hook event with `compact_summary` field; `get_settings` control request for reading effective merged settings; `planFilePath` field on `ExitPlanMode` tool input
1020
- - Includes `Elicitation`/`ElicitationResult` hook events, `onElicitation` option, `ElicitationCompleteMessage`, `LocalCommandOutputMessage`, `FastModeState` (undocumented in changelog, present in types)
1023
+ - Some features present in types but undocumented in changelog: `StopFailure` hook, `Elicitation`/`ElicitationResult` hooks, `onElicitation` option, `ElicitationCompleteMessage`, `LocalCommandOutputMessage`, `FastModeState`
1021
1024
 
1022
1025
  ### Python SDK
1023
- - Full source available with `Transport` abstract class
1024
- - Partial control protocol: query and client support interrupt, setPermissionMode, setModel, rewindFiles, mcpStatus, reconnectMcpServer, toggleMcpServer, stopTask
1025
- - Has `CLINotFoundError`, `CLIConnectionError`, `ProcessError`, `CLIJSONDecodeError`, `MessageParseError` error types
1026
- - Has `TaskStartedMessage`, `TaskProgressMessage`, `TaskNotificationMessage` typed message classes (v0.1.46+)
1027
- - Has `stop_reason` field on ResultMessage (v0.1.46+)
1028
- - Has `SDKSessionInfo`, `SessionMessage` types with `list_sessions()`/`get_session_messages()` functions (v0.1.46+)
1029
- - Has `McpServerStatus` with all fields (name, status, serverInfo, error, config, scope, tools) (v0.1.46+)
1030
- - Has `agent_id`/`agent_type` on tool-lifecycle hook inputs (v0.1.46+)
1031
- - Has `add_mcp_server()`/`remove_mcp_server()` client methods for runtime MCP management (v0.1.46+)
1032
- - Has `include_worktrees` parameter on `list_sessions()` (v0.1.46+)
1033
- - Missing hooks: SessionEnd, Setup, TeammateIdle, TaskCompleted, Elicitation, ElicitationResult, ConfigChange, WorktreeCreate, WorktreeRemove, InstructionsLoaded
1034
- - Missing permission modes: `dontAsk`
1035
- - Missing options: `allowDangerouslySkipPermissions`, `persistSession`, `resumeSessionAt`, `sessionId`, `strictMcpConfig`, `init`/`initOnly`/`maintenance`, `debug`/`debugFile`, `promptSuggestions`, `onElicitation`, `toolConfig`, `agentProgressSummaries`, `agent` (main thread agent)
1036
- - `ToolPermissionContext` missing `blockedPath`, `decisionReason`, `toolUseID`, `agentID`, `description`
1037
- - Has `rename_session()`/`tag_session()` for session mutation
1038
- - Has `RateLimitEvent`/`RateLimitInfo` types with full field coverage
1039
- - Has SDK MCP server support with `tool()` helper and annotations
1040
- - Missing `getSessionInfo()`, `offset` on `list_sessions`, `tag`/`createdAt` on `SDKSessionInfo`
1041
- - Added `thinking` config and `effort` option in v0.1.36
1042
- - Handles `rate_limit_event` and unknown message types gracefully (v0.1.40)
1043
- - Client has `get_server_info()` for accessing the initialization result (v0.1.31+)
1044
- - v0.1.45 – v0.1.48: Major catch-up with TypeScript SDK (task messages, session APIs, MCP control methods, stop_reason)
1045
- - v0.1.48: Fixed fine-grained tool streaming regression
1046
- - Added `RateLimitEvent` message type with `RateLimitInfo`
1047
- - Added `rename_session()` and `tag_session()` session management functions
1048
- - Missing: `onElicitation`, `Elicitation`/`ElicitationResult` hooks, `ElicitationCompleteMessage`, `LocalCommandOutputMessage`, `FastModeState`, `InstructionsLoaded` hook, `agentProgressSummaries`, `getSessionInfo()`, `forkSession()`, `PostCompact` hook, `cancel_async_message`, `get_settings`
1026
+ - Partial control protocol: supports interrupt, setPermissionMode, setModel, rewindFiles, mcpStatus, reconnectMcp, toggleMcp, stopTask
1027
+ - Has `add_mcp_server()`/`remove_mcp_server()` client methods (not in TypeScript)
1028
+ - `AgentDefinition.memory` is Python-only (not in TypeScript or Ruby)
1029
+ - Missing hooks: SessionEnd, StopFailure, Setup, TeammateIdle, TaskCompleted, Elicitation, ElicitationResult, ConfigChange, WorktreeCreate, WorktreeRemove, InstructionsLoaded, PostCompact
1030
+ - Missing options: `allowDangerouslySkipPermissions`, `persistSession`, `resumeSessionAt`, `sessionId`, `strictMcpConfig`, `debug`/`debugFile`, `promptSuggestions`, `onElicitation`, `toolConfig`, `agentProgressSummaries`, `agent` (main thread agent), `dontAsk` permission mode
1031
+ - `ToolPermissionContext` missing `blockedPath`, `decisionReason`, `toolUseID`, `agentID`, `description`, `title`, `displayName`
1032
+ - Missing: `forkSession()`, `offset` on `list_sessions`, `cancel_async_message`, `get_settings`, `APIRetryMessage`
1049
1033
 
1050
1034
  ### Ruby SDK (This Repository)
1051
- - Feature parity with TypeScript SDK v0.2.76
1035
+ - Feature parity with TypeScript SDK v0.2.80
1052
1036
  - Ruby-idiomatic patterns (Data.define, snake_case)
1053
1037
  - Complete control protocol, hook, and V2 Session API support
1054
1038
  - Dedicated Client class for multi-turn conversations
data/docs/hooks.md CHANGED
@@ -64,11 +64,11 @@ When both global and per-conversation hooks are set, they are merged additively
64
64
 
65
65
  Each hook method accepts an optional first argument that filters which tool names trigger the callback. The matcher is passed as the first positional argument, before any keyword arguments.
66
66
 
67
- | Matcher type | Behavior | Example |
68
- |---|---|---|
69
- | `nil` (omitted) | Catch-all, fires for every tool | `h.before_tool_use { \|i, c\| ... }` |
70
- | `String` | Treated as a regex pattern | `h.before_tool_use("Bash") { \|i, c\| ... }` |
71
- | `Regexp` | Normalized to its `source` string | `h.before_tool_use(/Bash\|Write/) { \|i, c\| ... }` |
67
+ | Matcher type | Behavior | Example |
68
+ |-----------------|-----------------------------------|-----------------------------------------------------|
69
+ | `nil` (omitted) | Catch-all, fires for every tool | `h.before_tool_use { \|i, c\| ... }` |
70
+ | `String` | Treated as a regex pattern | `h.before_tool_use("Bash") { \|i, c\| ... }` |
71
+ | `Regexp` | Normalized to its `source` string | `h.before_tool_use(/Bash\|Write/) { \|i, c\| ... }` |
72
72
 
73
73
  A `Regexp` is converted to its `.source` string internally so it can be serialized over the control protocol. This means flags like `Regexp::IGNORECASE` are not preserved.
74
74
 
@@ -133,7 +133,7 @@ end
133
133
 
134
134
  ## Event Mapping Table
135
135
 
136
- All 22 hook events with their Ruby DSL method, CLI event name, and description:
136
+ All 23 hook events with their Ruby DSL method, CLI event name, and description:
137
137
 
138
138
  | Ruby method | CLI event | Description |
139
139
  |--------------------------|----------------------|-------------------------------------------------|
@@ -145,6 +145,7 @@ All 22 hook events with their Ruby DSL method, CLI event name, and description:
145
145
  | `on_session_start` | `SessionStart` | When a session begins. |
146
146
  | `on_session_end` | `SessionEnd` | When a session ends. |
147
147
  | `on_stop` | `Stop` | When the agent stops. |
148
+ | `on_stop_failure` | `StopFailure` | When the agent stops due to an API error. |
148
149
  | `on_subagent_start` | `SubagentStart` | When a subagent is spawned. |
149
150
  | `on_subagent_stop` | `SubagentStop` | When a subagent stops. |
150
151
  | `before_compact` | `PreCompact` | Before context compaction. |
@@ -190,6 +191,7 @@ All input types inherit these fields from `BaseHookInput`:
190
191
  | `SessionStart` | `SessionStartInput` | `source`, `agent_type`, `model` |
191
192
  | `SessionEnd` | `SessionEndInput` | `reason` |
192
193
  | `Stop` | `StopInput` | `stop_hook_active`, `last_assistant_message` |
194
+ | `StopFailure` | `StopFailureInput` | `error`, `error_details`, `last_assistant_message` |
193
195
  | `SubagentStart` | `SubagentStartInput` | `agent_id`, `agent_type` |
194
196
  | `SubagentStop` | `SubagentStopInput` | `stop_hook_active`, `agent_id`, `agent_transcript_path`, `agent_type`, `last_assistant_message` |
195
197
  | `PreCompact` | `PreCompactInput` | `trigger`, `custom_instructions` |
data/docs/messages.md CHANGED
@@ -61,7 +61,7 @@ end
61
61
 
62
62
  ## Message Types
63
63
 
64
- 22 message types, grouped by category.
64
+ 24 message types, grouped by category.
65
65
 
66
66
  ### Conversation Messages
67
67
 
@@ -223,6 +223,28 @@ Methods:
223
223
  - `trigger` -- compaction trigger type (`"manual"` or `"auto"`)
224
224
  - `pre_tokens` -- token count before compaction
225
225
 
226
+ #### APIRetryMessage
227
+
228
+ Emitted when an API request fails with a retryable error and will be retried.
229
+
230
+ ```ruby
231
+ APIRetryMessage = Data.define(:uuid, :session_id, :attempt, :max_retries, :retry_delay_ms, :error_status, :error)
232
+ ```
233
+
234
+ | Field | Type | Default |
235
+ |------------------|----------------|---------|
236
+ | `uuid` | `String` | `""` |
237
+ | `session_id` | `String` | `""` |
238
+ | `attempt` | `Integer` | `0` |
239
+ | `max_retries` | `Integer` | `0` |
240
+ | `retry_delay_ms` | `Integer` | `0` |
241
+ | `error_status` | `Integer, nil` | `nil` |
242
+ | `error` | `String, nil` | `nil` |
243
+
244
+ Methods:
245
+
246
+ - `type` -- `:api_retry`
247
+
226
248
  #### StatusMessage
227
249
 
228
250
  Session status report (e.g., `"compacting"`).
@@ -64,6 +64,8 @@ module ClaudeAgent
64
64
  tool_use_id: request["tool_use_id"],
65
65
  agent_id: request["agent_id"],
66
66
  description: request["description"],
67
+ title: request["title"],
68
+ display_name: request["display_name"],
67
69
  signal: @abort_signal,
68
70
  request: perm_request
69
71
  )
@@ -28,6 +28,7 @@ module ClaudeAgent
28
28
  on_session_start: "SessionStart",
29
29
  on_session_end: "SessionEnd",
30
30
  on_stop: "Stop",
31
+ on_stop_failure: "StopFailure",
31
32
  on_subagent_start: "SubagentStart",
32
33
  on_subagent_stop: "SubagentStop",
33
34
  before_compact: "PreCompact",
@@ -11,6 +11,7 @@ module ClaudeAgent
11
11
  SessionStart
12
12
  SessionEnd
13
13
  Stop
14
+ StopFailure
14
15
  SubagentStart
15
16
  SubagentStop
16
17
  PreCompact
@@ -175,6 +176,10 @@ module ClaudeAgent
175
176
  BaseHookInput.define_input "Stop",
176
177
  optional: { stop_hook_active: false, last_assistant_message: nil }
177
178
 
179
+ BaseHookInput.define_input "StopFailure",
180
+ required: [ :error ],
181
+ optional: { error_details: nil, last_assistant_message: nil }
182
+
178
183
  BaseHookInput.define_input "SubagentStart",
179
184
  required: [ :agent_id, :agent_type ]
180
185
 
@@ -86,6 +86,7 @@ module ClaudeAgent
86
86
  register "system:task_progress", :parse_task_progress_message
87
87
  register "system:elicitation_complete", :parse_elicitation_complete_message
88
88
  register "system:local_command_output", :parse_local_command_output_message
89
+ register "system:api_retry", :parse_api_retry_message
89
90
 
90
91
  private
91
92
 
@@ -421,5 +422,17 @@ module ClaudeAgent
421
422
  suggestion: raw[:suggestion] || ""
422
423
  )
423
424
  end
425
+
426
+ def parse_api_retry_message(raw)
427
+ APIRetryMessage.new(
428
+ uuid: raw[:uuid] || "",
429
+ session_id: raw[:session_id] || "",
430
+ attempt: raw[:attempt] || 0,
431
+ max_retries: raw[:max_retries] || 0,
432
+ retry_delay_ms: raw[:retry_delay_ms] || 0,
433
+ error_status: raw[:error_status],
434
+ error: raw[:error]
435
+ )
436
+ end
424
437
  end
425
438
  end
@@ -55,6 +55,33 @@ module ClaudeAgent
55
55
  # status: "compacting"
56
56
  # )
57
57
  #
58
+ # API retry message (TypeScript SDK v0.2.77 parity)
59
+ #
60
+ # Emitted when an API request fails with a retryable error and will be
61
+ # retried after a delay. Exposes attempt count, max retries, delay, and
62
+ # error status for observability.
63
+ #
64
+ # @example
65
+ # msg = APIRetryMessage.new(
66
+ # uuid: "msg-123",
67
+ # session_id: "session-abc",
68
+ # attempt: 1,
69
+ # max_retries: 3,
70
+ # retry_delay_ms: 5000,
71
+ # error_status: 529,
72
+ # error: "rate_limit"
73
+ # )
74
+ #
75
+ APIRetryMessage = Data.define(:uuid, :session_id, :attempt, :max_retries, :retry_delay_ms, :error_status, :error) do
76
+ def initialize(uuid: "", session_id: "", attempt: 0, max_retries: 0, retry_delay_ms: 0, error_status: nil, error: nil)
77
+ super
78
+ end
79
+
80
+ def type
81
+ :api_retry
82
+ end
83
+ end
84
+
58
85
  StatusMessage = Data.define(:uuid, :session_id, :status, :permission_mode) do
59
86
  def initialize(uuid:, session_id:, status:, permission_mode: nil)
60
87
  super
@@ -34,6 +34,7 @@ module ClaudeAgent
34
34
  PromptSuggestionMessage,
35
35
  ElicitationCompleteMessage,
36
36
  LocalCommandOutputMessage,
37
+ APIRetryMessage,
37
38
  GenericMessage
38
39
  ].freeze
39
40
  end
@@ -147,6 +147,8 @@ module ClaudeAgent
147
147
  # decision_reason: "Path outside allowed directories",
148
148
  # tool_use_id: "tool_123",
149
149
  # agent_id: "agent_456",
150
+ # title: "Claude wants to read /etc/passwd",
151
+ # display_name: "Read file",
150
152
  # signal: abort_signal
151
153
  # )
152
154
  #
@@ -158,6 +160,8 @@ module ClaudeAgent
158
160
  :agent_id,
159
161
  :signal,
160
162
  :description,
163
+ :title,
164
+ :display_name,
161
165
  :request
162
166
  ) do
163
167
  def initialize(
@@ -168,6 +172,8 @@ module ClaudeAgent
168
172
  agent_id: nil,
169
173
  signal: nil,
170
174
  description: nil,
175
+ title: nil,
176
+ display_name: nil,
171
177
  request: nil
172
178
  )
173
179
  super
@@ -85,17 +85,19 @@ module ClaudeAgent
85
85
  end
86
86
  end
87
87
 
88
- # Filesystem-specific configuration for sandbox mode (TypeScript SDK v0.2.49 parity)
88
+ # Filesystem-specific configuration for sandbox mode (TypeScript SDK v0.2.77 parity)
89
89
  #
90
90
  # @example
91
91
  # filesystem = SandboxFilesystemConfig.new(
92
92
  # allow_write: ["/tmp/*"],
93
93
  # deny_write: ["/etc/*"],
94
- # deny_read: ["/secrets/*"]
94
+ # deny_read: ["/secrets/*"],
95
+ # allow_read: ["/secrets/public/*"],
96
+ # allow_managed_read_paths_only: false
95
97
  # )
96
98
  #
97
- SandboxFilesystemConfig = Data.define(:allow_write, :deny_write, :deny_read) do
98
- def initialize(allow_write: [], deny_write: [], deny_read: [])
99
+ SandboxFilesystemConfig = Data.define(:allow_write, :deny_write, :deny_read, :allow_read, :allow_managed_read_paths_only) do
100
+ def initialize(allow_write: [], deny_write: [], deny_read: [], allow_read: [], allow_managed_read_paths_only: false)
99
101
  super
100
102
  end
101
103
 
@@ -104,6 +106,8 @@ module ClaudeAgent
104
106
  result[:allowWrite] = allow_write unless allow_write.empty?
105
107
  result[:denyWrite] = deny_write unless deny_write.empty?
106
108
  result[:denyRead] = deny_read unless deny_read.empty?
109
+ result[:allowRead] = allow_read unless allow_read.empty?
110
+ result[:allowManagedReadPathsOnly] = allow_managed_read_paths_only if allow_managed_read_paths_only
107
111
  result
108
112
  end
109
113
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeAgent
4
- VERSION = "0.7.16"
4
+ VERSION = "0.7.18"
5
5
  end
data/sig/claude_agent.rbs CHANGED
@@ -314,8 +314,10 @@ module ClaudeAgent
314
314
  attr_reader allow_write: Array[String]
315
315
  attr_reader deny_write: Array[String]
316
316
  attr_reader deny_read: Array[String]
317
+ attr_reader allow_read: Array[String]
318
+ attr_reader allow_managed_read_paths_only: bool
317
319
 
318
- def initialize: (?allow_write: Array[String], ?deny_write: Array[String], ?deny_read: Array[String]) -> void
320
+ def initialize: (?allow_write: Array[String], ?deny_write: Array[String], ?deny_read: Array[String], ?allow_read: Array[String], ?allow_managed_read_paths_only: bool) -> void
319
321
  def to_h: () -> Hash[Symbol, untyped]
320
322
  end
321
323
 
@@ -573,6 +575,20 @@ module ClaudeAgent
573
575
  def type: () -> :local_command_output
574
576
  end
575
577
 
578
+ # API retry message (TypeScript SDK v0.2.77 parity)
579
+ class APIRetryMessage
580
+ attr_reader uuid: String
581
+ attr_reader session_id: String
582
+ attr_reader attempt: Integer
583
+ attr_reader max_retries: Integer
584
+ attr_reader retry_delay_ms: Integer
585
+ attr_reader error_status: Integer?
586
+ attr_reader error: String?
587
+
588
+ def initialize: (?uuid: String, ?session_id: String, ?attempt: Integer, ?max_retries: Integer, ?retry_delay_ms: Integer, ?error_status: Integer?, ?error: String?) -> void
589
+ def type: () -> :api_retry
590
+ end
591
+
576
592
  class GenericMessage
577
593
  attr_reader message_type: String?
578
594
  attr_reader raw: Hash[Symbol, untyped]
@@ -584,7 +600,7 @@ module ClaudeAgent
584
600
  end
585
601
 
586
602
  # Message types
587
- type message = UserMessage | UserMessageReplay | AssistantMessage | SystemMessage | ResultMessage | StreamEvent | CompactBoundaryMessage | StatusMessage | ToolProgressMessage | HookResponseMessage | AuthStatusMessage | TaskNotificationMessage | HookStartedMessage | HookProgressMessage | ToolUseSummaryMessage | FilesPersistedEvent | TaskStartedMessage | TaskProgressMessage | RateLimitEvent | PromptSuggestionMessage | ElicitationCompleteMessage | LocalCommandOutputMessage | GenericMessage
603
+ type message = UserMessage | UserMessageReplay | AssistantMessage | SystemMessage | ResultMessage | StreamEvent | CompactBoundaryMessage | StatusMessage | ToolProgressMessage | HookResponseMessage | AuthStatusMessage | TaskNotificationMessage | HookStartedMessage | HookProgressMessage | ToolUseSummaryMessage | FilesPersistedEvent | TaskStartedMessage | TaskProgressMessage | RateLimitEvent | PromptSuggestionMessage | ElicitationCompleteMessage | LocalCommandOutputMessage | APIRetryMessage | GenericMessage
588
604
 
589
605
  MESSAGE_TYPES: Array[Class]
590
606
 
@@ -987,6 +1003,14 @@ module ClaudeAgent
987
1003
  def initialize: (?stop_hook_active: bool, ?last_assistant_message: String?, **untyped) -> void
988
1004
  end
989
1005
 
1006
+ class StopFailureInput < BaseHookInput
1007
+ attr_reader error: String
1008
+ attr_reader error_details: String?
1009
+ attr_reader last_assistant_message: String?
1010
+
1011
+ def initialize: (error: String, ?error_details: String?, ?last_assistant_message: String?, **untyped) -> void
1012
+ end
1013
+
990
1014
  class SubagentStartInput < BaseHookInput
991
1015
  attr_reader agent_id: String
992
1016
  attr_reader agent_type: String
@@ -1161,9 +1185,11 @@ module ClaudeAgent
1161
1185
  attr_reader agent_id: String?
1162
1186
  attr_reader signal: AbortSignal?
1163
1187
  attr_reader description: String?
1188
+ attr_reader title: String?
1189
+ attr_reader display_name: String?
1164
1190
  attr_reader request: PermissionRequest?
1165
1191
 
1166
- def initialize: (?permission_suggestions: untyped, ?blocked_path: String?, ?decision_reason: String?, ?tool_use_id: String?, ?agent_id: String?, ?signal: AbortSignal?, ?description: String?, ?request: PermissionRequest?) -> void
1192
+ def initialize: (?permission_suggestions: untyped, ?blocked_path: String?, ?decision_reason: String?, ?tool_use_id: String?, ?agent_id: String?, ?signal: AbortSignal?, ?description: String?, ?title: String?, ?display_name: String?, ?request: PermissionRequest?) -> void
1167
1193
  end
1168
1194
 
1169
1195
  # Deferred permission request resolved from any thread
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.7.16
4
+ version: 0.7.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Carr