Skip to content

Latest commit

 

History

History
152 lines (114 loc) · 4.46 KB

File metadata and controls

152 lines (114 loc) · 4.46 KB

Claude Code SDK Ruby v0.4.0 Release Summary

🎯 Major Discovery: Hooks Implementation Corrected

The Problem

The SDK documentation incorrectly stated that hooks receive data through the $HOOK_INPUT environment variable. Testing revealed this variable was always empty, preventing hooks from working properly.

The Solution

Through deep analysis of the Claude Code source code and extensive testing, we discovered that hooks actually receive data via STDIN as JSON. This is a fundamental correction to how hooks should be implemented.

🔄 Breaking Changes

Before (v0.3.0 and earlier - INCORRECT):

#!/usr/bin/env ruby
require 'json'

# WRONG: This doesn't work
hook_input = ENV['HOOK_INPUT']
data = JSON.parse(hook_input) if hook_input

After (v0.4.0 - CORRECT):

#!/usr/bin/env ruby
require 'json'

# CORRECT: Read from STDIN
data = JSON.parse(STDIN.read)

📦 What's Changed

Updated Files

  1. README.md - Corrected hooks documentation with STDIN examples
  2. AI_SUMMARY.md - Updated with critical finding about STDIN
  3. CLAUDE_CODE_ANALYSIS.md - Added comprehensive analysis of hooks mechanism
  4. CHANGELOG.md - Documented breaking changes
  5. lib/claude_code_sdk/version.rb - Bumped to 0.4.0

New Examples

  1. examples/hooks_stdin_reader.rb - Basic hook reading from STDIN
  2. examples/allspark_webhook_hook.rb - Complete webhook integration
  3. examples/inline_hooks.rb - Inline commands for direct use

Test Files

  1. test_hooks_simple.rb - Simplified test demonstrating STDIN approach
  2. test_hooks_v4.rb - Comprehensive test suite for v0.4.0

🔑 Key Implementation Points

For Ruby Hooks:

# Read hook data
data = JSON.parse(STDIN.read)

# Access hook information
hook_event = data['hook_event_name']
tool_name = data['tool_name']
session_id = data['session_id']
tool_input = data['tool_input']

For Python Hooks:

import json
import sys

# Read hook data
data = json.load(sys.stdin)

# Access hook information
hook_event = data.get('hook_event_name')
tool_name = data.get('tool_name')

For Shell/Bash Hooks:

#!/bin/bash
# Read JSON from STDIN
hook_data=$(cat)

# Process with jq or other tools
echo "$hook_data" | jq '.tool_name'

⚠️ Known Limitations

  1. Hooks don't work with --print flag: The SDK uses --print for output formatting, which disables hooks in the CLI. This is a Claude Code CLI limitation, not an SDK bug.

  2. Workaround Options:

    • Use hooks for monitoring/logging in production (without --print)
    • Implement SDK-level hooks that process messages after receiving them
    • Use the CLI directly for operations that require hooks

🚀 Migration Guide

Step 1: Update Hook Scripts

Replace all instances of ENV['HOOK_INPUT'] with STDIN.read:

# Old (broken)
data = JSON.parse(ENV['HOOK_INPUT'] || '{}')

# New (working)
data = JSON.parse(STDIN.read)

Step 2: Update Hook Configuration

Ensure your hooks configuration uses the correct command format:

hooks = {
  "hooks" => {
    "PostToolUse" => [
      {
        "matcher" => ".*",
        "hooks" => [
          {
            "type" => "command",
            "command" => "ruby /path/to/hook.rb"  # Hook must read from STDIN
          }
        ]
      }
    ]
  }
}

Step 3: Test Your Hooks

Use the provided test files to verify your hooks work correctly:

ruby test_hooks_simple.rb

📝 Documentation References

  • Full hooks documentation: See README.md "Hooks (Advanced)" section
  • Implementation examples: See examples/hooks_stdin_reader.rb
  • Webhook integration: See examples/allspark_webhook_hook.rb
  • Claude Code analysis: See CLAUDE_CODE_ANALYSIS.md

🎉 Summary

Version 0.4.0 represents a critical fix to the SDK's hooks implementation. While the hooks configuration and setup were correct, the documentation about how hooks receive data was fundamentally wrong. This release corrects that misconception and provides working examples that properly read from STDIN.

This discovery came from deep analysis of the Claude Code source code and extensive testing, demonstrating the importance of verifying assumptions against actual implementation rather than relying solely on documentation.

🙏 Acknowledgments

Special thanks to the thorough testing and analysis that revealed this critical issue. The SDK is now correctly documented and developers can successfully implement hooks following the examples provided.