claude_agent 0.7.14 → 0.7.16

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/rules/conventions.md +66 -16
  3. data/CHANGELOG.md +20 -0
  4. data/CLAUDE.md +24 -4
  5. data/README.md +52 -1529
  6. data/SPEC.md +56 -29
  7. data/docs/architecture.md +339 -0
  8. data/docs/client.md +526 -0
  9. data/docs/configuration.md +571 -0
  10. data/docs/conversations.md +461 -0
  11. data/docs/errors.md +127 -0
  12. data/docs/events.md +225 -0
  13. data/docs/getting-started.md +310 -0
  14. data/docs/hooks.md +380 -0
  15. data/docs/logging.md +96 -0
  16. data/docs/mcp.md +308 -0
  17. data/docs/messages.md +871 -0
  18. data/docs/permissions.md +611 -0
  19. data/docs/queries.md +227 -0
  20. data/docs/sessions.md +335 -0
  21. data/lib/claude_agent/abort_controller.rb +24 -0
  22. data/lib/claude_agent/client/commands.rb +32 -0
  23. data/lib/claude_agent/client.rb +10 -4
  24. data/lib/claude_agent/configuration.rb +129 -0
  25. data/lib/claude_agent/control_protocol/commands.rb +28 -0
  26. data/lib/claude_agent/conversation.rb +37 -4
  27. data/lib/claude_agent/errors.rb +21 -4
  28. data/lib/claude_agent/event_handler.rb +14 -0
  29. data/lib/claude_agent/fork_session.rb +117 -0
  30. data/lib/claude_agent/hook_registry.rb +110 -0
  31. data/lib/claude_agent/hooks.rb +4 -0
  32. data/lib/claude_agent/mcp/server.rb +22 -0
  33. data/lib/claude_agent/mcp/tool.rb +24 -3
  34. data/lib/claude_agent/message.rb +93 -0
  35. data/lib/claude_agent/messages/streaming.rb +37 -0
  36. data/lib/claude_agent/options.rb +10 -0
  37. data/lib/claude_agent/permission_policy.rb +174 -0
  38. data/lib/claude_agent/permission_request.rb +17 -0
  39. data/lib/claude_agent/session.rb +100 -11
  40. data/lib/claude_agent/session_paths.rb +5 -2
  41. data/lib/claude_agent/turn_result.rb +20 -2
  42. data/lib/claude_agent/types/sessions.rb +8 -0
  43. data/lib/claude_agent/version.rb +1 -1
  44. data/lib/claude_agent.rb +187 -0
  45. data/sig/claude_agent.rbs +38 -1
  46. metadata +20 -1
