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 +4 -4
- data/CHANGELOG.md +13 -0
- data/SPEC.md +63 -79
- data/docs/hooks.md +8 -6
- data/docs/messages.md +23 -1
- data/lib/claude_agent/control_protocol/request_handling.rb +2 -0
- data/lib/claude_agent/hook_registry.rb +1 -0
- data/lib/claude_agent/hooks.rb +5 -0
- data/lib/claude_agent/message_parser.rb +13 -0
- data/lib/claude_agent/messages/system.rb +27 -0
- data/lib/claude_agent/messages.rb +1 -0
- data/lib/claude_agent/permissions.rb +6 -0
- data/lib/claude_agent/sandbox_settings.rb +8 -4
- data/lib/claude_agent/version.rb +1 -1
- data/sig/claude_agent.rbs +29 -3
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 564803b88efd1e1690c1d44078c2dc9ddf10e8d74fc48cbacee1705843a50ef8
|
|
4
|
+
data.tar.gz: 03e53177abed5def635fad5152f7ec9046e9d16280df70200b9f1b53d8bd647b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
7
|
-
- Python SDK: from GitHub (commit
|
|
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-
|
|
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()` | ✅ |
|
|
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` | ✅ |
|
|
796
|
-
| `createdAt` | ✅ |
|
|
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` | ✅ | ❌ |
|
|
803
|
-
| `upToMessageId` | ✅ | ❌ |
|
|
804
|
-
| `title` | ✅ | ❌ |
|
|
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` | ✅ | ❌ |
|
|
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` | ✅ |
|
|
837
|
-
| `criticalSystemReminder_EXPERIMENTAL` | ✅ | ❌ | ✅ | Critical reminder (experimental)
|
|
838
|
-
| `skills` | ✅ |
|
|
839
|
-
| `
|
|
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
|
|
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()` | ✅ |
|
|
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
|
|
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
|
-
- `
|
|
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
|
-
-
|
|
1024
|
-
-
|
|
1025
|
-
-
|
|
1026
|
-
-
|
|
1027
|
-
-
|
|
1028
|
-
-
|
|
1029
|
-
-
|
|
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.
|
|
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
|
|
68
|
-
|
|
69
|
-
| `nil` (omitted) | Catch-all, fires for every tool
|
|
70
|
-
| `String`
|
|
71
|
-
| `Regexp`
|
|
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
|
|
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
|
-
|
|
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"`).
|
data/lib/claude_agent/hooks.rb
CHANGED
|
@@ -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
|
|
@@ -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.
|
|
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
|
data/lib/claude_agent/version.rb
CHANGED
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
|