claude_agent 0.2.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +126 -3
- data/SPEC.md +136 -63
- data/lib/claude_agent/hooks.rb +36 -2
- data/lib/claude_agent/message_parser.rb +14 -1
- data/lib/claude_agent/messages.rb +66 -1
- data/lib/claude_agent/options.rb +21 -2
- data/lib/claude_agent/query.rb +54 -0
- data/lib/claude_agent/types.rb +17 -3
- data/lib/claude_agent/version.rb +1 -1
- data/sig/claude_agent.rbs +3 -1
- 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: 0df3ed3f8ade7108ed89ab51e5f42ad2f0d358bfa99a63a88919a39899570e89
|
|
4
|
+
data.tar.gz: 19ad8e7da48f2ba038deec0b1dc31737009a8cfe8b079da53b34348f55b6fe7b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 39138c727a4bf8786302225d9cf1b7415117f9077fb494f6d0afb0c5b6f5aff5121a28696e435cfb321660b6e1ea7fb68f734fb673aca562b9f1fada84229784
|
|
7
|
+
data.tar.gz: aabad329d3a406695b9cd0fecc8a774464b23f7794aaa995b60f8755832759145d4a8e7c620939f39d1d3127dcf5a31042350ea473ef1bddfc8a0fcf2942646b
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-01-18
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `TaskNotificationMessage` for background task completion notifications
|
|
14
|
+
- `Setup` hook event with `SetupInput` for init/maintenance triggers
|
|
15
|
+
- `skills` and `max_turns` fields in `AgentDefinition` (TypeScript SDK v0.2.12 parity)
|
|
16
|
+
- `init`, `init_only`, `maintenance` options for running Setup hooks
|
|
17
|
+
- `ClaudeAgent.run_setup` convenience method for CI/CD pipelines
|
|
18
|
+
- Hook-specific output fields documentation (`additionalContext`, `permissionDecision`, `updatedMCPToolOutput`, etc.)
|
|
19
|
+
- Document `settings` option accepts JSON strings (for plansDirectory, etc.)
|
|
20
|
+
|
|
21
|
+
## [0.3.0] - 2026-01-16
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- `agent` option for specifying main thread agent name (TypeScript SDK v0.2.9 parity)
|
|
25
|
+
- `model` field in `SessionStartInput` hook input
|
|
26
|
+
|
|
10
27
|
## [0.2.0] - 2026-01-11
|
|
11
28
|
|
|
12
29
|
### Added
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ClaudeAgent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ruby gem for building AI-powered applications with the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview). This library essentially wraps the Claude Code CLI, providing both simple one-shot queries and interactive bidirectional sessions.
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
@@ -64,6 +64,26 @@ ClaudeAgent::Client.open do |client|
|
|
|
64
64
|
end
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
### Run Setup Hooks
|
|
68
|
+
|
|
69
|
+
Run Setup hooks without starting a conversation (useful for CI/CD pipelines):
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
require "claude_agent"
|
|
73
|
+
|
|
74
|
+
# Run init Setup hooks (default)
|
|
75
|
+
messages = ClaudeAgent.run_setup
|
|
76
|
+
result = messages.last
|
|
77
|
+
puts "Setup completed" if result.success?
|
|
78
|
+
|
|
79
|
+
# Run init Setup hooks with custom options
|
|
80
|
+
options = ClaudeAgent::Options.new(cwd: "/my/project")
|
|
81
|
+
ClaudeAgent.run_setup(trigger: :init, options: options)
|
|
82
|
+
|
|
83
|
+
# Run maintenance Setup hooks
|
|
84
|
+
ClaudeAgent.run_setup(trigger: :maintenance)
|
|
85
|
+
```
|
|
86
|
+
|
|
67
87
|
## Configuration
|
|
68
88
|
|
|
69
89
|
Use `ClaudeAgent::Options` to customize behavior:
|
|
@@ -95,6 +115,9 @@ options = ClaudeAgent::Options.new(
|
|
|
95
115
|
cwd: "/path/to/project",
|
|
96
116
|
add_dirs: ["/additional/path"],
|
|
97
117
|
|
|
118
|
+
# Agent configuration
|
|
119
|
+
agent: "my-agent", # Agent name for main thread
|
|
120
|
+
|
|
98
121
|
# Session management
|
|
99
122
|
resume: "session-id",
|
|
100
123
|
continue_conversation: true,
|
|
@@ -158,7 +181,9 @@ agents = {
|
|
|
158
181
|
description: "Runs tests and reports results",
|
|
159
182
|
prompt: "You are a test runner. Execute tests and report failures clearly.",
|
|
160
183
|
tools: ["Read", "Bash"],
|
|
161
|
-
model: "haiku"
|
|
184
|
+
model: "haiku",
|
|
185
|
+
max_turns: 5, # Max agentic turns before stopping
|
|
186
|
+
skills: ["testing", "debug"] # Skills to preload into agent context
|
|
162
187
|
)
|
|
163
188
|
}
|
|
164
189
|
|
|
@@ -274,6 +299,20 @@ auth.output # Auth output messages
|
|
|
274
299
|
auth.error # Error message (if any)
|
|
275
300
|
```
|
|
276
301
|
|
|
302
|
+
### TaskNotificationMessage
|
|
303
|
+
|
|
304
|
+
Background task completion notifications:
|
|
305
|
+
|
|
306
|
+
```ruby
|
|
307
|
+
notification.task_id # Background task ID
|
|
308
|
+
notification.status # "completed", "failed", or "stopped"
|
|
309
|
+
notification.output_file # Path to task output file
|
|
310
|
+
notification.summary # Task summary
|
|
311
|
+
notification.completed? # Convenience predicate
|
|
312
|
+
notification.failed? # Convenience predicate
|
|
313
|
+
notification.stopped? # Convenience predicate
|
|
314
|
+
```
|
|
315
|
+
|
|
277
316
|
## Content Blocks
|
|
278
317
|
|
|
279
318
|
Assistant messages contain content blocks:
|
|
@@ -446,6 +485,7 @@ All available hook events:
|
|
|
446
485
|
- `SubagentStop` - When subagent stops
|
|
447
486
|
- `PreCompact` - Before conversation compaction
|
|
448
487
|
- `PermissionRequest` - When permission is requested
|
|
488
|
+
- `Setup` - Initial setup or maintenance (trigger: "init" or "maintenance")
|
|
449
489
|
|
|
450
490
|
### Hook Input Types
|
|
451
491
|
|
|
@@ -456,13 +496,14 @@ All available hook events:
|
|
|
456
496
|
| PostToolUseFailure | `PostToolUseFailureInput` | tool_name, tool_input, error, tool_use_id, is_interrupt |
|
|
457
497
|
| Notification | `NotificationInput` | message, title, notification_type |
|
|
458
498
|
| UserPromptSubmit | `UserPromptSubmitInput` | prompt |
|
|
459
|
-
| SessionStart | `SessionStartInput` | source, agent_type
|
|
499
|
+
| SessionStart | `SessionStartInput` | source, agent_type, model |
|
|
460
500
|
| SessionEnd | `SessionEndInput` | reason |
|
|
461
501
|
| Stop | `StopInput` | stop_hook_active |
|
|
462
502
|
| SubagentStart | `SubagentStartInput` | agent_id, agent_type |
|
|
463
503
|
| SubagentStop | `SubagentStopInput` | stop_hook_active, agent_id, agent_transcript_path |
|
|
464
504
|
| PreCompact | `PreCompactInput` | trigger, custom_instructions |
|
|
465
505
|
| PermissionRequest | `PermissionRequestInput` | tool_name, tool_input, permission_suggestions |
|
|
506
|
+
| Setup | `SetupInput` | trigger (init/maintenance) |
|
|
466
507
|
|
|
467
508
|
All hook inputs inherit from `BaseHookInput` with: `hook_event_name`, `session_id`, `transcript_path`, `cwd`, `permission_mode`.
|
|
468
509
|
|
|
@@ -591,6 +632,88 @@ puts client.account_info.email
|
|
|
591
632
|
client.disconnect
|
|
592
633
|
```
|
|
593
634
|
|
|
635
|
+
## V2 Session API (Unstable)
|
|
636
|
+
|
|
637
|
+
> **⚠️ Alpha API**: This API is unstable and may change without notice.
|
|
638
|
+
|
|
639
|
+
The V2 Session API provides a simpler interface for multi-turn conversations, matching the TypeScript SDK's `SDKSession` interface.
|
|
640
|
+
|
|
641
|
+
### Create a Session
|
|
642
|
+
|
|
643
|
+
```ruby
|
|
644
|
+
# Create a new session
|
|
645
|
+
session = ClaudeAgent.unstable_v2_create_session(
|
|
646
|
+
model: "claude-sonnet-4-5-20250514",
|
|
647
|
+
permission_mode: "acceptEdits"
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
# Send a message
|
|
651
|
+
session.send("Hello, Claude!")
|
|
652
|
+
|
|
653
|
+
# Stream responses
|
|
654
|
+
session.stream.each do |msg|
|
|
655
|
+
case msg
|
|
656
|
+
when ClaudeAgent::AssistantMessage
|
|
657
|
+
puts msg.text
|
|
658
|
+
when ClaudeAgent::ResultMessage
|
|
659
|
+
puts "Done! Cost: $#{msg.total_cost_usd}"
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
# Continue the conversation
|
|
664
|
+
session.send("Tell me more")
|
|
665
|
+
session.stream.each { |msg| puts msg.text if msg.is_a?(ClaudeAgent::AssistantMessage) }
|
|
666
|
+
|
|
667
|
+
# Close when done
|
|
668
|
+
session.close
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Resume a Session
|
|
672
|
+
|
|
673
|
+
```ruby
|
|
674
|
+
# Resume an existing session by ID
|
|
675
|
+
session = ClaudeAgent.unstable_v2_resume_session(
|
|
676
|
+
"session-abc123",
|
|
677
|
+
model: "claude-sonnet-4-5-20250514"
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
session.send("What were we discussing?")
|
|
681
|
+
session.stream.each { |msg| puts msg.text if msg.is_a?(ClaudeAgent::AssistantMessage) }
|
|
682
|
+
session.close
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### One-Shot Prompt
|
|
686
|
+
|
|
687
|
+
```ruby
|
|
688
|
+
# Simple one-shot prompt (auto-closes session)
|
|
689
|
+
result = ClaudeAgent.unstable_v2_prompt(
|
|
690
|
+
"What is 2 + 2?",
|
|
691
|
+
model: "claude-sonnet-4-5-20250514"
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
puts "Success: #{result.success?}"
|
|
695
|
+
puts "Cost: $#{result.total_cost_usd}"
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### SessionOptions
|
|
699
|
+
|
|
700
|
+
The V2 API uses a simplified options type:
|
|
701
|
+
|
|
702
|
+
```ruby
|
|
703
|
+
options = ClaudeAgent::SessionOptions.new(
|
|
704
|
+
model: "claude-sonnet-4-5-20250514", # Required
|
|
705
|
+
permission_mode: "acceptEdits", # Optional
|
|
706
|
+
allowed_tools: ["Read", "Grep"], # Optional
|
|
707
|
+
disallowed_tools: ["Write"], # Optional
|
|
708
|
+
can_use_tool: ->(name, input, ctx) { ... }, # Optional
|
|
709
|
+
hooks: { "PreToolUse" => [...] }, # Optional
|
|
710
|
+
env: { "MY_VAR" => "value" }, # Optional
|
|
711
|
+
path_to_claude_code_executable: "/custom/path" # Optional
|
|
712
|
+
)
|
|
713
|
+
|
|
714
|
+
session = ClaudeAgent.unstable_v2_create_session(options)
|
|
715
|
+
```
|
|
716
|
+
|
|
594
717
|
## Types Reference
|
|
595
718
|
|
|
596
719
|
### Return Types
|
data/SPEC.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
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:
|
|
6
|
+
- TypeScript SDK: v0.2.12 (npm package)
|
|
7
|
+
- Python SDK: v0.1.20 from GitHub (commit 05d2eb4)
|
|
8
8
|
- Ruby SDK: This repository
|
|
9
9
|
|
|
10
10
|
---
|
|
@@ -30,49 +30,54 @@ This document provides a comprehensive specification of the Claude Agent SDK, co
|
|
|
30
30
|
|
|
31
31
|
Configuration options for SDK queries and clients.
|
|
32
32
|
|
|
33
|
-
| Option | TypeScript | Python | Ruby | Notes
|
|
34
|
-
|
|
35
|
-
| `model` | ✅ | ✅ | ✅ | Claude model identifier
|
|
36
|
-
| `fallbackModel` | ✅ | ✅ | ✅ | Fallback if primary fails
|
|
37
|
-
| `systemPrompt` | ✅ | ✅ | ✅ | String or preset object
|
|
38
|
-
| `appendSystemPrompt` | ✅ | ❌ | ✅ | Append to system prompt (TS SDK has via preset)
|
|
39
|
-
| `tools` | ✅ | ✅ | ✅ | Array or preset
|
|
40
|
-
| `allowedTools` | ✅ | ✅ | ✅ | Auto-allowed tools
|
|
41
|
-
| `disallowedTools` | ✅ | ✅ | ✅ | Blocked tools
|
|
42
|
-
| `permissionMode` | ✅ | ✅ | ✅ | default/acceptEdits/plan/bypassPermissions/delegate/dontAsk
|
|
43
|
-
| `allowDangerouslySkipPermissions` | ✅ | ❌ | ✅ | Required for bypassPermissions
|
|
44
|
-
| `canUseTool` | ✅ | ✅ | ✅ | Permission callback
|
|
45
|
-
| `permissionPromptToolName` | ✅ | ✅ | ✅ | MCP tool for permission prompts
|
|
46
|
-
| `maxTurns` | ✅ | ✅ | ✅ | Max conversation turns
|
|
47
|
-
| `maxBudgetUsd` | ✅ | ✅ | ✅ | Max USD budget
|
|
48
|
-
| `maxThinkingTokens` | ✅ | ✅ | ✅ | Max thinking tokens
|
|
49
|
-
| `continue` | ✅ | ✅ | ✅ | Continue most recent conversation
|
|
50
|
-
| `resume` | ✅ | ✅ | ✅ | Resume session by ID
|
|
51
|
-
| `resumeSessionAt` | ✅ | ❌ | ✅ | Resume to specific message UUID
|
|
52
|
-
| `forkSession` | ✅ | ✅ | ✅ | Fork on resume
|
|
53
|
-
| `persistSession` | ✅ | ❌ | ✅ | Whether to persist to disk
|
|
54
|
-
| `enableFileCheckpointing` | ✅ | ✅ | ✅ | Track file changes for rewind
|
|
55
|
-
| `includePartialMessages` | ✅ | ✅ | ✅ | Include stream events
|
|
56
|
-
| `outputFormat` | ✅ | ✅ | ✅ | JSON schema for structured output
|
|
57
|
-
| `mcpServers` | ✅ | ✅ | ✅ | MCP server configurations
|
|
58
|
-
| `strictMcpConfig` | ✅ | ❌ | ✅ | Strict validation of MCP config
|
|
59
|
-
| `hooks` | ✅ | ✅ | ✅ | Hook callbacks
|
|
60
|
-
| `agents` | ✅ | ✅ | ✅ | Custom subagent definitions
|
|
61
|
-
| `cwd` | ✅ | ✅ | ✅ | Working directory
|
|
62
|
-
| `additionalDirectories` | ✅ | ✅ | ✅ | Extra allowed directories
|
|
63
|
-
| `env` | ✅ | ✅ | ✅ | Environment variables
|
|
64
|
-
| `sandbox` | ✅ | ✅ | ✅ | Sandbox settings
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
33
|
+
| Option | TypeScript | Python | Ruby | Notes |
|
|
34
|
+
|-----------------------------------|:----------:|:------:|:----:|--------------------------------------------------------------|
|
|
35
|
+
| `model` | ✅ | ✅ | ✅ | Claude model identifier |
|
|
36
|
+
| `fallbackModel` | ✅ | ✅ | ✅ | Fallback if primary fails |
|
|
37
|
+
| `systemPrompt` | ✅ | ✅ | ✅ | String or preset object |
|
|
38
|
+
| `appendSystemPrompt` | ✅ | ❌ | ✅ | Append to system prompt (TS SDK has via preset) |
|
|
39
|
+
| `tools` | ✅ | ✅ | ✅ | Array or preset |
|
|
40
|
+
| `allowedTools` | ✅ | ✅ | ✅ | Auto-allowed tools |
|
|
41
|
+
| `disallowedTools` | ✅ | ✅ | ✅ | Blocked tools |
|
|
42
|
+
| `permissionMode` | ✅ | ✅ | ✅ | default/acceptEdits/plan/bypassPermissions/delegate/dontAsk |
|
|
43
|
+
| `allowDangerouslySkipPermissions` | ✅ | ❌ | ✅ | Required for bypassPermissions |
|
|
44
|
+
| `canUseTool` | ✅ | ✅ | ✅ | Permission callback |
|
|
45
|
+
| `permissionPromptToolName` | ✅ | ✅ | ✅ | MCP tool for permission prompts |
|
|
46
|
+
| `maxTurns` | ✅ | ✅ | ✅ | Max conversation turns |
|
|
47
|
+
| `maxBudgetUsd` | ✅ | ✅ | ✅ | Max USD budget |
|
|
48
|
+
| `maxThinkingTokens` | ✅ | ✅ | ✅ | Max thinking tokens |
|
|
49
|
+
| `continue` | ✅ | ✅ | ✅ | Continue most recent conversation |
|
|
50
|
+
| `resume` | ✅ | ✅ | ✅ | Resume session by ID |
|
|
51
|
+
| `resumeSessionAt` | ✅ | ❌ | ✅ | Resume to specific message UUID |
|
|
52
|
+
| `forkSession` | ✅ | ✅ | ✅ | Fork on resume |
|
|
53
|
+
| `persistSession` | ✅ | ❌ | ✅ | Whether to persist to disk |
|
|
54
|
+
| `enableFileCheckpointing` | ✅ | ✅ | ✅ | Track file changes for rewind |
|
|
55
|
+
| `includePartialMessages` | ✅ | ✅ | ✅ | Include stream events |
|
|
56
|
+
| `outputFormat` | ✅ | ✅ | ✅ | JSON schema for structured output |
|
|
57
|
+
| `mcpServers` | ✅ | ✅ | ✅ | MCP server configurations |
|
|
58
|
+
| `strictMcpConfig` | ✅ | ❌ | ✅ | Strict validation of MCP config |
|
|
59
|
+
| `hooks` | ✅ | ✅ | ✅ | Hook callbacks |
|
|
60
|
+
| `agents` | ✅ | ✅ | ✅ | Custom subagent definitions |
|
|
61
|
+
| `cwd` | ✅ | ✅ | ✅ | Working directory |
|
|
62
|
+
| `additionalDirectories` | ✅ | ✅ | ✅ | Extra allowed directories |
|
|
63
|
+
| `env` | ✅ | ✅ | ✅ | Environment variables |
|
|
64
|
+
| `sandbox` | ✅ | ✅ | ✅ | Sandbox settings |
|
|
65
|
+
| `settings` | ✅ | ❌ | ✅ | Settings file path or JSON string (e.g., plansDirectory) |
|
|
66
|
+
| `settingSources` | ✅ | ✅ | ✅ | Which settings to load |
|
|
67
|
+
| `plugins` | ✅ | ✅ | ✅ | Plugin configurations |
|
|
68
|
+
| `betas` | ✅ | ✅ | ✅ | Beta features (e.g., context-1m-2025-08-07) |
|
|
69
|
+
| `agent` | ✅ | ❌ | ✅ | Agent name for main thread |
|
|
70
|
+
| `abortController` | ✅ | ❌ | ✅ | Cancellation controller |
|
|
71
|
+
| `stderr` | ✅ | ✅ | ✅ | Stderr callback |
|
|
72
|
+
| `spawnClaudeCodeProcess` | ✅ | ❌ | ✅ | Custom spawn function |
|
|
73
|
+
| `pathToClaudeCodeExecutable` | ✅ | ✅ | ✅ | Custom CLI path |
|
|
74
|
+
| `executable` | ✅ | N/A | N/A | JS runtime (node/bun/deno) - JS-specific |
|
|
75
|
+
| `executableArgs` | ✅ | N/A | N/A | JS runtime args - JS-specific |
|
|
76
|
+
| `extraArgs` | ✅ | ✅ | ✅ | Extra CLI arguments |
|
|
77
|
+
| `user` | ✅ | ✅ | ✅ | User identifier (V2 Session API) |
|
|
78
|
+
| `init` | ✅ | ❌ | ✅ | Run Setup hooks (init trigger), then continue (hidden CLI) |
|
|
79
|
+
| `initOnly` | ✅ | ❌ | ✅ | Run Setup hooks (init trigger), then exit (hidden CLI) |
|
|
80
|
+
| `maintenance` | ✅ | ❌ | ✅ | Run Setup hooks (maintenance trigger), continue (hidden CLI) |
|
|
76
81
|
|
|
77
82
|
---
|
|
78
83
|
|
|
@@ -93,6 +98,7 @@ Messages exchanged between SDK and CLI.
|
|
|
93
98
|
| `ToolProgressMessage` | ✅ | ❌ | ✅ | Long-running tool progress |
|
|
94
99
|
| `HookResponseMessage` | ✅ | ❌ | ✅ | Hook execution output |
|
|
95
100
|
| `AuthStatusMessage` | ✅ | ❌ | ✅ | Authentication status |
|
|
101
|
+
| `TaskNotificationMessage`| ✅ | ❌ | ✅ | Background task completion |
|
|
96
102
|
|
|
97
103
|
### Message Fields
|
|
98
104
|
|
|
@@ -202,20 +208,21 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
202
208
|
|
|
203
209
|
### Hook Events
|
|
204
210
|
|
|
205
|
-
| Event | TypeScript | Python | Ruby | Notes
|
|
206
|
-
|
|
207
|
-
| `PreToolUse` | ✅ | ✅ | ✅ | Before tool execution
|
|
208
|
-
| `PostToolUse` | ✅ | ✅ | ✅ | After tool execution
|
|
209
|
-
| `PostToolUseFailure` | ✅ | ❌ | ✅ | After tool failure
|
|
210
|
-
| `Notification` | ✅ | ❌ | ✅ | System notifications
|
|
211
|
-
| `UserPromptSubmit` | ✅ | ✅ | ✅ | User message submitted
|
|
212
|
-
| `SessionStart` | ✅ | ❌ | ✅ | Session starts
|
|
213
|
-
| `SessionEnd` | ✅ | ❌ | ✅ | Session ends
|
|
214
|
-
| `Stop` | ✅ | ✅ | ✅ | Agent stops
|
|
215
|
-
| `SubagentStart` | ✅ | ❌ | ✅ | Subagent starts
|
|
216
|
-
| `SubagentStop` | ✅ | ✅ | ✅ | Subagent stops
|
|
217
|
-
| `PreCompact` | ✅ | ✅ | ✅ | Before compaction
|
|
218
|
-
| `PermissionRequest` | ✅ | ❌ | ✅ | Permission requested
|
|
211
|
+
| Event | TypeScript | Python | Ruby | Notes |
|
|
212
|
+
|----------------------|:----------:|:------:|:----:|---------------------------|
|
|
213
|
+
| `PreToolUse` | ✅ | ✅ | ✅ | Before tool execution |
|
|
214
|
+
| `PostToolUse` | ✅ | ✅ | ✅ | After tool execution |
|
|
215
|
+
| `PostToolUseFailure` | ✅ | ❌ | ✅ | After tool failure |
|
|
216
|
+
| `Notification` | ✅ | ❌ | ✅ | System notifications |
|
|
217
|
+
| `UserPromptSubmit` | ✅ | ✅ | ✅ | User message submitted |
|
|
218
|
+
| `SessionStart` | ✅ | ❌ | ✅ | Session starts |
|
|
219
|
+
| `SessionEnd` | ✅ | ❌ | ✅ | Session ends |
|
|
220
|
+
| `Stop` | ✅ | ✅ | ✅ | Agent stops |
|
|
221
|
+
| `SubagentStart` | ✅ | ❌ | ✅ | Subagent starts |
|
|
222
|
+
| `SubagentStop` | ✅ | ✅ | ✅ | Subagent stops |
|
|
223
|
+
| `PreCompact` | ✅ | ✅ | ✅ | Before compaction |
|
|
224
|
+
| `PermissionRequest` | ✅ | ❌ | ✅ | Permission requested |
|
|
225
|
+
| `Setup` | ✅ | ❌ | ✅ | Initial setup/maintenance |
|
|
219
226
|
|
|
220
227
|
### Hook Input Types
|
|
221
228
|
|
|
@@ -233,6 +240,7 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
233
240
|
| `SubagentStopHookInput` | ✅ | ✅ | ✅ |
|
|
234
241
|
| `PreCompactHookInput` | ✅ | ✅ | ✅ |
|
|
235
242
|
| `PermissionRequestHookInput` | ✅ | ❌ | ✅ |
|
|
243
|
+
| `SetupHookInput` | ✅ | ❌ | ✅ |
|
|
236
244
|
|
|
237
245
|
### Hook Output Types
|
|
238
246
|
|
|
@@ -248,6 +256,62 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
248
256
|
| `reason` | ✅ | ✅ | ✅ | Reason feedback |
|
|
249
257
|
| `hookSpecificOutput` | ✅ | ✅ | ✅ | Event-specific output |
|
|
250
258
|
|
|
259
|
+
### Hook-Specific Output Fields
|
|
260
|
+
|
|
261
|
+
Event-specific fields returned via `hookSpecificOutput`:
|
|
262
|
+
|
|
263
|
+
#### PreToolUseHookSpecificOutput
|
|
264
|
+
|
|
265
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
266
|
+
|----------------------------|:----------:|:------:|:----:|------------------------------------|
|
|
267
|
+
| `permissionDecision` | ✅ | ❌ | ✅ | `allow`, `deny`, or `ask` |
|
|
268
|
+
| `permissionDecisionReason` | ✅ | ❌ | ✅ | Reason for permission decision |
|
|
269
|
+
| `updatedInput` | ✅ | ✅ | ✅ | Modified tool input |
|
|
270
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
271
|
+
|
|
272
|
+
#### PostToolUseHookSpecificOutput
|
|
273
|
+
|
|
274
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
275
|
+
|------------------------|:----------:|:------:|:----:|----------------------------------|
|
|
276
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
277
|
+
| `updatedMCPToolOutput` | ✅ | ❌ | ✅ | Modified MCP tool output |
|
|
278
|
+
|
|
279
|
+
#### PostToolUseFailureHookSpecificOutput
|
|
280
|
+
|
|
281
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
282
|
+
|---------------------|:----------:|:------:|:----:|----------------------------------|
|
|
283
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
284
|
+
|
|
285
|
+
#### SessionStartHookSpecificOutput
|
|
286
|
+
|
|
287
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
288
|
+
|---------------------|:----------:|:------:|:----:|----------------------------------|
|
|
289
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
290
|
+
|
|
291
|
+
#### SetupHookSpecificOutput
|
|
292
|
+
|
|
293
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
294
|
+
|---------------------|:----------:|:------:|:----:|----------------------------------|
|
|
295
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
296
|
+
|
|
297
|
+
#### SubagentStartHookSpecificOutput
|
|
298
|
+
|
|
299
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
300
|
+
|---------------------|:----------:|:------:|:----:|----------------------------------|
|
|
301
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
302
|
+
|
|
303
|
+
#### UserPromptSubmitHookSpecificOutput
|
|
304
|
+
|
|
305
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
306
|
+
|---------------------|:----------:|:------:|:----:|----------------------------------|
|
|
307
|
+
| `additionalContext` | ✅ | ❌ | ✅ | Context string returned to model |
|
|
308
|
+
|
|
309
|
+
#### PermissionRequestHookSpecificOutput
|
|
310
|
+
|
|
311
|
+
| Field | TypeScript | Python | Ruby | Notes |
|
|
312
|
+
|------------|:----------:|:------:|:----:|------------------------------------------|
|
|
313
|
+
| `decision` | ✅ | ❌ | ✅ | `{ behavior: 'allow'/'deny', ... }` obj |
|
|
314
|
+
|
|
251
315
|
### Hook Matcher
|
|
252
316
|
|
|
253
317
|
| Field | TypeScript | Python | Ruby |
|
|
@@ -414,6 +478,8 @@ Custom subagent definitions.
|
|
|
414
478
|
| `model` | ✅ | ✅ | ✅ | Model override (sonnet/opus/haiku/inherit) |
|
|
415
479
|
| `mcpServers` | ✅ | ❌ | ✅ | Agent-specific MCP servers |
|
|
416
480
|
| `criticalSystemReminder_EXPERIMENTAL` | ✅ | ❌ | ✅ | Critical reminder (experimental) |
|
|
481
|
+
| `skills` | ✅ | ❌ | ✅ | Skills to preload into agent context |
|
|
482
|
+
| `maxTurns` | ✅ | ❌ | ✅ | Max agentic turns before stopping |
|
|
417
483
|
|
|
418
484
|
---
|
|
419
485
|
|
|
@@ -531,6 +597,7 @@ Public API surface for SDK clients.
|
|
|
531
597
|
|
|
532
598
|
- ✅ = Fully implemented
|
|
533
599
|
- ❌ = Not implemented
|
|
600
|
+
- N/A = Not applicable (language-specific feature)
|
|
534
601
|
- Partial = Partially implemented
|
|
535
602
|
|
|
536
603
|
---
|
|
@@ -541,21 +608,27 @@ Public API surface for SDK clients.
|
|
|
541
608
|
- Primary reference for API surface (most comprehensive)
|
|
542
609
|
- Source is bundled/minified, but `sdk.d.ts` provides complete type definitions
|
|
543
610
|
- Includes unstable V2 session API
|
|
544
|
-
- Version 0.2.5 includes `maxOutputTokens` field in `ModelUsage`
|
|
545
611
|
- Adds `deno` as supported executable option
|
|
546
612
|
- Includes experimental `criticalSystemReminder_EXPERIMENTAL` for agent definitions
|
|
613
|
+
- `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
|
|
547
618
|
|
|
548
619
|
### Python SDK
|
|
549
|
-
- Full source available
|
|
620
|
+
- Full source available (v0.1.20)
|
|
550
621
|
- Fewer control protocol features than TypeScript
|
|
551
622
|
- Does not support SessionStart/SessionEnd/Notification hooks due to setup limitations
|
|
552
623
|
- Missing several permission modes (delegate, dontAsk)
|
|
553
624
|
- `excludedCommands` in sandbox now supported
|
|
625
|
+
- `tool_use_id` now included in PreToolUseHookInput
|
|
554
626
|
|
|
555
627
|
### Ruby SDK (This Repository)
|
|
556
|
-
-
|
|
628
|
+
- Full TypeScript SDK feature parity achieved
|
|
557
629
|
- Ruby-idiomatic patterns (Data.define, snake_case)
|
|
558
630
|
- Complete control protocol support
|
|
559
631
|
- Dedicated Client class for multi-turn conversations
|
|
560
|
-
- Full hook event support including all
|
|
632
|
+
- Full hook event support including all 13 events
|
|
561
633
|
- Full V2 Session API support (unstable)
|
|
634
|
+
- `executable`/`executableArgs` marked N/A (JS runtime options not applicable to Ruby)
|
data/lib/claude_agent/hooks.rb
CHANGED
|
@@ -15,6 +15,7 @@ module ClaudeAgent
|
|
|
15
15
|
SubagentStop
|
|
16
16
|
PreCompact
|
|
17
17
|
PermissionRequest
|
|
18
|
+
Setup
|
|
18
19
|
].freeze
|
|
19
20
|
|
|
20
21
|
# Matcher configuration for hooks
|
|
@@ -141,14 +142,16 @@ module ClaudeAgent
|
|
|
141
142
|
# Input for SessionStart hook (TypeScript SDK parity)
|
|
142
143
|
#
|
|
143
144
|
class SessionStartInput < BaseHookInput
|
|
144
|
-
attr_reader :source, :agent_type
|
|
145
|
+
attr_reader :source, :agent_type, :model
|
|
145
146
|
|
|
146
147
|
# @param source [String] One of: "startup", "resume", "clear", "compact"
|
|
147
148
|
# @param agent_type [String, nil] Type of agent if running in subagent context
|
|
148
|
-
|
|
149
|
+
# @param model [String, nil] Model being used for this session
|
|
150
|
+
def initialize(source:, agent_type: nil, model: nil, **kwargs)
|
|
149
151
|
super(hook_event_name: "SessionStart", **kwargs)
|
|
150
152
|
@source = source
|
|
151
153
|
@agent_type = agent_type
|
|
154
|
+
@model = model
|
|
152
155
|
end
|
|
153
156
|
end
|
|
154
157
|
|
|
@@ -225,4 +228,35 @@ module ClaudeAgent
|
|
|
225
228
|
@permission_suggestions = permission_suggestions
|
|
226
229
|
end
|
|
227
230
|
end
|
|
231
|
+
|
|
232
|
+
# Input for Setup hook (TypeScript SDK parity)
|
|
233
|
+
#
|
|
234
|
+
# Triggered during initial setup or maintenance operations.
|
|
235
|
+
#
|
|
236
|
+
# @example
|
|
237
|
+
# input = SetupInput.new(trigger: "init", session_id: "abc-123")
|
|
238
|
+
# input.trigger # => "init"
|
|
239
|
+
# input.init? # => true
|
|
240
|
+
#
|
|
241
|
+
class SetupInput < BaseHookInput
|
|
242
|
+
attr_reader :trigger
|
|
243
|
+
|
|
244
|
+
# @param trigger [String] One of: "init", "maintenance"
|
|
245
|
+
def initialize(trigger:, **kwargs)
|
|
246
|
+
super(hook_event_name: "Setup", **kwargs)
|
|
247
|
+
@trigger = trigger
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Check if this is an init trigger
|
|
251
|
+
# @return [Boolean]
|
|
252
|
+
def init?
|
|
253
|
+
trigger == "init"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Check if this is a maintenance trigger
|
|
257
|
+
# @return [Boolean]
|
|
258
|
+
def maintenance?
|
|
259
|
+
trigger == "maintenance"
|
|
260
|
+
end
|
|
261
|
+
end
|
|
228
262
|
end
|
|
@@ -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]
|
|
14
|
+
# @return [UserMessage, UserMessageReplay, AssistantMessage, SystemMessage, ResultMessage, StreamEvent, CompactBoundaryMessage, StatusMessage, ToolProgressMessage, HookResponseMessage, AuthStatusMessage, TaskNotificationMessage]
|
|
15
15
|
# @raise [MessageParseError] If message cannot be parsed
|
|
16
16
|
def parse(raw)
|
|
17
17
|
type = raw["type"]
|
|
@@ -30,6 +30,8 @@ module ClaudeAgent
|
|
|
30
30
|
parse_status_message(raw)
|
|
31
31
|
when "hook_response"
|
|
32
32
|
parse_hook_response_message(raw)
|
|
33
|
+
when "task_notification"
|
|
34
|
+
parse_task_notification_message(raw)
|
|
33
35
|
else
|
|
34
36
|
parse_system_message(raw)
|
|
35
37
|
end
|
|
@@ -258,5 +260,16 @@ module ClaudeAgent
|
|
|
258
260
|
error: raw["error"]
|
|
259
261
|
)
|
|
260
262
|
end
|
|
263
|
+
|
|
264
|
+
def parse_task_notification_message(raw)
|
|
265
|
+
TaskNotificationMessage.new(
|
|
266
|
+
uuid: raw["uuid"] || "",
|
|
267
|
+
session_id: fetch_dual(raw, :session_id, ""),
|
|
268
|
+
task_id: fetch_dual(raw, :task_id, ""),
|
|
269
|
+
status: raw["status"] || "unknown",
|
|
270
|
+
output_file: fetch_dual(raw, :output_file, ""),
|
|
271
|
+
summary: raw["summary"] || ""
|
|
272
|
+
)
|
|
273
|
+
end
|
|
261
274
|
end
|
|
262
275
|
end
|
|
@@ -404,6 +404,70 @@ module ClaudeAgent
|
|
|
404
404
|
end
|
|
405
405
|
end
|
|
406
406
|
|
|
407
|
+
# Task notification message (TypeScript SDK parity)
|
|
408
|
+
#
|
|
409
|
+
# Sent when a background task completes, fails, or is stopped.
|
|
410
|
+
# Used for tracking async task execution status.
|
|
411
|
+
#
|
|
412
|
+
# @example
|
|
413
|
+
# msg = TaskNotificationMessage.new(
|
|
414
|
+
# uuid: "msg-123",
|
|
415
|
+
# session_id: "session-abc",
|
|
416
|
+
# task_id: "task-456",
|
|
417
|
+
# status: "completed",
|
|
418
|
+
# output_file: "/path/to/output.txt",
|
|
419
|
+
# summary: "Task completed successfully"
|
|
420
|
+
# )
|
|
421
|
+
# msg.completed? # => true
|
|
422
|
+
# msg.failed? # => false
|
|
423
|
+
#
|
|
424
|
+
# Status values:
|
|
425
|
+
# - "completed" - Task finished successfully
|
|
426
|
+
# - "failed" - Task encountered an error
|
|
427
|
+
# - "stopped" - Task was manually stopped
|
|
428
|
+
#
|
|
429
|
+
TaskNotificationMessage = Data.define(
|
|
430
|
+
:uuid,
|
|
431
|
+
:session_id,
|
|
432
|
+
:task_id,
|
|
433
|
+
:status,
|
|
434
|
+
:output_file,
|
|
435
|
+
:summary
|
|
436
|
+
) do
|
|
437
|
+
def initialize(
|
|
438
|
+
uuid:,
|
|
439
|
+
session_id:,
|
|
440
|
+
task_id:,
|
|
441
|
+
status:,
|
|
442
|
+
output_file:,
|
|
443
|
+
summary:
|
|
444
|
+
)
|
|
445
|
+
super
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def type
|
|
449
|
+
:task_notification
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
# Check if task completed successfully
|
|
453
|
+
# @return [Boolean]
|
|
454
|
+
def completed?
|
|
455
|
+
status == "completed"
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
# Check if task failed
|
|
459
|
+
# @return [Boolean]
|
|
460
|
+
def failed?
|
|
461
|
+
status == "failed"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
# Check if task was stopped
|
|
465
|
+
# @return [Boolean]
|
|
466
|
+
def stopped?
|
|
467
|
+
status == "stopped"
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
407
471
|
# All message types
|
|
408
472
|
MESSAGE_TYPES = [
|
|
409
473
|
UserMessage,
|
|
@@ -416,6 +480,7 @@ module ClaudeAgent
|
|
|
416
480
|
StatusMessage,
|
|
417
481
|
ToolProgressMessage,
|
|
418
482
|
HookResponseMessage,
|
|
419
|
-
AuthStatusMessage
|
|
483
|
+
AuthStatusMessage,
|
|
484
|
+
TaskNotificationMessage
|
|
420
485
|
].freeze
|
|
421
486
|
end
|
data/lib/claude_agent/options.rb
CHANGED
|
@@ -38,7 +38,10 @@ module ClaudeAgent
|
|
|
38
38
|
include_partial_messages: false,
|
|
39
39
|
enable_file_checkpointing: false,
|
|
40
40
|
persist_session: true,
|
|
41
|
-
betas: []
|
|
41
|
+
betas: [],
|
|
42
|
+
init: false,
|
|
43
|
+
init_only: false,
|
|
44
|
+
maintenance: false
|
|
42
45
|
}.freeze
|
|
43
46
|
|
|
44
47
|
# All configurable attributes
|
|
@@ -50,11 +53,12 @@ module ClaudeAgent
|
|
|
50
53
|
continue_conversation resume fork_session resume_session_at
|
|
51
54
|
max_turns max_budget_usd max_thinking_tokens
|
|
52
55
|
strict_mcp_config mcp_servers hooks
|
|
53
|
-
settings sandbox cwd add_dirs env user
|
|
56
|
+
settings sandbox cwd add_dirs env user agent
|
|
54
57
|
cli_path extra_args agents setting_sources plugins
|
|
55
58
|
include_partial_messages output_format enable_file_checkpointing
|
|
56
59
|
persist_session betas max_buffer_size stderr_callback
|
|
57
60
|
abort_controller spawn_claude_code_process
|
|
61
|
+
init init_only maintenance
|
|
58
62
|
].freeze
|
|
59
63
|
|
|
60
64
|
attr_accessor(*ATTRIBUTES)
|
|
@@ -83,6 +87,7 @@ module ClaudeAgent
|
|
|
83
87
|
args.concat(settings_args)
|
|
84
88
|
args.concat(environment_args)
|
|
85
89
|
args.concat(output_args)
|
|
90
|
+
args.concat(setup_hook_args)
|
|
86
91
|
args.concat(extra_cli_args)
|
|
87
92
|
end
|
|
88
93
|
end
|
|
@@ -206,6 +211,7 @@ module ClaudeAgent
|
|
|
206
211
|
def environment_args
|
|
207
212
|
[].tap do |args|
|
|
208
213
|
args.push("--user", user) if user
|
|
214
|
+
args.push("--agent", agent) if agent
|
|
209
215
|
add_dirs.each { |dir| args.push("--add-dir", dir.to_s) }
|
|
210
216
|
args.push("--setting-sources", setting_sources.join(",")) if setting_sources&.any?
|
|
211
217
|
plugins.each do |plugin|
|
|
@@ -229,6 +235,14 @@ module ClaudeAgent
|
|
|
229
235
|
end
|
|
230
236
|
end
|
|
231
237
|
|
|
238
|
+
def setup_hook_args
|
|
239
|
+
[].tap do |args|
|
|
240
|
+
args.push("--init") if init
|
|
241
|
+
args.push("--init-only") if init_only
|
|
242
|
+
args.push("--maintenance") if maintenance
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
232
246
|
def extra_cli_args
|
|
233
247
|
[].tap do |args|
|
|
234
248
|
extra_args.each do |key, value|
|
|
@@ -261,6 +275,11 @@ module ClaudeAgent
|
|
|
261
275
|
if max_budget_usd && (!max_budget_usd.is_a?(Numeric) || max_budget_usd <= 0)
|
|
262
276
|
raise ConfigurationError, "max_budget_usd must be a positive number"
|
|
263
277
|
end
|
|
278
|
+
|
|
279
|
+
setup_options = [ init, init_only, maintenance ].count { |opt| opt }
|
|
280
|
+
if setup_options > 1
|
|
281
|
+
raise ConfigurationError, "Only one of init, init_only, or maintenance can be set at a time"
|
|
282
|
+
end
|
|
264
283
|
end
|
|
265
284
|
end
|
|
266
285
|
end
|
data/lib/claude_agent/query.rb
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
module ClaudeAgent
|
|
4
4
|
class << self
|
|
5
|
+
# Run Setup hooks and exit
|
|
6
|
+
#
|
|
7
|
+
# This is a convenience method for running Setup hooks without starting
|
|
8
|
+
# a conversation. Useful for CI/CD pipelines or scripts that need to
|
|
9
|
+
# ensure setup is complete before proceeding.
|
|
10
|
+
#
|
|
11
|
+
# @param trigger [Symbol] The setup trigger (:init or :maintenance)
|
|
12
|
+
# @param options [Options, nil] Additional configuration options
|
|
13
|
+
# @return [Array<Message>] All messages received during setup
|
|
14
|
+
#
|
|
15
|
+
# @example Run init setup
|
|
16
|
+
# messages = ClaudeAgent.run_setup
|
|
17
|
+
# result = messages.last
|
|
18
|
+
# puts "Setup completed" if result.success?
|
|
19
|
+
#
|
|
20
|
+
# @example Run init setup with custom options
|
|
21
|
+
# options = ClaudeAgent::Options.new(cwd: "/my/project")
|
|
22
|
+
# ClaudeAgent.run_setup(trigger: :init, options: options)
|
|
23
|
+
#
|
|
24
|
+
# @note The :maintenance trigger requires --maintenance flag which
|
|
25
|
+
# continues into a conversation. For maintenance-only behavior,
|
|
26
|
+
# use options with maintenance: true and handle accordingly.
|
|
27
|
+
#
|
|
28
|
+
def run_setup(trigger: :init, options: nil)
|
|
29
|
+
options ||= Options.new
|
|
30
|
+
|
|
31
|
+
case trigger
|
|
32
|
+
when :init
|
|
33
|
+
# Create new options with init_only set
|
|
34
|
+
setup_options = Options.new(**options_to_hash(options).merge(init_only: true))
|
|
35
|
+
when :maintenance
|
|
36
|
+
# Note: There's no --maintenance-only flag, so we use --maintenance
|
|
37
|
+
# which will continue into a conversation. The caller should handle this.
|
|
38
|
+
setup_options = Options.new(**options_to_hash(options).merge(maintenance: true))
|
|
39
|
+
else
|
|
40
|
+
raise ArgumentError, "Invalid trigger: #{trigger}. Must be :init or :maintenance"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Run with an empty prompt - setup hooks run before the prompt is processed
|
|
44
|
+
query(prompt: "", options: setup_options).to_a
|
|
45
|
+
end
|
|
46
|
+
|
|
5
47
|
# One-shot query to Claude Code CLI
|
|
6
48
|
#
|
|
7
49
|
# This is a simple, stateless interface for sending a single prompt
|
|
@@ -86,5 +128,17 @@ module ClaudeAgent
|
|
|
86
128
|
end
|
|
87
129
|
end
|
|
88
130
|
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
# Convert an Options object to a hash for merging
|
|
135
|
+
# @param options [Options] The options object
|
|
136
|
+
# @return [Hash] Hash of option values
|
|
137
|
+
def options_to_hash(options)
|
|
138
|
+
Options::ATTRIBUTES.each_with_object({}) do |attr, hash|
|
|
139
|
+
value = options.send(attr)
|
|
140
|
+
hash[attr] = value unless value.nil?
|
|
141
|
+
end
|
|
142
|
+
end
|
|
89
143
|
end
|
|
90
144
|
end
|
data/lib/claude_agent/types.rb
CHANGED
|
@@ -150,7 +150,7 @@ module ClaudeAgent
|
|
|
150
150
|
|
|
151
151
|
# Agent definition for custom subagents (TypeScript SDK parity)
|
|
152
152
|
#
|
|
153
|
-
# @example
|
|
153
|
+
# @example Basic agent
|
|
154
154
|
# agent = AgentDefinition.new(
|
|
155
155
|
# description: "Runs tests and reports results",
|
|
156
156
|
# prompt: "You are a test runner...",
|
|
@@ -158,6 +158,14 @@ module ClaudeAgent
|
|
|
158
158
|
# model: "haiku"
|
|
159
159
|
# )
|
|
160
160
|
#
|
|
161
|
+
# @example Agent with skills and max_turns
|
|
162
|
+
# agent = AgentDefinition.new(
|
|
163
|
+
# description: "Research agent with specialized skills",
|
|
164
|
+
# prompt: "You are a research expert...",
|
|
165
|
+
# skills: ["web-search", "summarization"],
|
|
166
|
+
# max_turns: 10
|
|
167
|
+
# )
|
|
168
|
+
#
|
|
161
169
|
AgentDefinition = Data.define(
|
|
162
170
|
:description,
|
|
163
171
|
:prompt,
|
|
@@ -165,7 +173,9 @@ module ClaudeAgent
|
|
|
165
173
|
:disallowed_tools,
|
|
166
174
|
:model,
|
|
167
175
|
:mcp_servers,
|
|
168
|
-
:critical_system_reminder
|
|
176
|
+
:critical_system_reminder,
|
|
177
|
+
:skills,
|
|
178
|
+
:max_turns
|
|
169
179
|
) do
|
|
170
180
|
def initialize(
|
|
171
181
|
description:,
|
|
@@ -174,7 +184,9 @@ module ClaudeAgent
|
|
|
174
184
|
disallowed_tools: nil,
|
|
175
185
|
model: nil,
|
|
176
186
|
mcp_servers: nil,
|
|
177
|
-
critical_system_reminder: nil
|
|
187
|
+
critical_system_reminder: nil,
|
|
188
|
+
skills: nil,
|
|
189
|
+
max_turns: nil
|
|
178
190
|
)
|
|
179
191
|
super
|
|
180
192
|
end
|
|
@@ -189,6 +201,8 @@ module ClaudeAgent
|
|
|
189
201
|
result[:model] = model if model
|
|
190
202
|
result[:mcpServers] = mcp_servers if mcp_servers
|
|
191
203
|
result[:criticalSystemReminder_EXPERIMENTAL] = critical_system_reminder if critical_system_reminder
|
|
204
|
+
result[:skills] = skills if skills
|
|
205
|
+
result[:maxTurns] = max_turns if max_turns
|
|
192
206
|
result
|
|
193
207
|
end
|
|
194
208
|
end
|
data/lib/claude_agent/version.rb
CHANGED
data/sig/claude_agent.rbs
CHANGED
|
@@ -279,6 +279,7 @@ module ClaudeAgent
|
|
|
279
279
|
attr_accessor add_dirs: Array[String]
|
|
280
280
|
attr_accessor env: Hash[String, String]
|
|
281
281
|
attr_accessor user: String?
|
|
282
|
+
attr_accessor agent: String?
|
|
282
283
|
|
|
283
284
|
# CLI configuration
|
|
284
285
|
attr_accessor cli_path: String?
|
|
@@ -633,8 +634,9 @@ module ClaudeAgent
|
|
|
633
634
|
class SessionStartInput < BaseHookInput
|
|
634
635
|
attr_reader source: String
|
|
635
636
|
attr_reader agent_type: String?
|
|
637
|
+
attr_reader model: String?
|
|
636
638
|
|
|
637
|
-
def initialize: (source: String, ?agent_type: String?, **untyped) -> void
|
|
639
|
+
def initialize: (source: String, ?agent_type: String?, ?model: String?, **untyped) -> void
|
|
638
640
|
end
|
|
639
641
|
|
|
640
642
|
class SessionEndInput < BaseHookInput
|