claude_hooks 1.0.2 → 1.2.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/skills/ci-monitoring/SKILL.md +103 -0
  3. data/.agents/skills/run-tests/SKILL.md +45 -0
  4. data/.claude/auto-fix.md +7 -0
  5. data/.claude/settings.local.json +21 -0
  6. data/AGENTS.md +46 -0
  7. data/CHANGELOG.md +93 -0
  8. data/README.md +159 -21
  9. data/docs/1.1.0_UPGRADE_GUIDE.md +269 -0
  10. data/docs/API/COMMON.md +7 -0
  11. data/docs/API/CONFIG_CHANGE.md +39 -0
  12. data/docs/API/CWD_CHANGED.md +34 -0
  13. data/docs/API/ELICITATION.md +44 -0
  14. data/docs/API/ELICITATION_RESULT.md +43 -0
  15. data/docs/API/FILE_CHANGED.md +37 -0
  16. data/docs/API/INSTRUCTIONS_LOADED.md +30 -0
  17. data/docs/API/MESSAGE_DISPLAY.md +38 -0
  18. data/docs/API/NOTIFICATION.md +1 -0
  19. data/docs/API/PERMISSION_DENIED.md +37 -0
  20. data/docs/API/PERMISSION_REQUEST.md +199 -0
  21. data/docs/API/POST_COMPACT.md +30 -0
  22. data/docs/API/POST_TOOL_BATCH.md +39 -0
  23. data/docs/API/POST_TOOL_USE.md +1 -0
  24. data/docs/API/POST_TOOL_USE_FAILURE.md +31 -0
  25. data/docs/API/PRE_COMPACT.md +10 -2
  26. data/docs/API/PRE_TOOL_USE.md +9 -1
  27. data/docs/API/SETUP.md +37 -0
  28. data/docs/API/STOP_FAILURE.md +19 -0
  29. data/docs/API/SUBAGENT_START.md +40 -0
  30. data/docs/API/TASK_COMPLETED.md +43 -0
  31. data/docs/API/TASK_CREATED.md +43 -0
  32. data/docs/API/TEAMMATE_IDLE.md +40 -0
  33. data/docs/API/USER_PROMPT_EXPANSION.md +43 -0
  34. data/docs/API/WORKTREE_CREATE.md +39 -0
  35. data/docs/API/WORKTREE_REMOVE.md +33 -0
  36. data/docs/PROMPT_BASED_HOOKS.md +386 -0
  37. data/docs/external/claude-hooks-reference.md +2846 -18
  38. data/docs/mitts/ideabox.md +12 -0
  39. data/docs/mitts/prd.md +417 -0
  40. data/docs/mitts/setup.md +303 -0
  41. data/docs/mitts/task.md +44 -0
  42. data/lib/claude_hooks/base.rb +30 -1
  43. data/lib/claude_hooks/config_change.rb +28 -0
  44. data/lib/claude_hooks/cwd_changed.rb +28 -0
  45. data/lib/claude_hooks/elicitation.rb +61 -0
  46. data/lib/claude_hooks/elicitation_result.rb +57 -0
  47. data/lib/claude_hooks/file_changed.rb +41 -0
  48. data/lib/claude_hooks/instructions_loaded.rb +23 -0
  49. data/lib/claude_hooks/message_display.rb +58 -0
  50. data/lib/claude_hooks/notification.rb +5 -1
  51. data/lib/claude_hooks/output/base.rb +48 -1
  52. data/lib/claude_hooks/output/config_change.rb +47 -0
  53. data/lib/claude_hooks/output/cwd_changed.rb +42 -0
  54. data/lib/claude_hooks/output/elicitation.rb +67 -0
  55. data/lib/claude_hooks/output/elicitation_result.rb +63 -0
  56. data/lib/claude_hooks/output/file_changed.rb +42 -0
  57. data/lib/claude_hooks/output/instructions_loaded.rb +19 -0
  58. data/lib/claude_hooks/output/message_display.rb +49 -0
  59. data/lib/claude_hooks/output/permission_denied.rb +42 -0
  60. data/lib/claude_hooks/output/permission_request.rb +120 -0
  61. data/lib/claude_hooks/output/post_compact.rb +18 -0
  62. data/lib/claude_hooks/output/post_tool_batch.rb +51 -0
  63. data/lib/claude_hooks/output/post_tool_use.rb +12 -0
  64. data/lib/claude_hooks/output/post_tool_use_failure.rb +42 -0
  65. data/lib/claude_hooks/output/pre_compact.rb +34 -3
  66. data/lib/claude_hooks/output/pre_tool_use.rb +26 -2
  67. data/lib/claude_hooks/output/session_start.rb +30 -8
  68. data/lib/claude_hooks/output/setup.rb +42 -0
  69. data/lib/claude_hooks/output/stop.rb +15 -0
  70. data/lib/claude_hooks/output/stop_failure.rb +19 -0
  71. data/lib/claude_hooks/output/subagent_start.rb +42 -0
  72. data/lib/claude_hooks/output/task_completed.rb +18 -0
  73. data/lib/claude_hooks/output/task_created.rb +18 -0
  74. data/lib/claude_hooks/output/teammate_idle.rb +18 -0
  75. data/lib/claude_hooks/output/user_prompt_expansion.rb +51 -0
  76. data/lib/claude_hooks/output/worktree_create.rb +60 -0
  77. data/lib/claude_hooks/output/worktree_remove.rb +19 -0
  78. data/lib/claude_hooks/permission_denied.rb +41 -0
  79. data/lib/claude_hooks/permission_request.rb +63 -0
  80. data/lib/claude_hooks/post_compact.rb +23 -0
  81. data/lib/claude_hooks/post_tool_batch.rb +59 -0
  82. data/lib/claude_hooks/post_tool_use.rb +15 -1
  83. data/lib/claude_hooks/post_tool_use_failure.rb +45 -0
  84. data/lib/claude_hooks/pre_compact.rb +7 -0
  85. data/lib/claude_hooks/pre_tool_use.rb +34 -1
  86. data/lib/claude_hooks/session_start.rb +28 -0
  87. data/lib/claude_hooks/setup.rb +25 -0
  88. data/lib/claude_hooks/stop.rb +17 -0
  89. data/lib/claude_hooks/stop_failure.rb +27 -0
  90. data/lib/claude_hooks/subagent_start.rb +23 -0
  91. data/lib/claude_hooks/subagent_stop.rb +5 -1
  92. data/lib/claude_hooks/task_completed.rb +35 -0
  93. data/lib/claude_hooks/task_created.rb +35 -0
  94. data/lib/claude_hooks/teammate_idle.rb +23 -0
  95. data/lib/claude_hooks/user_prompt_expansion.rb +45 -0
  96. data/lib/claude_hooks/version.rb +1 -1
  97. data/lib/claude_hooks/worktree_create.rb +27 -0
  98. data/lib/claude_hooks/worktree_remove.rb +19 -0
  99. data/lib/claude_hooks.rb +42 -0
  100. metadata +76 -2