@@ -0,0 +1,571 @@
1
+ # Configuration
2
+
3
+ The ClaudeAgent Ruby SDK uses a layered configuration system inspired by the Stripe Ruby gem. Global defaults are set once at boot and apply to every request. Per-request overrides refine or replace those defaults for a single `ask`, `chat`, or `Conversation`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Global Configuration](#global-configuration)
8
+ - [Configuration Tiers](#configuration-tiers)
9
+ - [Per-Request Overrides](#per-request-overrides)
10
+ - [Options Class Reference](#options-class-reference)
11
+ - [Tools Preset](#tools-preset)
12
+ - [Sandbox Settings](#sandbox-settings)
13
+ - [Custom Agents](#custom-agents)
14
+ - [Environment Variables](#environment-variables)
15
+
16
+ ---
17
+
18
+ ## Global Configuration
19
+
20
+ ### Module-level setters
21
+
22
+ Set individual defaults directly on the `ClaudeAgent` module:
23
+
24
+ ```ruby
25
+ ClaudeAgent.model = "opus"
26
+ ClaudeAgent.permission_mode = "acceptEdits"
27
+ ClaudeAgent.max_turns = 10
28
+ ClaudeAgent.debug = true
29
+ ```
30
+
31
+ ### Block-based bulk configuration
32
+
33
+ Use `configure` to set multiple defaults in one call:
34
+
35
+ ```ruby
36
+ ClaudeAgent.configure do |c|
37
+ c.model = "opus"
38
+ c.permission_mode = "acceptEdits"
39
+ c.max_turns = 10
40
+ c.max_budget_usd = 1.00
41
+ c.system_prompt = "You are a code review assistant."
42
+ c.cwd = "/path/to/project"
43
+ end
44
+ ```
45
+
46
+ ### Resetting to defaults
47
+
48
+ ```ruby
49
+ ClaudeAgent.reset_config!
50
+ ```
51
+
52
+ This replaces the current `Configuration` with a fresh instance where all fields are `nil` (or their constructor defaults).
53
+
54
+ ### Global permissions
55
+
56
+ Register a declarative permission policy that applies to all requests:
57
+
58
+ ```ruby
59
+ ClaudeAgent.permissions do |p|
60
+ p.allow "Read", "Grep", "Glob"
61
+ p.deny "Bash", message: "Bash not allowed"
62
+ p.deny_all
63
+ end
64
+ ```
65
+
66
+ ### Global hooks
67
+
68
+ Register hooks that fire for all requests:
69
+
70
+ ```ruby
71
+ ClaudeAgent.hooks do |h|
72
+ h.before_tool_use(/Bash/) { |input, ctx| { continue_: true } }
73
+ h.on_session_start { |input, ctx| { continue_: true } }
74
+ end
75
+ ```
76
+
77
+ ### Global MCP servers
78
+
79
+ Register MCP servers that are included in all requests:
80
+
81
+ ```ruby
82
+ server = ClaudeAgent::MCP::Server.new(name: "calculator") do |s|
83
+ s.tool("add", "Add numbers", { a: :number, b: :number }) do |args|
84
+ args[:a] + args[:b]
85
+ end
86
+ end
87
+
88
+ ClaudeAgent.register_mcp_server(server)
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Configuration Tiers
94
+
95
+ The `Configuration` class organizes fields into three tiers based on how they are typically used.
96
+
97
+ ### Tier 1 – Module-level delegators
98
+
99
+ These fields have convenience delegators on the `ClaudeAgent` module itself (`ClaudeAgent.model = "opus"`). They represent settings that are typically set once at boot time.
100
+
101
+ | Field | Type | Description |
102
+ |------------------------|-------------------|--------------------------------------------------------------------------|
103
+ | `model` | `String` | Model name or alias (e.g., `"opus"`, `"sonnet"`) |
104
+ | `permission_mode` | `String` | One of: `default`, `acceptEdits`, `plan`, `bypassPermissions`, `dontAsk` |
105
+ | `max_turns` | `Integer` | Maximum agentic turns per request |
106
+ | `max_budget_usd` | `Float` | Maximum cost in USD per request |
107
+ | `system_prompt` | `String`, `Hash` | Custom system prompt (replaces default) |
108
+ | `append_system_prompt` | `String` | Appended to the default system prompt |
109
+ | `cli_path` | `String` | Path to `claude` CLI binary |
110
+ | `cwd` | `String` | Working directory for CLI process |
111
+ | `sandbox` | `SandboxSettings` | Sandbox configuration (see below) |
112
+ | `debug` | `Boolean` | Enable CLI `--debug` flag |
113
+ | `effort` | `String` | Effort level: `low`, `medium`, `high`, `max` |
114
+ | `persist_session` | `Boolean` | Persist session to disk (default: `true`) |
115
+ | `fallback_model` | `String` | Fallback model when primary is unavailable |
116
+
117
+ ### Tier 2 – Per-request overrides
118
+
119
+ These fields are commonly set as keyword arguments on `ask`, `chat`, or `Conversation.new`. They are also configurable via the global `Configuration`.
120
+
121
+ | Field | Type | Description |
122
+ |--------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------|
123
+ | `tools` | `Array`, `ToolsPreset`, `Hash` | Tools available to the model |
124
+ | `allowed_tools` | `Array<String>` | Allowlist of tool names |
125
+ | `disallowed_tools` | `Array<String>` | Denylist of tool names |
126
+ | `thinking` | `Hash` | Thinking config: `{ type: "adaptive" }`, `{ type: "enabled", budget_tokens: 10000 }`, `{ type: "disabled" }` |
127
+ | `output_format` | `Hash` | JSON Schema for structured output |
128
+
129
+ ### Tier 3 – Advanced
130
+
131
+ These fields are accessible via `ClaudeAgent.configure` or by constructing `Options` directly. They cover MCP servers, hooks, environment, plugins, and internal SDK plumbing.
132
+
133
+ | Field | Type | Description |
134
+ |-----------------------------|------------------------|-----------------------------------------------------------|
135
+ | `mcp_servers` | `Hash` | MCP server configurations |
136
+ | `hooks` | `Hash`, `HookRegistry` | Hook event handlers |
137
+ | `env` | `Hash` | Extra environment variables for CLI process |
138
+ | `extra_args` | `Hash` | Additional CLI flags (`{ "--flag" => "value" }`) |
139
+ | `agents` | `Hash` | Custom agent definitions (see below) |
140
+ | `setting_sources` | `Array` | Setting source overrides |
141
+ | `settings` | `String`, `Hash` | Inline settings or path to settings file |
142
+ | `plugins` | `Array` | Plugin directories |
143
+ | `betas` | `Array` | Beta feature flags |
144
+ | `spawn_claude_code_process` | `Proc` | Custom spawn function (Docker, SSH, etc.) |
145
+ | `agent` | `String` | Built-in agent to use (e.g., `"Explore"`) |
146
+ | `add_dirs` | `Array` | Additional directories to include |
147
+ | `max_buffer_size` | `Integer` | Max JSON buffer size (default: 1MB) |
148
+ | `stderr_callback` | `Proc` | Callback for stderr output |
149
+ | `include_partial_messages` | `Boolean` | Include partial streaming messages |
150
+ | `enable_file_checkpointing` | `Boolean` | Enable file checkpointing |
151
+ | `prompt_suggestions` | `Boolean` | Enable prompt suggestions |
152
+ | `strict_mcp_config` | `Boolean` | Strict MCP config validation |
153
+ | `tool_config` | `Hash` | Per-tool configuration |
154
+ | `agent_progress_summaries` | any | Agent progress summary configuration |
155
+ | `max_thinking_tokens` | `Integer` | Max thinking tokens (standalone, without `thinking` hash) |
156
+ | `debug_file` | `String` | Path to debug log file |
157
+
158
+ ---
159
+
160
+ ## Per-Request Overrides
161
+
162
+ When you call `ask`, `chat`, or create a `Conversation`, keyword arguments merge with the global configuration. Per-request values always win over config defaults.
163
+
164
+ ### With `ask`
165
+
166
+ ```ruby
167
+ # Uses global config defaults
168
+ turn = ClaudeAgent.ask("What is 2+2?")
169
+
170
+ # Per-request overrides: model and max_turns override config
171
+ turn = ClaudeAgent.ask("Fix the bug",
172
+ model: "opus",
173
+ max_turns: 5,
174
+ system_prompt: "You are a debugging expert."
175
+ )
176
+
177
+ # Event callbacks are also passed as kwargs
178
+ turn = ClaudeAgent.ask("Explain Ruby",
179
+ on_stream: ->(text) { print text },
180
+ on_tool_use: ->(tool) { puts "Tool: #{tool.name}" }
181
+ )
182
+ ```
183
+
184
+ ### With `chat`
185
+
186
+ ```ruby
187
+ # Global config applies to the conversation
188
+ ClaudeAgent.chat(model: "opus", max_turns: 10) do |c|
189
+ c.say("Hello")
190
+ c.say("Now add tests")
191
+ end
192
+
193
+ # Without block -- caller manages lifecycle
194
+ c = ClaudeAgent.chat(permission_mode: "acceptEdits")
195
+ c.say("Refactor this module")
196
+ c.close
197
+ ```
198
+
199
+ ### With `Conversation.new`
200
+
201
+ ```ruby
202
+ conversation = ClaudeAgent::Conversation.new(
203
+ model: "opus",
204
+ max_turns: 10,
205
+ on_stream: ->(text) { print text },
206
+ on_permission: :accept_edits
207
+ )
208
+ ```
209
+
210
+ ### Merge behavior
211
+
212
+ The merge follows a simple rule: **per-request wins**.
213
+
214
+ ```ruby
215
+ ClaudeAgent.model = "sonnet"
216
+ ClaudeAgent.max_turns = 20
217
+
218
+ # model = "opus" (overridden), max_turns = 20 (from config)
219
+ turn = ClaudeAgent.ask("Hello", model: "opus")
220
+ ```
221
+
222
+ Internally, `Configuration#to_options` iterates all fields. If a per-request override is provided (even if `nil`), it takes precedence. If no override is provided, the config default is used. The result is a fully resolved `Options` instance.
223
+
224
+ ### Pre-built Options
225
+
226
+ You can bypass the config merge entirely by passing a pre-built `Options` object:
227
+
228
+ ```ruby
229
+ opts = ClaudeAgent::Options.new(
230
+ model: "opus",
231
+ max_turns: 5,
232
+ permission_mode: "acceptEdits"
233
+ )
234
+
235
+ # Global config is ignored -- opts is used directly
236
+ turn = ClaudeAgent.ask("Fix the bug", options: opts)
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Options Class Reference
242
+
243
+ `ClaudeAgent::Options` is the fully-resolved configuration object passed to the transport layer. It validates all fields at construction time and serializes them to CLI arguments and environment variables.
244
+
245
+ ### Constructor
246
+
247
+ ```ruby
248
+ options = ClaudeAgent::Options.new(
249
+ # --- Model ---
250
+ model: "opus",
251
+ fallback_model: "sonnet",
252
+
253
+ # --- Tools ---
254
+ tools: ["Read", "Write", "Bash"], # Array of tool names
255
+ # tools: ToolsPreset.new(preset: "claude_code"), # Or a preset
256
+ # tools: { type: "preset", preset: "claude_code" }, # Or Hash shorthand
257
+ allowed_tools: [], # Allowlist (default: [])
258
+ disallowed_tools: [], # Denylist (default: [])
259
+
260
+ # --- System prompt ---
261
+ system_prompt: "You are a helpful assistant.",
262
+ append_system_prompt: "Always respond in JSON.",
263
+
264
+ # --- Permissions ---
265
+ permission_mode: "acceptEdits", # "default", "acceptEdits", "plan", "bypassPermissions", "dontAsk"
266
+ permission_prompt_tool_name: nil, # Auto-set to "stdio" when can_use_tool is present
267
+ can_use_tool: ->(name, input, ctx) { { behavior: "allow" } },
268
+ on_elicitation: ->(data) { { behavior: "allow" } },
269
+ allow_dangerously_skip_permissions: false, # Required for bypassPermissions mode
270
+ permission_queue: nil, # Enable permission queue (Conversation default)
271
+
272
+ # --- Session ---
273
+ continue_conversation: false,
274
+ resume: nil, # Session ID to resume
275
+ fork_session: false,
276
+ resume_session_at: nil,
277
+ session_id: nil,
278
+ persist_session: true, # Default: true
279
+
280
+ # --- Limits ---
281
+ max_turns: nil, # Positive integer
282
+ max_budget_usd: nil, # Positive number
283
+ effort: nil, # "low", "medium", "high", "max"
284
+
285
+ # --- Thinking ---
286
+ thinking: nil, # { type: "adaptive" }, { type: "enabled", budget_tokens: 10000 }, { type: "disabled" }
287
+ max_thinking_tokens: nil, # Standalone (without thinking hash)
288
+
289
+ # --- MCP ---
290
+ mcp_servers: {}, # Default: {}
291
+ strict_mcp_config: false,
292
+
293
+ # --- Hooks ---
294
+ hooks: nil, # Hash or HookRegistry
295
+
296
+ # --- Sandbox ---
297
+ sandbox: nil, # SandboxSettings instance
298
+
299
+ # --- Environment ---
300
+ cwd: nil,
301
+ add_dirs: [], # Default: []
302
+ env: {}, # Default: {}
303
+ agent: nil, # Built-in agent name
304
+ agents: nil, # Hash of AgentDefinition
305
+ cli_path: nil,
306
+
307
+ # --- Output ---
308
+ output_format: nil, # JSON Schema for structured output
309
+ include_partial_messages: false,
310
+ enable_file_checkpointing: false,
311
+ prompt_suggestions: false,
312
+
313
+ # --- Advanced ---
314
+ extra_args: {}, # Default: {}
315
+ setting_sources: nil,
316
+ settings: nil,
317
+ plugins: [], # Default: []
318
+ betas: [], # Default: []
319
+ max_buffer_size: nil, # Default: 1MB
320
+ stderr_callback: nil,
321
+ abort_controller: nil,
322
+ spawn_claude_code_process: nil,
323
+ tool_config: nil,
324
+ agent_progress_summaries: nil,
325
+ logger: nil, # Per-instance logger override
326
+
327
+ # --- Debug ---
328
+ debug: false,
329
+ debug_file: nil
330
+ )
331
+ ```
332
+
333
+ ### Defaults
334
+
335
+ Fields with non-nil defaults:
336
+
337
+ | Field | Default |
338
+ |--------------------------------------|---------|
339
+ | `allowed_tools` | `[]` |
340
+ | `disallowed_tools` | `[]` |
341
+ | `allow_dangerously_skip_permissions` | `false` |
342
+ | `continue_conversation` | `false` |
343
+ | `fork_session` | `false` |
344
+ | `strict_mcp_config` | `false` |
345
+ | `mcp_servers` | `{}` |
346
+ | `add_dirs` | `[]` |
347
+ | `env` | `{}` |
348
+ | `extra_args` | `{}` |
349
+ | `plugins` | `[]` |
350
+ | `include_partial_messages` | `false` |
351
+ | `enable_file_checkpointing` | `false` |
352
+ | `persist_session` | `true` |
353
+ | `betas` | `[]` |
354
+ | `prompt_suggestions` | `false` |
355
+ | `debug` | `false` |
356
+
357
+ ### Validation
358
+
359
+ `Options` validates at construction and raises `ClaudeAgent::ConfigurationError` for:
360
+
361
+ - Invalid `permission_mode` (must be one of `default`, `acceptEdits`, `plan`, `bypassPermissions`, `dontAsk`)
362
+ - `bypassPermissions` without `allow_dangerously_skip_permissions: true`
363
+ - Non-callable `can_use_tool` (must respond to `#call`)
364
+ - Non-callable `on_elicitation` (must respond to `#call`)
365
+ - Non-positive `max_turns` or `max_budget_usd`
366
+ - Invalid `thinking` hash (`:type` must be `adaptive`, `enabled`, or `disabled`)
367
+ - Invalid `effort` (must be `low`, `medium`, `high`, or `max`)
368
+ - `session_id` with `continue_conversation` or `resume` unless `fork_session` is also set
369
+
370
+ ### Serialization
371
+
372
+ `Options` includes a `Serializer` module that converts to CLI arguments and environment variables:
373
+
374
+ ```ruby
375
+ options.to_cli_args # => ["--model", "opus", "--max-turns", "10", ...]
376
+ options.to_env # => {"CLAUDE_CODE_ENTRYPOINT" => "sdk-rb", ...}
377
+ ```
378
+
379
+ ---
380
+
381
+ ## Tools Preset
382
+
383
+ Use `ToolsPreset` to select a named preset instead of listing individual tools:
384
+
385
+ ```ruby
386
+ preset = ClaudeAgent::ToolsPreset.new(preset: "claude_code")
387
+ options = ClaudeAgent::Options.new(tools: preset)
388
+ ```
389
+
390
+ The `type` field defaults to `"preset"`. You can also pass a plain Hash:
391
+
392
+ ```ruby
393
+ options = ClaudeAgent::Options.new(
394
+ tools: { type: "preset", preset: "claude_code" }
395
+ )
396
+ ```
397
+
398
+ Or pass an Array of tool name strings:
399
+
400
+ ```ruby
401
+ options = ClaudeAgent::Options.new(
402
+ tools: ["Read", "Write", "Bash", "Grep", "Glob"]
403
+ )
404
+ ```
405
+
406
+ ---
407
+
408
+ ## Sandbox Settings
409
+
410
+ `SandboxSettings` configures execution sandboxing for the CLI process. It is an immutable `Data.define` type.
411
+
412
+ ### Basic sandbox
413
+
414
+ ```ruby
415
+ sandbox = ClaudeAgent::SandboxSettings.new(enabled: true)
416
+
417
+ ClaudeAgent.sandbox = sandbox
418
+ # or
419
+ ClaudeAgent.configure { |c| c.sandbox = sandbox }
420
+ ```
421
+
422
+ ### Full configuration
423
+
424
+ ```ruby
425
+ sandbox = ClaudeAgent::SandboxSettings.new(
426
+ enabled: true,
427
+ auto_allow_bash_if_sandboxed: true,
428
+ excluded_commands: ["docker"],
429
+ allow_unsandboxed_commands: false,
430
+ enable_weaker_nested_sandbox: false,
431
+ enable_weaker_network_isolation: false,
432
+ network: ClaudeAgent::SandboxNetworkConfig.new(
433
+ allowed_domains: ["api.example.com", "registry.npmjs.org"],
434
+ allow_local_binding: true,
435
+ allow_unix_sockets: ["/var/run/docker.sock"],
436
+ allow_all_unix_sockets: false,
437
+ allow_managed_domains_only: false,
438
+ http_proxy_port: nil,
439
+ socks_proxy_port: nil
440
+ ),
441
+ filesystem: ClaudeAgent::SandboxFilesystemConfig.new(
442
+ allow_write: ["/tmp/*"],
443
+ deny_write: ["/etc/*"],
444
+ deny_read: ["/secrets/*"]
445
+ ),
446
+ ignore_violations: ClaudeAgent::SandboxIgnoreViolations.new(
447
+ file: ["/tmp/*"],
448
+ network: ["localhost:*"]
449
+ ),
450
+ ripgrep: ClaudeAgent::SandboxRipgrepConfig.new(
451
+ command: "/usr/local/bin/rg",
452
+ args: ["--hidden"]
453
+ )
454
+ )
455
+ ```
456
+
457
+ ### Sub-configuration types
458
+
459
+ | Type | Fields |
460
+ |---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
461
+ | `SandboxSettings` | `enabled`, `auto_allow_bash_if_sandboxed`, `excluded_commands`, `allow_unsandboxed_commands`, `network`, `ignore_violations`, `enable_weaker_nested_sandbox`, `enable_weaker_network_isolation`, `ripgrep`, `filesystem` |
462
+ | `SandboxNetworkConfig` | `allowed_domains`, `allow_local_binding`, `allow_unix_sockets`, `allow_all_unix_sockets`, `allow_managed_domains_only`, `http_proxy_port`, `socks_proxy_port` |
463
+ | `SandboxFilesystemConfig` | `allow_write`, `deny_write`, `deny_read` |
464
+ | `SandboxIgnoreViolations` | `file`, `network` |
465
+ | `SandboxRipgrepConfig` | `command`, `args` |
466
+
467
+ All sandbox types implement `to_h` for serialization to the CLI's JSON format.
468
+
469
+ ---
470
+
471
+ ## Custom Agents
472
+
473
+ Define custom subagents using `AgentDefinition`:
474
+
475
+ ```ruby
476
+ test_runner = ClaudeAgent::AgentDefinition.new(
477
+ description: "Runs tests and reports results",
478
+ prompt: "You are a test runner. Run the specified tests and report pass/fail status.",
479
+ tools: ["Read", "Grep", "Glob", "Bash"],
480
+ model: "haiku",
481
+ max_turns: 10
482
+ )
483
+
484
+ research = ClaudeAgent::AgentDefinition.new(
485
+ description: "Research agent with specialized skills",
486
+ prompt: "You are a research expert. Find and summarize information.",
487
+ skills: ["web-search", "summarization"],
488
+ disallowed_tools: ["Write", "Edit"],
489
+ mcp_servers: { "search" => { "command" => "npx", "args" => ["-y", "search-server"] } },
490
+ critical_system_reminder: "Never modify files."
491
+ )
492
+
493
+ options = ClaudeAgent::Options.new(
494
+ agents: {
495
+ "test_runner" => test_runner,
496
+ "research" => research
497
+ }
498
+ )
499
+ ```
500
+
501
+ ### AgentDefinition fields
502
+
503
+ | Field | Type | Required | Description |
504
+ |----------------------------|-----------------|----------|--------------------------------------|
505
+ | `description` | `String` | Yes | What this agent does |
506
+ | `prompt` | `String` | Yes | System prompt for the agent |
507
+ | `tools` | `Array<String>` | No | Tools available to this agent |
508
+ | `disallowed_tools` | `Array<String>` | No | Tools denied to this agent |
509
+ | `model` | `String` | No | Model override for this agent |
510
+ | `mcp_servers` | `Hash` | No | MCP servers for this agent |
511
+ | `critical_system_reminder` | `String` | No | Critical reminder appended to prompt |
512
+ | `skills` | `Array<String>` | No | Skills available to this agent |
513
+ | `max_turns` | `Integer` | No | Max turns for this agent |
514
+
515
+ ---
516
+
517
+ ## Environment Variables
518
+
519
+ The SDK sets and reads several environment variables.
520
+
521
+ ### Set by the SDK
522
+
523
+ These are automatically set in the CLI process environment via `Options#to_env`:
524
+
525
+ | Variable | Value | Description |
526
+ |---------------------------------------------|-----------------|------------------------------------------------|
527
+ | `CLAUDE_CODE_ENTRYPOINT` | `"sdk-rb"` | Identifies the SDK to the CLI |
528
+ | `CLAUDE_AGENT_SDK_VERSION` | Current version | SDK version string (e.g., `"0.7.15"`) |
529
+ | `CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING` | `"true"` | Set when `enable_file_checkpointing` is true |
530
+ | `PWD` | `cwd` value | Working directory override (when `cwd` is set) |
531
+
532
+ ### Read by the SDK
533
+
534
+ These environment variables influence SDK behavior at runtime:
535
+
536
+ | Variable | Effect |
537
+ |---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
538
+ | `CLAUDE_AGENT_DEBUG` | When set (any truthy value), enables debug-level logging to stderr automatically at boot. Equivalent to calling `ClaudeAgent.debug!`. |
539
+ | `CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK` | When set to `"true"`, skips the CLI version check that runs before spawning the subprocess. Useful in CI or when using a custom CLI build. |
540
+
541
+ ### Passing custom environment variables
542
+
543
+ Use the `env` option to pass additional environment variables to the CLI process:
544
+
545
+ ```ruby
546
+ ClaudeAgent.configure do |c|
547
+ c.env = {
548
+ "ANTHROPIC_API_KEY" => "sk-...",
549
+ "MY_CUSTOM_VAR" => "value"
550
+ }
551
+ end
552
+
553
+ # Or per-request
554
+ turn = ClaudeAgent.ask("Hello", env: { "CUSTOM" => "value" })
555
+ ```
556
+
557
+ ### Debug logging
558
+
559
+ Three ways to enable debug logging:
560
+
561
+ ```ruby
562
+ # 1. Environment variable (auto-detected at boot)
563
+ # CLAUDE_AGENT_DEBUG=1 ruby my_script.rb
564
+
565
+ # 2. Convenience method
566
+ ClaudeAgent.debug!
567
+ ClaudeAgent.debug!(output: File.open("debug.log", "a"))
568
+
569
+ # 3. Custom logger
570
+ ClaudeAgent.logger = Logger.new($stderr, level: :debug)
571
+ ```