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.
- checksums.yaml +4 -4
- data/.agents/skills/ci-monitoring/SKILL.md +103 -0
- data/.agents/skills/run-tests/SKILL.md +45 -0
- data/.claude/auto-fix.md +7 -0
- data/.claude/settings.local.json +21 -0
- data/AGENTS.md +46 -0
- data/CHANGELOG.md +93 -0
- data/README.md +159 -21
- data/docs/1.1.0_UPGRADE_GUIDE.md +269 -0
- data/docs/API/COMMON.md +7 -0
- data/docs/API/CONFIG_CHANGE.md +39 -0
- data/docs/API/CWD_CHANGED.md +34 -0
- data/docs/API/ELICITATION.md +44 -0
- data/docs/API/ELICITATION_RESULT.md +43 -0
- data/docs/API/FILE_CHANGED.md +37 -0
- data/docs/API/INSTRUCTIONS_LOADED.md +30 -0
- data/docs/API/MESSAGE_DISPLAY.md +38 -0
- data/docs/API/NOTIFICATION.md +1 -0
- data/docs/API/PERMISSION_DENIED.md +37 -0
- data/docs/API/PERMISSION_REQUEST.md +199 -0
- data/docs/API/POST_COMPACT.md +30 -0
- data/docs/API/POST_TOOL_BATCH.md +39 -0
- data/docs/API/POST_TOOL_USE.md +1 -0
- data/docs/API/POST_TOOL_USE_FAILURE.md +31 -0
- data/docs/API/PRE_COMPACT.md +10 -2
- data/docs/API/PRE_TOOL_USE.md +9 -1
- data/docs/API/SETUP.md +37 -0
- data/docs/API/STOP_FAILURE.md +19 -0
- data/docs/API/SUBAGENT_START.md +40 -0
- data/docs/API/TASK_COMPLETED.md +43 -0
- data/docs/API/TASK_CREATED.md +43 -0
- data/docs/API/TEAMMATE_IDLE.md +40 -0
- data/docs/API/USER_PROMPT_EXPANSION.md +43 -0
- data/docs/API/WORKTREE_CREATE.md +39 -0
- data/docs/API/WORKTREE_REMOVE.md +33 -0
- data/docs/PROMPT_BASED_HOOKS.md +386 -0
- data/docs/external/claude-hooks-reference.md +2846 -18
- data/docs/mitts/ideabox.md +12 -0
- data/docs/mitts/prd.md +417 -0
- data/docs/mitts/setup.md +303 -0
- data/docs/mitts/task.md +44 -0
- data/lib/claude_hooks/base.rb +30 -1
- data/lib/claude_hooks/config_change.rb +28 -0
- data/lib/claude_hooks/cwd_changed.rb +28 -0
- data/lib/claude_hooks/elicitation.rb +61 -0
- data/lib/claude_hooks/elicitation_result.rb +57 -0
- data/lib/claude_hooks/file_changed.rb +41 -0
- data/lib/claude_hooks/instructions_loaded.rb +23 -0
- data/lib/claude_hooks/message_display.rb +58 -0
- data/lib/claude_hooks/notification.rb +5 -1
- data/lib/claude_hooks/output/base.rb +48 -1
- data/lib/claude_hooks/output/config_change.rb +47 -0
- data/lib/claude_hooks/output/cwd_changed.rb +42 -0
- data/lib/claude_hooks/output/elicitation.rb +67 -0
- data/lib/claude_hooks/output/elicitation_result.rb +63 -0
- data/lib/claude_hooks/output/file_changed.rb +42 -0
- data/lib/claude_hooks/output/instructions_loaded.rb +19 -0
- data/lib/claude_hooks/output/message_display.rb +49 -0
- data/lib/claude_hooks/output/permission_denied.rb +42 -0
- data/lib/claude_hooks/output/permission_request.rb +120 -0
- data/lib/claude_hooks/output/post_compact.rb +18 -0
- data/lib/claude_hooks/output/post_tool_batch.rb +51 -0
- data/lib/claude_hooks/output/post_tool_use.rb +12 -0
- data/lib/claude_hooks/output/post_tool_use_failure.rb +42 -0
- data/lib/claude_hooks/output/pre_compact.rb +34 -3
- data/lib/claude_hooks/output/pre_tool_use.rb +26 -2
- data/lib/claude_hooks/output/session_start.rb +30 -8
- data/lib/claude_hooks/output/setup.rb +42 -0
- data/lib/claude_hooks/output/stop.rb +15 -0
- data/lib/claude_hooks/output/stop_failure.rb +19 -0
- data/lib/claude_hooks/output/subagent_start.rb +42 -0
- data/lib/claude_hooks/output/task_completed.rb +18 -0
- data/lib/claude_hooks/output/task_created.rb +18 -0
- data/lib/claude_hooks/output/teammate_idle.rb +18 -0
- data/lib/claude_hooks/output/user_prompt_expansion.rb +51 -0
- data/lib/claude_hooks/output/worktree_create.rb +60 -0
- data/lib/claude_hooks/output/worktree_remove.rb +19 -0
- data/lib/claude_hooks/permission_denied.rb +41 -0
- data/lib/claude_hooks/permission_request.rb +63 -0
- data/lib/claude_hooks/post_compact.rb +23 -0
- data/lib/claude_hooks/post_tool_batch.rb +59 -0
- data/lib/claude_hooks/post_tool_use.rb +15 -1
- data/lib/claude_hooks/post_tool_use_failure.rb +45 -0
- data/lib/claude_hooks/pre_compact.rb +7 -0
- data/lib/claude_hooks/pre_tool_use.rb +34 -1
- data/lib/claude_hooks/session_start.rb +28 -0
- data/lib/claude_hooks/setup.rb +25 -0
- data/lib/claude_hooks/stop.rb +17 -0
- data/lib/claude_hooks/stop_failure.rb +27 -0
- data/lib/claude_hooks/subagent_start.rb +23 -0
- data/lib/claude_hooks/subagent_stop.rb +5 -1
- data/lib/claude_hooks/task_completed.rb +35 -0
- data/lib/claude_hooks/task_created.rb +35 -0
- data/lib/claude_hooks/teammate_idle.rb +23 -0
- data/lib/claude_hooks/user_prompt_expansion.rb +45 -0
- data/lib/claude_hooks/version.rb +1 -1
- data/lib/claude_hooks/worktree_create.rb +27 -0
- data/lib/claude_hooks/worktree_remove.rb +19 -0
- data/lib/claude_hooks.rb +42 -0
- 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`.
|
data/docs/API/NOTIFICATION.md
CHANGED
|
@@ -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).
|