@@ -0,0 +1,269 @@
1
+ # Upgrading to v1.1.0
2
+
3
+ Version 1.1.0 adds new features to align with Anthropic's updated Claude Code Hooks documentation. **All changes are backward compatible** - existing hooks continue to work without modification.
4
+
5
+ ## What's New
6
+
7
+ ### 1. New PermissionRequest Hook
8
+
9
+ Handle permission request events from Claude Code:
10
+
11
+ ```ruby
12
+ class PermissionGuard < ClaudeHooks::PermissionRequest
13
+ def call
14
+ if dangerous_tool?
15
+ deny_permission!("Requires manual approval")
16
+ else
17
+ allow_permission!("Safe to proceed")
18
+ end
19
+ output
20
+ end
21
+
22
+ private
23
+
24
+ def dangerous_tool?
25
+ %w[rm git-reset curl].include?(tool_name)
26
+ end
27
+ end
28
+ ```
29
+
30
+ **When to use**: Create permission guards that automatically approve/deny permission requests based on custom logic.
31
+
32
+ ### 2. New Fields Available
33
+
34
+ All hooks now receive these additional fields:
35
+
36
+ - **`permission_mode`** (all hooks): Access via `permission_mode` method
37
+ - Values: `'default'`, `'plan'`, `'acceptEdits'`, `'dontAsk'`, `'bypassPermissions'`
38
+ - Defaults to `'default'`
39
+
40
+ - **`tool_use_id`** (PreToolUse, PostToolUse, PermissionRequest): Access via `tool_use_id` method
41
+ - Unique identifier for each tool use (e.g., `"toolu_01ABC123..."`)
42
+
43
+ - **`notification_type`** (Notification): Access via `notification_type` method
44
+ - Values: `'permission_prompt'`, `'idle_prompt'`, `'auth_success'`, `'elicitation_dialog'`
45
+
46
+ **Example usage:**
47
+
48
+ ```ruby
49
+ class MyHook < ClaudeHooks::PreToolUse
50
+ def call
51
+ log "Permission mode: #{permission_mode}"
52
+ log "Tool use ID: #{tool_use_id}"
53
+
54
+ # Adjust behavior based on permission mode
55
+ if permission_mode == 'bypassPermissions'
56
+ # More restrictive checks
57
+ deny_permission!("Cannot bypass for sensitive operations")
58
+ else
59
+ approve_tool!("Approved")
60
+ end
61
+
62
+ output
63
+ end
64
+ end
65
+ ```
66
+
67
+ ### 3. Update Tool Input (PreToolUse)
68
+
69
+ Modify tool input before execution:
70
+
71
+ ```ruby
72
+ class InputModifier < ClaudeHooks::PreToolUse
73
+ def call
74
+ case tool_name
75
+ when 'Bash'
76
+ # Add safety flags to bash commands
77
+ if tool_input['command']&.include?('rm')
78
+ sanitized = tool_input.merge('command' => "#{tool_input['command']} --interactive")
79
+ update_tool_input!(sanitized)
80
+ else
81
+ approve_tool!("Safe command")
82
+ end
83
+ when 'Write'
84
+ # Validate file paths
85
+ if tool_input['file_path']&.start_with?('/etc')
86
+ deny_permission!("Cannot write to /etc")
87
+ else
88
+ approve_tool!("Safe write")
89
+ end
90
+ else
91
+ approve_tool!("No special handling")
92
+ end
93
+
94
+ output
95
+ end
96
+ end
97
+ ```
98
+
99
+ **Output helpers:**
100
+ - `output.input_updated?` - Check if input was modified
101
+ - `output.updated_input` - Get the updated input hash
102
+
103
+ ## Do I Need to Change My Existing Hooks?
104
+
105
+ **No!** All changes are backward compatible:
106
+
107
+ - New fields have sensible defaults (return `nil` or `'default'`)
108
+ - Existing methods continue to work exactly as before
109
+ - No breaking changes to any APIs
110
+ - Your existing hooks will work with v1.1.0 without any modifications
111
+
112
+ ## Should I Update My Hooks?
113
+
114
+ Consider updating if:
115
+
116
+ - ✅ You want to handle PermissionRequest events
117
+ - ✅ You need to check the current permission mode
118
+ - ✅ You want to modify tool inputs dynamically
119
+ - ✅ You need to differentiate notification types
120
+ - ✅ You want to track specific tool use instances via IDs
121
+
122
+ ## New Hook Type Summary
123
+
124
+ | Hook Type | When It Runs | Key Methods |
125
+ |-----------|--------------|-------------|
126
+ | **PermissionRequest** | When Claude requests permission | `allow_permission!`, `deny_permission!`, `update_input_and_allow!` |
127
+
128
+ ## New Fields Summary
129
+
130
+ | Field | Available In | Purpose |
131
+ |-------|--------------|---------|
132
+ | `permission_mode` | All hooks | Know the current permission mode |
133
+ | `tool_use_id` | PreToolUse, PermissionRequest, PostToolUse | Track specific tool use instances |
134
+ | `notification_type` | Notification | Filter notifications by type |
135
+
136
+ ## New PreToolUse Features
137
+
138
+ | Feature | Method | Description |
139
+ |---------|--------|-------------|
140
+ | Update input | `update_tool_input!(hash)` | Modify tool input and auto-approve |
141
+ | Check if updated | `output.input_updated?` | Boolean check for modification |
142
+ | Get updated input | `output.updated_input` | Retrieve the modified input |
143
+
144
+ ## Testing
145
+
146
+ All existing tests should pass without modification. Run:
147
+
148
+ ```bash
149
+ bundle exec rake test
150
+ # or
151
+ ruby test/run_all_tests.rb
152
+ ```
153
+
154
+ ## Migration Examples
155
+
156
+ ### Example 1: Using permission_mode
157
+
158
+ **Before (v1.0.x):**
159
+ ```ruby
160
+ class GitGuard < ClaudeHooks::PreToolUse
161
+ def call
162
+ if tool_name == 'Bash' && tool_input['command']&.include?('git push')
163
+ ask_for_permission!("Git push requires confirmation")
164
+ else
165
+ approve_tool!("Approved")
166
+ end
167
+ output
168
+ end
169
+ end
170
+ ```
171
+
172
+ **After (v1.1.0 - enhanced):**
173
+ ```ruby
174
+ class GitGuard < ClaudeHooks::PreToolUse
175
+ def call
176
+ if tool_name == 'Bash' && tool_input['command']&.include?('git push')
177
+ # Skip asking in dontAsk mode, but still log
178
+ if permission_mode == 'dontAsk'
179
+ log "Auto-approving git push in dontAsk mode", level: :warn
180
+ approve_tool!("Auto-approved due to permission mode")
181
+ else
182
+ ask_for_permission!("Git push requires confirmation")
183
+ end
184
+ else
185
+ approve_tool!("Approved")
186
+ end
187
+ output
188
+ end
189
+ end
190
+ ```
191
+
192
+ ### Example 2: Using PermissionRequest
193
+
194
+ **Before (v1.0.x):**
195
+ ```ruby
196
+ # Permission requests couldn't be handled automatically
197
+ ```
198
+
199
+ **After (v1.1.0 - new capability):**
200
+ ```ruby
201
+ class AutoPermissionGuard < ClaudeHooks::PermissionRequest
202
+ SAFE_TOOLS = %w[ls cat grep find read].freeze
203
+
204
+ def call
205
+ if SAFE_TOOLS.include?(tool_name)
206
+ allow_permission!("Safe tool, auto-approved")
207
+ else
208
+ # Let user decide
209
+ deny_permission!("Requires manual approval")
210
+ end
211
+ output
212
+ end
213
+ end
214
+ ```
215
+
216
+ ### Example 3: Updating tool input
217
+
218
+ **Before (v1.0.x):**
219
+ ```ruby
220
+ class BashSanitizer < ClaudeHooks::PreToolUse
221
+ def call
222
+ # Could only approve or deny, not modify
223
+ if tool_input['command']&.include?('rm')
224
+ block_tool!("Dangerous command blocked")
225
+ else
226
+ approve_tool!("Safe")
227
+ end
228
+ output
229
+ end
230
+ end
231
+ ```
232
+
233
+ **After (v1.1.0 - new capability):**
234
+ ```ruby
235
+ class BashSanitizer < ClaudeHooks::PreToolUse
236
+ def call
237
+ if tool_input['command']&.include?('rm')
238
+ # Add safety flags instead of blocking
239
+ safe_command = "#{tool_input['command']} --interactive --verbose"
240
+ update_tool_input!({'command' => safe_command})
241
+ log "Added safety flags to rm command"
242
+ else
243
+ approve_tool!("Safe")
244
+ end
245
+ output
246
+ end
247
+ end
248
+ ```
249
+
250
+ ## Questions?
251
+
252
+ - See the [full CHANGELOG](../CHANGELOG.md) for all changes
253
+ - Check the [API documentation](API/) for detailed method references
254
+ - Review the [PermissionRequest API](API/PERMISSION_REQUEST.md) for the new hook type
255
+ - Look at [example implementations](../example_dotclaude/) for patterns
256
+
257
+ ## Rollback
258
+
259
+ If you need to rollback to v1.0.2:
260
+
261
+ ```bash
262
+ gem uninstall claude_hooks
263
+ gem install claude_hooks -v 1.0.2
264
+ ```
265
+
266
+ Or in your Gemfile:
267
+ ```ruby
268
+ gem 'claude_hooks', '~> 1.0.2'
269
+ ```
data/docs/API/COMMON.md CHANGED
@@ -12,6 +12,11 @@ Input helpers to access the data provided by Claude Code through `STDIN`.
12
12
  | `transcript_path` | Get path to the transcript file |
