claude_hooks 0.2.1 → 1.0.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +137 -0
  3. data/README.md +287 -356
  4. data/claude_hooks.gemspec +2 -2
  5. data/docs/1.0.0_MIGRATION_GUIDE.md +228 -0
  6. data/docs/API/COMMON.md +83 -0
  7. data/docs/API/NOTIFICATION.md +32 -0
  8. data/docs/API/POST_TOOL_USE.md +45 -0
  9. data/docs/API/PRE_COMPACT.md +39 -0
  10. data/docs/API/PRE_TOOL_USE.md +110 -0
  11. data/docs/API/SESSION_END.md +100 -0
  12. data/docs/API/SESSION_START.md +40 -0
  13. data/docs/API/STOP.md +47 -0
  14. data/docs/API/SUBAGENT_STOP.md +47 -0
  15. data/docs/API/USER_PROMPT_SUBMIT.md +47 -0
  16. data/{WHY.md → docs/WHY.md} +15 -8
  17. data/docs/external/claude-hooks-reference.md +34 -0
  18. data/example_dotclaude/hooks/entrypoints/pre_tool_use.rb +25 -0
  19. data/example_dotclaude/hooks/entrypoints/session_end.rb +35 -0
  20. data/example_dotclaude/hooks/entrypoints/user_prompt_submit.rb +17 -12
  21. data/example_dotclaude/hooks/handlers/pre_tool_use/github_guard.rb +253 -0
  22. data/example_dotclaude/hooks/handlers/session_end/cleanup_handler.rb +55 -0
  23. data/example_dotclaude/hooks/handlers/session_end/log_session_stats.rb +64 -0
  24. data/example_dotclaude/hooks/handlers/user_prompt_submit/append_rules.rb +3 -2
  25. data/example_dotclaude/hooks/handlers/user_prompt_submit/log_user_prompt.rb +2 -2
  26. data/example_dotclaude/plugins/README.md +175 -0
  27. data/example_dotclaude/settings.json +22 -0
  28. data/lib/claude_hooks/base.rb +16 -24
  29. data/lib/claude_hooks/cli.rb +75 -1
  30. data/lib/claude_hooks/logger.rb +0 -1
  31. data/lib/claude_hooks/output/base.rb +152 -0
  32. data/lib/claude_hooks/output/notification.rb +22 -0
  33. data/lib/claude_hooks/output/post_tool_use.rb +76 -0
  34. data/lib/claude_hooks/output/pre_compact.rb +20 -0
  35. data/lib/claude_hooks/output/pre_tool_use.rb +94 -0
  36. data/lib/claude_hooks/output/session_end.rb +24 -0
  37. data/lib/claude_hooks/output/session_start.rb +49 -0
  38. data/lib/claude_hooks/output/stop.rb +83 -0
  39. data/lib/claude_hooks/output/subagent_stop.rb +14 -0
  40. data/lib/claude_hooks/output/user_prompt_submit.rb +78 -0
  41. data/lib/claude_hooks/post_tool_use.rb +6 -12
  42. data/lib/claude_hooks/pre_tool_use.rb +0 -37
  43. data/lib/claude_hooks/session_end.rb +43 -0
  44. data/lib/claude_hooks/session_start.rb +0 -23
  45. data/lib/claude_hooks/stop.rb +8 -25
  46. data/lib/claude_hooks/user_prompt_submit.rb +0 -26
  47. data/lib/claude_hooks/version.rb +1 -1
  48. data/lib/claude_hooks.rb +15 -0
  49. metadata +37 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08b8b23bcfdeed5cf98e3477b6339f29488d6e547fd2fb10ef40947bbc3d45dc'
4
- data.tar.gz: 20d0f599bac9dcde566829dabba1d1f3f13756181ed4ea7bbe4cfa1c0a95838a
3
+ metadata.gz: d82c5deaa5426bc2ca898300f7772fa58c56a2998fd00af4eb1a93de25d3336e
4
+ data.tar.gz: ffde711d996ad0f43f7f75a3002f5a1e74e84f28ed2197ddf9c53c8b982a5152
5
5
  SHA512:
