claude_agent 0.3.0 → 0.4.2
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/.claude/rules/releases.md +35 -114
- data/CHANGELOG.md +25 -0
- data/README.md +39 -1
- data/SPEC.md +130 -62
- data/lib/claude_agent/hooks.rb +32 -0
- data/lib/claude_agent/message_parser.rb +14 -1
- data/lib/claude_agent/messages.rb +66 -1
- data/lib/claude_agent/options.rb +19 -1
- data/lib/claude_agent/query.rb +54 -0
- data/lib/claude_agent/types.rb +17 -3
- data/lib/claude_agent/version.rb +1 -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: 3dad011bddaedd68fe720527eeeda0a4dbe1f2b7ee9621e0ea6a0b2a3c09bc62
|
|
4
|
+
data.tar.gz: 161a59562a2cd86cfc6aca140259c996892dc68b604fc9500c3337dd814be4b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a157be028a9102d174db09a0298a63eb7051253d5c6d2173a5f6d111f72da5a9c7fd286d41e948cf35ddecfdd9c45a14d08e7dca397fe7391b0505f9cc8a507
|
|
7
|
+
data.tar.gz: f16dd8d278d5291145fae97cf14bc525f47cdae4b2c2de34cfa041b754a9bdd4bdc57aae2ee8b4e0ad0081de026e53affeded6c53e8d11549903d6d3a3c69f53
|
data/.claude/rules/releases.md
CHANGED
|
@@ -12,72 +12,18 @@ Follow [Semantic Versioning 2.0.0](https://semver.org/):
|
|
|
12
12
|
| **MINOR** | New features (backward compatible) | `1.0.0` → `1.1.0` |
|
|
13
13
|
| **PATCH** | Bug fixes (backward compatible) | `1.0.0` → `1.0.1` |
|
|
14
14
|
|
|
15
|
-
### Pre-release Versions
|
|
16
|
-
|
|
17
|
-
For beta/alpha releases, append a pre-release identifier:
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
1.0.0-alpha.1
|
|
21
|
-
1.0.0-beta.1
|
|
22
|
-
1.0.0-rc.1
|
|
23
|
-
```
|
|
24
|
-
|
|
25
15
|
## Changelog Format
|
|
26
16
|
|
|
27
|
-
Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format
|
|
28
|
-
|
|
29
|
-
```markdown
|
|
30
|
-
## [Unreleased]
|
|
31
|
-
|
|
32
|
-
## [1.2.0] - 2025-03-15
|
|
33
|
-
|
|
34
|
-
### Added
|
|
35
|
-
- New feature description
|
|
36
|
-
|
|
37
|
-
### Changed
|
|
38
|
-
- Modified behavior description
|
|
39
|
-
|
|
40
|
-
### Deprecated
|
|
41
|
-
- Feature scheduled for removal
|
|
42
|
-
|
|
43
|
-
### Removed
|
|
44
|
-
- Deleted feature description
|
|
45
|
-
|
|
46
|
-
### Fixed
|
|
47
|
-
- Bug fix description
|
|
48
|
-
|
|
49
|
-
### Security
|
|
50
|
-
- Security patch description
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Changelog Guidelines
|
|
54
|
-
|
|
55
|
-
1. **Maintain [Unreleased]** - Always keep an Unreleased section at the top
|
|
56
|
-
2. **Add entries as you work** - Don't wait until release time
|
|
57
|
-
3. **User-focused language** - Write for gem users, not developers
|
|
58
|
-
4. **Link to issues/PRs** - Reference GitHub issues when relevant
|
|
59
|
-
5. **Newest first** - Most recent version at top
|
|
60
|
-
|
|
61
|
-
### What to Include
|
|
62
|
-
|
|
63
|
-
| Include | Exclude |
|
|
64
|
-
|---------|---------|
|
|
65
|
-
| API additions/changes | Internal refactors |
|
|
66
|
-
| Bug fixes users might hit | Code style changes |
|
|
67
|
-
| Deprecation notices | Test-only changes |
|
|
68
|
-
| Breaking changes (prominent) | Documentation typos |
|
|
69
|
-
| Security fixes | Dependency updates (minor) |
|
|
17
|
+
Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. Maintain an `[Unreleased]` section at the top for work in progress.
|
|
70
18
|
|
|
71
19
|
## Release Process
|
|
72
20
|
|
|
73
21
|
### Prerequisites
|
|
74
22
|
|
|
75
|
-
Before releasing:
|
|
76
|
-
|
|
77
23
|
1. All tests pass (`bundle exec rake`)
|
|
78
|
-
2. CHANGELOG.md has entry for new version
|
|
79
|
-
3.
|
|
80
|
-
4.
|
|
24
|
+
2. CHANGELOG.md has entry for the new version
|
|
25
|
+
3. You have push access to main branch
|
|
26
|
+
4. You have RubyGems publish credentials configured
|
|
81
27
|
|
|
82
28
|
### Release Command
|
|
83
29
|
|
|
@@ -94,19 +40,40 @@ bin/release 1.2.0
|
|
|
94
40
|
|
|
95
41
|
1. Validates version format (semantic versioning)
|
|
96
42
|
2. Checks CHANGELOG.md has entry for version
|
|
97
|
-
3.
|
|
98
|
-
4. Updates `
|
|
99
|
-
5.
|
|
100
|
-
6.
|
|
101
|
-
7. Pushes
|
|
102
|
-
8.
|
|
43
|
+
3. Checks tag doesn't already exist
|
|
44
|
+
4. Updates `lib/claude_agent/version.rb`
|
|
45
|
+
5. Updates `Gemfile.lock`
|
|
46
|
+
6. Commits with message "Bump version for X.Y.Z"
|
|
47
|
+
7. Pushes to current branch
|
|
48
|
+
8. Creates and pushes tag `vX.Y.Z`
|
|
49
|
+
9. Builds and publishes gem to RubyGems
|
|
103
50
|
|
|
104
|
-
###
|
|
51
|
+
### Example Workflow
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# 1. Ensure tests pass
|
|
55
|
+
bundle exec rake
|
|
105
56
|
|
|
106
|
-
|
|
57
|
+
# 2. Update CHANGELOG.md
|
|
58
|
+
# Move items from [Unreleased] to new version section:
|
|
59
|
+
## [1.2.0] - 2025-03-15
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
- New feature description
|
|
107
63
|
|
|
108
|
-
|
|
109
|
-
|
|
64
|
+
# 3. Commit changelog
|
|
65
|
+
git add CHANGELOG.md
|
|
66
|
+
git commit -m "docs: update changelog for 1.2.0"
|
|
67
|
+
git push
|
|
68
|
+
|
|
69
|
+
# 4. Release
|
|
70
|
+
bin/release 1.2.0
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Post-Release
|
|
74
|
+
|
|
75
|
+
1. Add `## [Unreleased]` section to CHANGELOG.md if needed
|
|
76
|
+
2. Optionally create a GitHub release at the new tag
|
|
110
77
|
|
|
111
78
|
## Version Bumping Guidelines
|
|
112
79
|
|
|
@@ -115,7 +82,6 @@ After running `bin/release`:
|
|
|
115
82
|
- Removing public methods/classes
|
|
116
83
|
- Changing method signatures (required params)
|
|
117
84
|
- Changing return types
|
|
118
|
-
- Renaming public constants
|
|
119
85
|
- Dropping Ruby version support
|
|
120
86
|
|
|
121
87
|
### When to Bump MINOR (Feature)
|
|
@@ -130,48 +96,3 @@ After running `bin/release`:
|
|
|
130
96
|
- Bug fixes
|
|
131
97
|
- Documentation corrections
|
|
132
98
|
- Performance improvements (no API change)
|
|
133
|
-
- Internal refactoring (no API change)
|
|
134
|
-
|
|
135
|
-
## Example Release Workflow
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# 1. Ensure tests pass
|
|
139
|
-
bundle exec rake
|
|
140
|
-
|
|
141
|
-
# 2. Update CHANGELOG.md
|
|
142
|
-
# Add entry under [Unreleased], then rename to version:
|
|
143
|
-
## [1.2.0] - 2025-03-15
|
|
144
|
-
|
|
145
|
-
### Added
|
|
146
|
-
- New `Client#foo` method for bar functionality
|
|
147
|
-
|
|
148
|
-
### Fixed
|
|
149
|
-
- Resolved timeout issue in subprocess transport
|
|
150
|
-
|
|
151
|
-
# 3. Commit changelog
|
|
152
|
-
git add CHANGELOG.md
|
|
153
|
-
git commit -m "docs: update changelog for 1.2.0"
|
|
154
|
-
|
|
155
|
-
# 4. Release
|
|
156
|
-
bin/release 1.2.0
|
|
157
|
-
|
|
158
|
-
# 5. Add new Unreleased section
|
|
159
|
-
# Edit CHANGELOG.md to add:
|
|
160
|
-
## [Unreleased]
|
|
161
|
-
|
|
162
|
-
# 6. Commit
|
|
163
|
-
git add CHANGELOG.md
|
|
164
|
-
git commit -m "docs: add unreleased section"
|
|
165
|
-
git push
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Gem Metadata
|
|
169
|
-
|
|
170
|
-
The gemspec includes these URIs for RubyGems.org:
|
|
171
|
-
|
|
172
|
-
```ruby
|
|
173
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
|
174
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
This enables the "Changelog" link on the RubyGems.org gem page.
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.2] - 2026-01-18
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Release script now uses `bundle install` (Bundler 4.x compatibility)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Release script prompts for RubyGems OTP upfront
|
|
17
|
+
- Release script creates GitHub releases automatically
|
|
18
|
+
|
|
19
|
+
## [0.4.1] - 2026-01-18
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Simplified release script to match Kamal's approach
|
|
23
|
+
|
|
24
|
+
## [0.4.0] - 2026-01-18
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- `TaskNotificationMessage` for background task completion notifications
|
|
28
|
+
- `Setup` hook event with `SetupInput` for init/maintenance triggers
|
|
29
|
+
- `skills` and `max_turns` fields in `AgentDefinition` (TypeScript SDK v0.2.12 parity)
|
|
30
|
+
- `init`, `init_only`, `maintenance` options for running Setup hooks
|
|
31
|
+
- `ClaudeAgent.run_setup` convenience method for CI/CD pipelines
|
|
32
|
+
- Hook-specific output fields documentation (`additionalContext`, `permissionDecision`, `updatedMCPToolOutput`, etc.)
|
|
33
|
+
- Document `settings` option accepts JSON strings (for plansDirectory, etc.)
|
|
34
|
+
|
|
10
35
|
## [0.3.0] - 2026-01-16
|
|
11
36
|
|
|
12
37
|
### Added
|
data/README.md
CHANGED
|
@@ -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:
|
|
@@ -161,7 +181,9 @@ agents = {
|
|
|
161
181
|
description: "Runs tests and reports results",
|
|
162
182
|
prompt: "You are a test runner. Execute tests and report failures clearly.",
|
|
163
183
|
tools: ["Read", "Bash"],
|
|
164
|
-
model: "haiku"
|
|
184
|
+
model: "haiku",
|
|
185
|
+
max_turns: 5, # Max agentic turns before stopping
|
|
186
|
+
skills: ["testing", "debug"] # Skills to preload into agent context
|
|
165
187
|
)
|
|
166
188
|
}
|
|
167
189
|
|
|
@@ -277,6 +299,20 @@ auth.output # Auth output messages
|
|
|
277
299
|
auth.error # Error message (if any)
|
|
278
300
|
```
|
|
279
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
|
+
|
|
280
316
|
## Content Blocks
|
|
281
317
|
|
|
282
318
|
Assistant messages contain content blocks:
|
|
@@ -449,6 +485,7 @@ All available hook events:
|
|
|
449
485
|
- `SubagentStop` - When subagent stops
|
|
450
486
|
- `PreCompact` - Before conversation compaction
|
|
451
487
|
- `PermissionRequest` - When permission is requested
|
|
488
|
+
- `Setup` - Initial setup or maintenance (trigger: "init" or "maintenance")
|
|
452
489
|
|
|
453
490
|
### Hook Input Types
|
|
454
491
|
|
|
@@ -466,6 +503,7 @@ All available hook events:
|
|
|
466
503
|
| SubagentStop | `SubagentStopInput` | stop_hook_active, agent_id, agent_transcript_path |
|
|
467
504
|
| PreCompact | `PreCompactInput` | trigger, custom_instructions |
|
|
468
505
|
| PermissionRequest | `PermissionRequestInput` | tool_name, tool_input, permission_suggestions |
|
|
506
|
+
| Setup | `SetupInput` | trigger (init/maintenance) |
|
|
469
507
|
|
|
470
508
|
All hook inputs inherit from `BaseHookInput` with: `hook_event_name`, `session_id`, `transcript_path`, `cwd`, `permission_mode`.
|
|
471
509
|
|
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: v0.1.20 from GitHub (commit
|
|
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,50 +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
|
-
| `
|
|
76
|
-
| `
|
|
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) |
|
|
77
81
|
|
|
78
82
|
---
|
|
79
83
|
|
|
@@ -94,6 +98,7 @@ Messages exchanged between SDK and CLI.
|
|
|
94
98
|
| `ToolProgressMessage` | ✅ | ❌ | ✅ | Long-running tool progress |
|
|
95
99
|
| `HookResponseMessage` | ✅ | ❌ | ✅ | Hook execution output |
|
|
96
100
|
| `AuthStatusMessage` | ✅ | ❌ | ✅ | Authentication status |
|
|
101
|
+
| `TaskNotificationMessage`| ✅ | ❌ | ✅ | Background task completion |
|
|
97
102
|
|
|
98
103
|
### Message Fields
|
|
99
104
|
|
|
@@ -203,20 +208,21 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
203
208
|
|
|
204
209
|
### Hook Events
|
|
205
210
|
|
|
206
|
-
| Event | TypeScript | Python | Ruby | Notes
|
|
207
|
-
|
|
208
|
-
| `PreToolUse` | ✅ | ✅ | ✅ | Before tool execution
|
|
209
|
-
| `PostToolUse` | ✅ | ✅ | ✅ | After tool execution
|
|
210
|
-
| `PostToolUseFailure` | ✅ | ❌ | ✅ | After tool failure
|
|
211
|
-
| `Notification` | ✅ | ❌ | ✅ | System notifications
|
|
212
|
-
| `UserPromptSubmit` | ✅ | ✅ | ✅ | User message submitted
|
|
213
|
-
| `SessionStart` | ✅ | ❌ | ✅ | Session starts
|
|
214
|
-
| `SessionEnd` | ✅ | ❌ | ✅ | Session ends
|
|
215
|
-
| `Stop` | ✅ | ✅ | ✅ | Agent stops
|
|
216
|
-
| `SubagentStart` | ✅ | ❌ | ✅ | Subagent starts
|
|
217
|
-
| `SubagentStop` | ✅ | ✅ | ✅ | Subagent stops
|
|
218
|
-
| `PreCompact` | ✅ | ✅ | ✅ | Before compaction
|
|
219
|
-
| `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 |
|
|
220
226
|
|
|
221
227
|
### Hook Input Types
|
|
222
228
|
|
|
@@ -234,6 +240,7 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
234
240
|
| `SubagentStopHookInput` | ✅ | ✅ | ✅ |
|
|
235
241
|
| `PreCompactHookInput` | ✅ | ✅ | ✅ |
|
|
236
242
|
| `PermissionRequestHookInput` | ✅ | ❌ | ✅ |
|
|
243
|
+
| `SetupHookInput` | ✅ | ❌ | ✅ |
|
|
237
244
|
|
|
238
245
|
### Hook Output Types
|
|
239
246
|
|
|
@@ -249,6 +256,62 @@ Event hooks for intercepting and modifying SDK behavior.
|
|
|
249
256
|
| `reason` | ✅ | ✅ | ✅ | Reason feedback |
|
|
250
257
|
| `hookSpecificOutput` | ✅ | ✅ | ✅ | Event-specific output |
|
|
251
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
|
+
|
|
252
315
|
### Hook Matcher
|
|
253
316
|
|
|
254
317
|
| Field | TypeScript | Python | Ruby |
|
|
@@ -415,6 +478,8 @@ Custom subagent definitions.
|
|
|
415
478
|
| `model` | ✅ | ✅ | ✅ | Model override (sonnet/opus/haiku/inherit) |
|
|
416
479
|
| `mcpServers` | ✅ | ❌ | ✅ | Agent-specific MCP servers |
|
|
417
480
|
| `criticalSystemReminder_EXPERIMENTAL` | ✅ | ❌ | ✅ | Critical reminder (experimental) |
|
|
481
|
+
| `skills` | ✅ | ❌ | ✅ | Skills to preload into agent context |
|
|
482
|
+
| `maxTurns` | ✅ | ❌ | ✅ | Max agentic turns before stopping |
|
|
418
483
|
|
|
419
484
|
---
|
|
420
485
|
|
|
@@ -543,10 +608,13 @@ Public API surface for SDK clients.
|
|
|
543
608
|
- Primary reference for API surface (most comprehensive)
|
|
544
609
|
- Source is bundled/minified, but `sdk.d.ts` provides complete type definitions
|
|
545
610
|
- Includes unstable V2 session API
|
|
546
|
-
- Version 0.2.9 adds `agent` option for specifying main thread agent
|
|
547
611
|
- Adds `deno` as supported executable option
|
|
548
612
|
- Includes experimental `criticalSystemReminder_EXPERIMENTAL` for agent definitions
|
|
549
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
|
|
550
618
|
|
|
551
619
|
### Python SDK
|
|
552
620
|
- Full source available (v0.1.20)
|
|
@@ -561,6 +629,6 @@ Public API surface for SDK clients.
|
|
|
561
629
|
- Ruby-idiomatic patterns (Data.define, snake_case)
|
|
562
630
|
- Complete control protocol support
|
|
563
631
|
- Dedicated Client class for multi-turn conversations
|
|
564
|
-
- Full hook event support including all
|
|
632
|
+
- Full hook event support including all 13 events
|
|
565
633
|
- Full V2 Session API support (unstable)
|
|
566
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
|
|
@@ -227,4 +228,35 @@ module ClaudeAgent
|
|
|
227
228
|
@permission_suggestions = permission_suggestions
|
|
228
229
|
end
|
|
229
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
|
|
230
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
|
|
@@ -55,6 +58,7 @@ module ClaudeAgent
|
|
|
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
|
|
@@ -230,6 +235,14 @@ module ClaudeAgent
|
|
|
230
235
|
end
|
|
231
236
|
end
|
|
232
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
|
+
|
|
233
246
|
def extra_cli_args
|
|
234
247
|
[].tap do |args|
|
|
235
248
|
extra_args.each do |key, value|
|
|
@@ -262,6 +275,11 @@ module ClaudeAgent
|
|
|
262
275
|
if max_budget_usd && (!max_budget_usd.is_a?(Numeric) || max_budget_usd <= 0)
|
|
263
276
|
raise ConfigurationError, "max_budget_usd must be a positive number"
|
|
264
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
|
|
265
283
|
end
|
|
266
284
|
end
|
|
267
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