13
13
  | `cwd` | Get current working directory |
14
14
  | `hook_event_name` | Get the hook event name |
15
+ | `permission_mode` | Get the permission mode: `'default'`, `'plan'`, `'acceptEdits'`, `'auto'`, `'dontAsk'`, `'bypassPermissions'` (defaults to `'default'`) |
16
+ | `prompt_id` | Get the current prompt ID |
17
+ | `agent_id` | Get the agent ID (present in subagent contexts) |
18
+ | `agent_type` | Get the agent type (present in subagent contexts) |
19
+ | `effort` | Get the effort level string (reads `effort.level`) |
15
20
  | `read_transcript` | Read the transcript file |
16
21
  | `transcript` | Alias for `read_transcript` |
17
22
 
@@ -27,6 +32,7 @@ Hook state methods are helpers to modify the hook's internal state (`output_data
27
32
  | `clear_specifics!` | Clear hook-specific output |
28
33
  | `system_message!(message)` | Set a system message shown to the user (not to Claude) |
29
34
  | `clear_system_message!` | Clear the system message |
35
+ | `terminal_sequence!(seq)` | Emit an ANSI/terminal escape sequence in the output |
30
36
 
31
37
  ## Output Helpers
32
38
 
@@ -44,6 +50,7 @@ This object provides helpers to access output data, for merging multiple outputs
44
50
  | `output.suppress_output?` | Check if output should be suppressed from transcript |
