Skip to content

Latest commit

 

History

History
216 lines (165 loc) · 8.08 KB

File metadata and controls

216 lines (165 loc) · 8.08 KB

AI Summary: Claude Code SDK for Ruby

Version: 0.2.0
Purpose: Ruby SDK that provides a native Ruby interface to Anthropic's Claude Code CLI
Key Focus: Dynamic hooks configuration and comprehensive Claude Code CLI integration

🎯 What This SDK Does

This is a Ruby wrapper around the Claude Code CLI that:

  • Converts CLI interactions into Ruby objects with strongly-typed message parsing
  • Provides dynamic hooks configuration via the settings parameter (crucial functionality!)
  • Handles both streaming and simple query patterns for Claude Code interactions
  • Manages CLI process lifecycle with proper error handling and resource cleanup
  • Offers Ruby-idiomatic APIs with blocks, enumerables, and familiar patterns

🏗️ Architecture Overview

Core Components

  1. Main Interface (lib/claude_code_sdk.rb)

    • ClaudeCodeSDK.query(prompt, options, &block) - Primary streaming interface
    • ClaudeCodeSDK.ask(prompt) - Simple text response helper
    • ClaudeCodeSDK.configure - Global configuration setup
  2. Transport Layer (lib/claude_code_sdk/transport/)

    • Base - Abstract transport interface
    • SubprocessCLI - ✅ ACTIVELY USED - Full streaming via subprocess (line 12 in internal/client.rb)
    • SimpleCLI - Alternative implementation, NOT currently used

    IMPORTANT: AllSpark Builder extends SubprocessCLI with custom overrides in config/initializers/zzz_claude_code_sdk_override.rb for Docker environment compatibility.

  3. Message System (lib/claude_code_sdk/messages.rb)

    • Message base class with id and type
    • UserMessage, AssistantMessage, SystemMessage, ResultMessage, ThinkingMessage
    • Content::* blocks: TextBlock, ToolUseBlock, ToolResultBlock
  4. Configuration System (lib/claude_code_sdk/types.rb, configuration.rb)

    • Options - Per-query configuration with all Claude Code CLI flags
    • Configuration - Singleton for global defaults
    • PermissionMode constants: DEFAULT, ACCEPT_EDITS, BYPASS_PERMISSIONS

🔗 Dynamic Hooks: The Crown Jewel

This is the most important feature for AllSpark Builder integration!

How Hooks Work

The SDK supports dynamic hooks via the settings parameter in Options. This enables session-specific hooks without modifying global config files.

# Three supported input formats:
options = ClaudeCodeSDK::Options.new(
  settings: hooks_hash         # Hash -> converted to JSON
  # OR
  settings: '{"hooks": {...}}' # JSON string -> passed directly  
  # OR
  settings: "/path/file.json"  # File path -> passed to CLI
)

Hook Configuration Structure

hooks_config = {
  "hooks" => {
    "PostToolUse" => [
      {
        "matcher" => "Bash|Write|Edit",  # Regex pattern for tool names
        "hooks" => [
          {
            "type" => "command",
            "command" => "curl -X POST webhook_url -d \"$HOOK_INPUT\""
          }
        ]
      }
    ],
    "PreToolUse" => [...],
    # Available events: PreToolUse, PostToolUse, UserPromptSubmit, 
    # Stop, SubagentStop, PreCompact, SessionStart, SessionEnd
  }
}

Critical Hook Implementation Details

Location: lib/claude_code_sdk/types.rb:56-76 - The to_cli_args method handles settings conversion

JSON Detection Logic: lines 84-93 - Distinguishes between JSON strings and file paths:

  • JSON strings: Start/end with {} or []
  • File paths: Everything else passed directly to CLI

Environment Variables Available in Hooks:

  • $HOOK_INPUT - JSON data about the tool execution
  • Standard environment variables

Security Considerations:

  • Hook commands execute with full system privileges
  • Always sanitize user input in hook commands
  • Use absolute paths and validate webhook URLs

🔧 Development Workflow & Commands

Essential Commands

# Run all tests
bundle exec rake spec

# Run with coverage  
bundle exec rake coverage

