claude-code-sdk-ruby 0.1.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +19 -0
- data/.ruby-version +1 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +43 -0
- data/LICENSE +21 -0
- data/README.md +220 -0
- data/Rakefile +13 -0
- data/claude-code-sdk-ruby.gemspec +36 -0
- data/examples/async_multiple_queries.rb +36 -0
- data/examples/basic_usage.rb +82 -0
- data/examples/enumerator_usage.rb +50 -0
- data/examples/error_handling.rb +31 -0
- data/examples/mcp_servers.rb +44 -0
- data/examples/with_options.rb +41 -0
- data/lib/claude_sdk/errors.rb +75 -0
- data/lib/claude_sdk/internal/client.rb +122 -0
- data/lib/claude_sdk/internal/transport/subprocess_cli.rb +362 -0
- data/lib/claude_sdk/internal/transport.rb +53 -0
- data/lib/claude_sdk/types.rb +427 -0
- data/lib/claude_sdk/version.rb +5 -0
- data/lib/claude_sdk.rb +59 -0
- data/ruby-sdk-maintenance-swarm.yml +67 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 154889ea495b7743bded0f1cf1ab96b74da5adc93bf19f1e226d6fd9f949dee1
|
4
|
+
data.tar.gz: 77039484cf7d9acbd273334aad182db014b8a5d471d41019d3565828479716a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73ad8a8341c21ef6cbac699ee4ce211619a853676632c6072374821b08737ccacbe8007dd9de0971dacdf3b6bc9e4b69d21275dc2e4b13e7106a1b7f8a8d34e9
|
7
|
+
data.tar.gz: fc9e88788b6783fd4a335b4553fb6c3607b65083ff1fe898756c4cbb5ee4566012562748107e748ab08f1a1c3dc712eab7bb1e91032bb8ca3818539b6755a1d7
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
|
+
|
4
|
+
plugins:
|
5
|
+
- rubocop-rspec
|
6
|
+
- rubocop-rake
|
7
|
+
|
8
|
+
AllCops:
|
9
|
+
TargetRubyVersion: 3.4
|
10
|
+
NewCops: enable
|
11
|
+
Exclude:
|
12
|
+
- '.ruby-lsp/**/*'
|
13
|
+
|
14
|
+
|
15
|
+
RSpec/MultipleExpectations:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
RSpec/ExampleLength:
|
19
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-3.4.2
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
- Removed unused `async-process` dependency
|
12
|
+
|
13
|
+
## [0.0.1] - 2024-07-14
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- Initial release of claude-sdk-ruby
|
17
|
+
- Core SDK functionality for interacting with Claude Code CLI
|
18
|
+
- Support for async query processing
|
19
|
+
- Message types: User, Assistant, System, and Result
|
20
|
+
- Content blocks: Text, ToolUse, and ToolResult
|
21
|
+
- Configuration options via ClaudeCodeOptions
|
22
|
+
- Error handling with specific error types:
|
23
|
+
- CLINotFoundError
|
24
|
+
- CLIConnectionError
|
25
|
+
- ProcessError
|
26
|
+
- Internal client for direct subprocess communication
|
27
|
+
- Comprehensive test suite with RSpec
|
28
|
+
- Examples and documentation
|
29
|
+
|
30
|
+
### Dependencies
|
31
|
+
- async (~> 2.0)
|
32
|
+
|
33
|
+
### Development Dependencies
|
34
|
+
- bundler (~> 2.0)
|
35
|
+
- rake (~> 13.0)
|
36
|
+
- rspec (~> 3.0)
|
37
|
+
- rubocop (~> 1.50)
|
38
|
+
- rubocop-rspec (~> 2.20)
|
39
|
+
- simplecov (~> 0.22)
|
40
|
+
- yard (~> 0.9)
|
41
|
+
|
42
|
+
[Unreleased]: https://github.com/anthropics/claude-code-sdk-ruby/compare/v0.0.1...HEAD
|
43
|
+
[0.0.1]: https://github.com/anthropics/claude-code-sdk-ruby/releases/tag/v0.0.1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025-present Paulo Arruda
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
# Claude SDK Ruby
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/claude-sdk-ruby)
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
5
|
+
|
6
|
+
Official Ruby SDK for interacting with Claude Code CLI. This gem provides a Ruby-idiomatic interface to Claude Code with full async support, proper error handling, and comprehensive type definitions.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'claude-sdk-ruby'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
bundle install
|
20
|
+
```
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
gem install claude-sdk-ruby
|
26
|
+
```
|
27
|
+
|
28
|
+
## Prerequisites
|
29
|
+
|
30
|
+
This SDK requires the Claude Code CLI to be installed:
|
31
|
+
|
32
|
+
```bash
|
33
|
+
npm install -g @anthropic-ai/claude-code
|
34
|
+
```
|
35
|
+
|
36
|
+
You'll also need to configure your API key. Please refer to the [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code) for detailed setup instructions.
|
37
|
+
|
38
|
+
## Quick Start
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'claude_sdk'
|
42
|
+
|
43
|
+
# Simple query
|
44
|
+
ClaudeSDK.query("What is 2+2?") do |message|
|
45
|
+
case message
|
46
|
+
when ClaudeSDK::Messages::Assistant
|
47
|
+
message.content.each do |block|
|
48
|
+
puts block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
|
49
|
+
end
|
50
|
+
when ClaudeSDK::Messages::Result
|
51
|
+
puts "Session completed in #{message.duration_ms}ms"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
## Usage
|
57
|
+
|
58
|
+
### Basic Query
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
require 'claude_sdk'
|
62
|
+
|
63
|
+
ClaudeSDK.query("Hello, Claude!") do |message|
|
64
|
+
puts message
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
### With Options
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
require 'claude_sdk'
|
72
|
+
|
73
|
+
options = ClaudeSDK::ClaudeCodeOptions.new(
|
74
|
+
allowed_tools: ['Read', 'Write', 'Bash'],
|
75
|
+
max_turns: 3,
|
76
|
+
system_prompt: 'You are a helpful coding assistant.',
|
77
|
+
cwd: '/path/to/working/directory'
|
78
|
+
)
|
79
|
+
|
80
|
+
ClaudeSDK.query("Help me write a Ruby script", options: options) do |message|
|
81
|
+
case message
|
82
|
+
when ClaudeSDK::Messages::Assistant
|
83
|
+
message.content.each do |block|
|
84
|
+
case block
|
85
|
+
when ClaudeSDK::ContentBlock::Text
|
86
|
+
puts block.text
|
87
|
+
when ClaudeSDK::ContentBlock::ToolUse
|
88
|
+
puts "Tool: #{block.name}"
|
89
|
+
puts "Input: #{block.input}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
when ClaudeSDK::Messages::Result
|
93
|
+
puts "Completed in #{message.num_turns} turns"
|
94
|
+
puts "Total cost: $#{message.total_cost_usd}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
### Without Block (Returns Enumerator)
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
require 'claude_sdk'
|
103
|
+
|
104
|
+
messages = ClaudeSDK.query("Hello")
|
105
|
+
messages.each do |message|
|
106
|
+
puts message
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
### Advanced: Using the Internal Client Directly
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
require 'claude_sdk/internal/client'
|
114
|
+
|
115
|
+
client = ClaudeSDK::Internal::InternalClient.new
|
116
|
+
options = ClaudeSDK::ClaudeCodeOptions.new(
|
117
|
+
allowed_tools: ['Read', 'Bash'],
|
118
|
+
max_turns: 5
|
119
|
+
)
|
120
|
+
|
121
|
+
Async do
|
122
|
+
client.process_query(prompt: "What files are in this directory?", options: options) do |message|
|
123
|
+
case message
|
124
|
+
when ClaudeSDK::Messages::Assistant
|
125
|
+
puts "Assistant response received"
|
126
|
+
when ClaudeSDK::Messages::System
|
127
|
+
puts "System message: #{message.subtype}"
|
128
|
+
when ClaudeSDK::Messages::Result
|
129
|
+
puts "Query completed"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
```
|
134
|
+
|
135
|
+
## Message Types
|
136
|
+
|
137
|
+
The SDK provides several message types:
|
138
|
+
|
139
|
+
- `ClaudeSDK::Messages::User` - User input messages
|
140
|
+
- `ClaudeSDK::Messages::Assistant` - Assistant responses containing content blocks
|
141
|
+
- `ClaudeSDK::Messages::System` - System messages (tool results, errors)
|
142
|
+
- `ClaudeSDK::Messages::Result` - Query completion results with timing and cost info
|
143
|
+
- `ClaudeSDK::Messages::Error` - Error messages from the CLI
|
144
|
+
|
145
|
+
## Content Blocks
|
146
|
+
|
147
|
+
Assistant messages contain content blocks:
|
148
|
+
|
149
|
+
- `ClaudeSDK::ContentBlock::Text` - Text content
|
150
|
+
- `ClaudeSDK::ContentBlock::ToolUse` - Tool usage
|
151
|
+
- `ClaudeSDK::ContentBlock::ToolResult` - Tool results
|
152
|
+
|
153
|
+
## Configuration Options
|
154
|
+
|
155
|
+
The `ClaudeCodeOptions` class supports all Claude Code CLI options:
|
156
|
+
|
157
|
+
- `allowed_tools` - Array of allowed tool names (e.g., `['Read', 'Write', 'Bash']`)
|
158
|
+
- `disallowed_tools` - Array of disallowed tool names
|
159
|
+
- `max_turns` - Maximum conversation turns
|
160
|
+
- `system_prompt` - System prompt for the conversation
|
161
|
+
- `append_system_prompt` - Additional system prompt to append
|
162
|
+
- `cwd` - Working directory for file operations
|
163
|
+
- `model` - Model to use (e.g., `'claude-3-opus'`)
|
164
|
+
- `permission_mode` - Permission mode (`:default`, `:accept_edits`, `:auto`, `:ask`)
|
165
|
+
- `permission_prompt_tool_name` - Tool for permission prompts
|
166
|
+
- `continue_conversation` - Whether to continue from previous conversation
|
167
|
+
- `resume` - Resume from a specific conversation ID
|
168
|
+
- `mcp_servers` - MCP server configuration
|
169
|
+
|
170
|
+
## Error Handling
|
171
|
+
|
172
|
+
The SDK provides specific error types:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
begin
|
176
|
+
ClaudeSDK.query("Hello") do |message|
|
177
|
+
puts message
|
178
|
+
end
|
179
|
+
rescue ClaudeSDK::CLINotFoundError => e
|
180
|
+
puts "Claude Code CLI not found: #{e.message}"
|
181
|
+
rescue ClaudeSDK::CLIConnectionError => e
|
182
|
+
puts "Connection error: #{e.message}"
|
183
|
+
rescue ClaudeSDK::ProcessError => e
|
184
|
+
puts "Process error: #{e.message}"
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
188
|
+
## Requirements
|
189
|
+
|
190
|
+
- Ruby 3.0 or higher
|
191
|
+
- Node.js (for Claude Code CLI)
|
192
|
+
- async gem for async support
|
193
|
+
|
194
|
+
## Development
|
195
|
+
|
196
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
197
|
+
|
198
|
+
```bash
|
199
|
+
# Run tests
|
200
|
+
bundle exec rspec
|
201
|
+
|
202
|
+
# Run tests with coverage
|
203
|
+
COVERAGE=true bundle exec rspec
|
204
|
+
|
205
|
+
# Build the gem
|
206
|
+
gem build claude-sdk-ruby.gemspec
|
207
|
+
|
208
|
+
# Install locally
|
209
|
+
gem install ./claude-sdk-ruby-0.1.0.gem
|
210
|
+
```
|
211
|
+
|
212
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
213
|
+
|
214
|
+
## Contributing
|
215
|
+
|
216
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/anthropics/claude-code-sdk-ruby.
|
217
|
+
|
218
|
+
## License
|
219
|
+
|
220
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
10
|
+
task default: [:spec, :rubocop]
|
11
|
+
|
12
|
+
desc "Run all tests and linting"
|
13
|
+
task test: [:spec, :rubocop]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/claude_sdk/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "claude-code-sdk-ruby"
|
7
|
+
spec.version = ClaudeSDK::VERSION
|
8
|
+
spec.authors = ["Paulo Arruda"]
|
9
|
+
spec.email = ["parrudaj@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Ruby SDK for Claude Code"
|
12
|
+
spec.description = "Ruby SDK for interacting with Claude Code"
|
13
|
+
spec.homepage = "https://github.com/parruda/claude-code-sdk-ruby"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.0.0"
|
16
|
+
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
24
|
+
%x(git ls-files -z).split("\x0").reject do |f|
|
25
|
+
(File.expand_path(f) == __FILE__) ||
|
26
|
+
f.start_with?("bin/", "test/", "spec/", "features/", ".git", ".github", "appveyor", "Gemfile")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
spec.bindir = "exe"
|
30
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
|
+
spec.require_paths = ["lib"]
|
32
|
+
|
33
|
+
# Runtime dependencies
|
34
|
+
spec.add_dependency("async", "~> 2.26")
|
35
|
+
spec.add_dependency("logger", "~> 1.7")
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "claude_sdk"
|
5
|
+
require "async"
|
6
|
+
|
7
|
+
# Example: Running multiple queries concurrently
|
8
|
+
|
9
|
+
Async do |task|
|
10
|
+
queries = [
|
11
|
+
"What is the capital of France?",
|
12
|
+
"Explain Ruby blocks in one sentence",
|
13
|
+
"List 3 benefits of async programming",
|
14
|
+
]
|
15
|
+
|
16
|
+
# Run queries concurrently
|
17
|
+
results = queries.map do |prompt|
|
18
|
+
task.async do
|
19
|
+
responses = []
|
20
|
+
ClaudeSDK.query(prompt) do |message|
|
21
|
+
if message.is_a?(ClaudeSDK::Messages::Assistant)
|
22
|
+
message.content.each do |block|
|
23
|
+
responses << block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
{ prompt: prompt, response: responses.join(" ") }
|
28
|
+
end
|
29
|
+
end.map(&:wait)
|
30
|
+
|
31
|
+
# Display results
|
32
|
+
results.each do |result|
|
33
|
+
puts "\nš Question: #{result[:prompt]}"
|
34
|
+
puts "š” Answer: #{result[:response]}"
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Add lib to load path for development
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
6
|
+
|
7
|
+
require "async"
|
8
|
+
require "claude_sdk/types"
|
9
|
+
require "claude_sdk/errors"
|
10
|
+
require "claude_sdk/internal/client"
|
11
|
+
|
12
|
+
# Example of using the Ruby Claude SDK internal client
|
13
|
+
#
|
14
|
+
# This demonstrates:
|
15
|
+
# - Creating an internal client
|
16
|
+
# - Processing a query with options
|
17
|
+
# - Handling different message types
|
18
|
+
# - Error handling
|
19
|
+
|
20
|
+
# Create options
|
21
|
+
options = ClaudeSDK::ClaudeCodeOptions.new(
|
22
|
+
allowed_tools: ["bash", "read"],
|
23
|
+
max_turns: 3,
|
24
|
+
system_prompt: "You are a helpful coding assistant.",
|
25
|
+
)
|
26
|
+
|
27
|
+
# Create client
|
28
|
+
client = ClaudeSDK::Internal::InternalClient.new
|
29
|
+
|
30
|
+
# Process query
|
31
|
+
Async do
|
32
|
+
puts "Sending query to Claude..."
|
33
|
+
puts "=" * 50
|
34
|
+
|
35
|
+
client.process_query("What is 2+2?", options) do |message|
|
36
|
+
case message
|
37
|
+
when ClaudeSDK::Messages::User
|
38
|
+
puts "\n[USER]"
|
39
|
+
puts message.content
|
40
|
+
|
41
|
+
when ClaudeSDK::Messages::Assistant
|
42
|
+
puts "\n[ASSISTANT]"
|
43
|
+
message.content.each do |block|
|
44
|
+
case block
|
45
|
+
when ClaudeSDK::ContentBlock::Text
|
46
|
+
puts block.text
|
47
|
+
when ClaudeSDK::ContentBlock::ToolUse
|
48
|
+
puts "Tool Use: #{block.name}"
|
49
|
+
puts "Input: #{block.input.inspect}"
|
50
|
+
when ClaudeSDK::ContentBlock::ToolResult
|
51
|
+
puts "Tool Result for #{block.tool_use_id}"
|
52
|
+
puts "Content: #{block.content}"
|
53
|
+
puts "Error: #{block.is_error}" if block.is_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
when ClaudeSDK::Messages::System
|
58
|
+
puts "\n[SYSTEM: #{message.subtype}]"
|
59
|
+
puts message.data.inspect
|
60
|
+
|
61
|
+
when ClaudeSDK::Messages::Result
|
62
|
+
puts "\n[RESULT]"
|
63
|
+
puts "Session ID: #{message.session_id}"
|
64
|
+
puts "Duration: #{message.duration_ms}ms (API: #{message.duration_api_ms}ms)"
|
65
|
+
puts "Turns: #{message.num_turns}"
|
66
|
+
puts "Cost: $#{message.total_cost_usd}" if message.total_cost_usd
|
67
|
+
puts "Error: #{message.is_error}" if message.is_error
|
68
|
+
end
|
69
|
+
end
|
70
|
+
rescue ClaudeSDK::CLINotFoundError => e
|
71
|
+
puts "Error: #{e.message}"
|
72
|
+
puts "Please install Claude Code CLI first"
|
73
|
+
rescue ClaudeSDK::CLIConnectionError => e
|
74
|
+
puts "Connection error: #{e.message}"
|
75
|
+
rescue ClaudeSDK::ProcessError => e
|
76
|
+
puts "Process error: #{e.message}"
|
77
|
+
puts "Exit code: #{e.exit_code}" if e.exit_code
|
78
|
+
puts "Stderr: #{e.stderr}" if e.stderr
|
79
|
+
rescue StandardError => e
|
80
|
+
puts "Unexpected error: #{e.class} - #{e.message}"
|
81
|
+
puts e.backtrace
|
82
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "claude_sdk"
|
5
|
+
|
6
|
+
# Example: Using enumerators for fine-grained control
|
7
|
+
|
8
|
+
# Get an enumerator instead of using a block
|
9
|
+
messages = ClaudeSDK.query("Write a haiku about Ruby programming")
|
10
|
+
|
11
|
+
# Process messages with more control
|
12
|
+
message_count = 0
|
13
|
+
assistant_messages = []
|
14
|
+
|
15
|
+
begin
|
16
|
+
loop do
|
17
|
+
message = messages.next
|
18
|
+
message_count += 1
|
19
|
+
|
20
|
+
case message
|
21
|
+
when ClaudeSDK::Messages::User
|
22
|
+
puts "šØ Message #{message_count}: User prompt received"
|
23
|
+
|
24
|
+
when ClaudeSDK::Messages::Assistant
|
25
|
+
assistant_messages << message
|
26
|
+
text_blocks = message.content.select { |b| b.is_a?(ClaudeSDK::ContentBlock::Text) }
|
27
|
+
puts "š¤ Message #{message_count}: Assistant responded with #{text_blocks.count} text blocks"
|
28
|
+
|
29
|
+
# We could break early if we wanted
|
30
|
+
# break if text_blocks.any? { |b| b.text.include?("haiku") }
|
31
|
+
|
32
|
+
when ClaudeSDK::Messages::System
|
33
|
+
puts "āļø Message #{message_count}: System message (#{message.subtype})"
|
34
|
+
|
35
|
+
when ClaudeSDK::Messages::Result
|
36
|
+
puts "ā
Message #{message_count}: Completed in #{message.duration_ms}ms"
|
37
|
+
break # End of conversation
|
38
|
+
end
|
39
|
+
end
|
40
|
+
rescue StopIteration
|
41
|
+
# Normal end of enumeration
|
42
|
+
end
|
43
|
+
|
44
|
+
# Display the haiku
|
45
|
+
puts "\nš Generated Haiku:"
|
46
|
+
assistant_messages.each do |msg|
|
47
|
+
msg.content.each do |block|
|
48
|
+
puts block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "claude_sdk"
|
5
|
+
|
6
|
+
# Example: Proper error handling with ClaudeSDK
|
7
|
+
|
8
|
+
begin
|
9
|
+
ClaudeSDK.query("Hello, Claude!") do |message|
|
10
|
+
puts message.inspect
|
11
|
+
end
|
12
|
+
rescue ClaudeSDK::CLINotFoundError => e
|
13
|
+
puts "ā Claude CLI not found!"
|
14
|
+
puts e.message
|
15
|
+
puts "\nTo install Claude CLI:"
|
16
|
+
puts " npm install -g @anthropic-ai/claude-code"
|
17
|
+
rescue ClaudeSDK::CLIConnectionError => e
|
18
|
+
puts "ā Failed to connect to Claude CLI"
|
19
|
+
puts e.message
|
20
|
+
rescue ClaudeSDK::ProcessError => e
|
21
|
+
puts "ā Process failed"
|
22
|
+
puts "Exit code: #{e.exit_code}"
|
23
|
+
puts "Error output: #{e.stderr}"
|
24
|
+
rescue ClaudeSDK::Error => e
|
25
|
+
# Catch any other ClaudeSDK errors
|
26
|
+
puts "ā An error occurred: #{e.message}"
|
27
|
+
rescue StandardError => e
|
28
|
+
# Catch unexpected errors
|
29
|
+
puts "ā Unexpected error: #{e.class} - #{e.message}"
|
30
|
+
puts e.backtrace.first(5).join("\n")
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "claude_sdk"
|
5
|
+
|
6
|
+
# Example: Using MCP (Model Context Protocol) servers
|
7
|
+
|
8
|
+
# Configure MCP servers
|
9
|
+
mcp_servers = {
|
10
|
+
"filesystem" => {
|
11
|
+
type: "stdio",
|
12
|
+
command: "npx",
|
13
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
|
14
|
+
},
|
15
|
+
"git" => {
|
16
|
+
type: "stdio",
|
17
|
+
command: "npx",
|
18
|
+
args: ["-y", "@modelcontextprotocol/server-git", "--repository", "."],
|
19
|
+
},
|
20
|
+
}
|
21
|
+
|
22
|
+
# Create options with MCP servers
|
23
|
+
options = ClaudeSDK::ClaudeCodeOptions.new(
|
24
|
+
mcp_servers: mcp_servers,
|
25
|
+
mcp_tools: ["read_file", "write_file", "git_status", "git_diff"],
|
26
|
+
)
|
27
|
+
|
28
|
+
# Query using MCP tools
|
29
|
+
ClaudeSDK.query("Read the README.md file and summarize it", options: options) do |message|
|
30
|
+
case message
|
31
|
+
when ClaudeSDK::Messages::Assistant
|
32
|
+
message.content.each do |block|
|
33
|
+
if block.is_a?(ClaudeSDK::ContentBlock::ToolUse) && block.name.start_with?("mcp_")
|
34
|
+
puts "š Using MCP tool: #{block.name}"
|
35
|
+
puts " Server: #{block.name.split("_")[1]}"
|
36
|
+
puts " Input: #{block.input.inspect}"
|
37
|
+
elsif block.is_a?(ClaudeSDK::ContentBlock::Text)
|
38
|
+
puts "š #{block.text}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
when ClaudeSDK::Messages::Result
|
42
|
+
puts "\nā
Done! Used #{message.num_turns} turns"
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "claude_sdk"
|
5
|
+
|
6
|
+
# Example: Using ClaudeSDK with various options
|
7
|
+
|
8
|
+
# Create options with custom settings
|
9
|
+
options = ClaudeSDK::ClaudeCodeOptions.new(
|
10
|
+
system_prompt: "You are a helpful Ruby programming assistant",
|
11
|
+
cwd: Dir.pwd,
|
12
|
+
max_thinking_tokens: 10_000,
|
13
|
+
permission_mode: :accept_edits, # Auto-accept file edits
|
14
|
+
allowed_tools: ["bash", "read", "write"],
|
15
|
+
model: "claude-3.5-sonnet",
|
16
|
+
)
|
17
|
+
|
18
|
+
# Query with options
|
19
|
+
ClaudeSDK.query("Write a Ruby function to calculate fibonacci numbers", options: options) do |message|
|
20
|
+
case message
|
21
|
+
when ClaudeSDK::Messages::User
|
22
|
+
puts "\nš¤ User: #{message.content}"
|
23
|
+
when ClaudeSDK::Messages::Assistant
|
24
|
+
message.content.each do |block|
|
25
|
+
case block
|
26
|
+
when ClaudeSDK::ContentBlock::Text
|
27
|
+
puts "\nš¤ Claude: #{block.text}"
|
28
|
+
when ClaudeSDK::ContentBlock::ToolUse
|
29
|
+
puts "\nš§ Using tool: #{block.name}"
|
30
|
+
puts " Input: #{block.input.inspect}"
|
31
|
+
when ClaudeSDK::ContentBlock::ToolResult
|
32
|
+
puts "\nš Tool result: #{block.content}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
when ClaudeSDK::Messages::Result
|
36
|
+
puts "\nā
Completed!"
|
37
|
+
puts " Duration: #{message.duration_ms}ms"
|
38
|
+
puts " API calls: #{message.duration_api_ms}ms"
|
39
|
+
puts " Total cost: $#{format("%.4f", message.total_cost_usd || 0)}"
|
40
|
+
end
|
41
|
+
end
|