6
- metadata.gz: 7cd6ecea85c72ce39e77613f68c3dc9f689aca7611dd499482e20538bbb456e2c6b4c23bc791372173fd4b955e8d4211c3c8c29e0e97957812916f901327ce22
7
- data.tar.gz: 93b6032c1c29c11081419d0415dae8ac5cd2494fa558af1637c081ce11d256403c1b26c49740c9aa8294c385aa311b12da2b3e5a6949e88a4a5f892b68abcf54
6
+ metadata.gz: 8256eeed53e717873271ea94b9d85610e741ade7d6009b41a9df6eccc8ea58ec4af3b4ab8883d8dfba3d0ef849afdcae6939786d7cb7ad4d000dd7dc749a73ab
7
+ data.tar.gz: 306144f71bd099d70df514ee21eb9e63a11389562322927465b1aecff447c78eaafc602aa973db8a925bf0885c4e212fbcbfacb410c6d34c30a7b56eb9e51145
data/CHANGELOG.md CHANGED
@@ -5,6 +5,143 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.2] - 2026-01-04
9
+
10
+ ### Fixed
11
+
12
+ - **Critical: Fixed hook output contract for JSON API** - Stop, PostToolUse, UserPromptSubmit, and PreToolUse hooks now correctly use stdout + exit 0 when outputting structured JSON
13
+ - Stop hooks now output to stdout with exit 0 instead of stderr with exit 2 (PR #15, fixes #11)
14
+ - PostToolUse hooks now use stdout + exit 0 for JSON API consistency
15
+ - UserPromptSubmit hooks now use stdout + exit 0 for JSON API consistency
16
+ - PreToolUse hooks now use exit 0 for all permission decisions (previously varied: 0 for allow, 1 for ask, 2 for deny)
17
+ - This aligns with Anthropic's official guidance: when using advanced JSON API with decision/reason fields, hooks must output to stdout with exit 0
18
+ - **Breaking behavior fixed**: Plugin hooks with `continue_with_instructions!` now work correctly
19
+ - Reference: https://github.com/anthropics/claude-code/issues/10875
20
+ - Reference: https://github.com/gabriel-dehan/claude_hooks/issues/11
21
+
22
+ ### Notes
23
+
24
+ - All tests updated and passing (147 runs, 262 assertions, 0 failures)
25
+ - This fix ensures compatibility with Claude Code's plugin system
26
+ - The exit code 2 + stderr approach is only for simple text output without JSON structure
27
+
28
+ ## [1.0.1] - 2025-10-13
29
+
30
+ ### Documentation
31
+
32
+ - **Added comprehensive plugin hooks documentation** - Full guide on using the Claude Hooks DSL with Claude Code plugins
33
+ - New "Plugin Hooks Support" section in README with working examples
34
+ - Created `example_dotclaude/plugins/README.md` with complete plugin development guide
35
+ - Example plugin formatter implementation using the DSL
36
+ - Environment variables documentation for plugin development
37
+ - Best practices and testing instructions for plugin hooks
38
+ - **Updated SessionStart hook documentation** - Added the new `compact` matcher introduced in official Claude Hooks documentation
39
+ - Updated `docs/API/SESSION_START.md` to include `'compact'` as a valid source value
40
+ - Updated SessionStart hook type description to mention compact functionality
41
+ - **Synchronized with official documentation** - All documentation now matches the official Claude Hooks reference as of 2025-10-13
42
+ - Plugin hooks feature (Issue #9)
43
+ - SessionStart `compact` matcher (Issue #2)
44
+
45
+ ### Notes
46
+
47
+ - No code changes required - the implementation already supports all documented features
48
+ - The DSL's dynamic implementation handles the new `compact` source automatically
49
+ - Plugin environment variables (`CLAUDE_PLUGIN_ROOT`) work seamlessly with existing configuration system
50
+
51
+ ## [1.0.0] - 2025-08-27
52
+
53
+ > [!WARNING]
54
+ > These changes are not backward compatible (hence the version bump to 1.0.0), the API has changed too much.
55
+
56
+ Follow the [migration guide](docs/1.0.0_MIGRATION_GUIDE.md) to migrate to the new API.
57
+
58
+ ### Changed
59
+
60
+ #### Revamped documentation
61
+
62
+ - **New documentation structure**:
63
+ - **API Reference**: Comprehensive API reference for all hook types
64
+ - **Common Helpers**: Shared helpers for all hook types
65
+ - **Output Helpers**: Helpers for working with the output state
66
+ - **Hook Exit Codes**: Exit codes for each hook type
67
+ - **Hook Types**: Overview of all hook types and their purpose
68
+
69
+ #### Added support for SessionEnd
70
+ Handles the new `SessionEnd` hook type.
71
+
72
+ #### Handles new field for PostToolUse
73
+ `additionalContext` field is now available in the `hookSpecificOutput` field.
74
+
75
+ #### Output Objects System
76
+ New output handling with intelligent exit code management.
77
+
78
+ - **Automatic Exit Code Selection**: Output objects automatically choose the correct exit code (0, 1, 2) based on hook type and the state of the hook
79
+ - - **Enhanced Base Class**: All hook instances now automatically get an `@output` attribute with a `output` accessor. They can still access raw `output_data`
80
+ - **Helper Methods**: Access to hook-specific data via methods like `output.blocked?`, `output.allowed?`, `output.should_ask_permission?`
81
+ - **Automatic Stream Selection**: Output objects automatically route to `STDOUT` or `STDERR` based on exit code and hook type
82
+ - **One-Line Output Execution**: New `output_and_exit` method handles JSON serialization, stream selection, and exit code in one call
83
+ - **Object-Based Merging**: New `ClaudeHooks::Output::*.merge()` methods for cleaner multi-hook merging
84
+ - **Comprehensive Output Classes**: Full coverage for all 8 hook types:
85
+ - `ClaudeHooks::Output::UserPromptSubmit` - Provides `blocked?`, `reason`, `additional_context`
86
+ - `ClaudeHooks::Output::PreToolUse` - Provides `allowed?`, `denied?`, `should_ask_permission?`
87
+ - `ClaudeHooks::Output::PostToolUse` - Provides `blocked?`, `reason`
88
+ - `ClaudeHooks::Output::Stop` - Provides `should_continue?`, `continue_instructions` (inverted logic)
89
+ - `ClaudeHooks::Output::SubagentStop` - Inherits Stop behavior
90
+ - `ClaudeHooks::Output::Notification` - Basic output handling
91
+ - `ClaudeHooks::Output::SessionStart` - Provides `additional_context`
92
+ - `ClaudeHooks::Output::PreCompact` - Basic output handling
93
+
94
+ ##### Migration Guide
95
+
96
+ **Before (Old Pattern):**
97
+ ```ruby
98
+ #!/usr/bin/env ruby
99
+ require 'claude_hooks'
100
+
101
+ begin
102
+ input_data = JSON.parse(STDIN.read)
103
+ hook = MyHook.new(input_data)
104
+ result = hook.call
105
+
106
+ # Manual stream and exit code selection
107
+ if result['continue'] != false
108
+ if result.dig('hookSpecificOutput', 'permissionDecision') == 'deny'
109
+ STDERR.puts hook.stringify_output
110
+ exit 1
111
+ elsif result.dig('hookSpecificOutput', 'permissionDecision') == 'ask'
112
+ STDERR.puts hook.stringify_output
113
+ exit 2
114
+ else
115
+ puts hook.stringify_output
116
+ exit 0
117
+ end
118
+ else # Continue == false
119
+ STDERR.puts hook.stringify_output
120
+ exit 2
121
+ end
122
+ rescue StandardError => e
123
+ # Error handling...
124
+ end
125
+ ```
126
+
127
+ **After (New Pattern):**
128
+ ```ruby
129
+ #!/usr/bin/env ruby
130
+ require 'claude_hooks'
131
+
132
+ # Just 3 lines for most cases!
133
+ begin
134
+ input_data = JSON.parse(STDIN.read)
135
+ hook = MyHook.new(input_data)
136
+ hook.call
137
+
138
+ # Handles everything automatically!
139
+ hook.output_and_exit
140
+ rescue StandardError => e
141
+ # Error handling...
142
+ end
143
+ ```
144
+
8
145
  ## [0.2.1] - 2025-08-21
9
146
 
10
147
  ### Fixed