# Integration tests (requires Claude Code CLI installed)
bundle exec rake integration

# Code style
bundle exec rubocop

# Documentation
bundle exec yard

# Interactive console with gem loaded
bundle exec rake console

Dependencies

Runtime: Only zeitwerk ~> 2.6 for autoloading Development: RSpec, RuboCop, SimpleCov, WebMock, YARD, Pry

🚨 Gotchas & Important Notes

Transport Layer Facts

  1. Internal::Client uses SubprocessCLI for all operations

    • This is the production transport with full streaming support
    • AllSpark Builder extends it with custom overrides for Docker compatibility
  2. Argument Ordering Critical

    • Prompt MUST come before CLI options to avoid argument parsing issues
    • See transport/simple_cli.rb:32-38 for proper command construction

Claude Code CLI Requirements

  • Must be installed: npm install -g @anthropic-ai/claude-code
  • API Key required: ANTHROPIC_API_KEY environment variable
  • CLI paths searched: claude-code, claude in PATH + common install locations

Hooks Processing Pipeline

  1. SDK receives settings parameter
  2. Options#to_cli_args converts to --settings CLI flag
  3. Claude Code CLI processes hooks and executes commands
  4. Hook commands receive $HOOK_INPUT with JSON tool data
  5. Commands can post to webhooks, log to files, etc.

Error Handling

  • CLINotFoundError - Claude Code CLI not installed/found
  • ProcessError - CLI process failed (includes exit code and stderr)
  • CLIJSONDecodeError - Failed to parse CLI JSON output

📁 Key Files for Development

Core Implementation:

  • lib/claude_code_sdk.rb - Main API surface
  • lib/claude_code_sdk/types.rb - Options & settings handling (HOOKS!)
  • lib/claude_code_sdk/transport/subprocess_cli.rb - Current active transport
  • lib/claude_code_sdk/internal/client.rb:12 - Where SubprocessCLI is instantiated

Examples (Essential for Understanding):

  • examples/dynamic_hooks.rb - Comprehensive hooks examples
  • examples/allspark_integration.rb - AllSpark Builder specific integration

Tests:

  • spec/claude_code_sdk/options_settings_spec.rb - Settings parameter tests
  • spec/integration/cli_interaction_spec.rb - End-to-end CLI tests

Configuration:

  • claude_code_sdk.gemspec - Dependencies and metadata
  • CLAUDE.md - Development guidance for Claude Code itself

🎯 AllSpark Builder Integration Points

Primary Use Cases

  1. Session-specific hooks via settings parameter
  2. Webhook integration for tool execution monitoring
  3. File operation tracking (Write, Edit, Read tools)
  4. Command execution monitoring (Bash, LS, Glob tools)

Integration Pattern

# In AllSpark Builder job:
hooks_json = CodeAgentHooksService.generate_settings_for_sdk(session)
options = ClaudeCodeSDK::Options.new(
  settings: hooks_json,  # JSON string with session-specific hooks
  allowed_tools: ["Bash", "Write", "Edit", "Read"],
  permission_mode: ClaudeCodeSDK::PermissionMode::ACCEPT_EDITS
)

ClaudeCodeSDK.query(user_prompt, options) do |message|
  # Handle streaming responses
end

🔮 Future Considerations

  1. Transport Layer - SubprocessCLI is working well with AllSpark's custom overrides
  2. Hooks Testing - Integration tests for webhook delivery and hook reliability
  3. Error Recovery - Better handling of webhook failures and hook command errors
  4. Performance - Caching and optimization for high-volume hook executions

📚 Documentation Locations

  • README.md - Comprehensive usage examples and API documentation
  • CLAUDE.md - Development guidance for Claude Code working on this project
  • CHANGELOG.md - Version history (notably v0.2.0 added hooks support)
  • examples/ - Working code examples for all major features
  • spec/ - Tests that double as usage documentation

Bottom Line: This SDK is a robust Ruby wrapper around Claude Code CLI with excellent hooks support. The hooks functionality via settings parameter is the key differentiator and enables powerful session-specific customization for AllSpark Builder. Focus on the Options#to_cli_args method and the examples directory when working with hooks.