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,199 @@
1
+ # PermissionRequest API
2
+
3
+ Available when inheriting from `ClaudeHooks::PermissionRequest`:
4
+
5
+ ## Input Helpers
6
+ Input helpers to access the data provided by Claude Code through `STDIN`.
7
+
8
+ [📚 Shared input helpers](COMMON.md#input-helpers)
9
+
10
+ | Method | Description |
11
+ |--------|-------------|
12
+ | `tool_name` | Get the name of the tool requiring permission |
13
+ | `tool_input` | Get the input data for the tool |
14
+ | `tool_use_id` | Get the unique identifier for this tool use |
15
+
16
+ ## Hook State Helpers
17
+ Hook state methods are helpers to modify the hook's internal state (`output_data`) before yielding back to Claude Code.
18
+
19
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
20
+
21
+ | Method | Description |
22
+ |--------|-------------|
23
+ | `allow_permission!(reason = '')` | Allow the permission request with optional reason |
24
+ | `deny_permission!(reason = '', interrupt: nil)` | Deny the permission request with reason; pass `interrupt: true` to interrupt the current operation |
25
+ | `update_input_and_allow!(updated_input, reason = '', updated_permissions: nil)` | Update tool input and allow |
26
+
27
+ ## Output Helpers
28
+ Output helpers provide access to the hook's output data and helper methods for working with the output state.
29
+
30
+ [📚 Shared output helpers](COMMON.md#output-helpers)
31
+
32
+ | Method | Description |
33
+ |--------|-------------|
34
+ | `output.allowed?` | Check if permission has been allowed |
35
+ | `output.denied?` | Check if permission has been denied |
36
+ | `output.input_updated?` | Check if tool input has been updated |
37
+ | `output.permission_decision` | Get the permission decision: `'allow'` or `'deny'` (reads nested `decision.behavior`; falls back to legacy flat key) |
38
+ | `output.permission_reason` | Get the decision message (reads nested `decision.message`; falls back to legacy `permissionDecisionReason`) |
39
+ | `output.updated_input` | Get the updated input (reads nested `decision.updatedInput`; falls back to legacy flat key) |
40
+ | `output.behavior` | Get the raw `decision.behavior` value |
41
+ | `output.updated_permissions` | Get the `decision.updatedPermissions` array (if provided) |
42
+ | `output.interrupt?` | Check if `decision.interrupt` was set to true |
43
+
44
+ ## Hook Exit Codes
45
+
46
+ PermissionRequest hooks use the JSON API with exit code 0 for all permission decisions.
47
+
48
+ | Exit Code | Behavior |
49
+ |-----------|----------|
50
+ | `exit 0` | Permission decision processed<br/>`STDOUT` contains JSON with decision |
51
+ | `exit 1` | Non-blocking error<br/>`STDERR` shown to user |
52
+ | `exit 2` | **Not recommended for PermissionRequest**<br/>Use JSON API with exit 0 instead |
53
+
54
+ ## Example: Basic Permission Guard
55
+
56
+ ```ruby
57
+ #!/usr/bin/env ruby
58
+ require 'claude_hooks'
59
+
60
+ class PermissionGuard < ClaudeHooks::PermissionRequest
61
+ SENSITIVE_TOOLS = %w[rm git-push curl wget].freeze
62
+ SAFE_TOOLS = %w[ls cat grep find].freeze
63
+
64
+ def call
65
+ log "Permission requested for: #{tool_name}"
66
+ log "Tool use ID: #{tool_use_id}"
67
+ log "Permission mode: #{permission_mode}"
68
+
69
+ # Auto-allow safe tools
70
+ if SAFE_TOOLS.include?(tool_name)
71
+ allow_permission!("Safe tool, automatically allowed")
72
+ return output
73
+ end
74
+
75
+ # Block dangerous tools
76
+ if SENSITIVE_TOOLS.include?(tool_name)
77
+ deny_permission!("Dangerous tool #{tool_name} requires manual approval")
78
+ return output
79
+ end
80
+
81
+ # Default: allow with logging
82
+ allow_permission!("Tool allowed by default")
83
+ output
84
+ end
85
+ end
86
+
87
+ if __FILE__ == $PROGRAM_NAME
88
+ input_data = JSON.parse(STDIN.read)
89
+ hook = PermissionGuard.new(input_data)
90
+ hook.call
91
+ hook.output_and_exit
92
+ end
93
+ ```
94
+
95
+ ## Example: Permission Mode-Aware Guard
96
+
97
+ ```ruby
98
+ #!/usr/bin/env ruby
99
+ require 'claude_hooks'
100
+
101
+ class SmartPermissionGuard < ClaudeHooks::PermissionRequest
102
+ DANGEROUS_TOOLS = %w[rm git-reset curl wget].freeze
103
+
104
+ def call
105
+ log "Permission mode: #{permission_mode}"
106
+
107
+ # Block dangerous tools in bypass mode
108
+ if permission_mode == 'bypassPermissions' && dangerous_tool?
109
+ log "Blocking dangerous tool in bypass mode", level: :warn
110
+ deny_permission!("Cannot bypass permissions for dangerous tool: #{tool_name}")
111
+ return output
112
+ end
113
+
114
+ # Allow in 'dontAsk' mode if tool is not dangerous
115
+ if permission_mode == 'dontAsk' && !dangerous_tool?
116
+ allow_permission!("Auto-allowed in dontAsk mode")
117
+ return output
118
+ end
119
+
120
+ # Default behavior
121
+ allow_permission!("Permission granted")
122
+ output
123
+ end
124
+
125
+ private
126
+
127
+ def dangerous_tool?
128
+ DANGEROUS_TOOLS.include?(tool_name)
129
+ end
130
+ end
131
+ ```
132
+
133
+ ## Example: Input Modification
134
+
135
+ ```ruby
136
+ #!/usr/bin/env ruby
137
+ require 'claude_hooks'
138
+
139
+ class InputSanitizer < ClaudeHooks::PermissionRequest
140
+ def call
141
+ case tool_name
142
+ when 'Bash'
143
+ # Add safety flags to bash commands
144
+ if tool_input['command']&.include?('rm')
145
+ sanitized_input = tool_input.merge(
146
+ 'command' => tool_input['command'] + ' --interactive'
147
+ )
148
+ update_input_and_allow!(sanitized_input, "Added --interactive flag for safety")
149
+ else
150
+ allow_permission!("Bash command is safe")
151
+ end
152
+ when 'Write'
153
+ # Validate file paths before writing
154
+ if tool_input['file_path']&.start_with?('/tmp')
155
+ deny_permission!("Cannot write to /tmp directory")
156
+ else
157
+ allow_permission!("File write is safe")
158
+ end
159
+ else
160
+ allow_permission!("No special handling needed")
161
+ end
162
+
163
+ output
164
+ end
165
+ end
166
+ ```
167
+
168
+ ## Multiple Hooks Merging
169
+
170
+ When multiple PermissionRequest hooks are executed, their outputs merge with these rules:
171
+
172
+ - **Decision**: `deny` > `allow` (most restrictive wins)
173
+ - **Reasons**: All `decision.message` values are concatenated with `'; '`
174
+ - **Updated Input**: Last `decision.updatedInput` wins (most recent transformation)
175
+
176
+ ```ruby
177
+ # Hook 1
178
+ hook1.deny_permission!("Reason 1")
179
+
180
+ # Hook 2
181
+ hook2.allow_permission!("Reason 2")
182
+
183
+ # Merged result
184
+ merged = ClaudeHooks::Output::PermissionRequest.merge(
185
+ hook1.output,
186
+ hook2.output
187
+ )
188
+
189
+ merged.denied? # => true (deny wins)
190
+ merged.permission_reason # => "Reason 1; Reason 2"
191
+ ```
192
+
193
+ ## Notes
194
+
195
+ - PermissionRequest runs when Claude Code shows a permission dialog
196
+ - It can automatically allow or deny on behalf of the user
197
+ - Uses the same JSON API pattern as PreToolUse hooks
198
+ - Supports modifying tool inputs before execution
199
+ - Works with all permission modes: `default`, `plan`, `acceptEdits`, `auto`, `dontAsk`, `bypassPermissions`
@@ -0,0 +1,30 @@
1
+ # PostCompact API
2
+
3
+ Available when inheriting from `ClaudeHooks::PostCompact`:
4
+
5
+ Runs after transcript compaction completes. Non-blocking — use for logging or post-compaction side effects.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `trigger` | What triggered the compaction: `'auto'` or `'manual'` |
14
+ | `compact_summary` | The summary produced by the compaction |
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.
@@ -0,0 +1,39 @@
1
+ # PostToolBatch API
2
+
3
+ Available when inheriting from `ClaudeHooks::PostToolBatch`:
4
+
5
+ Runs after a full batch of tool calls completes. Can block Claude from continuing.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `tool_calls` | Array of tool call results; each entry has `tool_name`, `tool_input`, `tool_use_id`, `tool_response` |
14
+
15
+ ## Hook State Helpers
16
+
17
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
18
+
19
+ | Method | Description |
20
+ |--------|-------------|
21
+ | `block!(reason)` | Block Claude from continuing after this batch |
22
+ | `add_additional_context!(context)` | Add additional context visible to Claude |
23
+
24
+ ## Output Helpers
25
+
26
+ [📚 Shared output helpers](COMMON.md#output-helpers)
27
+
28
+ | Method | Description |
29
+ |--------|-------------|
30
+ | `output.blocked?` | Check if the batch 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` | Claude continues |
39
+ | `exit 2` | Blocks Claude; `STDERR` shown to Claude |
@@ -12,6 +12,7 @@ Input helpers to access the data provided by Claude Code through `STDIN`.
12
12
  | `tool_name` | Get the name of the tool that was used |
13
13
  | `tool_input` | Get the input that was passed to the tool |
14
14
  | `tool_response` | Get the tool's response/output |
15
+ | `tool_use_id` | Get the unique identifier for this tool use (e.g., `"toolu_01ABC123..."`) |
15
16
 
16
17
  ## Hook State Helpers
17
18
  Hook state methods are helpers to modify the hook's internal state (`output_data`) before yielding back to Claude Code.
@@ -0,0 +1,31 @@
1
+ # PostToolUseFailure API
2
+
3
+ Available when inheriting from `ClaudeHooks::PostToolUseFailure`:
4
+
5
+ Runs when a tool call fails. Non-blocking — output and exit code are ignored except for `additionalContext`.
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 that failed |
14
+ | `tool_input` | The input data for the tool |
15
+ | `tool_use_id` | The unique identifier for this tool use |
16
+ | `error` | The error message |
17
+ | `is_interrupt` | Whether the failure was caused by an interrupt (`true`/`false`) |
18
+ | `interrupt?` | Alias for `is_interrupt` |
19
+ | `duration_ms` | How long the tool ran before failing (milliseconds) |
20
+
21
+ ## Hook State Helpers
22
+
23
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
24
+
25
+ | Method | Description |
26
+ |--------|-------------|
27
+ | `add_additional_context!(context)` | Add additional context visible to Claude about the failure |
28
+
29
+ ## Hook Exit Codes
30
+
31
+ Non-blocking. Exit code and output are ignored by Claude Code; only `additionalContext` is consumed.
@@ -13,10 +13,13 @@ Input helpers to access the data provided by Claude Code through `STDIN`.
13
13
  | `custom_instructions` | Get custom instructions (only available for manual trigger) |
14
14
 
15
15
  ## Hook State Helpers
16
- No specific hook state methods are available to alter compaction behavior.
17
16
 
18
17
  [📚 Shared hook state methods](COMMON.md#hook-state-methods)
19
18
 
19
+ | Method | Description |
20
+ |--------|-------------|
21
+ | `block!(reason)` | Block the compaction with a reason (top-level `decision: 'block'`) |
22
+
20
23
  ## Utility Methods
21
24
  Utility methods for transcript management.
22
25
 
@@ -26,10 +29,15 @@ Utility methods for transcript management.
26
29
 
27
30
  ## Output Helpers
28
31
  Output helpers provide access to the hook's output data and helper methods for working with the output state.
29
- PreCompact hooks don't have any specific hook state and thus doesn't have any specific output helpers.
30
32
 
31
33
  [📚 Shared output helpers](COMMON.md#output-helpers)
32
34
 
35
+ | Method | Description |
36
+ |--------|-------------|
37
+ | `output.blocked?` | Check if the compaction was blocked |
38
+ | `output.decision` | Get the decision (`'block'` or nil) |
39
+ | `output.reason` | Get the block reason |
40
+
33
41
  ## Hook Exit Codes
34
42
 
35
43
  | Exit Code | Behavior |
@@ -11,6 +11,7 @@ Input helpers to access the data provided by Claude Code through `STDIN`.
11
11
  |--------|-------------|
12
12
  | `tool_name` | Get the name of the tool being used |
13
13
  | `tool_input` | Get the input data for the tool |
14
+ | `tool_use_id` | Get the unique identifier for this tool use (e.g., `"toolu_01ABC123..."`) |
14
15
 
15
16
  ## Hook State Helpers
16
17
  Hook state methods are helpers to modify the hook's internal state (`output_data`) before yielding back to Claude Code.
@@ -22,6 +23,10 @@ Hook state methods are helpers to modify the hook's internal state (`output_data
22
23
  | `approve_tool!(reason)` | Explicitly approve tool usage |
23
24
  | `block_tool!(reason)` | Block tool usage with feedback |
24
25
  | `ask_for_permission!(reason)` | Request user permission |
26
+ | `defer_permission!` | Defer the permission decision to a later hook in the chain |
27
+ | `update_tool_input!(updated_input)` | Update the tool input and automatically approve the tool (sets `permissionDecision` to `'allow'`) |
28
+ | `update_input!(updated_input)` | Update `updatedInput` without changing the permission decision |
29
+ | `add_additional_context!(context)` | Add additional context visible to Claude |
25
30
 
26
31
  ## Output Helpers
27
32
  Output helpers provide access to the hook's output data and helper methods for working with the output state.
@@ -33,9 +38,12 @@ Output helpers provide access to the hook's output data and helper methods for w
33
38
  | `output.allowed?` | Check if the tool has been explicitly allowed (permission_decision == 'allow') |
34
39
  | `output.denied?` | Check if the tool has been denied (permission_decision == 'deny') |
35
40
  | `output.blocked?` | Alias for `denied?` |
41
+ | `output.deferred?` | Check if the permission decision was deferred (permission_decision == 'defer') |
36
42
  | `output.should_ask_permission?` | Check if user permission is required (permission_decision == 'ask') |
37
- | `output.permission_decision` | Get the permission decision: 'allow', 'deny', or 'ask' |
43
+ | `output.input_updated?` | Check if tool input has been updated |
44
+ | `output.permission_decision` | Get the permission decision: `'allow'`, `'deny'`, `'ask'`, or `'defer'` |
38
45
  | `output.permission_reason` | Get the reason for the permission decision |
46
+ | `output.updated_input` | Get the updated input (if provided) |
39
47
 
40
48
  ## Hook Exit Codes
41
49
 
data/docs/API/SETUP.md ADDED
@@ -0,0 +1,37 @@
1
+ # Setup API
2
+
3
+ Available when inheriting from `ClaudeHooks::Setup`:
4
+
5
+ Runs once during Claude Code startup (before any session begins). Use it to inject global context or perform one-time initialization.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `source` | Startup reason: `'init'` (first launch) or `'maintenance'` |
14
+
15
+ ## Hook State Helpers
16
+
17
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
18
+
19
+ | Method | Description |
20
+ |--------|-------------|
21
+ | `add_additional_context!(context)` | Add contextual information for Claude |
22
+ | `add_context!(context)` | Alias for `add_additional_context!` |
23
+
24
+ ## Output Helpers
25
+
26
+ [📚 Shared output helpers](COMMON.md#output-helpers)
27
+
28
+ | Method | Description |
29
+ |--------|-------------|
30
+ | `output.additional_context` | Get the additional context that was added |
31
+
32
+ ## Hook Exit Codes
33
+
34
+ | Exit Code | Behavior |
35
+ |-----------|----------|
36
+ | `exit 0` | Continues normally; `STDOUT` added as context |
37
+ | `exit 2` | N/A — non-blocking event |
@@ -0,0 +1,19 @@
1
+ # StopFailure API
2
+
3
+ Available when inheriting from `ClaudeHooks::StopFailure`:
4
+
5
+ Runs when the stop phase itself errors. Purely a logging event — output and exit code are completely ignored by Claude Code.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `error` | The error message |
14
+ | `error_details` | Additional error detail (stack trace, etc.) |
15
+ | `last_assistant_message` | The last message Claude produced before the failure |
16
+
17
+ ## Hook Exit Codes
18
+
19
+ Exit code and all output are ignored. Use this hook only for logging or alerting.
@@ -0,0 +1,40 @@
1
+ # SubagentStart API
2
+
3
+ Available when inheriting from `ClaudeHooks::SubagentStart`:
4
+
5
+ Runs when a subagent task starts. Use it to inject context specific to the subagent or log the start.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ The `agent_id` and `agent_type` common fields are populated for this event.
12
+
13
+ | Method | Description |
14
+ |--------|-------------|
15
+ | `agent_id` | The subagent's unique ID |
16
+ | `agent_type` | The subagent's type |
17
+
18
+ ## Hook State Helpers
19
+
20
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
21
+
22
+ | Method | Description |
23
+ |--------|-------------|
24
+ | `add_additional_context!(context)` | Add contextual information for the subagent |
25
+ | `add_context!(context)` | Alias for `add_additional_context!` |
26
+
27
+ ## Output Helpers
28
+
29
+ [📚 Shared output helpers](COMMON.md#output-helpers)
30
+
31
+ | Method | Description |
32
+ |--------|-------------|
33
+ | `output.additional_context` | Get the additional context that was added |
34
+
35
+ ## Hook Exit Codes
36
+
37
+ | Exit Code | Behavior |
38
+ |-----------|----------|
39
+ | `exit 0` | Continues normally; `STDOUT` added as context |
40
+ | `exit 2` | N/A — non-blocking event |
@@ -0,0 +1,43 @@
1
+ # TaskCompleted API
2
+
3
+ Available when inheriting from `ClaudeHooks::TaskCompleted`:
4
+
5
+ Runs when a teammate task completes. Can block Claude from continuing via `prevent_continue!` or exit 2.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `task_id` | The unique task ID |
14
+ | `task_subject` | Short title of the task |
15
+ | `task_description` | Optional longer description |
16
+ | `teammate_name` | The teammate who completed the task |
17
+ | `team_name` | The team name |
18
+
19
+ ## Hook State Helpers
20
+
21
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
22
+
23
+ | Method | Description |
24
+ |--------|-------------|
25
+ | `prevent_continue!(reason)` | Block Claude from continuing (`continue: false` + `stopReason`) |
26
+
27
+ There is no top-level `decision` field for this event — block via `prevent_continue!` or exit 2.
28
+
29
+ ## Output Helpers
30
+
31
+ [📚 Shared output helpers](COMMON.md#output-helpers)
32
+
33
+ | Method | Description |
34
+ |--------|-------------|
35
+ | `output.continue?` | Whether Claude will continue |
36
+ | `output.stop_reason` | The reason Claude was stopped |
37
+
38
+ ## Hook Exit Codes
39
+
40
+ | Exit Code | Behavior |
41
+ |-----------|----------|
42
+ | `exit 0` | Claude continues |
43
+ | `exit 2` | Blocks Claude (`continue: false`) |
@@ -0,0 +1,43 @@
1
+ # TaskCreated API
2
+
3
+ Available when inheriting from `ClaudeHooks::TaskCreated`:
4
+
5
+ Runs when a teammate task is created. Can block Claude from continuing via `prevent_continue!` or exit 2.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `task_id` | The unique task ID |
14
+ | `task_subject` | Short title of the task |
15
+ | `task_description` | Optional longer description |
16
+ | `teammate_name` | The teammate assigned to the task |
17
+ | `team_name` | The team name |
18
+
19
+ ## Hook State Helpers
20
+
21
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
22
+
23
+ | Method | Description |
24
+ |--------|-------------|
25
+ | `prevent_continue!(reason)` | Block Claude from continuing (`continue: false` + `stopReason`) |
26
+
27
+ There is no top-level `decision` field for this event — block via `prevent_continue!` or exit 2.
28
+
29
+ ## Output Helpers
30
+
31
+ [📚 Shared output helpers](COMMON.md#output-helpers)
32
+
33
+ | Method | Description |
34
+ |--------|-------------|
35
+ | `output.continue?` | Whether Claude will continue |
36
+ | `output.stop_reason` | The reason Claude was stopped |
37
+
38
+ ## Hook Exit Codes
39
+
40
+ | Exit Code | Behavior |
41
+ |-----------|----------|
42
+ | `exit 0` | Claude continues |
43
+ | `exit 2` | Blocks Claude (`continue: false`) |
@@ -0,0 +1,40 @@
1
+ # TeammateIdle API
2
+
3
+ Available when inheriting from `ClaudeHooks::TeammateIdle`:
4
+
5
+ Runs when a teammate goes idle. Can block Claude from continuing via `prevent_continue!` or exit 2.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `teammate_name` | The name of the idle teammate |
14
+ | `team_name` | The team name |
15
+
16
+ ## Hook State Helpers
17
+
18
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
19
+
20
+ | Method | Description |
21
+ |--------|-------------|
22
+ | `prevent_continue!(reason)` | Block Claude from continuing (`continue: false` + `stopReason`) |
23
+
24
+ There is no top-level `decision` field for this event — block via `prevent_continue!` or exit 2.
25
+
26
+ ## Output Helpers
27
+
28
+ [📚 Shared output helpers](COMMON.md#output-helpers)
29
+
30
+ | Method | Description |
31
+ |--------|-------------|
32
+ | `output.continue?` | Whether Claude will continue |
33
+ | `output.stop_reason` | The reason Claude was stopped |
34
+
35
+ ## Hook Exit Codes
36
+
37
+ | Exit Code | Behavior |
38
+ |-----------|----------|
39
+ | `exit 0` | Claude continues |
40
+ | `exit 2` | Blocks Claude (`continue: false`) |
@@ -0,0 +1,43 @@
1
+ # UserPromptExpansion API
2
+
3
+ Available when inheriting from `ClaudeHooks::UserPromptExpansion`:
4
+
5
+ Runs when a slash command or other prompt-expansion mechanism is triggered. Can block the expansion.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `expansion_type` | Type of expansion (e.g. `'slash_command'`) |
14
+ | `command_name` | The command name (without the `/`) |
15
+ | `command_args` | The arguments passed to the command |
16
+ | `command_source` | Where the command was defined (`'user'`, `'project'`, etc.) |
17
+ | `prompt` | The expanded prompt text |
18
+
19
+ ## Hook State Helpers
20
+
21
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
22
+
23
+ | Method | Description |
24
+ |--------|-------------|
25
+ | `block!(reason)` | Block the expansion with a reason |
26
+ | `add_additional_context!(context)` | Add additional context visible to Claude |
27
+
28
+ ## Output Helpers
29
+
30
+ [📚 Shared output helpers](COMMON.md#output-helpers)
31
+
32
+ | Method | Description |
33
+ |--------|-------------|
34
+ | `output.blocked?` | Check if the expansion was blocked |
35
+ | `output.decision` | Get the decision (`'block'` or nil) |
36
+ | `output.reason` | Get the block reason |
37
+
38
+ ## Hook Exit Codes
39
+
40
+ | Exit Code | Behavior |
41
+ |-----------|----------|
42
+ | `exit 0` | Expansion proceeds |
43
+ | `exit 2` | Blocks the expansion; `STDERR` shown to Claude |
@@ -0,0 +1,39 @@
1
+ # WorktreeCreate API
2
+
3
+ Available when inheriting from `ClaudeHooks::WorktreeCreate`:
4
+
5
+ Runs when Claude Code is about to create a git worktree. **Special contract**: the hook must print the worktree path as the last non-empty line of stdout and exit 0. An empty or missing path is treated as failure.
6
+
7
+ ## Input Helpers
8
+
9
+ [📚 Shared input helpers](COMMON.md#input-helpers)
10
+
11
+ | Method | Description |
12
+ |--------|-------------|
13
+ | `name` | The slug/name for the worktree (e.g. `'feature-x'`) |
14
+
15
+ ## Hook State Helpers
16
+
17
+ [📚 Shared hook state methods](COMMON.md#hook-state-methods)
18
+
19
+ | Method | Description |
20
+ |--------|-------------|
21
+ | `worktree_path!(path)` | Set the path where the worktree will be created |
22
+
23
+ ## Output Helpers
24
+
25
+ [📚 Shared output helpers](COMMON.md#output-helpers)
26
+
27
+ | Method | Description |
28
+ |--------|-------------|
29
+ | `output.worktree_path` | Get the configured worktree path |
30
+
31
+ ## Hook Exit Codes
32
+
33
+ | Exit Code | Behavior |
34
+ |-----------|----------|
35
+ | `exit 0` (with path on stdout) | Worktree created at the printed path |
36
+ | `exit 1` / empty stdout | Creation fails |
37
+
38
+ > [!IMPORTANT]
39
+ > `output_and_exit` for WorktreeCreate prints the **bare path** (not JSON). Do not emit JSON for this hook type.