45
51
  | `output.hook_specific_output` | Get the hook-specific output data |
46
52
  | `output.system_message` | Get the system message if any |
53
+ | `output.terminal_sequence` | Get the terminal escape sequence (if set) |
47
54
 
48
55
  ### Output data merging
49
56
  For each hook type, the `output` object provides a **class method** `merge` that will try to intelligently merge multiple hook results, e.g. `ClaudeHooks::Output::UserPromptSubmit.merge(output1, output2, output3)`.
@@ -0,0 +1,39 @@
1
+ # ConfigChange API
2
+
3
+ Available when inheriting from `ClaudeHooks::ConfigChange`:
4
+
5
+ Runs when Claude Code configuration changes. Can block the change for most sources (note: `policy_settings` changes cannot be blocked).
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `source` | The source of the config change (e.g. `'project'`, `'user'`, `'policy_settings'`) |
14
+ | `file_path` | Path to the changed config file (optional) |
15
+
16
+ ## Hook State Helpers
17
+
18
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
19
+
20
+ | Method | Description |
21
+ |--------|-------------|
22
+ | `block!(reason)` | Block the config change (ineffective for `policy_settings`) |
23
+
24
+ ## Output Helpers
25
+
26
+ [📚 Shared output helpers](COMMON.md#output-helpers)
27
+
28
+ | Method | Description |
29
+ |--------|-------------|
30
+ | `output.blocked?` | Check if the change was blocked |
31
+ | `output.decision` | Get the decision (`'block'` or nil) |
32
+ | `output.reason` | Get the block reason |
33
+
34
+ ## Hook Exit Codes
35
+
36
+ | Exit Code | Behavior |
37
+ |-----------|----------|
38
+ | `exit 0` | Config change proceeds |
39
+ | `exit 2` | Blocks the change; `STDERR` shown to Claude |
@@ -0,0 +1,34 @@
1
+ # CwdChanged API
2
+
3
+ Available when inheriting from `ClaudeHooks::CwdChanged`:
4
+
5
+ Runs when the working directory changes. Can update the list of watched paths.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `old_cwd` | The previous working directory |
14
+ | `new_cwd` | The new working directory |
15
+
16
+ ## Hook State Helpers
17
+
18
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
19
+
20
+ | Method | Description |
21
+ |--------|-------------|
22
+ | `watch_paths!(paths)` | Set the list of paths Claude Code should watch for changes |
23
+
24
+ ## Output Helpers
25
+
26
+ [📚 Shared output helpers](COMMON.md#output-helpers)
27
+
28
+ | Method | Description |
29
+ |--------|-------------|
30
+ | `output.watch_paths` | Get the configured watch paths |
31
+
32
+ ## Hook Exit Codes
33
+
34
+ Non-blocking. Only `watchPaths` output is consumed.
@@ -0,0 +1,44 @@
1
+ # Elicitation API
2
+
3
+ Available when inheriting from `ClaudeHooks::Elicitation`:
4
+
5
+ Runs when an MCP server requests user input (an elicitation dialog). Can accept, decline, or cancel the request.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `mcp_server_name` | The MCP server requesting input |
14
+ | `message` | The message / prompt shown to the user |
15
+ | `mode` | Optional interaction mode |
16
+ | `url` | Optional URL associated with the request |
17
+ | `elicitation_id` | Optional unique ID for this elicitation |
18
+ | `requested_schema` | Optional JSON schema describing the expected response |
19
+
20
+ ## Hook State Helpers
21
+
22
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
23
+
24
+ | Method | Description |
25
+ |--------|-------------|
26
+ | `accept!(content = {})` | Accept the elicitation with optional content hash |
27
+ | `decline!` | Decline the elicitation |
28
+ | `cancel!` | Cancel the elicitation |
29
+
30
+ ## Output Helpers
31
+
32
+ [📚 Shared output helpers](COMMON.md#output-helpers)
33
+
34
+ | Method | Description |
35
+ |--------|-------------|
36
+ | `output.action` | Get the chosen action: `'accept'`, `'decline'`, or `'cancel'` |
37
+ | `output.content` | Get the accepted content hash |
38
+ | `output.accepted?` | Check if the elicitation was accepted |
39
+ | `output.declined?` | Check if the elicitation was declined |
40
+ | `output.cancelled?` | Check if the elicitation was cancelled |
41
+
42
+ ## Hook Exit Codes
43
+
44
+ Uses the JSON API (exit 0 / stdout). The `hookSpecificOutput.action` field controls the response.
@@ -0,0 +1,43 @@
1
+ # ElicitationResult API
2
+
3
+ Available when inheriting from `ClaudeHooks::ElicitationResult`:
4
+
5
+ Runs after a user has responded to an elicitation dialog. Can override the action or content before it is sent back to the MCP server.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `mcp_server_name` | The MCP server that requested input |
14
+ | `action` | The user's chosen action: `'accept'`, `'decline'`, or `'cancel'` |
15
+ | `mode` | Optional interaction mode |
16
+ | `elicitation_id` | Optional unique ID for this elicitation |
17
+ | `content` | The content the user provided (for `'accept'` action) |
18
+
19
+ ## Hook State Helpers
20
+
21
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
22
+
23
+ | Method | Description |
24
+ |--------|-------------|
25
+ | `accept!(content = {})` | Override the response with an accept + content |
26
+ | `decline!` | Override the response to decline |
27
+ | `cancel!` | Override the response to cancel |
28
+
29
+ ## Output Helpers
30
+
31
+ [📚 Shared output helpers](COMMON.md#output-helpers)
32
+
33
+ | Method | Description |
34
+ |--------|-------------|
35
+ | `output.action` | Get the (possibly overridden) action |
36
+ | `output.content` | Get the (possibly overridden) content |
37
+ | `output.accepted?` | Check if the action is `'accept'` |
38
+ | `output.declined?` | Check if the action is `'decline'` |
39
+ | `output.cancelled?` | Check if the action is `'cancel'` |
40
+
41
+ ## Hook Exit Codes
42
+
43
+ Uses the JSON API (exit 0 / stdout).
@@ -0,0 +1,37 @@
1
+ # FileChanged API
2
+
3
+ Available when inheriting from `ClaudeHooks::FileChanged`:
4
+
5
+ Runs when a watched file is created, modified, or deleted. Can update the watch paths list.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `file_path` | The path of the changed file |
14
+ | `event` | The type of change: `'change'`, `'add'`, or `'unlink'` |
15
+ | `modified?` | Convenience: `event == 'change'` |
16
+ | `created?` | Convenience: `event == 'add'` |
17
+ | `deleted?` | Convenience: `event == 'unlink'` |
18
+
19
+ ## Hook State Helpers
20
+
21
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
22
+
23
+ | Method | Description |
24
+ |--------|-------------|
25
+ | `watch_paths!(paths)` | Update the list of paths Claude Code should watch |
26
+
27
+ ## Output Helpers
28
+
29
+ [📚 Shared output helpers](COMMON.md#output-helpers)
30
+
31
+ | Method | Description |
32
+ |--------|-------------|
33
+ | `output.watch_paths` | Get the configured watch paths |
34
+
35
+ ## Hook Exit Codes
36
+
37
+ Non-blocking. Only `watchPaths` output is consumed.
@@ -0,0 +1,30 @@
1
+ # InstructionsLoaded API
2
+
3
+ Available when inheriting from `ClaudeHooks::InstructionsLoaded`:
4
+
5
+ Runs when a `CLAUDE.md` instructions file is loaded. Non-blocking — exit code is ignored.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `file_path` | Path to the loaded instructions file |
14
+ | `load_reason` | Why the file was loaded (e.g. `'startup'`, `'cwd_change'`) |
15
+
16
+ ## Hook State Helpers
17
+
18
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
19
+
20
+ No event-specific state methods — this hook is non-blocking.
21
+
22
+ ## Output Helpers
23
+
24
+ [📚 Shared output helpers](COMMON.md#output-helpers)
25
+
26
+ No event-specific output helpers.
27
+
28
+ ## Hook Exit Codes
29
+
30
+ Non-blocking. Exit code is ignored by Claude Code.
@@ -0,0 +1,38 @@
1
+ # MessageDisplay API
2
+
3
+ Available when inheriting from `ClaudeHooks::MessageDisplay`:
4
+
5
+ Runs when a message is about to be displayed. Can override the displayed text via `hookSpecificOutput.displayContent`.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `turn_id` | ID of the current turn |
14
+ | `message_id` | ID of this message |
15
+ | `index` | Position of this message in the turn |
16
+ | `final` | Whether this is the final message chunk (`true`/`false`) |
17
+ | `delta` | The incremental text content of this message |
18
+ | `message_text` | Alias for `delta` |
19
+
20
+ ## Hook State Helpers
21
+
22
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
23
+
24
+ | Method | Description |
25
+ |--------|-------------|
26
+ | `display_content!(text)` | Override the displayed text for this message |
27
+
28
+ ## Output Helpers
29
+
30
+ [📚 Shared output helpers](COMMON.md#output-helpers)
31
+
32
+ | Method | Description |
33
+ |--------|-------------|
34
+ | `output.display_content` | Get the overridden display content (if set) |
35
+
36
+ ## Hook Exit Codes
37
+
38
+ Exit code and output stream are ignored for MessageDisplay. The only honored output is `hookSpecificOutput.displayContent`.
@@ -11,6 +11,7 @@ Input helpers to access the data provided by Claude Code through `STDIN`.
11
11
  |--------|-------------|
12
12
  | `message` | Get the notification message content |
13
13
  | `notification_message` | Alias for `message` |
14
+ | `notification_type` | Get the notification type: `'permission_prompt'`, `'idle_prompt'`, `'auth_success'`, `'elicitation_dialog'` |
14
15
 
15
16
  ## Hook State Helpers
16
17
  Notifications are outside facing and do not have any specific state to modify.
@@ -0,0 +1,37 @@
1
+ # PermissionDenied API
2
+
3
+ Available when inheriting from `ClaudeHooks::PermissionDenied`:
4
+
5
+ Runs when a permission request is denied. Can request that Claude Code retries the request.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `tool_name` | The name of the tool whose permission was denied |
14
+ | `tool_input` | The input data for the tool |
15
+ | `tool_use_id` | The unique identifier for this tool use |
16
+ | `reason` | The reason the permission was denied |
17
+
18
+ ## Hook State Helpers
19
+
20
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
21
+
22
+ | Method | Description |
23
+ |--------|-------------|
24
+ | `retry!` | Request that Claude Code retry the permission request |
25
+ | `no_retry!` | Explicitly decline to retry (default) |
26
+
27
+ ## Output Helpers
28
+
29
+ [📚 Shared output helpers](COMMON.md#output-helpers)
30
+
31
+ | Method | Description |
32
+ |--------|-------------|
33
+ | `output.retry?` | Check if a retry was requested |
34
+
35
+ ## Hook Exit Codes
36
+
37
+ Exit code is ignored. Output is via `hookSpecificOutput.retry` (JSON API, exit 0 / stdout).